Save TAC pseudo registers in the symbol table
This commit is contained in:
@@ -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,17 +1634,16 @@ 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);
|
||||
|
||||
rtl_declaration^.body := stack_instruction;
|
||||
stack_instruction := elna_rtl_instruction_create(ElnaRtlOperator.ret);
|
||||
elna_rtl_instruction_set_operand(stack_instruction, 1, ElnaRtlKind.immediate, temporary_variable_counter, 0);
|
||||
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);
|
||||
|
||||
elna_instruction_list_concatenate(rtl_declaration^.body, stack_instruction)
|
||||
end;
|
||||
rtl_declaration^.body := stack_instruction;
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user