diff --git a/boot/stage19/cl.elna b/boot/stage19/cl.elna index f721aef..881bf88 100644 --- a/boot/stage19/cl.elna +++ b/boot/stage19/cl.elna @@ -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;