From eb691db24aaaa43eca03d82a5075b3eba52beedc Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Fri, 28 Nov 2025 12:42:51 +0100 Subject: [PATCH] Allow parsing multiple designator expressions in a row --- boot/stage16/cl.elna | 70 +++++-- boot/stage17/cl.elna | 451 +++++++++++++++++++++---------------------- 2 files changed, 270 insertions(+), 251 deletions(-) diff --git a/boot/stage16/cl.elna b/boot/stage16/cl.elna index 89399fb..fc44bc7 100644 --- a/boot/stage16/cl.elna +++ b/boot/stage16/cl.elna @@ -1789,14 +1789,18 @@ var begin simple_expression := elna_parser_simple_expression(); + .elna_parser_designator_loop; _elna_lexer_read_token(@token_kind); if token_kind = ElnaLexerKind.hat then - simple_expression := elna_parser_dereference_expression(simple_expression) + simple_expression := elna_parser_dereference_expression(simple_expression); + goto elna_parser_designator_loop elsif token_kind = ElnaLexerKind.dot then - simple_expression := elna_parser_field_access_expression(simple_expression) + simple_expression := elna_parser_field_access_expression(simple_expression); + goto elna_parser_designator_loop elsif token_kind = ElnaLexerKind.left_paren then - simple_expression := elna_parser_call(simple_expression) + simple_expression := elna_parser_call(simple_expression); + goto elna_parser_designator_loop end; return simple_expression end; @@ -2414,12 +2418,21 @@ var first_instruction: Word; last_instruction: Word; type_kind: Word; + designator_base: Word; + aggregate_type: Word; + name_pointer: Word; + name_length: Word; + field_name_pointer: Word; + field_name_length: Word; + field_count: Word; + current_field: Word; + field_offset: Word; begin node_kind := ElnaTreeNode_get_kind(parser_node); if node_kind = ElnaTreeKind.dereference_expression then parser_node := ElnaTreeDereferenceExpression_get_pointer(parser_node); - first_instruction := _elna_tac_simple_expression(parser_node, symbol_table, operand_type, operand_value, operand_length); + first_instruction := _elna_tac_designator(parser_node, symbol_table, is_address, operand_type, operand_value, operand_length); last_instruction := _elna_tac_instruction_create(ElnaTacOperator.copy); _elna_tac_instruction_set_operand(last_instruction, 1, ElnaTacOperand.temporary, 6, 0); @@ -2436,17 +2449,42 @@ begin type_kind := ElnaType_get_kind(expression_type); if type_kind = ElnaTypeKind.enumeration then - first_instruction := _elna_tac_enumeration_value(parser_node, operand_type, operand_value, operand_length) + first_instruction := _elna_tac_enumeration_value(parser_node, operand_type, operand_value, operand_length); + is_address^ := 0 else - (* Stub for record field access. Always generate nil for field access expression until it is implemented. *) + designator_base := ElnaTreeFieldAccessExpression_get_aggregate(parser_node); + first_instruction := _elna_tac_designator(designator_base, symbol_table, is_address, operand_type, operand_value, operand_length); + aggregate_type := ElnaTreeExpression_get_type_decoration(designator_base); + name_pointer := ElnaTreeFieldAccessExpression_get_field(parser_node); + name_length := ElnaTreeFieldAccessExpression_get_length(parser_node); - operand_type^ := ElnaTacOperand.immediate; - operand_value^ := 0; + field_count := ElnaTypeRecord_get_length(aggregate_type); + current_field := ElnaTypeRecord_get_members(aggregate_type); + field_offset := 0; + + .elna_tac_designator_field; + + field_name_pointer := ElnaTypeField_get_name(current_field); + field_name_length := ElnaTypeField_get_length(current_field); + + if string_compare(name_pointer, name_length, field_name_pointer, field_name_length) = 0 then + field_count := field_count - 1; + current_field := current_field + ElnaTypeField_size(); + field_offset := field_offset + 4; + goto elna_tac_designator_field + end; + last_instruction := _elna_tac_instruction_create(ElnaTacOperator.add); + _elna_tac_instruction_set_operand(last_instruction, 1, ElnaTacOperand.temporary, 6, 0); + _elna_tac_instruction_set_operand(last_instruction, 2, ElnaTacOperand.immediate, field_offset, 0); + _elna_tac_instruction_set_operand(last_instruction, 3, operand_type^, operand_value^, operand_length^); + + operand_type^ := ElnaTacOperand.temporary; + operand_value^ := 6; operand_length^ := 0; - first_instruction := nil + is_address^ := 1; + first_instruction := elna_instruction_list_concatenate(first_instruction, last_instruction) end; - is_address^ := 0 elsif node_kind = ElnaTreeKind.call then first_instruction := _elna_tac_call(parser_node, symbol_table); @@ -4411,7 +4449,7 @@ begin if expression_kind = ElnaTreeKind.dereference_expression then designator_base := ElnaTreeDereferenceExpression_get_pointer(parser_node); - elna_type_simple_expression(designator_base, symbol_table); + elna_type_designator(designator_base, symbol_table); base_type := ElnaTreeExpression_get_type_decoration(designator_base); type_kind := ElnaType_get_kind(base_type); @@ -4442,7 +4480,7 @@ begin end; (* If the base_type is still nil this is record field access. *) if base_type = nil then - elna_type_simple_expression(designator_base, symbol_table); + elna_type_designator(designator_base, symbol_table); aggregate_type := ElnaTreeExpression_get_type_decoration(designator_base); name_pointer := ElnaTreeFieldAccessExpression_get_field(parser_node); name_length := ElnaTreeFieldAccessExpression_get_length(parser_node); @@ -4455,12 +4493,12 @@ begin field_name_pointer := ElnaTypeField_get_name(current_field); field_name_length := ElnaTypeField_get_length(current_field); - if string_compare(name_pointer, name_length, field_name_pointer, field_name_length) then + if string_compare(name_pointer, name_length, field_name_pointer, field_name_length) = 0 then (* Debug. Error stream output. - _syscall(2, name_pointer, name_length, 0, 0, 0, 64); *) + _syscall(2, name_pointer, name_length, 0, 0, 0, 64); printf("# if %.*s\n\0", name_length, name_pointer); - fflush(0) - else + fflush(0) *) + field_count := field_count - 1; current_field := current_field + ElnaTypeField_size(); goto elna_type_designator_field diff --git a/boot/stage17/cl.elna b/boot/stage17/cl.elna index 66f4282..7f33df0 100644 --- a/boot/stage17/cl.elna +++ b/boot/stage17/cl.elna @@ -938,19 +938,19 @@ end; proc elna_rtl_binary_operands(tac_instruction: Word, next_instruction: Word); var - lhs: Word; - rhs: Word; + lhs: ^ElnaInstructionList; + rhs: ^ElnaInstructionList; begin lhs := elna_rtl_load_operand_value(tac_instruction, 2, ElnaRtlRegister.t2); rhs := elna_rtl_load_operand_value(tac_instruction, 3, ElnaRtlRegister.t3); - next_instruction^ := ElnaInstructionList_get_next(lhs); + next_instruction^ := lhs^.next; if next_instruction^ = 0 then - ElnaInstructionList_set_next(lhs, rhs) + lhs^.next := rhs else - ElnaInstructionList_set_next(next_instruction^, rhs) + next_instruction^^ := rhs end; - next_instruction^ := ElnaInstructionList_get_next(rhs); + next_instruction^ := rhs^.next; if next_instruction^ = 0 then next_instruction^ := rhs end; @@ -1040,12 +1040,12 @@ end; proc elna_rtl_instruction(tac_instruction: Word, next_instruction: Word); var - result: Word; + result: ^ElnaInstructionList; instruction_size: Word; instruction_kind: Word; operand_type: Word; operand_value: Word; - operands: Word; + operands: ^ElnaInstructionList; intermediate_instruction: Word; begin instruction_size := elna_rtl_instruction_size(); @@ -1101,7 +1101,7 @@ begin operands := elna_rtl_load_operand_value(tac_instruction, 1, ElnaRtlRegister.t0); next_instruction^ := elna_rtl_instruction_create(ElnaRtlOperator.sw); result := operands; - operands := ElnaInstructionList_get_next(result); + operands := result^.next; elna_rtl_instruction_set_operand(next_instruction^, 1, ElnaRtlOperand.register, ElnaRtlRegister.t0, 0); @@ -1214,11 +1214,11 @@ begin if operand_type = ElnaTacOperand.temporary then result := elna_rtl_load_operand_value(tac_instruction, 2, operand_value); - next_instruction^ := ElnaInstructionList_get_next(result) + next_instruction^ := result^.next elsif operand_type = ElnaTacOperand.stack then operands := elna_rtl_load_operand_value(tac_instruction, 2, ElnaRtlRegister.t4); result := operands; - operands := ElnaInstructionList_get_next(result); + operands := result^.next; next_instruction^ := elna_rtl_instruction_create(ElnaRtlOperator.sw); _elna_tac_instruction_set_operand(next_instruction^, 1, ElnaRtlOperand.register, ElnaRtlRegister.t4, 0); @@ -1413,7 +1413,7 @@ begin _write_c('\n') end; -proc elna_rtl_instructions(instruction: Word); +proc elna_rtl_instructions(instruction: ^ElnaInstructionList); var current_copy: Word; next_copy: Word; @@ -1422,7 +1422,7 @@ var begin if instruction <> 0 then first_copy := elna_rtl_instruction(instruction, @current_copy); - instruction := ElnaInstructionList_get_next(instruction) + instruction := instruction^.next else first_copy := 0; current_copy := 0 @@ -1432,7 +1432,7 @@ begin if instruction <> 0 then next_copy := elna_rtl_instruction(instruction, @last_copy); - instruction := ElnaInstructionList_get_next(instruction); + instruction := instruction^.next; ElnaInstructionList_set_next(current_copy, next_copy); current_copy := last_copy; goto elna_rtl_instructions_start @@ -1441,120 +1441,96 @@ begin return first_copy end; -proc _elna_writer_instructions(instruction: Word); +proc _elna_writer_instructions(instruction: ^ElnaInstructionList); begin .elna_writer_instructions_start; if instruction <> 0 then _elna_writer_instruction(instruction); - instruction := ElnaInstructionList_get_next(instruction); + instruction := instruction^.next; goto elna_writer_instructions_start end end; -proc _elna_writer_procedure(procedure: Word); -var - name_pointer: Word; - name_length: Word; - body_statements: Word; - has_stack: Word; +proc _elna_writer_procedure(procedure: ^ElnaInstructionDeclaration); begin .elna_writer_procedure_loop; - name_pointer := ElnaInstructionDeclaration_get_name(procedure); - name_length := ElnaInstructionDeclaration_get_length(procedure); - body_statements := ElnaInstructionDeclaration_get_body(procedure); - has_stack := ElnaInstructionDeclaration_get_stack(procedure); (* Write .type _procedure_name, @function. *) _write_z(".type \0"); - _write_s(name_pointer, name_length); + _write_s(procedure^.name, procedure^.length); _write_z(", @function\n\0"); (* Write procedure label, _procedure_name: *) - _write_s(name_pointer, name_length); + _write_s(procedure^.name, procedure^.length); _write_z(":\n\0"); (* Write the prologue. *) - if has_stack then + if procedure^.stack then _write_z("\taddi sp, sp, -144\n\tsw ra, 140(sp)\n\tsw s0, 136(sp)\n\taddi s0, sp, 144\n\0") end; - _elna_writer_instructions(body_statements); + _elna_writer_instructions(procedure^.body); (* Write the epilogue. *) - if has_stack then + if procedure^.stack then _write_z("\tlw ra, 140(sp)\n\tlw s0, 136(sp)\n\taddi sp, sp, 144\n\0") end; _write_z("\tret\n\0"); - procedure := ElnaInstructionList_get_next(procedure); + procedure := procedure^.next; if procedure <> 0 then goto elna_writer_procedure_loop end end; -proc _elna_writer_variable(variable: Word); -var - name: Word; - name_length: Word; - size: Word; +proc _elna_writer_variable(variable: ^ElnaInstructionDeclaration); begin .elna_writer_variable_loop; if variable <> 0 then - name := ElnaInstructionDeclaration_get_name(variable); - name_length := ElnaInstructionDeclaration_get_length(variable); - size := ElnaInstructionDeclaration_get_body(variable); - _write_z(".type \0"); - _write_s(name, name_length); + _write_s(variable^.name, variable^.length); _write_z(", @object\n\0"); - _write_s(name, name_length); + _write_s(variable^.name, variable^.length); _write_c(':'); _write_z(" .zero \0"); - _write_i(size); + _write_i(variable^.body); _write_c('\n'); - variable := ElnaInstructionList_get_next(variable); + variable := variable^.next; goto elna_writer_variable_loop end end; -proc elna_rtl_module_declaration(tac_module: Word); +proc elna_rtl_module_declaration(tac_module: ^ElnaInstructionModule); var code_part: Word; data_part: Word; - current_part: Word; begin - current_part := ElnaInstructionModule_get_data(tac_module); - data_part := elna_rtl_globals(current_part); - - current_part := ElnaInstructionModule_get_code(tac_module); - code_part := elna_rtl_procedures(current_part); + data_part := elna_rtl_globals(tac_module^.data); + code_part := elna_rtl_procedures(tac_module^.code); return elna_instruction_module_create(data_part, code_part) end; -proc _elna_writer_module(pair: Word); +proc _elna_writer_module(pair: ^ElnaInstructionModule); var compiler_strings_copy: Word; compiler_strings_end: Word; current_byte: Word; - current_part: Word; begin _write_z(".globl main\n\n\0"); _write_z(".section .data\n\0"); - current_part := ElnaInstructionModule_get_data(pair); - _elna_writer_variable(current_part); + _elna_writer_variable(pair^.data); _write_z(".section .text\n\n\0"); _write_z(".type _syscall, @function\n_syscall:\n\tmv a7, a6\n\tecall\n\tret\n\n\0"); _write_z(".type _load_byte, @function\n_load_byte:\n\tlb a0, (a0)\nret\n\n\0"); _write_z(".type _store_byte, @function\n_store_byte:\n\tsb a0, (a1)\nret\n\n\0"); - current_part := ElnaInstructionModule_get_code(pair); - _elna_writer_procedure(current_part); + _elna_writer_procedure(pair^.code); _write_z(".section .rodata\n.type strings, @object\nstrings: .ascii \0"); _write_c('"'); @@ -1578,43 +1554,44 @@ proc elna_parser_integer_literal(); var integer_token: Word; integer_length: Word; - result: Word; + result: ^ElnaTreeIntegerLiteral; begin result := malloc(ElnaTreeIntegerLiteral_size()); + (* TODO: Convert the integer string to a number. *) integer_token := _elna_lexer_global_get_start(); integer_length := _elna_lexer_global_get_end(); integer_length := integer_length - integer_token; _elna_lexer_skip_token(); - ElnaTreeNode_set_kind(result, ElnaTreeKind.integer_literal); - ElnaTreeIntegerLiteral_set_value(result, integer_token); - ElnaTreeIntegerLiteral_set_length(result, integer_length); - ElnaTreeExpression_set_type_decoration(result, nil); + result^.kind := ElnaTreeKind.integer_literal; + result^.value := integer_token; + result^.length := integer_length; + result^.type_decoration := nil; return result end; proc elna_parser_nil_literal(); var - result: Word; + result: ^ElnaTreeNilLiteral; begin _elna_lexer_skip_token(); result := malloc(ElnaTreeNilLiteral_size()); - ElnaTreeNode_set_kind(result, ElnaTreeKind.null); - ElnaTreeExpression_set_type_decoration(result, nil); + result^.kind := ElnaTreeKind.null; + result^.type_decoration := nil; return result end; -proc _elna_tac_integer_literal(integer_literal_node: Word, operand_type: Word, operand_value: Word, operand_length: Word); +proc _elna_tac_integer_literal(integer_literal_node: ^ElnaTreeIntegerLiteral, operand_type: Word, operand_value: Word, operand_length: Word); begin operand_type^ := ElnaTacOperand.immediate; - operand_value^ := ElnaTreeIntegerLiteral_get_value(integer_literal_node); - operand_length^ := ElnaTreeIntegerLiteral_get_length(integer_literal_node); + operand_value^ := integer_literal_node^.value; + operand_length^ := integer_literal_node^.length; - return 0 + return nil end; proc _elna_tac_nil_literal(nil_node: Word, operand_type: Word, operand_value: Word, operand_length: Word); @@ -1623,14 +1600,14 @@ begin operand_value^ := 0; operand_length^ := 0; - return 0 + return nil end; proc elna_parser_character_literal(); var character: Word; character_length: Word; - result: Word; + result: ^ElnaTreeIntegerLiteral; begin result := malloc(ElnaTreeCharacterLiteral_size()); @@ -1639,28 +1616,28 @@ begin character_length := character_length - character; _elna_lexer_skip_token(); - ElnaTreeNode_set_kind(result, ElnaTreeKind.character_literal); - ElnaTreeIntegerLiteral_set_value(result, character); - ElnaTreeIntegerLiteral_set_length(result, character_length); - ElnaTreeExpression_set_type_decoration(result, nil); + result^.kind := ElnaTreeKind.character_literal; + result^.value := character; + result^.length := character_length; + result^.type_decoration := nil; return result end; -proc _elna_tac_character_literal(character_literal_node: Word, operand_type: Word, operand_value: Word, operand_length: Word); +proc _elna_tac_character_literal(character_literal_node: ^ElnaTreeCharacterLiteral, operand_type: Word, operand_value: Word, operand_length: Word); begin operand_type^ := ElnaTacOperand.immediate; - operand_value^ :=ElnaTreeCharacterLiteral_get_value(character_literal_node); - operand_length^ := ElnaTreeCharacterLiteral_get_length(character_literal_node); + operand_value^ := character_literal_node^.value; + operand_length^ := character_literal_node^.length; - return 0 + return nil end; proc elna_parser_variable_expression(); var name_pointer: Word; name_length: Word; - result: Word; + result: ^ElnaTreeVariableExpression; begin name_pointer := _elna_lexer_global_get_start(); name_length := _elna_lexer_global_get_end() - name_pointer; @@ -1668,34 +1645,29 @@ begin result := malloc(ElnaTreeVariableExpression_size()); - ElnaTreeNode_set_kind(result, ElnaTreeKind.variable_expression); - ElnaTreeVariableExpression_set_name(result, name_pointer); - ElnaTreeVariableExpression_set_length(result, name_length); - ElnaTreeExpression_set_type_decoration(result, nil); + result^.kind := ElnaTreeKind.variable_expression; + result^.name := name_pointer; + result^.length := name_length; + result^.type_decoration := nil; return result end; -proc _elna_tac_variable_expression(variable_expression: Word, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word); +proc _elna_tac_variable_expression(variable_expression: ^ElnaTreeVariableExpression, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word); var - name_pointer: Word; - name_length: Word; - lookup_result: Word; + lookup_result: ^_parameter_info; begin - name_pointer := ElnaTreeVariableExpression_get_name(variable_expression); - name_length := ElnaTreeVariableExpression_get_length(variable_expression); - - lookup_result := _symbol_table_lookup(symbol_table, name_pointer, name_length); - if lookup_result <> 0 then + lookup_result := _symbol_table_lookup(symbol_table, variable_expression^.name, variable_expression^.length); + if lookup_result <> nil then operand_type^ := ElnaTacOperand.stack; - operand_value^ := _parameter_info_get_offset(lookup_result); + operand_value^ := lookup_result^.offset; operand_length^ := 0 else operand_type^ := ElnaTacOperand.symbol; - operand_value^ := name_pointer; - operand_length^ := name_length + operand_value^ := variable_expression^.name; + operand_length^ := variable_expression^.length end; - return 0 + return nil end; proc elna_parser_string_literal(); @@ -1789,14 +1761,18 @@ var begin simple_expression := elna_parser_simple_expression(); + .elna_parser_designator_loop; _elna_lexer_read_token(@token_kind); if token_kind = ElnaLexerKind.hat then - simple_expression := elna_parser_dereference_expression(simple_expression) + simple_expression := elna_parser_dereference_expression(simple_expression); + goto elna_parser_designator_loop elsif token_kind = ElnaLexerKind.dot then - simple_expression := elna_parser_field_access_expression(simple_expression) + simple_expression := elna_parser_field_access_expression(simple_expression); + goto elna_parser_designator_loop elsif token_kind = ElnaLexerKind.left_paren then - simple_expression := elna_parser_call(simple_expression) + simple_expression := elna_parser_call(simple_expression); + goto elna_parser_designator_loop end; return simple_expression end; @@ -2414,12 +2390,21 @@ var first_instruction: Word; last_instruction: Word; type_kind: Word; + designator_base: Word; + aggregate_type: Word; + name_pointer: Word; + name_length: Word; + field_name_pointer: Word; + field_name_length: Word; + field_count: Word; + current_field: Word; + field_offset: Word; begin node_kind := ElnaTreeNode_get_kind(parser_node); if node_kind = ElnaTreeKind.dereference_expression then parser_node := ElnaTreeDereferenceExpression_get_pointer(parser_node); - first_instruction := _elna_tac_simple_expression(parser_node, symbol_table, operand_type, operand_value, operand_length); + first_instruction := _elna_tac_designator(parser_node, symbol_table, is_address, operand_type, operand_value, operand_length); last_instruction := _elna_tac_instruction_create(ElnaTacOperator.copy); _elna_tac_instruction_set_operand(last_instruction, 1, ElnaTacOperand.temporary, 6, 0); @@ -2436,17 +2421,42 @@ begin type_kind := ElnaType_get_kind(expression_type); if type_kind = ElnaTypeKind.enumeration then - first_instruction := _elna_tac_enumeration_value(parser_node, operand_type, operand_value, operand_length) + first_instruction := _elna_tac_enumeration_value(parser_node, operand_type, operand_value, operand_length); + is_address^ := 0 else - (* Stub for record field access. Always generate nil for field access expression until it is implemented. *) + designator_base := ElnaTreeFieldAccessExpression_get_aggregate(parser_node); + first_instruction := _elna_tac_designator(designator_base, symbol_table, is_address, operand_type, operand_value, operand_length); + aggregate_type := ElnaTreeExpression_get_type_decoration(designator_base); + name_pointer := ElnaTreeFieldAccessExpression_get_field(parser_node); + name_length := ElnaTreeFieldAccessExpression_get_length(parser_node); - operand_type^ := ElnaTacOperand.immediate; - operand_value^ := 0; + field_count := ElnaTypeRecord_get_length(aggregate_type); + current_field := ElnaTypeRecord_get_members(aggregate_type); + field_offset := 0; + + .elna_tac_designator_field; + + field_name_pointer := ElnaTypeField_get_name(current_field); + field_name_length := ElnaTypeField_get_length(current_field); + + if string_compare(name_pointer, name_length, field_name_pointer, field_name_length) = 0 then + field_count := field_count - 1; + current_field := current_field + ElnaTypeField_size(); + field_offset := field_offset + 4; + goto elna_tac_designator_field + end; + last_instruction := _elna_tac_instruction_create(ElnaTacOperator.add); + _elna_tac_instruction_set_operand(last_instruction, 1, ElnaTacOperand.temporary, 6, 0); + _elna_tac_instruction_set_operand(last_instruction, 2, ElnaTacOperand.immediate, field_offset, 0); + _elna_tac_instruction_set_operand(last_instruction, 3, operand_type^, operand_value^, operand_length^); + + operand_type^ := ElnaTacOperand.temporary; + operand_value^ := 6; operand_length^ := 0; - first_instruction := nil + is_address^ := 1; + first_instruction := elna_instruction_list_concatenate(first_instruction, last_instruction) end; - is_address^ := 0 elsif node_kind = ElnaTreeKind.call then first_instruction := _elna_tac_call(parser_node, symbol_table); @@ -3505,40 +3515,28 @@ begin return first_instruction end; -proc elna_rtl_global_declaration(tac_declaration: Word); +proc elna_rtl_global_declaration(tac_declaration: ^ElnaInstructionDeclaration); var - name: Word; - length: Word; - body: Word; - result: Word; + result: ElnaInstructionDeclaration; begin result := malloc(ElnaInstructionDeclaration_size()); - name := ElnaInstructionDeclaration_get_name(tac_declaration); - length := ElnaInstructionDeclaration_get_length(tac_declaration); - body := ElnaInstructionDeclaration_get_body(tac_declaration); - ElnaInstructionList_set_next(result, 0); - ElnaInstructionDeclaration_set_name(result, name); - ElnaInstructionDeclaration_set_length(result, length); - ElnaInstructionDeclaration_set_body(result, body); + result^.next := 0; + result^.name := tac_declaration^.name; + result^.length := tac_declaration^.length; + result^.body := tac_declaration^.body; return result end; -proc elna_rtl_procedure_declaration(tac_declaration: Word); +proc elna_rtl_procedure_declaration(tac_declaration: ^ElnaInstructionDeclaration); var - name: Word; - length: Word; body: Word; - result: Word; + result: ^ElnaInstructionDeclaration; return_instruction: Word; - has_stack: Word; begin result := malloc(ElnaInstructionDeclaration_size()); - name := ElnaInstructionDeclaration_get_name(tac_declaration); - length := ElnaInstructionDeclaration_get_length(tac_declaration); - has_stack := ElnaInstructionDeclaration_get_stack(tac_declaration); - body := ElnaInstructionDeclaration_get_body(tac_declaration); + body := tac_declaration^.body; body := elna_rtl_instructions(body); return_instruction := elna_rtl_instruction_create(ElnaRtlOperator.allocate_stack); @@ -3547,50 +3545,45 @@ begin return_instruction := elna_rtl_instruction_create(ElnaRtlOperator.ret); elna_instruction_list_concatenate(body, return_instruction); - ElnaInstructionList_set_next(result, 0); - ElnaInstructionDeclaration_set_name(result, name); - ElnaInstructionDeclaration_set_length(result, length); - ElnaInstructionDeclaration_set_stack(result, has_stack); - ElnaInstructionDeclaration_set_body(result, body); + result^.next := nil; + result^.name := tac_declaration^.name; + result^.length := tac_declaration^.length; + result^.stack := tac_declaration^.stack; + result^.body := body; return result end; -proc _elna_tac_procedure_declaration(parser_node: Word); +proc _elna_tac_procedure_declaration(parser_node: _procedure_declaration); var - name_pointer: Word; - name_length: Word; current_parameter: Word; body: Word; new_symbol_table: Word; - symbol_info: Word; + symbol_info: ^_procedure_info; instruction: Word; first_instruction: Word; - result: Word; + result: ^ElnaInstructionDeclaration; result_size: Word; begin result := malloc(ElnaInstructionDeclaration_size()); - ElnaInstructionList_set_next(result, 0); - ElnaInstructionDeclaration_set_stack(result, 1); + result^.next := nil; + result^.stack := 1; - name_pointer := _declaration_get_name(parser_node); - name_length := _declaration_get_length(parser_node); + result^.name := parser_node^.name; + result^.length := parser_node^.length; - ElnaInstructionDeclaration_set_name(result, name_pointer); - ElnaInstructionDeclaration_set_length(result, name_length); + symbol_info := _symbol_table_lookup(@symbol_table_global, parser_node^.name, parser_node^.length); + new_symbol_table := symbol_info^.symbol_table; - symbol_info := _symbol_table_lookup(@symbol_table_global, name_pointer, name_length); - new_symbol_table := _procedure_info_get_symbol_table(symbol_info); - - current_parameter := _procedure_declaration_get_parameters(parser_node); + current_parameter := parser_node^.parameters; first_instruction := _elna_tac_parameters(current_parameter, new_symbol_table); body := _procedure_declaration_get_body(parser_node); instruction := _elna_tac_statements(body, new_symbol_table); first_instruction := elna_instruction_list_concatenate(first_instruction, instruction); - ElnaInstructionDeclaration_set_body(result, first_instruction); + result^.body := first_instruction; return result end; @@ -3626,17 +3619,17 @@ begin return result end; -proc elna_rtl_globals(tac_procedure: Word); +proc elna_rtl_globals(tac_procedure: ^ElnaInstructionList); var - current_copy: Word; + current_copy: ^ElnaInstructionList; next_copy: Word; - first_copy: Word; + first_copy: ^ElnaInstructionList; begin if tac_procedure <> 0 then first_copy := elna_rtl_global_declaration(tac_procedure); - tac_procedure := ElnaInstructionList_get_next(tac_procedure) + tac_procedure := tac_procedure^.next else - first_copy := 0; + first_copy := nil end; current_copy := first_copy; @@ -3645,8 +3638,8 @@ begin if tac_procedure <> 0 then next_copy := elna_rtl_global_declaration(tac_procedure); - tac_procedure := ElnaInstructionList_get_next(tac_procedure); - ElnaInstructionList_set_next(current_copy, next_copy); + tac_procedure := tac_procedure^.next; + current_copy^.next := next_copy; current_copy := next_copy; goto elna_rtl_globals_start end; @@ -3654,27 +3647,27 @@ begin return first_copy end; -proc elna_rtl_procedures(tac_procedure: Word); +proc elna_rtl_procedures(tac_procedure: ^ElnaInstructionList); var - current_copy: Word; + current_copy: ^ElnaInstructionList; next_copy: Word; - first_copy: Word; + first_copy: ^ElnaInstructionList; begin - if tac_procedure <> 0 then + if tac_procedure <> nil then first_copy := elna_rtl_procedure_declaration(tac_procedure); - tac_procedure := ElnaInstructionList_get_next(tac_procedure) + tac_procedure := tac_procedure^.next else - first_copy := 0; + first_copy := nil; end; current_copy := first_copy; .elna_rtl_procedures_start; - if tac_procedure <> 0 then + if tac_procedure <> nil then next_copy := elna_rtl_procedure_declaration(tac_procedure); - tac_procedure := ElnaInstructionList_get_next(tac_procedure); - ElnaInstructionList_set_next(current_copy, next_copy); + tac_procedure := tac_procedure^.next; + current_copy^.next := next_copy; current_copy := next_copy; goto elna_rtl_procedures_start end; @@ -3682,10 +3675,10 @@ begin return first_copy end; -proc _elna_tac_procedures(parser_node: Word); +proc _elna_tac_procedures(parser_node: ^_declaration); var result: Word; - current_procedure: Word; + current_procedure: ^ElnaInstructionList; first_procedure: Word; begin first_procedure := 0; @@ -3698,11 +3691,11 @@ begin if first_procedure = 0 then first_procedure := result else - ElnaInstructionList_set_next(current_procedure, result) + current_procedure^.next := result end; current_procedure := result; - parser_node := _declaration_get_next(parser_node); + parser_node := parser_node^.next; goto elna_tac_procedures_loop; .elna_tac_procedures_end; @@ -3757,16 +3750,16 @@ begin return result end; -proc elna_name_type_declaration(parser_node: Word); +proc elna_name_type_declaration(parser_node: ^_type_declaration); var type_name: Word; name_length: Word; type_info: Word; begin - type_name := _declaration_get_name(parser_node); - name_length := _declaration_get_length(parser_node); + type_name := parser_node^.name; + name_length := parser_node^.length; - parser_node := _type_declaration_get__type(parser_node); + parser_node := parser_node^._type; type_info := elna_name_type_expression(parser_node); type_info := _type_info_create(type_info); @@ -3843,32 +3836,32 @@ begin return result end; -proc _elna_tac_variable_declaration(parser_tree: Word); +proc _elna_tac_variable_declaration(parser_tree: ^_variable_declaration); var name: Word; name_length: Word; - variable_type: Word; - result: Word; + variable_type: ^ElnaTreeNamedTypeExpression; + result: ^ElnaInstructionDeclaration; begin result := malloc(ElnaInstructionDeclaration_size()); - ElnaInstructionList_set_next(result, 0); + result^.next := nil; - name := _declaration_get_name(parser_tree); - name_length := _declaration_get_length(parser_tree); - variable_type := _variable_declaration_get__type(parser_tree); + name := parser_tree^.name; + name_length := parser_tree^.length; + variable_type := parser_tree^._type; - ElnaInstructionDeclaration_set_name(result, name); - ElnaInstructionDeclaration_set_length(result, name_length); + result^.name := name; + result^.length := name_length; - name := ElnaTreeNamedTypeExpression_get_name(variable_type); - name_length := ElnaTreeNamedTypeExpression_get_length(variable_type); + name := variable_type^.name; + name_length := variable_type^.length; if string_compare("Array", 5, name, name_length) then (* Else we assume this is a zeroed 4096 bytes big array. *) - ElnaInstructionDeclaration_set_body(result, 4096) + result^.body := 4096 else - ElnaInstructionDeclaration_set_body(result, 4) + result^.body := 4 end; return result end; @@ -3937,11 +3930,10 @@ begin return first_result end; -proc _elna_tac_type_record(name_pointer: Word, name_length: Word, type_representation: Word, current_result: Word); +proc _elna_tac_type_record(name_pointer: Word, name_length: Word, type_representation: ^ElnaTypeRecord, current_result: Word); var first_result: Word; - result: Word; - type_size: Word; + result: ^ElnaInstructionList; new_name: Word; new_length: Word; instruction: Word; @@ -3952,7 +3944,6 @@ begin first_result := malloc(ElnaInstructionDeclaration_size()); result := 0; - type_size := ElnaType_get_size(type_representation); new_length := name_length + 5; new_name := malloc(new_length); @@ -3964,12 +3955,12 @@ begin instruction := _elna_tac_instruction_create(ElnaTacOperator.copy); _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 11, 0); - _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.immediate, type_size, 0); + _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.immediate, type_representation^.size, 0); ElnaInstructionDeclaration_set_body(first_result, instruction); - field_count := ElnaTypeRecord_get_length(type_representation); - field_pointer := ElnaTypeRecord_get_members(type_representation); + field_count := type_representation^.length; + field_pointer := type_representation^.members; field_offset := 0; current_result^ := first_result; @@ -3978,7 +3969,7 @@ begin result := _elna_tac_type_field(name_pointer, name_length, field_pointer, field_offset); ElnaInstructionList_set_next(current_result^, result); - current_result^ := ElnaInstructionList_get_next(result); + current_result^ := result^.next; field_offset := field_offset + 4; field_count := field_count - 1; @@ -3989,17 +3980,15 @@ begin return first_result end; -proc _elna_tac_type_part(parser_node: Word); +proc _elna_tac_type_part(parser_node: ^_declaration); var - name_pointer: Word; - name_length: Word; result: Word; first_result: Word; - symbol: Word; - info_type: Word; + symbol: ^_type_info; + info_type: ^ElnaType; type_kind: Word; - current_result: Word; - out_result: Word; + current_result: ^ElnaInstructionList; + out_result: ^ElnaInstructionList; begin first_result := 0; @@ -4007,16 +3996,13 @@ begin if parser_node = 0 then goto elna_tac_type_part_end end; + symbol := _symbol_table_lookup(@symbol_table_global, parser_node^.name, parser_node^.length); - name_pointer := _declaration_get_name(parser_node); - name_length := _declaration_get_length(parser_node); - symbol := _symbol_table_lookup(@symbol_table_global, name_pointer, name_length); - - info_type := _type_info_get__type(symbol); - type_kind := ElnaType_get_kind(info_type); + info_type := symbol^._type; + type_kind := info_type^.kind; if type_kind = ElnaTypeKind._record then - result := _elna_tac_type_record(name_pointer, name_length, info_type, @out_result) + result := _elna_tac_type_record(parser_node^.name, parser_node^.length, info_type, @out_result) else result := 0; out_result := 0 @@ -4025,10 +4011,10 @@ begin first_result := result; current_result := out_result elsif result <> 0 then - ElnaInstructionList_set_next(current_result, result); + current_result^.next := result; current_result := out_result end; - parser_node := _declaration_get_next(parser_node); + parser_node := parser_node^.next; goto elna_tac_type_part_loop; .elna_tac_type_part_end; @@ -4075,10 +4061,10 @@ begin return result end; -proc _elna_tac_var_part(parser_node: Word); +proc _elna_tac_var_part(parser_node: ^_declaration); var node: Word; - current_variable: Word; + current_variable: ^ElnaInstructionList; first_variable: Word; begin first_variable := 0; @@ -4091,11 +4077,11 @@ begin if first_variable = 0 then first_variable := node else - ElnaInstructionList_set_next(current_variable, node) + current_variable^.next := node end; current_variable := node; - parser_node := _declaration_get_next(parser_node); + parser_node := parser_node^.next; if parser_node <> 0 then goto elna_tac_var_part_loop end; @@ -4136,33 +4122,28 @@ end; (** * Process the source code and print the generated code. *) -proc _elna_tac_module_declaration(parser_node: Word); +proc _elna_tac_module_declaration(parser_node: ^_module_declaration); var data_part: Word; code_part: Word; type_part: Word; - current_declaration: Word; + current_declaration: ^ElnaInstructionList; next_declaration: Word; begin - type_part := _module_declaration_get_types(parser_node); - type_part := _elna_tac_type_part(type_part); - - data_part := _module_declaration_get_globals(parser_node); - data_part := _elna_tac_var_part(data_part); - - code_part := _module_declaration_get_procedures(parser_node); - code_part := _elna_tac_procedures(code_part); + type_part := _elna_tac_type_part(parser_node^.types); + data_part := _elna_tac_var_part(parser_node^.globals); + code_part := _elna_tac_procedures(parser_node^.procedures); current_declaration := code_part; .elna_tac_module_declaration_types; - next_declaration := ElnaInstructionList_get_next(current_declaration); - if next_declaration <> 0 then + next_declaration := current_declaration^.next; + if next_declaration <> nil then current_declaration := next_declaration; goto elna_tac_module_declaration_types end; - ElnaInstructionList_set_next(current_declaration, type_part); + current_declaration^.next := type_part; return elna_instruction_module_create(data_part, code_part) end; @@ -4411,7 +4392,7 @@ begin if expression_kind = ElnaTreeKind.dereference_expression then designator_base := ElnaTreeDereferenceExpression_get_pointer(parser_node); - elna_type_simple_expression(designator_base, symbol_table); + elna_type_designator(designator_base, symbol_table); base_type := ElnaTreeExpression_get_type_decoration(designator_base); type_kind := ElnaType_get_kind(base_type); @@ -4442,7 +4423,7 @@ begin end; (* If the base_type is still nil this is record field access. *) if base_type = nil then - elna_type_simple_expression(designator_base, symbol_table); + elna_type_designator(designator_base, symbol_table); aggregate_type := ElnaTreeExpression_get_type_decoration(designator_base); name_pointer := ElnaTreeFieldAccessExpression_get_field(parser_node); name_length := ElnaTreeFieldAccessExpression_get_length(parser_node); @@ -4455,12 +4436,12 @@ begin field_name_pointer := ElnaTypeField_get_name(current_field); field_name_length := ElnaTypeField_get_length(current_field); - if string_compare(name_pointer, name_length, field_name_pointer, field_name_length) then + if string_compare(name_pointer, name_length, field_name_pointer, field_name_length) = 0 then (* Debug. Error stream output. - _syscall(2, name_pointer, name_length, 0, 0, 0, 64); *) + _syscall(2, name_pointer, name_length, 0, 0, 0, 64); printf("# if %.*s\n\0", name_length, name_pointer); - fflush(0) - else + fflush(0) *) + field_count := field_count - 1; current_field := current_field + ElnaTypeField_size(); goto elna_type_designator_field @@ -5558,5 +5539,5 @@ proc f(x: ElnaTreeExpression); var y: Word; begin - y := x.type_decoration + y := x.kind end;