Save TAC pseudo registers in the symbol table

This commit is contained in:
2026-02-04 23:13:15 +01:00
parent 8e89d33c21
commit e9bcd234e5

View File

@@ -23,7 +23,6 @@ type
name: Word;
length: Word;
body: Word;
stack: Word;
parameters: Word;
count: Word
end;
@@ -288,6 +287,15 @@ type
end;
(* Symbol table information. *)
ElnaSymbolEntry = record
name: Word;
length: Word;
symbol_info: Word
end;
ElnaSymbolTable = record
count: Word;
symbols: ^ElnaSymbolEntry
end;
ElnaSymbolInfoKind = (type_info, parameter_info, temporary_info, procedure_info);
ElnaSymbolInfo = record
kind: ElnaSymbolInfoKind
@@ -296,14 +304,15 @@ type
kind: ElnaSymbolInfoKind;
_type: ^ElnaType
end;
(* ElnaSymbolTemporaryInfo.offset is 0 or 1, 0: local variable, 1: pseudo register *)
ElnaSymbolTemporaryInfo = record
kind: ElnaSymbolInfoKind;
offset: Word;
attr: Word;
variable_type: ^ElnaType
end;
ElnaSymbolProcedureInfo = record
kind: ElnaSymbolInfoKind;
symbol_table: Word
symbol_table: ^ElnaSymbolTable
end;
ElnaErrorList = record
@@ -485,9 +494,9 @@ type
name: Word;
length: Word;
body: Word;
stack: Word;
parameters: Word;
count: Word
count: Word;
symbol_table: ^ElnaSymbolTable
end;
ElnaTacStaticVariable = record
next: Word;
@@ -588,11 +597,12 @@ var
transition_table: [19][23]ElnaLexerTransition;
lexer_state: ElnaLexerCursor;
word_type: ^ElnaType;
source_code: Word;
compiler_strings_position: Word;
compiler_strings_length: Word;
label_counter: Word;
symbol_table_store: Word;
temporary_variable_counter: Word;
pseudo_counter: Word;
@@ -726,9 +736,10 @@ proc _is_alnum(character: Word);
return _is_alpha(character) or isdigit(character)
end;
proc elna_tac_generate_pseudo(operand_type: Word, operand_value: Word, operand_length: Word);
proc elna_tac_generate_pseudo(operand_type: Word, operand_value: Word, operand_length: Word, symbol_table: ^ElnaSymbolTable);
var
buffer: Word;
temporary_info: ^ElnaSymbolTemporaryInfo;
begin
pseudo_counter := pseudo_counter + 1;
buffer := malloc(6);
@@ -738,6 +749,9 @@ begin
operand_type^ := ElnaTacKind.pseudo;
operand_value^ := buffer;
operand_length^ := strlen(buffer);
temporary_info := _temporary_info_create(1, word_type);
elna_symbol_table_enter(symbol_table, buffer, operand_length^, temporary_info)
end;
proc elna_instruction_list_concatenate(this: ^ElnaInstructionList, value: Word);
@@ -1358,12 +1372,12 @@ proc elna_alloc_variable(operand_value: Word, operand_length: Word);
var
pseudo_symbol: ^ElnaRtlInfo;
begin
pseudo_symbol := _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
pseudo_symbol := malloc(#size(ElnaRtlInfo));
pseudo_symbol^.counter := temporary_variable_counter;
_symbol_table_enter(@variable_map, operand_value, operand_length, pseudo_symbol);
elna_symbol_table_enter(@variable_map, operand_value, operand_length, pseudo_symbol);
temporary_variable_counter := temporary_variable_counter + 4
end;
return pseudo_symbol
@@ -1620,7 +1634,7 @@ begin
variable_map := 0;
elna_alloc_instructions(rtl_declaration^.body);
if rtl_declaration^.stack then
stack_instruction := elna_rtl_instruction_create(ElnaRtlOperator.allocate_stack);
stack_instruction^.next := rtl_declaration^.body;
elna_rtl_instruction_set_operand(stack_instruction, 1, ElnaRtlKind.immediate, temporary_variable_counter, 0);
@@ -1629,8 +1643,7 @@ begin
stack_instruction := elna_rtl_instruction_create(ElnaRtlOperator.ret);
elna_rtl_instruction_set_operand(stack_instruction, 1, ElnaRtlKind.immediate, temporary_variable_counter, 0);
elna_instruction_list_concatenate(rtl_declaration^.body, stack_instruction)
end;
elna_instruction_list_concatenate(rtl_declaration^.body, stack_instruction);
rtl_declaration := rtl_declaration^.next;
if rtl_declaration <> nil then
@@ -1837,11 +1850,12 @@ begin
return result
end;
proc elna_tac_variable_expression(variable_expression: ^ElnaTreeVariableExpression, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word);
proc elna_tac_variable_expression(variable_expression: ^ElnaTreeVariableExpression, symbol_table: ^ElnaSymbolTable,
operand_type: Word, operand_value: Word, operand_length: Word);
var
lookup_result: ^ElnaSymbolTemporaryInfo;
begin
lookup_result := _symbol_table_lookup(symbol_table, variable_expression^.name, variable_expression^.length);
lookup_result := elna_symbol_table_lookup(symbol_table, variable_expression^.name, variable_expression^.length);
if lookup_result <> nil then
operand_type^ := ElnaTacKind.pseudo;
@@ -1871,7 +1885,8 @@ begin
return result
end;
proc elna_tac_string_literal(string_literal_node: ^ElnaTreeStringLiteral, operand_type: Word, operand_value: Word, operand_length: Word);
proc elna_tac_string_literal(string_literal_node: ^ElnaTreeStringLiteral, symbol_table: ^ElnaSymbolTable,
operand_type: Word, operand_value: Word, operand_length: Word);
var
offset: Word;
first_instruction: Word;
@@ -1879,7 +1894,7 @@ var
begin
offset := _add_string(string_literal_node^.value);
elna_tac_generate_pseudo(operand_type, operand_value, operand_length);
elna_tac_generate_pseudo(operand_type, operand_value, operand_length, symbol_table);
first_instruction := elna_tac_instruction_create(ElnaTacOperator.get_address);
elna_tac_instruction_set_operand(first_instruction, 1, operand_type^, operand_value^, operand_length^);
@@ -1991,7 +2006,7 @@ var
parser_node: ^ElnaTreeNamedTypeExpression;
begin
parser_node := trait_node^.argument;
symbol := _symbol_table_lookup(@symbol_table_global, parser_node^.name, parser_node^.length);
symbol := elna_symbol_table_lookup(@symbol_table_global, parser_node^.name, parser_node^.length);
info_type := symbol^._type;
operand_type^ := ElnaTacKind.immediate;
@@ -2001,14 +2016,15 @@ begin
return nil
end;
proc elna_tac_simple_expression(parser_node: ^ElnaTreeNode, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word);
proc elna_tac_simple_expression(parser_node: ^ElnaTreeNode, symbol_table: ^ElnaSymbolTable,
operand_type: Word, operand_value: Word, operand_length: Word);
var
instruction: Word;
begin
if parser_node^.kind = ElnaTreeKind.character_literal then
instruction := elna_tac_character_literal(parser_node, operand_type, operand_value, operand_length)
elsif parser_node^.kind = ElnaTreeKind.string_literal then
instruction := elna_tac_string_literal(parser_node, operand_type, operand_value, operand_length)
instruction := elna_tac_string_literal(parser_node, symbol_table, operand_type, operand_value, operand_length)
elsif parser_node^.kind = ElnaTreeKind.integer_literal then
instruction := elna_tac_integer_literal(parser_node, operand_type, operand_value, operand_length)
elsif parser_node^.kind = ElnaTreeKind.boolean_literal then
@@ -2073,7 +2089,7 @@ begin
return instruction
end;
proc elna_tac_unary_expression(parser_node: ^ElnaTreeUnaryExpression, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word);
proc elna_tac_unary_expression(parser_node: ^ElnaTreeUnaryExpression, symbol_table: ^ElnaSymbolTable, operand_type: Word, operand_value: Word, operand_length: Word);
var
token_kind: Word;
operator: Word;
@@ -2095,7 +2111,7 @@ begin
end;
first_instruction := elna_tac_designator(operand, symbol_table, @is_address, @base_type, @base_value, @base_length);
elna_tac_generate_pseudo(operand_type, operand_value, operand_length);
elna_tac_generate_pseudo(operand_type, operand_value, operand_length, symbol_table);
if operator = '@' then
instruction := elna_tac_copy_address(is_address, base_type, base_value, base_length,
@@ -2188,7 +2204,7 @@ begin
return result
end;
proc elna_tac_binary_expression(parser_node: ^ElnaTreeBinaryExpression, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word);
proc elna_tac_binary_expression(parser_node: ^ElnaTreeBinaryExpression, symbol_table: ^ElnaSymbolTable, operand_type: Word, operand_value: Word, operand_length: Word);
var
first_instruction: Word;
instruction: Word;
@@ -2236,7 +2252,7 @@ begin
elsif parser_node^.operator = ElnaLexerKind.not_equal then
instruction := elna_tac_instruction_create(ElnaTacOperator.not_equal)
end;
elna_tac_generate_pseudo(operand_type, operand_value, operand_length);
elna_tac_generate_pseudo(operand_type, operand_value, operand_length, symbol_table);
elna_tac_instruction_set_operand(instruction, 1, operand_type^, operand_value^, operand_length^);
elna_tac_instruction_set_operand(instruction, 2, lhs_type, lhs_value, lhs_length);
@@ -2297,7 +2313,7 @@ begin
return result
end;
proc elna_tac_call(parsed_call: ^ElnaTreeCall, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word);
proc elna_tac_call(parsed_call: ^ElnaTreeCall, symbol_table: ^ElnaSymbolTable, operand_type: Word, operand_value: Word, operand_length: Word);
var
parsed_expression: ^ElnaTreeVariableExpression;
instruction: Word;
@@ -2314,7 +2330,7 @@ begin
first_instruction := nil;
arguments_operand := malloc(parsed_call^.count * #size(ElnaTacOperand));
elna_tac_generate_pseudo(operand_type, operand_value, operand_length);
elna_tac_generate_pseudo(operand_type, operand_value, operand_length, symbol_table);
call_instruction := elna_tac_instruction_create(ElnaTacOperator.proc_call);
elna_tac_instruction_set_operand(call_instruction, 1, ElnaTacKind.symbol, parsed_expression^.name, parsed_expression^.length);
@@ -2424,7 +2440,8 @@ var
enumeration_type_name: ^ElnaTreeVariableExpression;
begin
enumeration_type_name := field_access_expression^.aggregate;
symbol_info := _symbol_table_lookup(@symbol_table_global, enumeration_type_name^.name, enumeration_type_name^.length);
symbol_info := elna_symbol_table_lookup(@symbol_table_global,
enumeration_type_name^.name, enumeration_type_name^.length);
enumeration_type := symbol_info^._type;
members := enumeration_type^.members;
@@ -2495,7 +2512,8 @@ begin
return result
end;
proc elna_tac_dereference_expression(dereference_expression: ^ElnaTreeDereferenceExpression, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word);
proc elna_tac_dereference_expression(dereference_expression: ^ElnaTreeDereferenceExpression, symbol_table: ^ElnaSymbolTable,
operand_type: Word, operand_value: Word, operand_length: Word);
var
result_instructions: Word;
load_instruction: Word;
@@ -2512,7 +2530,8 @@ begin
return result_instructions
end;
proc elna_tac_designator(parser_node: ^ElnaTreeExpression, symbol_table: Word, is_address: Word, operand_type: Word, operand_value: Word, operand_length: Word);
proc elna_tac_designator(parser_node: ^ElnaTreeExpression, symbol_table: ElnaSymbolTable, is_address: Word,
operand_type: Word, operand_value: Word, operand_length: Word);
var
field_access_expression: ^ElnaTreeFieldAccessExpression;
result_instructions: Word;
@@ -2545,7 +2564,8 @@ begin
return result_instructions
end;
proc elna_tac_field_access_expression(field_access_expression: ^ElnaTreeFieldAccessExpression, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word);
proc elna_tac_field_access_expression(field_access_expression: ^ElnaTreeFieldAccessExpression, symbol_table: ^ElnaSymbolTable,
operand_type: Word, operand_value: Word, operand_length: Word);
var
field_type: ^ElnaType;
first_instruction: Word;
@@ -2578,7 +2598,7 @@ begin
field_offset := field_offset + field_type^.size;
goto elna_tac_field_access_expression_field
end;
elna_tac_generate_pseudo(operand_type, operand_value, operand_length);
elna_tac_generate_pseudo(operand_type, operand_value, operand_length, symbol_table);
last_instruction := elna_tac_copy_address(is_address, base_type, base_value, base_length, operand_type^, operand_value^, operand_length^);
first_instruction := elna_instruction_list_concatenate(first_instruction, last_instruction);
@@ -2591,7 +2611,8 @@ begin
return elna_instruction_list_concatenate(first_instruction, last_instruction)
end;
proc elna_tac_array_access_expression(array_access_expression: ^ElnaTreeArrayAccessExpression, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word);
proc elna_tac_array_access_expression(array_access_expression: ^ElnaTreeArrayAccessExpression, symbol_table: ^ElnaSymbolTable,
operand_type: Word, operand_value: Word, operand_length: Word);
var
array_instructions: Word;
index_instructions: Word;
@@ -2613,7 +2634,7 @@ begin
element_type := aggregate_type^.base;
index_instructions := elna_tac_binary_expression(array_access_expression^.index, symbol_table, @inter_type, @inter_value, @inter_length);
elna_tac_generate_pseudo(@index_type, @index_value, @index_length);
elna_tac_generate_pseudo(@index_type, @index_value, @index_length, symbol_table);
add_instruction := elna_tac_instruction_create(ElnaTacOperator.subtract);
elna_tac_instruction_set_operand(add_instruction, 1, index_type, index_value, index_length);
@@ -2629,7 +2650,7 @@ begin
index_instructions := elna_instruction_list_concatenate(index_instructions, add_instruction);
array_instructions := elna_tac_designator(array_access_expression^.array, symbol_table, @is_address, @inter_type, @inter_value, @inter_length);
elna_tac_generate_pseudo(operand_type, operand_value, operand_length);
elna_tac_generate_pseudo(operand_type, operand_value, operand_length, symbol_table);
elna_instruction_list_concatenate(offset_instruction, array_instructions);
array_instructions := elna_tac_copy_address(is_address, inter_type, inter_value, inter_length,
@@ -2664,7 +2685,7 @@ begin
return result
end;
proc elna_tac_assign_statement(parser_tree: ^ElnaTreeAssignStatement, symbol_table: Word);
proc elna_tac_assign_statement(parser_tree: ^ElnaTreeAssignStatement, symbol_table: ^ElnaSymbolTable);
var
is_address: Word;
first_instruction: Word;
@@ -2690,7 +2711,7 @@ begin
current_instruction := elna_tac_instruction_create(ElnaTacOperator.copy);
if is_address then
elna_tac_generate_pseudo(@operand_type, @operand_value, @operand_length);
elna_tac_generate_pseudo(@operand_type, @operand_value, @operand_length, symbol_table);
(* Save the assignee address on the stack. *)
elna_tac_instruction_set_operand(current_instruction, 1, operand_type, operand_value, operand_length);
@@ -2714,7 +2735,7 @@ begin
first_instruction := elna_instruction_list_concatenate(instruction, current_instruction)
end
else
elna_tac_generate_pseudo(@operand_type, @operand_value, @operand_length);
elna_tac_generate_pseudo(@operand_type, @operand_value, @operand_length, symbol_table);
(* Save the assignee address on the stack. *)
current_instruction := elna_tac_instruction_create(ElnaTacOperator.get_address);
@@ -2757,7 +2778,7 @@ begin
return result
end;
proc elna_tac_return_statement(parser_node: ^ElnaTreeReturnStatement, symbol_table: Word);
proc elna_tac_return_statement(parser_node: ^ElnaTreeReturnStatement, symbol_table: ^ElnaSymbolTable);
var
first_instruction: Word;
instruction: Word;
@@ -2815,7 +2836,7 @@ begin
return result
end;
proc elna_tac_conditional_statements(parser_node: ^ElnaTreeConditionalStatements, after_end_label: Word, symbol_table: Word);
proc elna_tac_conditional_statements(parser_node: ^ElnaTreeConditionalStatements, after_end_label: Word, symbol_table: ^ElnaSymbolTable);
var
condition_label: Word;
instruction: Word;
@@ -2953,14 +2974,12 @@ begin
return first_statement
end;
proc elna_tac_statements(parser_node: Word, symbol_table: Word);
proc elna_tac_statements(current_statement: ^ElnaTreeStatement, symbol_table: ^ElnaSymbolTable);
var
current_statement: ^ElnaTreeStatement;
instruction: Word;
first_instruction: Word;
current_instruction: Word;
begin
current_statement := parser_node;
first_instruction := nil;
.elna_tac_statements_loop;
@@ -2983,7 +3002,7 @@ begin
return first_instruction
end;
proc elna_tac_if_statement(parser_node: ^ElnaTreeIfStatement, symbol_table: Word);
proc elna_tac_if_statement(parser_node: ^ElnaTreeIfStatement, symbol_table: ^ElnaSymbolTable);
var
current_node: ^ElnaTreeConditionalStatements;
after_end_label: Word;
@@ -3022,7 +3041,7 @@ begin
return first_instruction
end;
proc elna_tac_statement(parser_node: ^ElnaTreeNode, symbol_table: Word);
proc elna_tac_statement(parser_node: ^ElnaTreeNode, symbol_table: ^ElnaSymbolTable);
var
instruction: Word;
operand_type: Word;
@@ -3392,7 +3411,8 @@ begin
if parser_node^.kind = ElnaTreeKind.named_type_expression then
named_type_expression := parser_node;
type_symbol := _symbol_table_lookup(@symbol_table_global, named_type_expression^.name, named_type_expression^.length);
type_symbol := elna_symbol_table_lookup(@symbol_table_global,
named_type_expression^.name, named_type_expression^.length);
result := type_symbol^._type
elsif parser_node^.kind = ElnaTreeKind.enumeration_type_expression then
result := elna_name_enumeration_type_expression(parser_node)
@@ -3420,10 +3440,10 @@ end;
(**
* Parameters:
* temporary_index - Local variable index.
* attr - Local variable attributes.
* temporary_type - Local variable type.
*)
proc _temporary_info_create(temporary_index: Word, temporary_type: Word);
proc _temporary_info_create(attr: Word, temporary_type: Word);
var
result: ^ElnaSymbolTemporaryInfo;
begin
@@ -3431,8 +3451,8 @@ begin
result^.kind := ElnaSymbolInfoKind.temporary_info;
(* Calculate the stack offset: 4 * variable_counter. *)
result^.offset := temporary_index * 4;
result^.variable_type := temporary_type;
result^.attr := attr;
return result
end;
@@ -3441,7 +3461,7 @@ end;
* Parameters:
* symbol_table - Local symbol table.
*)
proc _procedure_info_create(symbol_table: Word);
proc _procedure_info_create(symbol_table: ^ElnaSymbolTable);
var
result: ^ElnaSymbolProcedureInfo;
begin
@@ -3456,28 +3476,23 @@ end;
* Parameters:
* variable_index - Variable index.
*)
proc elna_name_procedure_temporary(parser_node: ^ElnaTreeVariableDeclaration, variable_index: Word, symbol_table: Word);
proc elna_name_procedure_temporary(parser_node: ^ElnaTreeVariableDeclaration, symbol_table: ^ElnaSymbolTable);
var
info: Word;
variable_type: Word;
begin
variable_type := elna_name_type_expression(parser_node^._type);
info := _temporary_info_create(variable_index, variable_type);
_symbol_table_enter(symbol_table, parser_node^.name, parser_node^.length, info)
info := _temporary_info_create(0, variable_type);
elna_symbol_table_enter(symbol_table, parser_node^.name, parser_node^.length, info)
end;
proc elna_name_procedure_temporaries(parser_node: ^ElnaTreeVariableDeclaration, symbol_table: Word);
var
temporary_counter: Word;
proc elna_name_procedure_temporaries(parser_node: ^ElnaTreeVariableDeclaration, symbol_table: ^ElnaSymbolTable);
begin
temporary_counter := 0;
.elna_name_procedure_temporaries_loop;
if parser_node <> nil then
elna_name_procedure_temporary(parser_node, temporary_counter, symbol_table);
elna_name_procedure_temporary(parser_node, symbol_table);
temporary_counter := temporary_counter + 1;
parser_node := parser_node^.next;
goto elna_name_procedure_temporaries_loop
end
@@ -3659,7 +3674,6 @@ begin
result^.next := nil;
result^.name := tac_declaration^.name;
result^.length := tac_declaration^.length;
result^.stack := tac_declaration^.stack;
parameters = elna_rtl_parameters(tac_declaration^.parameters, tac_declaration^.count);
body := elna_rtl_instructions(tac_declaration^.body);
@@ -3671,18 +3685,18 @@ end;
proc elna_tac_procedure_declaration(parser_node: ElnaTreeProcedureDeclaration);
var
symbol_info: ^ElnaSymbolProcedureInfo;
result: ^ElnaInstructionDeclaration;
result: ^ElnaTacProcedure;
parameter_count: Word;
begin
result := malloc(#size(ElnaInstructionDeclaration));
result := malloc(#size(ElnaTacProcedure));
result^.next := nil;
result^.stack := 1;
result^.name := parser_node^.name;
result^.length := parser_node^.length;
symbol_info := _symbol_table_lookup(@symbol_table_global, parser_node^.name, parser_node^.length);
symbol_info := elna_symbol_table_lookup(@symbol_table_global, parser_node^.name, parser_node^.length);
result^.symbol_table := symbol_info^.symbol_table;
result^.parameters := elna_tac_parameters(parser_node^.parameters, @parameter_count);
result^.count := parameter_count;
@@ -3864,7 +3878,7 @@ begin
type_info := elna_name_type_expression(parser_node);
type_info := _type_info_create(type_info);
_symbol_table_enter(@symbol_table_global, type_name, name_length, type_info)
elna_symbol_table_enter(@symbol_table_global, type_name, name_length, type_info)
end;
proc elna_type_type_declaration(parser_node: Word);
@@ -3943,7 +3957,7 @@ var
variable_info: ^ElnaSymbolTemporaryInfo;
begin
result := malloc(#size(ElnaTacStaticVariable));
variable_info := _symbol_table_lookup(@symbol_table_global, parser_tree^.name, parser_tree^.length);
variable_info := elna_symbol_table_lookup(@symbol_table_global, parser_tree^.name, parser_tree^.length);
result^.next := nil;
result^.name := parser_tree^.name;
@@ -4070,19 +4084,19 @@ end;
proc elna_name_procedure_declaration(parser_node: ^ElnaTreeProcedureDeclaration);
var
new_symbol_table: Word;
new_symbol_table: ^ElnaSymbolTable;
symbol_info: Word;
begin
new_symbol_table := _symbol_table_create();
new_symbol_table := elna_symbol_table_create();
symbol_info := _procedure_info_create(new_symbol_table);
elna_name_procedure_temporaries(parser_node^.parameters, new_symbol_table);
elna_name_procedure_temporaries(parser_node^.temporaries, new_symbol_table);
_symbol_table_enter(@symbol_table_global, parser_node^.name, parser_node^.length, symbol_info)
elna_symbol_table_enter(@symbol_table_global, parser_node^.name, parser_node^.length, symbol_info)
end;
proc elna_type_conditional_statements(parser_node: ^ElnaTreeConditionalStatements, symbol_table: Word);
proc elna_type_conditional_statements(parser_node: ^ElnaTreeConditionalStatements, symbol_table: ^ElnaSymbolTable);
begin
.elna_type_conditional_statements_loop;
elna_type_binary_expression(parser_node^.condition, symbol_table);
@@ -4094,7 +4108,7 @@ begin
end
end;
proc elna_type_if_statement(parser_node: ^ElnaTreeIfStatement, symbol_table: Word);
proc elna_type_if_statement(parser_node: ^ElnaTreeIfStatement, symbol_table: ^ElnaSymbolTable);
var
block: ^ElnaTreeConditionalStatements;
begin
@@ -4113,12 +4127,12 @@ begin
end
end;
proc elna_type_return_statement(parser_node: ^ElnaTreeReturnStatement, symbol_table: Word);
proc elna_type_return_statement(parser_node: ^ElnaTreeReturnStatement, symbol_table: ^ElnaSymbolTable);
begin
elna_type_binary_expression(parser_node^.returned, symbol_table)
end;
proc elna_type_call(parser_node: ^ElnaTreeCall, symbol_table: Word);
proc elna_type_call(parser_node: ^ElnaTreeCall, symbol_table: ^ElnaSymbolTable);
var
argument_tree: ^ElnaTreeExpressionList;
begin
@@ -4133,13 +4147,13 @@ begin
end
end;
proc elna_type_assign_statement(parser_node: ^ElnaTreeAssignStatement, symbol_table: Word);
proc elna_type_assign_statement(parser_node: ^ElnaTreeAssignStatement, symbol_table: ^ElnaSymbolTable);
begin
elna_type_designator(parser_node^.assignee, symbol_table);
elna_type_binary_expression(parser_node^.assignment, symbol_table)
end;
proc elna_type_statement(parser_node: ^ElnaTreeNode, symbol_table: Word);
proc elna_type_statement(parser_node: ^ElnaTreeNode, symbol_table: ^ElnaSymbolTable);
begin
(* Skipping goto and label declarations. *)
if parser_node^.kind = ElnaTreeKind.if_statement then
@@ -4153,7 +4167,7 @@ begin
end
end;
proc elna_type_statements(parser_node: ^ElnaTreeStatement, symbol_table: Word);
proc elna_type_statements(parser_node: ^ElnaTreeStatement, symbol_table: ^ElnaSymbolTable);
begin
.elna_type_statements_loop;
if parser_node <> nil then
@@ -4165,34 +4179,25 @@ begin
end;
proc elna_type_character_literal(parser_node: ^ElnaTreeCharacterLiteral);
var
symbol_info: ^ElnaSymbolTypeInfo;
begin
symbol_info := _symbol_table_lookup(@symbol_table_global, "Word", 4);
parser_node^.type_decoration := symbol_info^._type
parser_node^.type_decoration := word_type
end;
proc elna_type_integer_literal(parser_node: ^ElnaTreeIntegerLiteral);
var
symbol_info: ^ElnaSymbolTypeInfo;
begin
symbol_info := _symbol_table_lookup(@symbol_table_global, "Word", 4);
parser_node^.type_decoration := symbol_info^._type
parser_node^.type_decoration := word_type
end;
proc elna_type_string_literal(parser_node: ^ElnaTreeStringLiteral);
var
symbol_info: ^ElnaSymbolTypeInfo;
begin
symbol_info := _symbol_table_lookup(@symbol_table_global, "Word", 4);
parser_node^.type_decoration := symbol_info^._type
parser_node^.type_decoration := word_type
end;
proc elna_type_boolean_literal(parser_node: ^ElnaTreeBooleanLiteral);
var
symbol_info: ^ElnaSymbolTypeInfo;
begin
symbol_info := _symbol_table_lookup(@symbol_table_global, "Bool", 4);
symbol_info := elna_symbol_table_lookup(@symbol_table_global, "Bool", 4);
parser_node^.type_decoration := symbol_info^._type
end;
@@ -4200,19 +4205,19 @@ proc elna_type_nil_literal(parser_node: ^ElnaTreeNilLiteral);
var
symbol_info: ^ElnaSymbolTypeInfo;
begin
symbol_info := _symbol_table_lookup(@symbol_table_global, "Pointer", 7);
symbol_info := elna_symbol_table_lookup(@symbol_table_global, "Pointer", 7);
parser_node^.type_decoration := symbol_info^._type
end;
proc elna_type_variable_expression(parser_node: ^ElnaTreeVariableExpression, symbol_table: Word);
proc elna_type_variable_expression(parser_node: ^ElnaTreeVariableExpression, symbol_table: ^ElnaSymbolTable);
var
variable_info: ^ElnaSymbolInfo;
temporary_info: ^ElnaSymbolTemporaryInfo;
begin
variable_info := _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 := _symbol_table_lookup(@symbol_table_global, parser_node^.name, parser_node^.length)
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;
@@ -4220,7 +4225,7 @@ begin
end
end;
proc elna_type_simple_expression(parser_node: ^ElnaTreeNode, symbol_table: Word);
proc elna_type_simple_expression(parser_node: ^ElnaTreeNode, symbol_table: ^ElnaSymbolTable);
begin
if parser_node^.kind = ElnaTreeKind.integer_literal then
elna_type_integer_literal(parser_node)
@@ -4237,7 +4242,7 @@ begin
end
end;
proc elna_type_dereference_expression(parser_node: ^ElnaTreeDereferenceExpression, symbol_table: Word);
proc elna_type_dereference_expression(parser_node: ^ElnaTreeDereferenceExpression, symbol_table: ^ElnaSymbolTable);
var
base_type: ^ElnaType;
pointer_type: ^ElnaTypePointer;
@@ -4256,7 +4261,7 @@ begin
parser_node^.type_decoration := base_type
end;
proc elna_type_field_access_expression(parser_node: ^ElnaTreeFieldAccessExpression, symbol_table: Word);
proc elna_type_field_access_expression(parser_node: ^ElnaTreeFieldAccessExpression, symbol_table: ^ElnaSymbolTable);
var
variable_expression: ^ElnaTreeVariableExpression;
base_type: Word;
@@ -4271,7 +4276,7 @@ begin
(* Check whether the field access is an enumeration value. *)
if variable_expression^.kind = ElnaTreeKind.variable_expression then
symbol_info := _symbol_table_lookup(@symbol_table_global, variable_expression^.name, variable_expression^.length);
symbol_info := elna_symbol_table_lookup(@symbol_table_global, variable_expression^.name, variable_expression^.length);
if symbol_info <> nil then
type_kind := symbol_info;
@@ -4301,7 +4306,7 @@ begin
parser_node^.type_decoration := base_type
end;
proc elna_type_array_access_expression(parser_node: ^ElnaTreeArrayAccessExpression, symbol_table: Word);
proc elna_type_array_access_expression(parser_node: ^ElnaTreeArrayAccessExpression, symbol_table: ^ElnaSymbolTable);
var
aggregate_type: ^ElnaTypeArray;
base_expression: ^ElnaTreeExpression;
@@ -4315,7 +4320,7 @@ begin
parser_node^.type_decoration := aggregate_type^.base
end;
proc elna_type_designator(parser_node: ^ElnaTreeNode, symbol_table: Word);
proc elna_type_designator(parser_node: ^ElnaTreeNode, symbol_table: ^ElnaSymbolTable);
begin
if parser_node^.kind = ElnaTreeKind.dereference_expression then
elna_type_dereference_expression(parser_node, symbol_table)
@@ -4330,7 +4335,7 @@ begin
end
end;
proc elna_type_unary_expression(parser_node: ^ElnaTreeUnaryExpression, symbol_table: Word);
proc elna_type_unary_expression(parser_node: ^ElnaTreeUnaryExpression, symbol_table: ^ElnaSymbolTable);
var
unary_operand: ^ElnaTreeExpression;
begin
@@ -4344,7 +4349,7 @@ begin
end
end;
proc elna_type_binary_expression(parser_node: ^ElnaTreeBinaryExpression, symbol_table: Word);
proc elna_type_binary_expression(parser_node: ^ElnaTreeBinaryExpression, symbol_table: ^ElnaSymbolTable);
var
binary_operand: ^ElnaTreeExpression;
begin
@@ -4363,12 +4368,10 @@ end;
proc elna_type_procedure_declaration(parser_node: ^ElnaTreeProcedureDeclaration);
var
procedure_info: ^ElnaSymbolProcedureInfo;
symbol_table: Word;
begin
procedure_info := _symbol_table_lookup(@symbol_table_global, parser_node^.name, parser_node^.length);
symbol_table := procedure_info^.symbol_table;
procedure_info := elna_symbol_table_lookup(@symbol_table_global, parser_node^.name, parser_node^.length);
elna_type_statements(parser_node^.body, symbol_table)
elna_type_statements(parser_node^.body, procedure_info^.symbol_table)
end;
proc elna_name_module_declaration(parser_node: ^ElnaTreeModuleDeclaration);
@@ -4386,7 +4389,7 @@ begin
current_part := parser_node^.globals;
.elna_name_module_declaration_global;
if current_part <> nil then
elna_name_procedure_temporary(current_part, 0, @symbol_table_global);
elna_name_procedure_temporary(current_part, @symbol_table_global);
current_part := current_part^.next;
goto elna_name_module_declaration_global
@@ -4461,7 +4464,7 @@ end;
*
* Returns the symbol pointer or 0 in a0.
*)
proc _symbol_table_lookup(symbol_table: Word, symbol_name: Word, name_length: Word);
proc elna_symbol_table_lookup(symbol_table: ^ElnaSymbolTable, symbol_name: Word, name_length: Word);
var
result: Word;
symbol_table_length: Word;
@@ -4469,9 +4472,7 @@ var
current_length: Word;
begin
result := 0;
(* The first word in the symbol table is its length, get it. *)
symbol_table_length := symbol_table^;
symbol_table_length := symbol_table^.count;
(* Go to the first symbol position. *)
symbol_table := symbol_table + 4;
@@ -4512,23 +4513,12 @@ end;
* Create a new local symbol table in the symbol memory region after the last
* known symbol table.
*)
proc _symbol_table_create();
proc elna_symbol_table_create();
var
new_symbol_table: Word;
table_length: Word;
current_table: Word;
new_symbol_table: ^ElnaSymbolTable;
begin
new_symbol_table := symbol_table_store;
.symbol_table_create_loop;
table_length := new_symbol_table^;
if table_length <> 0 then
table_length := table_length * 12;
table_length := table_length + 4;
new_symbol_table := new_symbol_table + table_length;
goto symbol_table_create_loop
end;
new_symbol_table := malloc(12288);
new_symbol_table^.count := 0;
return new_symbol_table
end;
@@ -4542,7 +4532,7 @@ end;
* name_length - Symbol name length.
* symbol - Symbol pointer.
*)
proc _symbol_table_enter(symbol_table: Word, symbol_name: Word, name_length: Word, symbol: Word);
proc elna_symbol_table_enter(symbol_table: ^ElnaSymbolTable, symbol_name: Word, name_length: Word, symbol: Word);
var
table_length: Word;
symbol_pointer: Word;
@@ -4566,7 +4556,7 @@ begin
symbol_table^ := table_length
end;
proc _symbol_table_build();
proc elna_symbol_table_build();
var
current_info: ^ElnaSymbolTypeInfo;
current_type: ^ElnaType;
@@ -4575,23 +4565,23 @@ begin
symbol_table_global := 0;
(* Enter built-in symbols. *)
current_type := malloc(#size(ElnaType));
current_type^.kind := ElnaTypeKind.primitive;
current_type^.size := 4;
current_info := _type_info_create(current_type);
_symbol_table_enter(@symbol_table_global, "Word", 4, current_info);
word_type := malloc(#size(ElnaType));
word_type^.kind := ElnaTypeKind.primitive;
word_type^.size := 4;
current_info := _type_info_create(word_type);
elna_symbol_table_enter(@symbol_table_global, "Word", 4, current_info);
current_type := malloc(#size(ElnaType));
current_type^.kind := ElnaTypeKind.primitive;
current_type^.size := 4;
current_info := _type_info_create(current_type);
_symbol_table_enter(@symbol_table_global, "Pointer", 7, current_info);
elna_symbol_table_enter(@symbol_table_global, "Pointer", 7, current_info);
current_type := malloc(#size(ElnaType));
current_type^.kind := ElnaTypeKind.primitive;
current_type^.size := 1;
current_info := _type_info_create(current_type);
_symbol_table_enter(@symbol_table_global, "Bool", 4, current_info);
elna_symbol_table_enter(@symbol_table_global, "Bool", 4, current_info);
end;
(**
@@ -5237,7 +5227,6 @@ proc _initialize_global_state();
begin
compiler_strings_position := @compiler_strings;
source_code := malloc(495616);
symbol_table_store := malloc(4194304);
end;
(*
@@ -5250,7 +5239,7 @@ var
begin
_initialize_global_state();
_elna_lexer_initialize(source_code);
_symbol_table_build();
elna_symbol_table_build();
(* Read the source from the standard input. *)
offset := source_code;