Save global symbols in the symbol table

This commit is contained in:
2026-04-17 22:37:37 +02:00
parent 5fbf413498
commit f3ddf0d671

View File

@@ -317,6 +317,7 @@ type
end;
ElnaSymbolTable = record
count: Word;
parent: Word;
symbols: ^ElnaSymbolEntry
end;
ElnaSymbolInfoKind = (type_info, parameter_info, temporary_info, procedure_info);
@@ -659,6 +660,7 @@ type
var
symbol_table_global: ^ElnaSymbolTable;
variable_map_global: ^ElnaSymbolTable;
compiler_strings: [1024]Word;
classification: [256]Word;
@@ -928,7 +930,7 @@ begin
elna_list_append(instructions, instruction)
elsif operand^.kind = ElnaTacKind.variable then
pseudo_symbol := elna_symbol_table_lookup(variable_map, operand^.value, operand^.length);
if pseudo_symbol = nil then
if pseudo_symbol^.kind = ElnaRtlInfoKind.static_info then
instruction := elna_rtl_instruction_create(ElnaRtlOperator.la);
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, into, 0, 0);
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.data, operand^.value, operand^.length, 0);
@@ -963,7 +965,7 @@ begin
elna_list_append(instructions, instruction)
elsif tac_operand^.kind = ElnaTacKind.variable then
pseudo_symbol := elna_symbol_table_lookup(variable_map, tac_operand^.value, tac_operand^.length);
if pseudo_symbol = nil then
if pseudo_symbol^.kind = ElnaRtlInfoKind.static_info then
elna_rtl_generate_pseudo(rtl_operand, variable_map);
instruction := elna_rtl_instruction_create(ElnaRtlOperator.la);
@@ -1104,9 +1106,14 @@ begin
elna_rtl_instruction_set_operand(instruction, 1, target_operand^.kind,
target_operand^.value, target_operand^.length, 0);
(* "strings" variable with static strings is in the end object and should be addressable,
but not in the symbol table. *)
if pseudo_symbol = nil then
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.data,
addressable^.value, addressable^.length, 0)
elsif pseudo_symbol^.kind = ElnaRtlInfoKind.static_info then
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.data,
addressable^.value, addressable^.length, 0)
elsif pseudo_symbol^.rtl_type^.kind = ElnaRtlTypeKind.byte_array then
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo_mem,
addressable^.value, addressable^.length, 0)
@@ -1272,7 +1279,7 @@ begin
pseudo_symbol := elna_symbol_table_lookup(variable_map,
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length);
if pseudo_symbol = nil then
if pseudo_symbol^.kind = ElnaRtlInfoKind.static_info then
elna_rtl_generate_pseudo(@target_operand, variable_map);
instruction := elna_rtl_instruction_create(ElnaRtlOperator.la);
@@ -1933,9 +1940,40 @@ end;
proc elna_rtl_module_declaration(tac_module: ^ElnaInstructionModule) -> ^ElnaInstructionModule;
var
result: ^ElnaInstructionModule;
count: Word;
current_entry: ^ElnaSymbolEntry;
pseudo_symbol: ^ElnaRtlStaticInfo;
variable_info: ^ElnaSymbolTemporaryInfo;
info: ^ElnaSymbolInfo;
begin
result := malloc(#size(ElnaInstructionModule));
result^.data := elna_rtl_globals(tac_module^.data);
(* Rewrite global symbol table into global backend symbol table. *)
variable_map_global := elna_symbol_table_create(nil);
count := symbol_table_global^.count;
current_entry := symbol_table_global^.symbols;
.elna_rtl_module_declaration_loop;
if count = 0 then
goto elna_rtl_module_declaration_end
end;
info := current_entry^.symbol_info;
if info^.kind = ElnaSymbolInfoKind.temporary_info then
variable_info := current_entry^.symbol_info;
pseudo_symbol := malloc(#size(ElnaRtlStaticInfo));
pseudo_symbol^.kind := ElnaRtlInfoKind.static_info;
pseudo_symbol^.rtl_type := elna_rtl_symbol_type(variable_info^.variable_type);
elna_symbol_table_enter(variable_map_global, current_entry^.name, current_entry^.length, pseudo_symbol)
end;
count := count - 1;
current_entry := current_entry + 1;
goto elna_rtl_module_declaration_loop;
.elna_rtl_module_declaration_end;
result^.code := elna_rtl_procedures(tac_module^.code);
return result
@@ -3846,54 +3884,35 @@ begin
return pseudo_symbol
end;
proc elna_rtl_symbol_table(symbol_table: ^ElnaSymbolTable) -> ^ElnaSymbolTable;
proc elna_rtl_symbol_type(variable_type: ^ElnaType);
var
variable_map: ^ElnaSymbolTable;
count: Word;
current_entry: ^ElnaSymbolEntry;
pseudo_symbol: ^ElnaRtlObjectInfo;
variable_info: ^ElnaSymbolTemporaryInfo;
byte_array: ^ElnaRtlTypeByteArray;
long_word: ^ElnaRtlTypeWord;
rtl_type: ^ElnaRtlType;
begin
variable_map := elna_symbol_table_create();
count := symbol_table^.count;
current_entry := symbol_table^.symbols;
if elna_type_is_aggregate(variable_type) then
byte_array := malloc(#size(ElnaRtlTypeByteArray));
byte_array^.kind := ElnaRtlTypeKind.byte_array;
byte_array^.size := variable_type^.size;
byte_array^.alignment := variable_type^.alignment;
.elna_rtl_symbol_table_loop;
if count > 0 then
variable_info := current_entry^.symbol_info;
rtl_type := byte_array
else
long_word := malloc(#size(ElnaRtlTypeWord));
long_word^.kind := ElnaRtlTypeKind.long_word;
pseudo_symbol := malloc(#size(ElnaRtlObjectInfo));
pseudo_symbol^.allocated := false;
pseudo_symbol^.kind := ElnaRtlInfoKind.object_info;
if elna_type_is_aggregate(variable_info^.variable_type) then
byte_array := malloc(#size(ElnaRtlTypeByteArray));
byte_array^.kind := ElnaRtlTypeKind.byte_array;
byte_array^.size := variable_info^.variable_type^.size;
byte_array^.alignment := variable_info^.variable_type^.alignment;
pseudo_symbol^.rtl_type := byte_array
else
long_word := malloc(#size(ElnaRtlTypeWord));
long_word^.kind := ElnaRtlTypeKind.long_word;
pseudo_symbol^.rtl_type := long_word
end;
elna_symbol_table_enter(variable_map, current_entry^.name, current_entry^.length, pseudo_symbol);
count := count - 1;
current_entry := current_entry + 1;
goto elna_rtl_symbol_table_loop
rtl_type := long_word
end;
return variable_map;
return rtl_type
end;
proc elna_rtl_procedure_declaration(tac_declaration: ^ElnaTacProcedure) -> ^ElnaRtlProcedure;
var
count: Word;
current_entry: ^ElnaSymbolEntry;
pseudo_symbol: ^ElnaRtlObjectInfo;
variable_info: ^ElnaSymbolTemporaryInfo;
info: ^ElnaSymbolInfo;
result: ^ElnaRtlProcedure;
begin
result := malloc(#size(ElnaRtlProcedure));
@@ -3906,7 +3925,32 @@ begin
pseudo_counter := 0;
elna_rtl_parameters(@result^.body, tac_declaration^.parameters, tac_declaration^.count);
result^.variable_map := elna_rtl_symbol_table(tac_declaration^.symbol_table);
result^.variable_map := elna_symbol_table_create(variable_map_global);
count := tac_declaration^.symbol_table^.count;
current_entry := tac_declaration^.symbol_table^.symbols;
.elna_rtl_procedure_declaration_loop;
if count = 0 then
goto elna_rtl_procedure_declaration_end
end;
info := current_entry^.symbol_info;
if info^.kind = ElnaSymbolInfoKind.temporary_info then
variable_info := current_entry^.symbol_info;
pseudo_symbol := malloc(#size(ElnaRtlObjectInfo));
pseudo_symbol^.allocated := false;
pseudo_symbol^.kind := ElnaRtlInfoKind.object_info;
pseudo_symbol^.rtl_type := elna_rtl_symbol_type(variable_info^.variable_type);
elna_symbol_table_enter(result^.variable_map, current_entry^.name, current_entry^.length, pseudo_symbol)
end;
count := count - 1;
current_entry := current_entry + 1;
goto elna_rtl_procedure_declaration_loop;
.elna_rtl_procedure_declaration_end;
elna_rtl_instructions(@result^.body, tac_declaration^.body.first, result^.variable_map);
return result
@@ -4352,7 +4396,7 @@ var
new_symbol_table: ^ElnaSymbolTable;
symbol_info: Word;
begin
new_symbol_table := elna_symbol_table_create();
new_symbol_table := elna_symbol_table_create(symbol_table_global);
symbol_info := procedure_info_create(new_symbol_table);
elna_name_procedure_temporaries(parser_node^.parameters, new_symbol_table);
@@ -4366,7 +4410,7 @@ var
new_symbol_table: ^ElnaSymbolTable;
symbol_info: Word;
begin
new_symbol_table := elna_symbol_table_create();
new_symbol_table := elna_symbol_table_create(symbol_table_global);
symbol_info := procedure_info_create(new_symbol_table);
elna_symbol_table_enter(symbol_table_global, "main", 4, symbol_info)
@@ -4492,9 +4536,6 @@ var
begin
variable_info := elna_symbol_table_lookup(symbol_table, parser_node^.name, parser_node^.length);
if variable_info = nil then
variable_info := elna_symbol_table_lookup(symbol_table_global, parser_node^.name, parser_node^.length)
end;
if variable_info^.kind = ElnaSymbolInfoKind.temporary_info then
temporary_info := variable_info;
parser_node^.type_decoration := temporary_info^.variable_type
@@ -4748,11 +4789,9 @@ proc elna_symbol_table_lookup(symbol_table: ^ElnaSymbolTable, symbol_name: Word,
var
result: Word;
symbol_table_length: Word;
current_name: Word;
current_length: Word;
current_entry: ^ElnaSymbolEntry;
begin
result := 0;
result := nil;
symbol_table_length := symbol_table^.count;
(* Go to the first symbol position. *)
@@ -4760,19 +4799,13 @@ begin
.symbol_table_lookup_loop;
if symbol_table_length = 0 then
if symbol_table^.parent <> nil then
result := elna_symbol_table_lookup(symbol_table^.parent, symbol_name, name_length)
end;
goto symbol_table_lookup_end
end;
(* Symbol name pointer and length. *)
current_name := current_entry^.name;
current_length := current_entry^.length;
(* If lengths don't match, exit and return nil. *)
if name_length <> current_length then
goto symbol_table_lookup_repeat
end;
(* If names don't match, exit and return nil. *)
if memcmp(symbol_name, current_name, name_length) then
(* If names don't match, try the next entry. *)
if string_compare(current_entry^.name, current_entry^.length, symbol_name, name_length) = false then
goto symbol_table_lookup_repeat
end;
(* Otherwise, the symbol is found. *)
@@ -4791,14 +4824,20 @@ end;
(**
* Create a new local symbol table in the symbol memory region after the last
* known symbol table.
*
* Parameters:
* parent - Outer scope.
*
* Returns newly allocated, empty symbol table.
*)
proc elna_symbol_table_create();
proc elna_symbol_table_create(parent: ^ElnaSymbolTable);
var
new_symbol_table: ^ElnaSymbolTable;
begin
new_symbol_table := malloc(#size(ElnaSymbolTable));
new_symbol_table^.symbols := malloc(16384);
new_symbol_table^.count := 0;
new_symbol_table^.parent := parent;
return new_symbol_table
end;
@@ -4827,14 +4866,14 @@ begin
symbol_table^.count := symbol_table^.count + 1
end;
(* Build global symbol table with predefined symbols. *)
proc elna_symbol_table_build();
var
current_info: ^ElnaSymbolTypeInfo;
current_type: ^ElnaType;
global_pointer: ^Word;
begin
(* Set the table length to 0. *)
symbol_table_global := elna_symbol_table_create();
symbol_table_global := elna_symbol_table_create(nil);
(* Enter built-in symbols. *)
word_type := malloc(#size(ElnaType));
@@ -4863,8 +4902,7 @@ begin
current_type^.size := 1;
current_type^.alignment := 1;
current_info := type_info_create(current_type);
elna_symbol_table_enter(symbol_table_global, "Char", 4, current_info);
elna_symbol_table_enter(symbol_table_global, "Char", 4, current_info)
end;
(**
@@ -5214,16 +5252,15 @@ begin
cursor^.position.end_location.column := 1
end;
(* Returns true of false depending whether to strings are equal. *)
(* Returns true or false depending whether two strings are equal. *)
proc string_compare(lhs_pointer: Word, lhs_length: Word, rhs_pointer: Word, rhs_length: Word);
var
result: Word;
begin
result := 0;
if lhs_length = rhs_length then
result := memcmp(lhs_pointer, rhs_pointer, lhs_length);
result := result = 0
result := memcmp(lhs_pointer, rhs_pointer, lhs_length) = 0
else
result := false
end;
return result
end;