|
|
DataMuseum.dkPresents historical artifacts from the history of: Rational R1000/400 Tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Rational R1000/400 Tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: B T
Length: 26676 (0x6834)
Types: TextFile
Names: »B«
└─⟦a7d1ea751⟧ Bits:30000550 8mm tape, Rational 1000, !users!projects 94_04_11
└─⟦129cab021⟧ »DATA«
└─⟦this⟧
with Nodes;
with Lexical;
with Bounded_Strings;
with Gen_Stack;
with Error;
with Text_Io;
package body Symbol is
type Object (Length : Positive);
type Pobject is access Object;
type Symbols (A_Kind : Kind := None) is
record
Name : Lexical.Lexeme;
case A_Kind is
when Category =>
Actors : Pobject := null;
when Station =>
Sta_Type : Lexical.Lexeme; -- Un nom de categorie
Sta_Adress : Natural;
Sta_Category : Pobject :=
null; -- Ptr sur table des acteurs
when Actor =>
Act_Type : Types := T_Void;
Act_Number : Natural range 0 .. Actor_Table_Size - 1 := 0;
when Variable =>
Var_Type : Types := T_Void;
Var_Value : Integer := 0;
when Effect | Scene =>
Local_Table : Pobject := null;
Code : Nodes.Pnode := null;
when Begining =>
Beg_Code : Nodes.Pnode := null;
when Argument =>
Arg_Number : Positive := 1;
Arg_Value : Natural := 0; -- Un index dans la globale
when None =>
null;
end case;
end record;
type Psymbols is access Symbols; -- MUTABLE !!!
type Symbols_Array is array (Positive range <>) of Psymbols;
type Object (Length : Positive) is
record
The_Previous : Pobject;
The_Index : Natural;
The_Content : Symbols_Array (1 .. Length);
end record;
-- Pile des tables => profondeur d'appel de 20
package Table_Stack is new Gen_Stack (20, Pobject);
-- Variables du package symbol
Null_Lexeme : Lexical.Lexeme;
Number : Natural := 0;
Current_Table : Pobject := null; -- Table Courante (Active)
Global_Table : Pobject := null; -- Table Globale
Symbol_Table_Stack : Table_Stack.Object; -- Pile des tables
-- Fonctions de gestion locales
function Is_In_Table (The_Name : in Lexical.Lexeme; The_Table : in Pobject)
return Boolean is
begin
for I in 1 .. The_Table.The_Index loop
if Bounded_Strings.Is_Equal
(The_Table.The_Content (I).Name, The_Name) then
return True;
end if;
end loop;
return False;
end Is_In_Table;
function Is_Existing (The_Name : in Lexical.Lexeme) return Boolean is
Table_Pointer : Pobject;
begin
Table_Pointer := Current_Table;
while Table_Pointer /= null loop
if Is_In_Table (The_Name, Table_Pointer) then
return True;
end if;
Table_Pointer := Table_Pointer.The_Previous;
end loop;
return False;
end Is_Existing;
function Get_Index (From_Name : in Lexical.Lexeme; In_Table : in Pobject)
return Positive is
begin
for I in 1 .. In_Table.The_Index loop
if Bounded_Strings.Is_Equal
(In_Table.The_Content (I).Name, From_Name) then
return I;
end if;
end loop;
end Get_Index;
function Is_Arg_Number (The_Number : in Positive) return Boolean is
begin
for I in 1 .. Current_Table.The_Index loop
if (Current_Table.The_Content (I).A_Kind = Argument) then
if (Current_Table.The_Content (I).Arg_Number = The_Number) then
return True;
end if;
end if;
end loop;
return False;
end Is_Arg_Number;
-- Creation/Liberation
procedure New_Table (Length : in Positive) is
Table_Pointer : Pobject;
begin
Number := 0;
if (Current_Table = null) then
Current_Table := new Object (Length);
Current_Table.The_Previous := null;
Current_Table.The_Index := 0;
Global_Table :=
Current_Table; -- Init du pointeur sur la globale
else
Table_Pointer := new Object (Length);
Table_Pointer.The_Previous := Current_Table;
Table_Pointer.The_Index := 0;
case Current_Table.The_Content (Current_Table.The_Index).A_Kind is
when Category =>
-- On rattache la table des acteurs a la categorie correspondante
-- Suppose que la derniere entree dans la table a ete cette categorie
Current_Table.The_Content (Current_Table.The_Index).
Actors := Table_Pointer;
when Effect | Scene =>
-- On rattache la table locale a l'effet ou la scene correspondante
-- Suppose que la derniere entree dans la table a ete cet effet ou
-- cette scene !
Current_Table.The_Content (Current_Table.The_Index).
Local_Table := Table_Pointer;
when Station | Actor | Variable | Begining | Argument | None =>
null;
end case;
Current_Table := Table_Pointer;
end if;
end New_Table;
procedure Release_Table is
begin
if Current_Table /= Global_Table then
Current_Table := Global_Table;
end if;
end Release_Table;
procedure Init_Tables_Stack is
begin
Table_Stack.Push (Symbol_Table_Stack, Global_Table);
end Init_Tables_Stack;
procedure Set_Current_Table (Name : in Lexical.Lexeme) is
use Table_Stack;
Crt_Index : Positive;
begin
if not Is_In_Table (Name, Global_Table) then
Error.Handle (Bounded_Strings.Image (Name) &
" absent de la table !", Error.Internal);
else
if Is_Full (Symbol_Table_Stack) then
Error.Handle ("pile des tables pleine !", Error.Internal);
else
Crt_Index := Get_Index (Name, Global_Table);
Current_Table :=
Global_Table.The_Content (Crt_Index).Local_Table;
Push (Symbol_Table_Stack, Current_Table);
end if;
end if;
end Set_Current_Table;
procedure Reset_Current_Table is
use Table_Stack;
begin
if Is_Empty (Symbol_Table_Stack) then
Error.Handle ("pile des tables vide !", Error.Internal);
Current_Table := Global_Table;
Init_Tables_Stack;
else
Pop (Symbol_Table_Stack);
Current_Table := Get_Top (Symbol_Table_Stack);
end if;
end Reset_Current_Table;
-- Modification
procedure Add (The_Name : in Lexical.Lexeme; Of_Kind : in Kind) is
Table_Pointer : Pobject;
Crt_Index : Positive;
begin
if Current_Table.The_Index < Current_Table.Length then
if Is_Existing (The_Name) then
if Is_In_Table (The_Name, Global_Table) then
Table_Pointer := Global_Table;
else
Table_Pointer := Current_Table;
end if;
Crt_Index := Get_Index (The_Name, Table_Pointer);
if Table_Pointer.The_Content (Crt_Index).A_Kind /= Variable then
Error.Handle ("nom d'identificateur " &
Bounded_Strings.Image (The_Name) &
" deja utilise !", Error.External);
end if;
else
Current_Table.The_Index := Current_Table.The_Index + 1;
case Of_Kind is
when Category =>
Current_Table.The_Content (Current_Table.The_Index) :=
new Symbols'(A_Kind => Category,
Name => The_Name,
Actors => null);
when Station =>
Current_Table.The_Content (Current_Table.The_Index) :=
new Symbols'(A_Kind => Station,
Name => The_Name,
Sta_Type => Null_Lexeme,
Sta_Adress => 0,
Sta_Category => null);
when Actor =>
Current_Table.The_Content (Current_Table.The_Index) :=
new Symbols'(A_Kind => Actor,
Name => The_Name,
Act_Type => T_Error,
Act_Number => Number);
Number := Number + 1;
when Variable =>
Current_Table.The_Content (Current_Table.The_Index) :=
new Symbols'(A_Kind => Variable,
Name => The_Name,
Var_Type => T_Error,
Var_Value => 0);
when Effect =>
Current_Table.The_Content (Current_Table.The_Index) :=
new Symbols'(A_Kind => Effect,
Name => The_Name,
Local_Table => null,
Code => null);
when Scene =>
Current_Table.The_Content (Current_Table.The_Index) :=
new Symbols'(A_Kind => Scene,
Name => The_Name,
Local_Table => null,
Code => null);
when Begining =>
Current_Table.The_Content (Current_Table.The_Index) :=
new Symbols'(A_Kind => Begining,
Name => The_Name,
Beg_Code => null);
when Argument =>
Number := Number +
1; -- car Number init et raj a 0
Current_Table.The_Content (Current_Table.The_Index) :=
new Symbols'(A_Kind => Argument,
Name => The_Name,
Arg_Number => Number,
Arg_Value => 0);
when None =>
null;
end case;
end if;
else
Error.Handle ("table des symboles pleine !!", Error.Internal);
end if;
end Add;
procedure Set_Code (Name : in Lexical.Lexeme; The_Code : in Nodes.Pnode) is
Crt_Index : Positive;
begin
if not Is_In_Table (Name, Global_Table) then
Error.Handle ("symbole absent de la table globale !",
Error.Internal);
else
Crt_Index := Get_Index (Name, Global_Table);
case Global_Table.The_Content (Crt_Index).A_Kind is
when Effect | Scene =>
Global_Table.The_Content (Crt_Index).Code := The_Code;
when Begining =>
Global_Table.The_Content (Crt_Index).Beg_Code := The_Code;
when Category | Actor | Station | Variable | Argument | None =>
null;
end case;
end if;
end Set_Code;
procedure Set_Value (Name : in Lexical.Lexeme; The_Value : in Integer) is
Table_Pointer : Pobject;
Crt_Index : Positive;
begin
if not Is_Existing (Name) then
Error.Handle (Bounded_Strings.Image (Name) & " inexistant !",
Error.Internal);
else
if Is_In_Table (Name, Current_Table) then
Table_Pointer := Current_Table;
else
Table_Pointer := Global_Table;
end if;
Crt_Index := Get_Index (Name, Table_Pointer);
case Table_Pointer.The_Content (Crt_Index).A_Kind is
when Station =>
Table_Pointer.The_Content (Crt_Index).Sta_Adress :=
The_Value;
when Variable =>
Table_Pointer.The_Content (Crt_Index).Var_Value :=
The_Value;
when Category | Actor | Effect | Scene |
Argument | Begining | None =>
null;
end case;
end if;
end Set_Value;
procedure Set_Arg_Value (With_Value : in Lexical.Lexeme;
Arg_Number : in Positive) is
Crt_Index : Positive;
begin
if not Is_Arg_Number (Arg_Number) then
Error.Handle ("argument " & Integer'Image (Arg_Number) &
" inexistant !", Error.Internal);
else
if not Is_In_Table (With_Value, Global_Table) then
Error.Handle ("station " & Bounded_Strings.Image (With_Value) &
" inexistante !", Error.Internal);
else
Crt_Index := Get_Index (With_Value, Global_Table);
Current_Table.The_Content (Arg_Number).Arg_Value := Crt_Index;
end if;
end if;
end Set_Arg_Value;
procedure Set_Type (Name : in Lexical.Lexeme; The_Type : in Types) is
Crt_Index : Positive;
begin
if not Is_In_Table (Name, Current_Table) then
Error.Handle (Bounded_Strings.Image (Name) & " inexistant !",
Error.External);
else
Crt_Index := Get_Index (Name, Current_Table);
case Current_Table.The_Content (Crt_Index).A_Kind is
when Variable =>
Current_Table.The_Content (Crt_Index).Var_Type := The_Type;
when Actor =>
Current_Table.The_Content (Crt_Index).Act_Type := The_Type;
when Category | Station | Argument |
Effect | Scene | Begining | None =>
null;
end case;
end if;
end Set_Type;
procedure Set_Type (From_Station : in Lexical.Lexeme;
With_Category : in Lexical.Lexeme) is
Crt_Index : Positive;
begin
if not Is_In_Table (From_Station, Global_Table) then
Error.Handle ("station " & Bounded_Strings.Image (From_Station) &
" inexistante !", Error.Internal);
else
if not Is_In_Table (With_Category, Global_Table) then
Error.Handle ("categorie " &
Bounded_Strings.Image (With_Category) &
" inexistante !", Error.External);
else
Crt_Index := Get_Index (From_Station, Global_Table);
if (Global_Table.The_Content (Crt_Index).A_Kind = Station) then
Bounded_Strings.Affect
(Global_Table.The_Content (Crt_Index).Sta_Type,
With_Category);
Global_Table.The_Content (Crt_Index).Sta_Category :=
Global_Table.The_Content
(Get_Index (With_Category, Current_Table)).Actors;
else
null;
end if;
end if;
end if;
end Set_Type;
-- Consultation
function Get_Code (From_Name : in Lexical.Lexeme) return Nodes.Pnode is
Crt_Index : Positive;
begin
if not Is_In_Table (From_Name, Global_Table) then
Error.Handle
("code de " & Bounded_Strings.Image (From_Name) & " absent !",
Error.Internal);
return null;
else
Crt_Index := Get_Index (From_Name, Global_Table);
case Global_Table.The_Content (Crt_Index).A_Kind is
when Effect | Scene =>
return Global_Table.The_Content (Crt_Index).Code;
when Begining =>
return Global_Table.The_Content (Crt_Index).Beg_Code;
when Category | Actor | Station | Variable | Argument | None =>
return null;
end case;
end if;
end Get_Code;
function Get_Value (From_Name : in Lexical.Lexeme) return Integer is
Crt_Index : Positive;
Table_Pointer : Pobject;
begin
if not Is_Existing (From_Name) then
Error.Handle (Bounded_Strings.Image (From_Name) & " inexistant !",
Error.Internal);
return 0;
else
if Is_In_Table (From_Name, Current_Table) then
Table_Pointer := Current_Table;
else
Table_Pointer := Global_Table;
end if;
Crt_Index := Get_Index (From_Name, Table_Pointer);
case Table_Pointer.The_Content (Crt_Index).A_Kind is
when Station =>
return Table_Pointer.The_Content (Crt_Index).Sta_Adress;
when Variable =>
return Table_Pointer.The_Content (Crt_Index).Var_Value;
when Argument =>
Crt_Index :=
Table_Pointer.The_Content (Crt_Index).Arg_Value;
return Global_Table.The_Content (Crt_Index).Sta_Adress;
when Category | Actor | Effect | Scene | Begining | None =>
return 0;
end case;
end if;
end Get_Value;
function Get_Effectfiv_Arg_Name
(Formal_Param : in Lexical.Lexeme) return Lexical.Lexeme is
use Table_Stack;
My_Table : Pobject;
Crt_Index : Positive;
begin
if Is_In_Table (Formal_Param, Global_Table) then
return Formal_Param;
else
Pop (Symbol_Table_Stack);
My_Table := Get_Top (Symbol_Table_Stack);
end if;
if not Is_In_Table (Formal_Param, My_Table) then
Error.Handle ("argument " & Bounded_Strings.Image (Formal_Param) &
" inexistant !", Error.Internal);
Push (Symbol_Table_Stack, Current_Table);
return Null_Lexeme;
else
Crt_Index := Get_Index (Formal_Param, My_Table);
Crt_Index := My_Table.The_Content (Crt_Index).Arg_Value;
Push (Symbol_Table_Stack, Current_Table);
return Global_Table.The_Content (Crt_Index).Name;
end if;
end Get_Effectfiv_Arg_Name;
function Get_Sta_Actor
(In_Station : in Lexical.Lexeme; From_Actor : in Lexical.Lexeme)
return Integer is
Crt_Index : Positive;
Table_Pointer : Pobject;
begin
if not Is_In_Table (In_Station, Global_Table) then
Error.Handle ("station " & Bounded_Strings.Image (In_Station) &
" inexistante !", Error.Internal);
return 0;
else
Crt_Index := Get_Index (In_Station, Global_Table);
Table_Pointer := Global_Table.The_Content (Crt_Index).Sta_Category;
if not Is_In_Table (From_Actor, Table_Pointer) then
Error.Handle ("acteur " & Bounded_Strings.Image (From_Actor) &
" inexistant !", Error.Internal);
return 0;
else
Crt_Index := Get_Index (From_Actor, Table_Pointer);
return Table_Pointer.The_Content (Crt_Index).Act_Number;
end if;
end if;
end Get_Sta_Actor;
function Get_Arg_Actor
(In_Station : in Lexical.Lexeme; From_Actor : in Lexical.Lexeme)
return Integer is
Crt_Index : Positive;
Table_Pointer : Pobject;
begin
Crt_Index := Get_Index (In_Station, Current_Table);
Crt_Index := Current_Table.The_Content (Crt_Index).Arg_Value;
Table_Pointer := Global_Table.The_Content (Crt_Index).Sta_Category;
if not Is_In_Table (From_Actor, Table_Pointer) then
Error.Handle ("acteur " & Bounded_Strings.Image (From_Actor) &
" inexistant !", Error.Internal);
return 0;
else
Crt_Index := Get_Index (From_Actor, Table_Pointer);
return Table_Pointer.The_Content (Crt_Index).Act_Number;
end if;
end Get_Arg_Actor;
function Get_Actor_Number
(In_Station : in Lexical.Lexeme; From_Actor : in Lexical.Lexeme)
return Integer is
Crt_Index : Positive;
Table_Pointer : Pobject;
begin
if not Is_In_Table (In_Station, Current_Table) then
Table_Pointer := Global_Table;
else
Table_Pointer := Current_Table;
end if;
Crt_Index := Get_Index (In_Station, Table_Pointer);
if (Table_Pointer.The_Content (Crt_Index).A_Kind = Argument) then
return Get_Arg_Actor (In_Station, From_Actor);
else
return Get_Sta_Actor (In_Station, From_Actor);
end if;
end Get_Actor_Number;
function Get_Type (From_Name : in Lexical.Lexeme) return Types is
Crt_Index : Positive;
Table_Pointer : Pobject;
begin
if not Is_Existing (From_Name) then
Error.Handle (Bounded_Strings.Image (From_Name) & " inexistant !",
Error.Internal);
return T_Error;
else
if Is_In_Table (From_Name, Current_Table) then
Table_Pointer := Current_Table;
else
Table_Pointer := Global_Table;
end if;
Crt_Index := Get_Index (From_Name, Table_Pointer);
case Table_Pointer.The_Content (Crt_Index).A_Kind is
when Category =>
return T_Category;
when Station =>
return T_Station;
when Variable =>
return Current_Table.The_Content (Crt_Index).Var_Type;
when Effect =>
return T_Effect;
when Scene =>
return T_Scene;
when Begining =>
return T_Begining;
when Argument =>
return Get_Type (Global_Table.The_Content
(Table_Pointer.The_Content (Crt_Index).
Arg_Value).Name);
when Actor | None =>
return T_Error;
end case;
end if;
end Get_Type;
function Get_Type
(In_Station : in Lexical.Lexeme; From_Actor : in Lexical.Lexeme)
return Types is
Crt_Index : Positive;
Table_Pointer : Pobject;
begin
if not Is_In_Table (In_Station, Global_Table) then
Error.Handle ("station " & Bounded_Strings.Image (From_Actor) &
" inexistante !", Error.External);
return T_Error;
else
Crt_Index := Get_Index (In_Station, Global_Table);
Table_Pointer := Global_Table.The_Content (Crt_Index).Actors;
if not Is_In_Table (From_Actor, Table_Pointer) then
Error.Handle ("acteur " & Bounded_Strings.Image (From_Actor) &
"inexistant pour cette station !",
Error.External);
return T_Error;
else
Crt_Index := Get_Index (From_Actor, Table_Pointer);
return Table_Pointer.The_Content (Crt_Index).Act_Type;
end if;
end if;
end Get_Type;
-- Tests
procedure Print_Recur (P : in Pobject) is
use Text_Io;
Done : Boolean := False;
I : Natural;
Index : Natural;
begin
I := 1;
Put_Line ("Debut-------------");
while ((P /= null) and then (not Done)) loop
Put (Integer'Image (I) & " ");
Put (Bounded_Strings.Image (P.The_Content (I).Name) & " ");
case P.The_Content (I).A_Kind is
when Category =>
Put_Line ("CAT");
Print_Recur (P.The_Content (I).Actors);
when Station =>
Put (Bounded_Strings.Image (P.The_Content (I).Sta_Type));
Put_Line (Integer'Image (P.The_Content (I).Sta_Adress));
-- Print_Recur (P.The_Content(I).Sta_Category);
when Actor =>
Put ("ACT ");
Put_Line (Integer'Image (P.The_Content (I).Act_Number));
when Variable =>
Put ("VAR = ");
Put_Line (Integer'Image (Get_Value
(P.The_Content (I).Name)));
when Effect =>
Put_Line ("EFF");
Current_Table := P.The_Content (I).Local_Table;
Print_Recur (Current_Table);
Release_Table;
when Scene =>
Put_Line ("SCE");
Current_Table := P.The_Content (I).Local_Table;
Print_Recur (Current_Table);
Release_Table;
when Argument =>
Put ("ARG");
Put (Integer'Image (P.The_Content (I).Arg_Number) & " : ");
Index := P.The_Content (I).Arg_Value;
if Index /= 0 then
Put (Bounded_Strings.Image
(Global_Table.The_Content (Index).Name));
Put_Line (Integer'Image (Get_Value
(P.The_Content (I).Name)));
else
Put_Line ("0");
end if;
when Begining =>
Put_Line ("BEG");
when None =>
null;
end case;
if I >= P.The_Index then
Done := True;
else
I := I + 1;
end if;
end loop;
Put_Line ("Fin--------------");
end Print_Recur;
procedure Print is
begin
Print_Recur (Current_Table);
end Print;
end Symbol;