1

Very new with Ada, this is my first time coding with it. Very lost. Any tips, and direction would be great.

Ada question:

I am trying to make: the function Top (S : Stack) return Item_Type, which returns the top item on the stack or raises the Underflow exception, to the generic unbounded stack package.

The function I added for this is at the bottom of this code block. Current errors: invalid use of subtype mark in expression or call actual for "From" must be a variable invalid use of subtype mark in expression or call

package body Unbound_Stack is

   type Cell is record
      Item : Item_Type;
      Next : Stack;
   end record;

   procedure Push (Item : in Item_Type; Onto : in out Stack) is
   begin
      Onto := new Cell'(Item => Item, Next => Onto);  -- '
   end Push;


   procedure Pop (Item : out Item_Type; From : in out Stack) is
   begin
      if Is_Empty(From) then
         raise Underflow;
      else
         Item := From.Item;
         From := From.Next;
      end if;
   end Pop;

   function Is_Empty (S : Stack) return Boolean is
   begin
      return S = null;
   end Is_Empty;

   --added this code, and then had errors!

   function Top (S : Stack) return Item_Type is
   begin
      --Raise the underflow
      if Is_Empty(S) then
         raise Underflow;
      else
         --or return top item from the stack, call pop
         Pop (Item_Type, from => S);--I think I should pull from the stack w/pop
      end if;

      return Item_Type;
   end Top;

end Unbound_Stack;
Jacob Sparre Andersen
  • 6,733
  • 17
  • 22
theSpleen
  • 13
  • 3

2 Answers2

1

You have two error messages referring to this line:

   Pop (Item_Type, from => S);--I think I should pull from the stack w/pop

The first one is pointing at Item_Type and says "invalid use of subtype mark in expression or call".

  • This means that you are using the name of a type in a place where that isn't allowed. Actual parameters to subprograms can never be types. You need to use (depending on the parameter direction) a variable or an expression for the actual parameter.
Jacob Sparre Andersen
  • 6,733
  • 17
  • 22
  • Thanks, but I am still unsure. I am used to c++, is there a c++ equivalent to this error that might help me better understand what I am doing wrong? – theSpleen Nov 03 '17 at 06:30
  • I don't know any C++ error messages. Try to declare a variable of type `Item_Type`, and pass the variable to `Pop` (as Simon also writes in his answer). – Jacob Sparre Andersen Nov 03 '17 at 09:24
1

You're passing in a type (Item_Type) into Pop. Instead you need to declare a variable of type Item_Type and use that.

e.g.

function Top (S : Stack) return Item_Type is

   Popped_Item : Item_Type;

begin
   ...

and then the call to Pop becomes:

   Pop (Item => Popped_Item, From => S)
Simon Wright
  • 25,108
  • 2
  • 35
  • 62
Leigh
  • 188
  • 2
  • 13
  • Wow, thanks so much. This explained a lot. However, now I have the issue of "Actual for "From" must be a variable" But that confuses me more, because I thought it was a getting a variable S, type Stack... New image: https://imgur.com/a/yFMFv – theSpleen Nov 03 '17 at 07:20
  • The problem is that Top is a function so S is an in parameter (basically read-only). So you can't use it in Pop as that writes a value out to From. If you create a new variable of type Stack and pass that in you will see the error disappear. – Leigh Nov 03 '17 at 07:58
  • You say `function Top (S : Stack) ...` which means that, within `Top`, `S` is read-only (not variable, so not "a variable"). The latest standard (Ada 2012) allows functions to have in-out parameters (`function Top (S : in out Stack) ...`). – Simon Wright Nov 03 '17 at 08:06
  • `function Top (S : Stack) ...` is equivalent to `function Top (S : in Stack) ...`, which effectively declares `S` as a local *constant* inside `Top`. – Jacob Sparre Andersen Nov 03 '17 at 09:26