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