From 713eff8de1c6c304b89ef9ead18228ea550a3228 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Sun, 22 Feb 2026 23:39:50 +0100 Subject: [PATCH] Extend ElnaErrorList to a generic ElnaList --- boot/stage20/cl.elna | 334 +++++++++++++++++++------------------------ 1 file changed, 151 insertions(+), 183 deletions(-) diff --git a/boot/stage20/cl.elna b/boot/stage20/cl.elna index 08d6b6c..b54d541 100644 --- a/boot/stage20/cl.elna +++ b/boot/stage20/cl.elna @@ -8,12 +8,17 @@ program; (* Stage 20 compiler. *) type + ElnaListNode = record + next: Word + end; + ElnaList = record + first: ^ElnaListNode; + last: ^ElnaListNode + end; + (** * List of intermediate representation items. *) - ElnaInstructionList = record - next: Word - end; ElnaInstructionModule = record data: Word; code: Word @@ -308,10 +313,6 @@ type symbol_table: ^ElnaSymbolTable end; - ElnaErrorList = record - first: Word; - last: Word - end; ElnaError = record next: Word end; @@ -475,8 +476,7 @@ type ElnaTacOperand = record kind: ElnaTacKind; value: Word; - length: Word; - offset: Word + length: Word end; ElnaTacInstruction = record next: Word; @@ -532,8 +532,7 @@ type ElnaRtlOperand = record kind: ElnaRtlKind; value: Word; - length: Word; - offset: Word + length: Word end; ElnaRtlStaticVariable = record next: Word; @@ -758,6 +757,32 @@ proc _is_alnum(character: Word); return _is_alpha(character) or isdigit(character) end; +proc elna_list_initialize(list: ^ElnaList); +begin + list^.first := nil; + list^.last := nil +end; + +proc elna_list_append(list: ^ElnaList, element: ^ElnaListNode); +begin + if element <> nil then + if list^.first = nil then + list^.first := element + else + list^.last^.next := element + end; + (* TODO: This is a temporary solution for the migration from the old lists. *) + .elna_list_append_loop; + if element^.next = nil then + list^.last := element + else + element := element^.next; + goto elna_list_append_loop + end + end; + return element +end; + proc elna_tac_generate_pseudo(operand_type: Word, operand_value: Word, operand_length: Word, symbol_table: ^ElnaSymbolTable); var buffer: Word; @@ -776,7 +801,7 @@ begin elna_symbol_table_enter(symbol_table, buffer, operand_length^, temporary_info) end; -proc elna_instruction_list_concatenate(this: ^ElnaInstructionList, value: Word); +proc elna_instruction_list_concatenate(this: ^ElnaListNode, value: Word); var start: Word; begin @@ -1261,15 +1286,13 @@ begin return result end; -proc elna_tac_label(counter: Word, length: Word); +proc elna_tac_label(instructions: ^ElnaList, counter: Word, length: Word); var result: Word; begin result := elna_tac_instruction_create(ElnaTacOperator.label); - elna_tac_instruction_set_operand(result, 1, ElnaTacKind.symbol, counter, length); - - return result + elna_list_append(instructions, result) end; proc elna_riscv_instruction_name(instruction_kind: Word); @@ -2095,7 +2118,7 @@ begin return result end; -proc elna_tac_copy_address(is_address: Word, from_type: Word, from_value: Word, from_length: Word, to_type: Word, to_value: Word, to_length: Word); +proc elna_tac_copy_address(is_address: Word, from: ^ElnaTacOperand, to: ^ElnaTacOperand); var instruction: Word; begin @@ -2104,23 +2127,21 @@ begin else instruction := elna_tac_instruction_create(ElnaTacOperator.get_address) end; - elna_tac_instruction_set_operand(instruction, 1, to_type, to_value, to_length); - elna_tac_instruction_set_operand(instruction, 2, from_type, from_value, from_length); + elna_tac_instruction_set_operand(instruction, 1, to^.kind, to^.value, to^.length); + elna_tac_instruction_set_operand(instruction, 2, from^.kind, from^.value, from^.length); return instruction end; -proc elna_tac_unary_expression(parser_node: ^ElnaTreeUnaryExpression, symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand); +proc elna_tac_unary_expression(instructions: ^ElnaList, parser_node: ^ElnaTreeUnaryExpression, symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand); var token_kind: Word; operator: Word; unary_operand: ^ElnaTreeExpression; is_address: Word; - first_instruction: Word; instruction: Word; base: ElnaTacOperand; begin - instruction := nil; if parser_node^.kind = ElnaTreeKind.unary_expression then operator := parser_node^.operator; unary_operand := parser_node^.operand @@ -2128,13 +2149,12 @@ begin operator := 0; unary_operand := parser_node end; - first_instruction := elna_tac_designator(unary_operand, symbol_table, @is_address, @base); + elna_tac_designator(instructions, unary_operand, symbol_table, @is_address, @base); elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table); if operator = '@' then - instruction := elna_tac_copy_address(is_address, base.kind, base.value, base.length, - operand^.kind, operand^.value, operand^.length) + instruction := elna_tac_copy_address(is_address, @base, operand) elsif operator = '-' then instruction := elna_tac_instruction_create(ElnaTacOperator.negate); elna_tac_instruction_set_operand(instruction, 1, operand^.kind, operand^.value, operand^.length); @@ -2152,7 +2172,7 @@ begin elna_tac_instruction_set_operand(instruction, 1, operand^.kind, operand^.value, operand^.length); elna_tac_instruction_set_operand(instruction, 2, base.kind, base.value, base.length) end; - return elna_instruction_list_concatenate(first_instruction, instruction) + elna_list_append(instructions, instruction) end; proc elna_parser_binary_expression(); @@ -2223,7 +2243,7 @@ begin return result end; -proc elna_tac_binary_expression(parser_node: ^ElnaTreeBinaryExpression, symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand); +proc elna_tac_binary_expression(instructions: ^ElnaList, parser_node: ^ElnaTreeBinaryExpression, symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand); var first_instruction: Word; instruction: Word; @@ -2231,11 +2251,10 @@ var rhs: ElnaTacOperand; begin if parser_node^.kind <> ElnaTreeKind.binary_expression then - first_instruction := elna_tac_unary_expression(parser_node, symbol_table, operand) + elna_tac_unary_expression(instructions, parser_node, symbol_table, operand) else - first_instruction := elna_tac_unary_expression(parser_node^.lhs, symbol_table, @lhs); - instruction := elna_tac_unary_expression(parser_node^.rhs, symbol_table, @rhs); - first_instruction := elna_instruction_list_concatenate(first_instruction, instruction); + elna_tac_unary_expression(instructions, parser_node^.lhs, symbol_table, @lhs); + elna_tac_unary_expression(instructions, parser_node^.rhs, symbol_table, @rhs); if parser_node^.operator = ElnaLexerKind.plus then instruction := elna_tac_instruction_create(ElnaTacOperator.add) @@ -2272,9 +2291,9 @@ begin elna_tac_instruction_set_operand(instruction, 2, lhs.kind, lhs.value, lhs.length); elna_tac_instruction_set_operand(instruction, 3, rhs.kind, rhs.value, rhs.length); - first_instruction := elna_instruction_list_concatenate(first_instruction, instruction) + elna_list_append(instructions, instruction) end; - return first_instruction + return instructions^.first end; proc elna_parser_call(callee: Word); @@ -2327,18 +2346,15 @@ begin return result end; -proc elna_tac_call(parsed_call: ^ElnaTreeCall, symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand); +proc elna_tac_call(instructions: ^ElnaList, parsed_call: ^ElnaTreeCall, symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand); var parsed_expression: ^ElnaTreeVariableExpression; instruction: Word; - first_instruction: Word; - current_instruction: Word; arguments_operand: ^ElnaTacOperand; call_instruction: Word; argument_entry: ^ElnaTreeExpressionList; begin parsed_expression := parsed_call^.callee; - first_instruction := nil; arguments_operand := malloc(parsed_call^.count * #size(ElnaTacOperand)); elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table); @@ -2352,26 +2368,13 @@ begin .elna_tac_call_loop; if argument_entry <> nil then - instruction := elna_tac_binary_expression(argument_entry^.expression, symbol_table, arguments_operand); - if first_instruction = nil then - first_instruction := instruction - else - elna_instruction_list_concatenate(current_instruction, instruction) - end; - if instruction <> nil then - current_instruction := instruction - end; + instruction := elna_tac_binary_expression(instructions, argument_entry^.expression, symbol_table, arguments_operand); arguments_operand := arguments_operand + #size(ElnaTacOperand); argument_entry := argument_entry^.next; goto elna_tac_call_loop end; - if first_instruction = nil then - first_instruction := call_instruction - else - elna_instruction_list_concatenate(current_instruction, call_instruction) - end; - return first_instruction + elna_list_append(instructions, call_instruction) end; proc elna_parser_goto_statement(); @@ -2393,21 +2396,21 @@ begin return result end; -proc elna_tac_goto_statement(parser_node: ^ElnaTreeGotoStatement); +proc elna_tac_goto_statement(instructions: ^ElnaList, parser_node: ^ElnaTreeGotoStatement); var - label_length1: Word; - label_with_dot1: Word; - instruction1: Word; + label_length: Word; + label_with_dot: Word; + instruction: Word; begin - label_length1 := parser_node^.length + 1; - label_with_dot1 := malloc(label_length1); + label_length := parser_node^.length + 1; + label_with_dot := malloc(label_length); - _store_byte('.', label_with_dot1); - memcpy(label_with_dot1 + 1, parser_node^.label, parser_node^.length); + _store_byte('.', label_with_dot); + memcpy(label_with_dot + 1, parser_node^.label, parser_node^.length); - instruction1 := elna_tac_instruction_create(ElnaTacOperator.jump); - elna_tac_instruction_set_operand(instruction1, 1, ElnaTacKind.symbol, label_with_dot1, label_length1); - return instruction1 + instruction := elna_tac_instruction_create(ElnaTacOperator.jump); + elna_tac_instruction_set_operand(instruction, 1, ElnaTacKind.symbol, label_with_dot, label_length); + elna_list_append(instructions, instruction) end; proc elna_parser_label_declaration(); @@ -2430,8 +2433,9 @@ begin return result end; -proc elna_tac_label_declaration(parser_node: ^ElnaTreeLabelDeclaration); - return elna_tac_label(parser_node^.label, parser_node^.length) +proc elna_tac_label_declaration(instructions: ^ElnaList, parser_node: ^ElnaTreeLabelDeclaration); +begin + elna_tac_label(instructions, parser_node^.label, parser_node^.length) end; proc elna_tac_enumeration_value(field_access_expression: ^ElnaTreeFieldAccessExpression, operand: ^ElnaTacOperand); @@ -2525,8 +2529,11 @@ var result_instructions: Word; load_instruction: Word; is_address: Word; + body: ElnaList; begin - result_instructions := elna_tac_designator(dereference_expression^.pointer, symbol_table, @is_address, operand); + elna_list_initialize(@body); + elna_tac_designator(@body, dereference_expression^.pointer, symbol_table, @is_address, operand); + result_instructions := body.first; if is_address = true then load_instruction := elna_tac_instruction_create(ElnaTacOperator.load); @@ -2538,7 +2545,7 @@ begin return result_instructions end; -proc elna_tac_designator(parser_node: ^ElnaTreeExpression, symbol_table: ElnaSymbolTable, is_address: Word, operand: ^ElnaTacOperand); +proc elna_tac_designator(instructions: ^ElnaList, parser_node: ^ElnaTreeExpression, symbol_table: ElnaSymbolTable, is_address: Word, operand: ^ElnaTacOperand); var field_access_expression: ^ElnaTreeFieldAccessExpression; result_instructions: Word; @@ -2546,6 +2553,7 @@ var begin if parser_node^.kind = ElnaTreeKind.dereference_expression then result_instructions := elna_tac_dereference_expression(parser_node, symbol_table, operand); + elna_list_append(instructions, result_instructions); is_address^ := true elsif parser_node^.kind = ElnaTreeKind.field_access_expression then field_access_expression := parser_node; @@ -2558,17 +2566,19 @@ begin result_instructions := elna_tac_field_access_expression(field_access_expression, symbol_table, operand); is_address^ := true end; + elna_list_append(instructions, result_instructions) elsif parser_node^.kind = ElnaTreeKind.array_access_expression then result_instructions := elna_tac_array_access_expression(parser_node, symbol_table, operand); + elna_list_append(instructions, result_instructions); is_address^ := true elsif parser_node^.kind = ElnaTreeKind.call then - result_instructions := elna_tac_call(parser_node, symbol_table, operand); + elna_tac_call(instructions, parser_node, symbol_table, operand); is_address^ := false else result_instructions := elna_tac_simple_expression(parser_node, symbol_table, operand); + elna_list_append(instructions, result_instructions); is_address^ := false - end; - return result_instructions + end end; proc elna_tac_field_access_expression(field_access_expression: ^ElnaTreeFieldAccessExpression, @@ -2584,11 +2594,14 @@ var field_offset: Word; is_address: Word; base: ElnaTacOperand; + body: ElnaList; begin designator_base := field_access_expression^.aggregate; aggregate_type := designator_base^.type_decoration; - first_instruction := elna_tac_designator(designator_base, symbol_table, @is_address, @base); + elna_list_initialize(@body); + elna_tac_designator(@body, designator_base, symbol_table, @is_address, @base); + first_instruction := body.first; field_count := aggregate_type^.length; current_field := aggregate_type^.members; @@ -2605,7 +2618,7 @@ begin end; elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table); - last_instruction := elna_tac_copy_address(is_address, base.kind, base.value, base.length, operand^.kind, operand^.value, operand^.length); + last_instruction := elna_tac_copy_address(is_address, @base, operand); first_instruction := elna_instruction_list_concatenate(first_instruction, last_instruction); last_instruction := elna_tac_instruction_create(ElnaTacOperator.add); @@ -2631,12 +2644,14 @@ var aggregate_type: ^ElnaTypeArray; designator_base: ^ElnaTreeExpression; element_type: ^ElnaType; + body: ElnaList; begin designator_base := array_access_expression^.array; aggregate_type := designator_base^.type_decoration; element_type := aggregate_type^.base; - index_instructions := elna_tac_binary_expression(array_access_expression^.index, symbol_table, @inter_operand); + elna_list_initialize(@body); + index_instructions := elna_tac_binary_expression(@body, array_access_expression^.index, symbol_table, @inter_operand); elna_tac_generate_pseudo(@index_type, @index_value, @index_length, symbol_table); add_instruction := elna_tac_instruction_create(ElnaTacOperator.subtract); @@ -2652,12 +2667,13 @@ begin elna_instruction_list_concatenate(add_instruction, offset_instruction); index_instructions := elna_instruction_list_concatenate(index_instructions, add_instruction); - array_instructions := elna_tac_designator(array_access_expression^.array, symbol_table, @is_address, @inter_operand); + elna_list_initialize(@body); + elna_tac_designator(@body, array_access_expression^.array, symbol_table, @is_address, @inter_operand); + array_instructions := body.first; elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table); elna_instruction_list_concatenate(offset_instruction, array_instructions); - array_instructions := elna_tac_copy_address(is_address, inter_operand.kind, inter_operand.value, inter_operand.length, - operand^.kind, operand^.value, operand^.length); + array_instructions := elna_tac_copy_address(is_address, @inter_operand, operand); elna_instruction_list_concatenate(offset_instruction, array_instructions); add_instruction := elna_tac_instruction_create(ElnaTacOperator.add); @@ -2688,70 +2704,60 @@ begin return result end; -proc elna_tac_assign_statement(parser_tree: ^ElnaTreeAssignStatement, symbol_table: ^ElnaSymbolTable); +proc elna_tac_assign_statement(instructions: ^ElnaList, parser_tree: ^ElnaTreeAssignStatement, symbol_table: ^ElnaSymbolTable); var is_address: Word; - first_instruction: Word; instruction: Word; - current_instruction: Word; operand_type: Word; operand_value: Word; operand_length: Word; assignment_operand: ElnaTacOperand; assignee: ElnaTacOperand; begin - first_instruction := elna_tac_designator(parser_tree^.assignee, symbol_table, @is_address, @assignee); + elna_tac_designator(instructions, parser_tree^.assignee, symbol_table, @is_address, @assignee); + (* Compile the assignment. *) - instruction := elna_tac_binary_expression(parser_tree^.assignment, symbol_table, @assignment_operand); + instruction := elna_tac_binary_expression(instructions, parser_tree^.assignment, symbol_table, @assignment_operand); if assignee.kind = ElnaTacKind.pseudo then - current_instruction := elna_tac_instruction_create(ElnaTacOperator.copy); + instruction := elna_tac_instruction_create(ElnaTacOperator.copy); if is_address then 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); - elna_tac_instruction_set_operand(current_instruction, 2, assignee.kind, assignee.value, assignee.length); - first_instruction := elna_instruction_list_concatenate(first_instruction, current_instruction); + elna_tac_instruction_set_operand(instruction, 1, operand_type, operand_value, operand_length); + elna_tac_instruction_set_operand(instruction, 2, assignee.kind, assignee.value, assignee.length); - if instruction <> nil then - elna_instruction_list_concatenate(current_instruction, instruction); - current_instruction := instruction - end; + elna_list_append(instructions, instruction); instruction := elna_tac_instruction_create(ElnaTacOperator.store); elna_tac_instruction_set_operand(instruction, 1, assignment_operand.kind, assignment_operand.value, assignment_operand.length); elna_tac_instruction_set_operand(instruction, 2, operand_type, operand_value, operand_length); - elna_instruction_list_concatenate(current_instruction, instruction) + elna_list_append(instructions, instruction) else - elna_tac_instruction_set_operand(current_instruction, 1, assignee.kind, assignee.value, assignee.length); - elna_tac_instruction_set_operand(current_instruction, 2, assignment_operand.kind, assignment_operand.value, assignment_operand.length); + elna_tac_instruction_set_operand(instruction, 1, assignee.kind, assignee.value, assignee.length); + elna_tac_instruction_set_operand(instruction, 2, assignment_operand.kind, assignment_operand.value, assignment_operand.length); - first_instruction := elna_instruction_list_concatenate(instruction, current_instruction) + elna_list_append(instructions, instruction) end else 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); - elna_tac_instruction_set_operand(current_instruction, 1, operand_type, operand_value, operand_length); - elna_tac_instruction_set_operand(current_instruction, 2, assignee.kind, assignee.value, assignee.length); - first_instruction := elna_instruction_list_concatenate(first_instruction, current_instruction); + instruction := elna_tac_instruction_create(ElnaTacOperator.get_address); + elna_tac_instruction_set_operand(instruction, 1, operand_type, operand_value, operand_length); + elna_tac_instruction_set_operand(instruction, 2, assignee.kind, assignee.value, assignee.length); - if instruction <> nil then - elna_instruction_list_concatenate(current_instruction, instruction); - current_instruction := instruction - end; + elna_list_append(instructions, instruction); instruction := elna_tac_instruction_create(ElnaTacOperator.store); elna_tac_instruction_set_operand(instruction, 1, assignment_operand.kind, assignment_operand.value, assignment_operand.length); elna_tac_instruction_set_operand(instruction, 2, operand_type, operand_value, operand_length); - elna_instruction_list_concatenate(current_instruction, instruction) - end; - return first_instruction + elna_list_append(instructions, instruction) + end end; proc elna_parser_return_statement(); @@ -2775,18 +2781,16 @@ begin return result end; -proc elna_tac_return_statement(parser_node: ^ElnaTreeReturnStatement, symbol_table: ^ElnaSymbolTable); +proc elna_tac_return_statement(instructions: ^ElnaList, parser_node: ^ElnaTreeReturnStatement, symbol_table: ^ElnaSymbolTable); var - first_instruction: Word; instruction: Word; operand: ElnaTacOperand; begin - first_instruction := elna_tac_binary_expression(parser_node^.returned, symbol_table, @operand); + instruction := elna_tac_binary_expression(instructions, parser_node^.returned, symbol_table, @operand); instruction := elna_tac_instruction_create(ElnaTacOperator._return); elna_tac_instruction_set_operand(instruction, 1, operand.kind, operand.value, operand.length); - - return elna_instruction_list_concatenate(first_instruction, instruction) + elna_list_append(instructions, instruction) end; (** @@ -2828,41 +2832,32 @@ begin return result end; -proc elna_tac_conditional_statements(parser_node: ^ElnaTreeConditionalStatements, after_end_label: Word, symbol_table: ^ElnaSymbolTable); +proc elna_tac_conditional_statements(instructions: ^ElnaList, parser_node: ^ElnaTreeConditionalStatements, + after_end_label: Word, symbol_table: ^ElnaSymbolTable); var condition_label: Word; instruction: Word; - current_instruction: Word; - first_instruction: Word; operand: ElnaTacOperand; begin (* Compile condition. *) - first_instruction := elna_tac_binary_expression(parser_node^.condition, symbol_table, @operand); + instruction := elna_tac_binary_expression(instructions, parser_node^.condition, symbol_table, @operand); (* condition_label is the label in front of the next elsif condition or end. *) condition_label := label_counter; label_counter := label_counter + 1; - current_instruction := elna_tac_instruction_create(ElnaTacOperator.jump_if_zero); - elna_tac_instruction_set_operand(current_instruction, 1, operand.kind, operand.value, operand.length); - elna_tac_instruction_set_operand(current_instruction, 2, ElnaTacKind.symbol, condition_label, 0); + instruction := elna_tac_instruction_create(ElnaTacOperator.jump_if_zero); + elna_tac_instruction_set_operand(instruction, 1, operand.kind, operand.value, operand.length); + elna_tac_instruction_set_operand(instruction, 2, ElnaTacKind.symbol, condition_label, 0); - first_instruction := elna_instruction_list_concatenate(first_instruction, current_instruction); - - instruction := elna_tac_statements(parser_node^.statements, symbol_table); - if instruction <> nil then - elna_instruction_list_concatenate(current_instruction, instruction); - current_instruction := instruction - end; + elna_list_append(instructions, instruction); + elna_tac_statements(instructions, parser_node^.statements, symbol_table); instruction := elna_tac_instruction_create(ElnaTacOperator.jump); elna_tac_instruction_set_operand(instruction, 1, ElnaTacKind.symbol, after_end_label, 0); - elna_instruction_list_concatenate(current_instruction, instruction); + elna_list_append(instructions, instruction); - current_instruction := elna_tac_label(condition_label, 0); - elna_instruction_list_concatenate(instruction, current_instruction); - - return first_instruction + elna_tac_label(instructions, condition_label, 0) end; proc elna_parser_if_statement(); @@ -2961,94 +2956,66 @@ begin return first_statement end; -proc elna_tac_statements(current_statement: ^ElnaTreeStatement, symbol_table: ^ElnaSymbolTable); +proc elna_tac_statements(instructions: ^ElnaList, current_statement: ^ElnaTreeStatement, symbol_table: ^ElnaSymbolTable); var instruction: Word; - first_instruction: Word; - current_instruction: Word; begin - first_instruction := nil; - .elna_tac_statements_loop; pseudo_counter := 0; if current_statement <> nil then - instruction := elna_tac_statement(current_statement, symbol_table); + elna_tac_statement(instructions, current_statement, symbol_table); current_statement := current_statement^.next; - if instruction = 0 then - goto elna_tac_statements_loop - end; - if first_instruction = nil then - first_instruction := instruction - else - elna_instruction_list_concatenate(current_instruction, instruction) - end; - current_instruction := instruction; + goto elna_tac_statements_loop end; - return first_instruction + return instructions^.first end; -proc elna_tac_if_statement(parser_node: ^ElnaTreeIfStatement, symbol_table: ^ElnaSymbolTable); +proc elna_tac_if_statement(instructions: ElnaList, parser_node: ^ElnaTreeIfStatement, symbol_table: ^ElnaSymbolTable); var current_node: ^ElnaTreeConditionalStatements; after_end_label: Word; condition_label: Word; - first_instruction: Word; - instruction: Word; - current_instruction: Word; begin after_end_label := label_counter; label_counter := label_counter + 1; - current_node := parser_node^.conditionals; - first_instruction := elna_tac_conditional_statements(current_node, after_end_label, symbol_table); - current_instruction := first_instruction; + + elna_tac_conditional_statements(instructions, current_node, after_end_label, symbol_table); .elna_tac_if_statement_loop; current_node := current_node^.next; if current_node <> nil then - instruction := elna_tac_conditional_statements(current_node, after_end_label, symbol_table); - elna_instruction_list_concatenate(current_instruction, instruction); - current_instruction := instruction; + elna_tac_conditional_statements(instructions, current_node, after_end_label, symbol_table); + goto elna_tac_if_statement_loop end; current_node := parser_node^._else; if parser_node^._else <> nil then - instruction := elna_tac_statements(parser_node^._else, symbol_table); - if instruction <> 0 then - elna_instruction_list_concatenate(current_instruction, instruction); - current_instruction := instruction - end + elna_tac_statements(instructions, parser_node^._else, symbol_table) end; - instruction := elna_tac_label(after_end_label, 0); - elna_instruction_list_concatenate(current_instruction, instruction); - - return first_instruction + elna_tac_label(instructions, after_end_label, 0) end; -proc elna_tac_statement(parser_node: ^ElnaTreeNode, symbol_table: ^ElnaSymbolTable); +proc elna_tac_statement(instructions: ElnaList, parser_node: ^ElnaTreeNode, symbol_table: ^ElnaSymbolTable); var - instruction: Word; operand: ElnaTacOperand; begin if parser_node^.kind = ElnaTreeKind.goto_statement then - instruction := elna_tac_goto_statement(parser_node) + elna_tac_goto_statement(instructions, parser_node) elsif parser_node^.kind = ElnaTreeKind.if_statement then - instruction := elna_tac_if_statement(parser_node, symbol_table) + elna_tac_if_statement(instructions, parser_node, symbol_table) elsif parser_node^.kind = ElnaTreeKind.return_statement then - instruction := elna_tac_return_statement(parser_node, symbol_table) + elna_tac_return_statement(instructions, parser_node, symbol_table) elsif parser_node^.kind = ElnaTreeKind.label_declaration then - instruction := elna_tac_label_declaration(parser_node) + elna_tac_label_declaration(instructions, parser_node) elsif parser_node^.kind = ElnaTreeKind.call then - instruction := elna_tac_call(parser_node, symbol_table, @operand) + elna_tac_call(instructions, parser_node, symbol_table, @operand) elsif parser_node^.kind = ElnaTreeKind.assign_statement then - instruction := elna_tac_assign_statement(parser_node, symbol_table) - else - instruction := nil - end; - return instruction + elna_tac_assign_statement(instructions, parser_node, symbol_table) + end end; (** @@ -3738,10 +3705,13 @@ var symbol_info: ^ElnaSymbolProcedureInfo; result: ^ElnaTacProcedure; parameter_count: Word; + body: ElnaList; begin result := malloc(#size(ElnaTacProcedure)); result^.next := nil; + elna_list_initialize(@body); + result^.name := parser_node^.name; result^.length := parser_node^.length; @@ -3751,7 +3721,7 @@ begin result^.parameters := elna_tac_parameters(parser_node^.parameters, @parameter_count); result^.count := parameter_count; - result^.body := elna_tac_statements(parser_node^.body, symbol_info^.symbol_table); + result^.body := elna_tac_statements(@body, parser_node^.body, symbol_info^.symbol_table); return result end; @@ -4087,7 +4057,7 @@ begin return first_variable end; -proc elna_parser_module_declaration(error_list: ^ElnaErrorList); +proc elna_parser_module_declaration(error_list: ^ElnaList); var parser_node: Word; result: ^ElnaTreeModuleDeclaration; @@ -4480,15 +4450,13 @@ var parser_node: Word; tac: Word; rtl: Word; - error_list: ^ElnaErrorList; + error_list: ElnaList; compiled: Word; begin - error_list := malloc(#size(ElnaErrorList)); - error_list^.first := nil; - error_list^.last := nil; + elna_list_initialize(@error_list); - parser_node := elna_parser_module_declaration(error_list); - compiled := error_list^.first = nil; + parser_node := elna_parser_module_declaration(@error_list); + compiled := error_list.first = nil; if compiled then elna_name_module_declaration(parser_node);