----- -- 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;