2011-02-22

Using the Bounded Stack

Here I'll use the Bounded_Stack module to output a program's input in reverse order.

use Bounded_Stack;
use NINA.IO.Text;

Reverse_Input : procedure body is
   type V_String (Length : General_Count_Value <- 0) is record
      Value : String (Length) <- String'(others => NUL);
   end V_String;

   "\" : function (Value : in String) return V_String;
   -- Converts Value to a V_String.

   module String_Stack is new Bounded_Stack (Element => V_String);

   "\" : function body (Value : in String) return V_String is
      null;
   "\" : begin
      return V_String'(Length => Value'Length, Value => Value);
   "\" : exception
   when others =>
      raise;
   "\" : end;

   Stack : String_Stack.Stack (Max_Size => 100);
Reverse_Input : begin
   Get_Input : loop
      exit Get_Input when NINA.IO.Text.End_Of_File or Stack.Is_Full;

      Stack.Push (Item => \NINA.IO.Text.Get_Line);
   Get_Input : end loop;

   if Stack.Is_Full then
      NINA.IO.Text.Put_Line (Item => "Too much input.");
   end if;

   Output : loop
      exit Output when Stack.Is_Empty;

      NINA.IO.Text.Put_Line (Item => Stack.Pop.Value);
   Output : end loop;
Reverse_Input : exception
when others =>
   null;
Reverse_Input : end;

Reverse_Input is an example of a main-program procedure body. Main-program procedure bodies are the only subprogram bodies that do not complete a subprogram specification, and the only subprograms at the library level.

"use" is NINA's equivalent of Ada's "with"; NINA has no equivalent of Ada's "use".

In Ada, a type like V_String might allocate enough space for the largest value, but two rules in NINA prevent this. First, a type like V_String is required to only allocate enough space for its current value (plus some small overhead). Second, objects that don't fit on the stack are required to be allocated on the heap. Between these two rules, a type like V_String works perfectly well in NINA, and is pretty much all that is needed for an unbounded string type.

Aggregates are required to be qualified.

"NUL" is the enumeration literal of Character'First.

"\" is a unary operator that exists for conversions. It was chosen to confuse people who like the C-family of languages.

The predefined type String is a half-constrained array type; the lower bound is constrained to 1, while the upper bound must be defined for each String object:

type String is array (General_Index_Value range 1 .. <>) : Character;

The rest should be fairly straightforward. Subprograms are required to have an exception handler with a "when others =>" part. Declarative parts are required to have at least one declaration; "null;" is an acceptable declaration if no others are needed.

No comments:

Post a Comment

Blog Archive