All pastes #460989 Raw Edit

Untitled

public text v1 · immutable
#460989 ·published 2007-04-27 13:15 UTC
rendered paste body
  -----
  -- Macro Pre-Processor package
  --
  -- Handles all of our Macro Pre-Processor functionality.
  --
  -- @access Public
  -----
  Package Body Macro is
  
    -- Holds the pointer to the head of the Macro Table.
    Head : Pointer_Macro_Table := Null;

    -- Holds current number value for the next system label.
    System_Label_Number : Integer := 0;

    -----
    -- Is Macro
    --
    -- Returns true if the macro name is a defined macro table.
    --
    -- @access Public
    -----
    Function Is_Macro (Macro_Name : String) Return Boolean is

      Scan : Pointer_Macro_Table := Head;

    Begin

      Loop

        If Scan.Name = Macro_Name Then

          Return True;

        End If;

        Exit When Scan.Next = null;

        Scan := Scan.Next;

      End Loop;

      Return False;

    End Is_Macro;

    -----
    -- Get Macro Table
    --
    -- This will search the macro table list and pull the macro table out for our macro name.
    --
    -- @access Private
    -----
    Function Get_Macro_Table (Macro_Name : String) Return Macro_Table is

      Scan : Pointer_Macro_Table := Head;
      Result : Macro_Table;

    Begin

      Result.Name := nus;
      Result.Formal := nus;
      Result.Lines(0) := nus;
      Result.Next := null;

      Loop

        If Scan.Name = Macro_Name Then

          Result.Name := Scan.Name;
          Result.Formal := Scan.Formal;
          Result.Lines := Scan.Lines;
          Result.Next := null;

        End If;

        Exit When Scan.Next = null;

        Scan := Scan.Next;

      End Loop;

      Return Result;

    End Get_Macro_Table;

    -----
    -- Get Next Parameter
    --
    -- This is used to parse out the next parameter in the parameter list.
    --
    -- @access Private
    -----
    Function Get_Next_Parameter (Parameter_List : String) Return String is

      Head, Index : Integer := Parameter_List'First;
      Tail : Integer := Parameter_List'Last;

    Begin

      Loop

        Exit When Parameter_List(Index) = ',' or Index = Tail;

        Index := Index + 1;

      End Loop;

      Return Parameter_List(Head..Index);

    End Get_Next_Parameter;
    Pragma Inline (Get_Next_Parameter);

    -----
    -- Tokenize Macro
    --
    -- This procedure will take the given macro name and tokenize it for future parameter replacement.
    --
    -- @access Private
    -----
    Function Tokenize (Line : String; Parameter_List : String) Return String is

      Function Get_Next_Word (Line : String; Index : Integer) Return String is

        Current : Integer := Index;
        Result : Ada.Strings.Unbounded.Unbounded_String := Ada.Strings.Unbounded.Null_Unbounded_String;

      Begin

        Skip_White_Space(Line, Current);

        While Line(Current) /= ' ' or Line(Current) /= Character'Val(9) Loop

          Ada.Strings.Unbounded.Append(Result, Line(Current));

        End Loop;

        Return Ada.Strings.Unbounded.To_String(Result);

      End Get_Next_Word;

      Prev, Index : Integer := Line'First;
      Tail        : Integer := Line'Last;
      Quit        : Boolean := False;
      Result      : Ada.Strings.Unbounded.Unbounded_String := Ada.Strings.Unbounded.Null_Unbounded_String;

    Begin

      While Index /= Tail Loop

        Declare

          Word    : String := Get_Next_Word(Line(Index..Tail), Index);
          Current : Integer := Parameter_List'First;

        Begin

          While Not Quit Loop

            Declare

              Parameter : String := Get_Next_Parameter(Parameter_List(Current..Parameter_List'Last));

            Begin

              If Parameter /= "" Then

                If Parameter(Parameter'First) = '%' And Then Word = Parameter(Parameter'First + 1 .. Parameter'Last) Then

                  Declare
                    System_Number : String := Integer'Image(System_Label_Number);
                  Begin
                    Ada.Strings.Unbounded.Append(Result, "SystemLabel" & System_Number(System_Number'First + 1 .. System_Number'Last) & ":");
                  End;
                  System_Label_Number := System_Label_Number + 1;

                Elsif Word(Word'First .. Word'Last - 1) = Parameter Then
                  
                  Ada.Strings.Unbounded.Append(Result, Token & Word);

                Else

                  Ada.Strings.Unbounded.Append(Result, Word);

                End If;

              Else

                Quit := True;

              End If;

              Current := Current + Parameter'Length + 1;

            End;

          End Loop;

        End;

        For Space in Prev .. Index Loop

          Ada.Strings.Unbounded.Append(Result, " ");

        End Loop;

        Prev := Index;

      End Loop;

      Return Ada.Strings.Unbounded.To_String(Result);

    End Tokenize;

    -----
    -- Append
    --
    -- Append a new macro to the macro table.
    --
    -- @access Private
    -----
    Procedure Append (Macro_Start : Integer; Macro_End : Integer; File_Handle : Ada.Text_IO.File_Type) is

      Type Line_Array is Array (Macro_Start .. Macro_End) of Line;
      Line_Data   : Line_Array;
      Index       : Integer := Macro_Start + 1;
      Temp_Table  : Macro_Table;
      Line_Number : Integer := 1;

    Begin

      -- Skip to the beginning of the line we are wanting.
      Ada.Text_IO.Flush(File_Handle);
      For LN in 1 .. (Macro_Start - 1) Loop
        Ada.Text_IO.Skip_Line(File_Handle);
      End Loop;

      Line_Data(Macro_Start) := Parse(Ada.Text_IO.Get_Line(File_Handle));

      For Line_Number in (Macro_Start + 1) .. (Macro_End + 1) Loop

        Line_Data(Index) := Parse(Ada.Text_IO.Get_Line(File_Handle));
        Temp_Table.Lines(Line_Number) := Ada.Strings.Unbounded.To_Unbounded_String(Tokenize(
          Ada.Strings.Unbounded.To_String(Line_Data(Line_Number).Label) & " " & 
          Ada.Strings.Unbounded.To_String(Line_Data(Line_Number).Opcode) & " " & 
          Ada.Strings.Unbounded.To_String(Line_Data(Line_Number).Operand), 
          Ada.Strings.Unbounded.To_String(Line_Data(Line_Number).Operand)));

        -- Debug Line
        Ada.Text_IO.Put_Line(Ada.Strings.Unbounded.To_String(Temp_Table.Lines(Line_Number)));

      End Loop;

      Temp_Table.Formal := Line_Data(Macro_Start).Operand;
      Temp_Table.Name   := Line_Data(Macro_Start).Label;

      -- Create new table and append to the macro table.

    End Append;

    -----
    -- Macro Expander
    --
    -- Expand our Macros
    --
    -- @access Public
    -----
    Procedure Expand (Macro_Name : String; Actual : String; File_Handle : Ada.Text_IO.File_Type) is

      Index : Integer := Macro_Name'First;
      Tail  : Integer := Macro_Name'Last;

    Begin
        
      Loop

        Exit When Index >= Tail;

        Declare
          Temp : String := Get_Next_Parameter(Macro_Name(Index..Tail));
        Begin
          Index := Index + Temp'Length;
          If Index < Tail Then
            Ada.Text_IO.Put_Line(Temp(Temp'First..(Temp'Last - 1)));
          Else
            Ada.Text_IO.Put_Line(Temp);
          End If;
        End;

      End Loop;

    End Expand;

  End Macro;