diff --git a/boot/stage16/cl.elna b/boot/stage16/cl.elna index fc44bc7..bc127d3 100644 --- a/boot/stage16/cl.elna +++ b/boot/stage16/cl.elna @@ -7,6 +7,9 @@ program; (* Stage 16 compiler. *) +(* - Support for field access on records. *) +(* - More than one nested designator expression in another designator expression. *) + type (** * List of intermediate representation items. diff --git a/boot/stage17/cl.elna b/boot/stage17/cl.elna index 7f33df0..7a33f6e 100644 --- a/boot/stage17/cl.elna +++ b/boot/stage17/cl.elna @@ -5,7 +5,7 @@ *) program; -(* Stage 16 compiler. *) +(* Stage 17 compiler. *) type (** @@ -801,12 +801,12 @@ end; proc elna_rtl_instruction_create(kind: Word); var - result: Word; + result: ^ElnaInstructionList; begin result := malloc(elna_rtl_instruction_size()); elna_rtl_instruction_set_kind(result, kind); - ElnaInstructionList_set_next(result, 0); + result^.next := nil; return result end; @@ -875,7 +875,7 @@ end; proc elna_rtl_load_operand_value(tac_instruction: Word, operand_number: Word, into: Word); var - result: Word; + result: ^ElnaInstructionList; operand_value: Word; operand_length: Word; operand_type: Word; @@ -902,7 +902,7 @@ begin elna_rtl_instruction_set_operand(next_instruction, 1, ElnaRtlOperand.register, into, 0); elna_rtl_instruction_set_operand(next_instruction, 2, ElnaRtlOperand.offset, into, 0); - ElnaInstructionList_set_next(result, next_instruction) + result^.next := next_instruction elsif operand_type = ElnaTacOperand.temporary then result := elna_rtl_instruction_create(ElnaRtlOperator.move); elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0); @@ -962,6 +962,7 @@ proc elna_rtl_binary_arithmetic(tac_instruction: Word, next_instruction: Word, o var lhs: Word; binary_result: Word; + intermediate_instruction: ^ElnaInstructionList; begin lhs := elna_rtl_binary_operands(tac_instruction, next_instruction); binary_result := elna_rtl_instruction_create(operation); @@ -971,7 +972,8 @@ begin elna_rtl_instruction_set_operand(binary_result, 3, ElnaRtlOperand.register, ElnaRtlRegister.t3, 0); elna_rtl_instruction_set_kind(binary_result, operation); - ElnaInstructionList_set_next(next_instruction^, binary_result); + intermediate_instruction := next_instruction^; + intermediate_instruction^.next := binary_result; next_instruction^ := binary_result; return lhs @@ -980,22 +982,26 @@ end; proc elna_rtl_binary_equality(tac_instruction: Word, instruction_kind: Word, next_instruction: Word); var operands: Word; - intermediate_instruction: Word; + intermediate_instruction: ^ElnaInstructionList; + operating_instruction: ^ElnaInstructionList; binary_result: Word; begin operands := elna_rtl_binary_operands(tac_instruction, next_instruction); - intermediate_instruction := elna_rtl_instruction_create(ElnaRtlOperator._xor); + operating_instruction := elna_rtl_instruction_create(ElnaRtlOperator._xor); - elna_rtl_instruction_set_operand(intermediate_instruction, 1, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0); - elna_rtl_instruction_set_operand(intermediate_instruction, 2, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0); - elna_rtl_instruction_set_operand(intermediate_instruction, 3, ElnaRtlOperand.register, ElnaRtlRegister.t3, 0); - ElnaInstructionList_set_next(next_instruction^, intermediate_instruction); - next_instruction^ := intermediate_instruction; + elna_rtl_instruction_set_operand(operating_instruction, 1, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0); + elna_rtl_instruction_set_operand(operating_instruction, 2, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0); + elna_rtl_instruction_set_operand(operating_instruction, 3, ElnaRtlOperand.register, ElnaRtlRegister.t3, 0); + + intermediate_instruction := next_instruction^; + intermediate_instruction^.next := operating_instruction; binary_result := elna_rtl_instruction_create(instruction_kind); elna_rtl_copy_operand(tac_instruction, 1, binary_result); elna_rtl_instruction_set_operand(binary_result, 2, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0); - ElnaInstructionList_set_next(next_instruction^, binary_result); + + intermediate_instruction := next_instruction^; + operating_instruction^.next := binary_result; next_instruction^ := binary_result; return operands @@ -1027,18 +1033,18 @@ end; proc elna_rtl_unary(tac_instruction: Word, rtl_operator: Word, next_instruction: Word); var - result: Word; + result: ^ElnaInstructionList; begin result := elna_rtl_load_operand_value(tac_instruction, 2, ElnaRtlRegister.t0); next_instruction^ := elna_rtl_instruction_create(rtl_operator); elna_rtl_copy_operand(tac_instruction, 1, result); elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.register, ElnaRtlRegister.t0); - result := ElnaInstructionList_set_next(result, next_instruction^); + result^.next := next_instruction^; return result end; -proc elna_rtl_instruction(tac_instruction: Word, next_instruction: Word); +proc elna_rtl_instruction(tac_instruction: Word, next_instruction: ^^ElnaInstructionList); var result: ^ElnaInstructionList; instruction_size: Word; @@ -1046,7 +1052,7 @@ var operand_type: Word; operand_value: Word; operands: ^ElnaInstructionList; - intermediate_instruction: Word; + intermediate_instruction: ^ElnaInstructionList; begin instruction_size := elna_rtl_instruction_size(); result := malloc(instruction_size); @@ -1089,7 +1095,7 @@ begin operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2); elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, operand_value); - ElnaInstructionList_set_next(result, next_instruction^) + result^.next := next_instruction^ elsif operand_type = ElnaTacOperand.temporary then result := elna_rtl_instruction_create(ElnaRtlOperator.lw); @@ -1114,9 +1120,9 @@ begin elna_rtl_instruction_set_operand(next_instruction^, 2, ElnaRtlOperand.offset, operand_value, 0) end; if operands = 0 then - ElnaInstructionList_set_next(result, next_instruction^) + result^.next := next_instruction^ else - ElnaInstructionList_set_next(operands, next_instruction^) + operands^.next := next_instruction^ end elsif instruction_kind = ElnaTacOperator.proc_call then result := elna_rtl_instruction_create(ElnaRtlOperator.jal); @@ -1145,7 +1151,8 @@ begin elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.register, ElnaRtlRegister.t3, 0); elna_rtl_instruction_set_operand(result, 3, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0); - ElnaInstructionList_set_next(next_instruction^, result); + intermediate_instruction := next_instruction^; + intermediate_instruction^.next := result; next_instruction^ := result; result := operands; @@ -1157,18 +1164,18 @@ begin elna_rtl_instruction_set_operand(intermediate_instruction, 1, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0); elna_rtl_instruction_set_operand(intermediate_instruction, 2, ElnaRtlOperand.register, ElnaRtlRegister.t3, 0); elna_rtl_instruction_set_operand(intermediate_instruction, 3, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0); - ElnaInstructionList_set_next(next_instruction^, intermediate_instruction); + result := next_instruction^; + result^.next := intermediate_instruction; next_instruction^ := intermediate_instruction; result := elna_rtl_instruction_create(ElnaRtlOperator.xori); elna_rtl_copy_operand(tac_instruction, 1, result); elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0); elna_rtl_instruction_set_operand(result, 3, ElnaRtlOperand.immediate, 1, 0); - ElnaInstructionList_set_next(next_instruction^, result); + intermediate_instruction := next_instruction^; + intermediate_instruction^.next := result; next_instruction^ := result; - - result := operands; - elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.xori) + result := operands elsif instruction_kind = ElnaTacOperator.greater_or_equal then operands := elna_rtl_binary_operands(tac_instruction, next_instruction); intermediate_instruction := elna_rtl_instruction_create(ElnaRtlOperator.slt); @@ -1176,18 +1183,18 @@ begin elna_rtl_instruction_set_operand(intermediate_instruction, 1, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0); elna_rtl_instruction_set_operand(intermediate_instruction, 2, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0); elna_rtl_instruction_set_operand(intermediate_instruction, 3, ElnaRtlOperand.register, ElnaRtlRegister.t3, 0); - ElnaInstructionList_set_next(next_instruction^, intermediate_instruction); + result := next_instruction^; + result^.next := intermediate_instruction; next_instruction^ := intermediate_instruction; result := elna_rtl_instruction_create(ElnaRtlOperator.xori); elna_rtl_copy_operand(tac_instruction, 1, result); elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0); elna_rtl_instruction_set_operand(result, 3, ElnaRtlOperand.immediate, 1, 0); - ElnaInstructionList_set_next(next_instruction^, result); + intermediate_instruction := next_instruction^; + intermediate_instruction^.next := result; next_instruction^ := result; - - result := operands; - elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.xori) + result := operands elsif instruction_kind = ElnaTacOperator.equal then result := elna_rtl_binary_equality(tac_instruction, ElnaRtlOperator.seqz, next_instruction) elsif instruction_kind = ElnaTacOperator.not_equal then @@ -1224,14 +1231,14 @@ begin _elna_tac_instruction_set_operand(next_instruction^, 1, ElnaRtlOperand.register, ElnaRtlRegister.t4, 0); _elna_tac_instruction_set_operand(next_instruction^, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, operand_value); - if operands = 0 then - ElnaInstructionList_set_next(result, next_instruction^) + if operands = nil then + result^.next := next_instruction^ else - ElnaInstructionList_set_next(operands, next_instruction^) + operands^.next := next_instruction^ end end end; - if next_instruction^ = 0 then + if next_instruction^ = nil then next_instruction^ := result; end; return result @@ -1239,12 +1246,12 @@ end; proc elna_instruction_module_create(data: Word, code: Word); var - result: Word; + result: ^ElnaInstructionModule; begin result := malloc(ElnaInstructionModule_size()); - ElnaInstructionModule_set_data(result, data); - ElnaInstructionModule_set_code(result, code); + result^.data := data; + result^.code := code; return result end; @@ -1415,25 +1422,25 @@ end; proc elna_rtl_instructions(instruction: ^ElnaInstructionList); var - current_copy: Word; - next_copy: Word; - first_copy: Word; - last_copy: Word; + current_copy: ^ElnaInstructionList; + next_copy: ^ElnaInstructionList; + first_copy: ^ElnaInstructionList; + last_copy: ^ElnaInstructionList; begin - if instruction <> 0 then + if instruction <> nil then first_copy := elna_rtl_instruction(instruction, @current_copy); instruction := instruction^.next else - first_copy := 0; - current_copy := 0 + first_copy := nil; + current_copy := nil end; .elna_rtl_instructions_start; - if instruction <> 0 then + if instruction <> nil then next_copy := elna_rtl_instruction(instruction, @last_copy); instruction := instruction^.next; - ElnaInstructionList_set_next(current_copy, next_copy); + current_copy^.next := next_copy; current_copy := last_copy; goto elna_rtl_instructions_start end; @@ -1674,7 +1681,7 @@ proc elna_parser_string_literal(); var length: Word; token_start: Word; - result: Word; + result: ^ElnaTreeStringLiteral; begin result := malloc(ElnaTreeStringLiteral_size()); @@ -1682,23 +1689,21 @@ begin length := _string_length(token_start); _elna_lexer_skip_token(); - ElnaTreeNode_set_kind(result, ElnaTreeKind.string_literal); - ElnaTreeStringLiteral_set_value(result, token_start); - ElnaTreeStringLiteral_set_length(result, length); - ElnaTreeExpression_set_type_decoration(result, nil); + result^.kind := ElnaTreeKind.string_literal; + result^.value := token_start; + result^.length := length; + result^.type_decoration := nil; return result end; -proc _elna_tac_string_literal(string_literal_node: Word, operand_type: Word, operand_value: Word, operand_length: Word); +proc _elna_tac_string_literal(string_literal_node: ^ElnaTreeStringLiteral, operand_type: Word, operand_value: Word, operand_length: Word); var - token_start: Word; offset: Word; first_instruction: Word; next_instruction: Word; begin - token_start := ElnaTreeStringLiteral_get_value(string_literal_node); - offset := _add_string(token_start); + offset := _add_string(string_literal_node^.value); first_instruction := _elna_tac_instruction_create(ElnaTacOperator.get_address); _elna_tac_instruction_set_operand(first_instruction, 1, ElnaTacOperand.temporary, 6, 0); @@ -1742,13 +1747,13 @@ end; proc elna_parser_dereference_expression(simple_expression: Word); var - result: Word; + result: ^ElnaTreeDereferenceExpression; begin result := malloc(ElnaTreeDereferenceExpression_size()); - ElnaTreeNode_set_kind(result, ElnaTreeKind.dereference_expression); - ElnaTreeDereferenceExpression_set_pointer(result, simple_expression); - ElnaTreeExpression_set_type_decoration(result, nil); + result^.kind := ElnaTreeKind.dereference_expression; + result^.pointer := simple_expression; + result^.type_decoration := nil; _elna_lexer_skip_token(); return result @@ -1777,20 +1782,17 @@ begin return simple_expression end; -proc _elna_tac_simple_expression(parser_node: Word, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word); +proc _elna_tac_simple_expression(parser_node: ^ElnaTreeNode, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word); var - node_kind: Word; instruction: Word; begin - node_kind := ElnaTreeNode_get_kind(parser_node); - - if node_kind = ElnaTreeKind.character_literal then + if parser_node^.kind = ElnaTreeKind.character_literal then instruction := _elna_tac_character_literal(parser_node, operand_type, operand_value, operand_length) - elsif node_kind = ElnaTreeKind.string_literal then + elsif parser_node^.kind = ElnaTreeKind.string_literal then instruction := _elna_tac_string_literal(parser_node, operand_type, operand_value, operand_length) - elsif node_kind = ElnaTreeKind.integer_literal then + elsif parser_node^.kind = ElnaTreeKind.integer_literal then instruction := _elna_tac_integer_literal(parser_node, operand_type, operand_value, operand_length) - elsif node_kind = ElnaTreeKind.null then + elsif parser_node^.kind = ElnaTreeKind.null then instruction := _elna_tac_nil_literal(parser_node, operand_type, operand_value, operand_length) else instruction := _elna_tac_variable_expression(parser_node, symbol_table, operand_type, operand_value, operand_length) @@ -1801,7 +1803,7 @@ end; proc elna_parser_unary_expression(); var token_kind: Word; - result: Word; + result: ^ElnaTreeUnaryExpression; operand: Word; operator: Word; begin @@ -1824,20 +1826,19 @@ begin operand := result; result := malloc(ElnaTreeUnaryExpression_size()); - ElnaTreeNode_set_kind(result, ElnaTreeKind.unary_expression); - ElnaTreeUnaryExpression_set_operand(result, operand); - ElnaTreeUnaryExpression_set_operator(result, operator); - ElnaTreeExpression_set_type_decoration(result, nil) + result^.kind := ElnaTreeKind.unary_expression; + result^.operand := operand; + result^.operator := operator; + result^.type_decoration := nil end; return result end; -proc _elna_tac_unary_expression(parser_node: Word, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word); +proc _elna_tac_unary_expression(parser_node: ^ElnaTreeUnaryExpression, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word); var current_character: Word; token_kind: Word; - expression_kind: Word; operator: Word; operand: Word; is_address: Word; @@ -1848,11 +1849,9 @@ begin operator := 0; operand := 0; - expression_kind := ElnaTreeNode_get_kind(parser_node); - - if expression_kind = ElnaTreeKind.unary_expression then - operator := ElnaTreeUnaryExpression_get_operator(parser_node); - operand := ElnaTreeUnaryExpression_get_operand(parser_node) + if parser_node^.kind = ElnaTreeKind.unary_expression then + operator := parser_node^.operator; + operand := parser_node^.operand else operand := parser_node end; @@ -1915,7 +1914,7 @@ var lhs_node: Word; rhs_node: Word; token_kind: Word; - result: Word; + result: ^ElnaTreeBinaryExpression; begin lhs_node := elna_parser_unary_expression(); rhs_node := 0; @@ -1967,21 +1966,20 @@ begin if rhs_node <> 0 then result := malloc(ElnaTreeBinaryExpression_size()); - ElnaTreeNode_set_kind(result, ElnaTreeKind.binary_expression); - ElnaTreeBinaryExpression_set_lhs(result, lhs_node); - ElnaTreeBinaryExpression_set_rhs(result, rhs_node); - ElnaTreeBinaryExpression_set_operator(result, token_kind); - ElnaTreeExpression_set_type_decoration(result, nil) + result^.kind := ElnaTreeKind.binary_expression; + result^.lhs := lhs_node; + result^.rhs := rhs_node; + result^.operator := token_kind; + result^.type_decoration := nil else result := lhs_node end; return result end; -proc _elna_tac_binary_expression(parser_node: Word, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word); +proc _elna_tac_binary_expression(parser_node: ^ElnaTreeBinaryExpression, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word); var token_kind: Word; - expression_kind: Word; operand_node: Word; first_instruction: Word; instruction: Word; @@ -1990,14 +1988,12 @@ var lhs_value: Word; lhs_length: Word; begin - expression_kind := ElnaTreeNode_get_kind(parser_node); - - if expression_kind <> ElnaTreeKind.binary_expression then + if parser_node^.kind <> ElnaTreeKind.binary_expression then first_instruction := _elna_tac_unary_expression(parser_node, symbol_table, operand_type, operand_value, operand_length) else - token_kind := ElnaTreeBinaryExpression_get_operator(parser_node); + token_kind := parser_node^.operator; - operand_node := ElnaTreeBinaryExpression_get_lhs(parser_node); + operand_node := parser_node^.lhs; lhs_type := 0; lhs_value := 0; lhs_length := 0; @@ -2015,7 +2011,7 @@ begin end; current_instruction := instruction; - operand_node := ElnaTreeBinaryExpression_get_rhs(parser_node); + operand_node := parser_node^.rhs; lhs_type := 0; lhs_value := 0; lhs_length := 0; @@ -2109,13 +2105,13 @@ end; proc elna_parser_call(callee: Word); var parsed_expression: Word; - result: Word; + result: ^_statement; argument_number: Word; token_kind: Word; begin result := malloc(_call_size()); - ElnaTreeNode_set_kind(result, ElnaTreeKind.call); - _statement_set_next(result, 0); + result^.kind := ElnaTreeKind.call; + result^.next := nil; argument_number := 1; _call_set_name(result, callee); @@ -2153,7 +2149,7 @@ var name: Word; argument_count: Word; stack_offset: Word; - parsed_expression: Word; + parsed_expression: ^ElnaTreeVariableExpression; instruction: Word; first_instruction: Word; current_instruction: Word; @@ -2162,8 +2158,8 @@ var operand_length: Word; begin parsed_expression := _call_get_name(parsed_call); - name := ElnaTreeVariableExpression_get_name(parsed_expression); - name_length := ElnaTreeVariableExpression_get_length(parsed_expression); + name := parsed_expression^.name; + name_length := parsed_expression^.length; argument_count := 0; first_instruction := 0; @@ -2234,7 +2230,7 @@ var token_kind: Word; label_name: Word; label_length: Word; - result: Word; + result: ^_goto_statement; begin _elna_lexer_skip_token(); _elna_lexer_read_token(@token_kind); @@ -2245,30 +2241,28 @@ begin result := malloc(_goto_statement_size()); - ElnaTreeNode_set_kind(result, ElnaTreeKind.goto_statement); - _statement_set_next(result, 0); - _goto_statement_set_label(result, label_name); - _goto_statement_set_length(result, label_length); + result^.kind := ElnaTreeKind.goto_statement; + result^.next := nil; + result^.label := label_name; + result^.length := label_length; return result end; -proc _elna_tac_goto_statement(parser_node: Word); +proc _elna_tac_goto_statement(parser_node: ^_goto_statement); var - label_name: Word; label_length: Word; label_with_dot: Word; instruction: Word; begin - label_name := _goto_statement_get_label(parser_node); - label_length := _goto_statement_get_length(parser_node); - label_with_dot := malloc(label_length + 1); + label_length := parser_node^.length + 1; + label_with_dot := malloc(label_length); _store_byte('.', label_with_dot); - memcpy(label_with_dot + 1, label_name, label_length); + memcpy(label_with_dot + 1, parser_node^.label, parser_node^.length); instruction := _elna_tac_instruction_create(ElnaTacOperator.jump); - _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.symbol, label_with_dot, label_length + 1); + _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.symbol, label_with_dot, label_length); return instruction end; @@ -2277,7 +2271,7 @@ var token_kind: Word; label_name: Word; label_length: Word; - result: Word; + result: ^_goto_statement; begin _elna_lexer_skip_token(); _elna_lexer_read_token(@token_kind); @@ -2288,52 +2282,38 @@ begin result := malloc(_label_declaration_size()); - ElnaTreeNode_set_kind(result, ElnaTreeKind.label_declaration); - _statement_set_next(result, 0); - _goto_statement_set_label(result, label_name); - _goto_statement_set_length(result, label_length); + result^.kind := ElnaTreeKind.label_declaration; + result^.next := nil; + result^.label := label_name; + result^.length := label_length; return result end; -proc _elna_tac_label_declaration(parser_node: Word); -var - label_name: Word; - label_length: Word; -begin - label_name := _label_declaration_get_label(parser_node); - label_length := _label_declaration_get_length(parser_node); - - return _elna_tac_label(label_name, label_length) +proc _elna_tac_label_declaration(parser_node: ^_label_declaration); + return _elna_tac_label(parser_node^.label, parser_node^.length) end; -proc _elna_tac_enumeration_value(field_access_expression: Word, operand_type: Word, operand_value: Word, operand_length: Word); +proc _elna_tac_enumeration_value(field_access_expression: ^ElnaTreeFieldAccessExpression, operand_type: Word, operand_value: Word, operand_length: Word); var - enumeration_type: Word; + enumeration_type: ^ElnaTypeEnumeration; members: Word; members_length: Word; token_type: Word; - value_name: Word; - name_length: Word; + symbol_info: ^_type_info; member_name: Word; member_length: Word; counter: Word; - symbol: Word; + enumeration_type_name: ^ElnaTreeVariableExpression; begin - symbol := ElnaTreeFieldAccessExpression_get_aggregate(field_access_expression); - value_name := ElnaTreeVariableExpression_get_name(symbol); - name_length := ElnaTreeVariableExpression_get_length(symbol); + enumeration_type_name := field_access_expression^.aggregate; + symbol_info := _symbol_table_lookup(@symbol_table_global, enumeration_type_name^.name, enumeration_type_name^.length); - symbol := _symbol_table_lookup(@symbol_table_global, value_name, name_length); - - enumeration_type := _type_info_get__type(symbol); - members := ElnaTypeEnumeration_get_members(enumeration_type); - members_length := ElnaTypeEnumeration_get_length(enumeration_type); + enumeration_type := symbol_info^._type; + members := enumeration_type^.members; + members_length := enumeration_type^.length; _elna_lexer_read_token(@token_type); - - value_name := ElnaTreeFieldAccessExpression_get_field(field_access_expression); - name_length := ElnaTreeFieldAccessExpression_get_length(field_access_expression); counter := 1; .elna_tac_enumeration_value_members; @@ -2342,7 +2322,7 @@ begin member_length := members + 4; member_length := member_length^; - if string_compare(value_name, name_length, member_name, member_length) = 0 then + if string_compare(field_access_expression^.field, field_access_expression^.length, member_name, member_length) = 0 then members_length := members_length - 1; members := members + 8; counter := counter + 1; @@ -2361,7 +2341,7 @@ var token_kind: Word; name_pointer: Word; name_length: Word; - result: Word; + result: ^ElnaTreeFieldAccessExpression; begin (* Skip dot. Read the enumeration value. *) _elna_lexer_skip_token(); @@ -2373,38 +2353,31 @@ begin _elna_lexer_skip_token(); result := malloc(ElnaTreeFieldAccessExpression_size()); - ElnaTreeNode_set_kind(result, ElnaTreeKind.field_access_expression); - ElnaTreeFieldAccessExpression_set_aggregate(result, aggregate); - ElnaTreeFieldAccessExpression_set_field(result, name_pointer); - ElnaTreeFieldAccessExpression_set_length(result, name_length); - ElnaTreeExpression_set_type_decoration(result, nil); + result^.kind := ElnaTreeKind.field_access_expression; + result^.aggregate := aggregate; + result^.field := name_pointer; + result^.length := name_length; + result^.type_decoration := nil; return result end; -proc _elna_tac_designator(parser_node: Word, symbol_table: Word, is_address: Word, operand_type: Word, operand_value: Word, operand_length: Word); +proc _elna_tac_designator(parser_node: ^ElnaTreeExpression, symbol_table: Word, is_address: Word, operand_type: Word, operand_value: Word, operand_length: Word); var - parser_node: Word; - node_kind: Word; - expression_type: Word; + field_access_expression: ^ElnaTreeFieldAccessExpression; + dereference_expression: ^ElnaTreeDereferenceExpression; + expression_type: ^ElnaType; 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; + designator_base: ^ElnaTreeExpression; + aggregate_type: ^ElnaTypeRecord; field_count: Word; - current_field: Word; + current_field: ^ElnaTypeField; 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_designator(parser_node, symbol_table, is_address, operand_type, operand_value, operand_length); + if parser_node^.kind = ElnaTreeKind.dereference_expression then + dereference_expression := parser_node; + first_instruction := _elna_tac_designator(dereference_expression^.pointer, 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); @@ -2414,32 +2387,27 @@ begin operand_value^ := 6; operand_length^ := 0; - is_address^ := 2; + is_address^ := 1; first_instruction := elna_instruction_list_concatenate(first_instruction, last_instruction) - elsif node_kind = ElnaTreeKind.field_access_expression then - expression_type := ElnaTreeExpression_get_type_decoration(parser_node); - type_kind := ElnaType_get_kind(expression_type); + elsif parser_node^.kind = ElnaTreeKind.field_access_expression then + field_access_expression := parser_node; + expression_type := field_access_expression^.type_decoration; - if type_kind = ElnaTypeKind.enumeration then - first_instruction := _elna_tac_enumeration_value(parser_node, operand_type, operand_value, operand_length); + if expression_type^.kind = ElnaTypeKind.enumeration then + first_instruction := _elna_tac_enumeration_value(field_access_expression, operand_type, operand_value, operand_length); is_address^ := 0 else - designator_base := ElnaTreeFieldAccessExpression_get_aggregate(parser_node); + designator_base := field_access_expression^.aggregate; 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); + aggregate_type := designator_base^.type_decoration; - field_count := ElnaTypeRecord_get_length(aggregate_type); - current_field := ElnaTypeRecord_get_members(aggregate_type); + field_count := aggregate_type^.length; + current_field := aggregate_type^.members; 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 + if string_compare(field_access_expression^.field, field_access_expression^.length, current_field^.name, current_field^.length) = 0 then field_count := field_count - 1; current_field := current_field + ElnaTypeField_size(); field_offset := field_offset + 4; @@ -2457,7 +2425,7 @@ begin is_address^ := 1; first_instruction := elna_instruction_list_concatenate(first_instruction, last_instruction) end; - elsif node_kind = ElnaTreeKind.call then + elsif parser_node^.kind = ElnaTreeKind.call then first_instruction := _elna_tac_call(parser_node, symbol_table); last_instruction := _elna_tac_instruction_create(ElnaTacOperator.copy); @@ -2479,29 +2447,26 @@ end; proc elna_parser_assign_statement(assignee: Word); var - result: Word; + result: ^_assign_statement; token_kind: Word; - assignment_node: Word; begin result := malloc(_assign_statement_size()); - ElnaTreeNode_set_kind(result, ElnaTreeKind.assign_statement); - _statement_set_next(result, 0); - _assign_statement_set_assignee(result, assignee); + result^.kind := ElnaTreeKind.assign_statement; + result^.next := nil; + result^.assignee := assignee; (* Skip the assignment sign (:=) with surrounding whitespaces. *) _elna_lexer_read_token(@token_kind); _elna_lexer_skip_token(); - assignment_node := elna_parser_binary_expression(); - _assign_statement_set_assignment(result, assignment_node); + result^.assignment := elna_parser_binary_expression(); return result end; -proc _elna_tac_assign_statement(parser_tree: Word, symbol_table: Word); +proc _elna_tac_assign_statement(parser_tree: ^_assign_statement, symbol_table: Word); var - current_expression: Word; is_address: Word; first_instruction: Word; instruction: Word; @@ -2510,11 +2475,10 @@ var operand_value: Word; operand_length: Word; begin - current_expression := _assign_statement_get_assignee(parser_tree); operand_type := 0; operand_value := 0; operand_length := 0; - first_instruction := _elna_tac_designator(current_expression, symbol_table, @is_address, @operand_type, @operand_value, @operand_length); + first_instruction := _elna_tac_designator(parser_tree^.assignee, symbol_table, @is_address, @operand_type, @operand_value, @operand_length); current_instruction := _elna_tac_instruction_create(ElnaTacOperator.get_address); _elna_tac_instruction_set_operand(current_instruction, 1, ElnaTacOperand.temporary, 6, 0); @@ -2528,11 +2492,10 @@ begin elna_instruction_list_concatenate(first_instruction, current_instruction); (* Compile the assignment. *) - current_expression := _assign_statement_get_assignment(parser_tree); operand_type := 0; operand_value := 0; operand_length := 0; - instruction := _elna_tac_binary_expression(current_expression, symbol_table, @operand_type, @operand_value, @operand_length); + instruction := _elna_tac_binary_expression(parser_tree^.assignment, symbol_table, @operand_type, @operand_value, @operand_length); if instruction <> 0 then elna_instruction_list_concatenate(current_instruction, instruction); @@ -2560,7 +2523,7 @@ var token_kind: Word; returned: Word; label_length: Word; - result: Word; + result: ^_return_statement; begin (* Skip "return" keyword and whitespace after it. *) _elna_lexer_skip_token(); @@ -2569,16 +2532,15 @@ begin returned := elna_parser_binary_expression(); result := malloc(_return_statement_size()); - ElnaTreeNode_set_kind(result, ElnaTreeKind.return_statement); - _statement_set_next(result, 0); - _return_statement_set_returned(result, returned); + result^.kind := ElnaTreeKind.return_statement; + result^.next := nil; + result^.returned := returned; return result end; -proc _elna_tac_return_statement(parser_node: Word, symbol_table: Word); +proc _elna_tac_return_statement(parser_node: ^_return_statement, symbol_table: Word); var - return_expression: Word; first_instruction: Word; instruction: Word; operand_type: Word; @@ -2588,8 +2550,7 @@ begin operand_type := 0; operand_value := 0; operand_length := 0; - return_expression := _return_statement_get_returned(parser_node); - first_instruction := _elna_tac_binary_expression(return_expression, symbol_table, @operand_type, @operand_value, @operand_length); + first_instruction := _elna_tac_binary_expression(parser_node^.returned, symbol_table, @operand_type, @operand_value, @operand_length); instruction := _elna_tac_instruction_create(ElnaTacOperator._return); _elna_tac_instruction_set_operand(instruction, 1, operand_type, operand_value, operand_length); @@ -2622,32 +2583,27 @@ end; proc elna_parser_conditional_statements(); var token_kind: Word; - current_node: Word; - result: Word; + result: ^_conditional_statements; begin result := malloc(_conditional_statements_size()); (* Skip "if", "while" or "elsif". *) _elna_lexer_skip_token(); - - current_node := elna_parser_binary_expression(); - _conditional_statements_set_condition(result, current_node); + result^.condition := elna_parser_binary_expression(); (* Skip "then" or "do". *) _elna_lexer_read_token(@token_kind); _elna_lexer_skip_token(); - current_node := elna_parser_statements(); - _conditional_statements_set_statements(result, current_node); + result^.statements := elna_parser_statements(); + result^.next := nil; - _conditional_statements_set_next(result, 0); return result end; -proc _elna_tac_conditional_statements(parser_node: Word, after_end_label: Word, symbol_table: Word); +proc _elna_tac_conditional_statements(parser_node: ^_conditional_statements, after_end_label: Word, symbol_table: Word); var condition_label: Word; - current_node: Word; instruction: Word; current_instruction: Word; first_instruction: Word; @@ -2659,8 +2615,7 @@ begin operand_type := 0; operand_value := 0; operand_length := 0; - current_node := _conditional_statements_get_condition(parser_node); - first_instruction := _elna_tac_binary_expression(current_node, symbol_table, @operand_type, @operand_value, @operand_length); + first_instruction := _elna_tac_binary_expression(parser_node^.condition, symbol_table, @operand_type, @operand_value, @operand_length); (* condition_label is the label in front of the next elsif condition or end. *) condition_label := label_counter; @@ -2672,8 +2627,7 @@ begin elna_instruction_list_concatenate(first_instruction, current_instruction); - current_node := _conditional_statements_get_statements(parser_node); - instruction := _elna_tac_statements(current_node, symbol_table); + instruction := _elna_tac_statements(parser_node^.statements, symbol_table); if instruction <> 0 then elna_instruction_list_concatenate(current_instruction, instruction); current_instruction := instruction @@ -2691,36 +2645,33 @@ end; proc elna_parser_if_statement(); var - current_node: Word; - result: Word; + result: ^_if_statement; token_kind: Word; - previous_conditional: Word; - next_conditional: Word; + previous_conditional: ^_conditional_statements; + next_conditional: ^_conditional_statements; begin result := malloc(_if_statement_size()); - ElnaTreeNode_set_kind(result, ElnaTreeKind.if_statement); - _statement_set_next(result, 0); + result^.kind := ElnaTreeKind.if_statement; + result^.next := nil; previous_conditional := elna_parser_conditional_statements(); - _if_statement_set_conditionals(result, previous_conditional); + result^.conditionals := previous_conditional; .elna_parser_if_statement_loop; _elna_lexer_read_token(@token_kind); if token_kind = ElnaLexerKind._elsif then next_conditional := elna_parser_conditional_statements(); - _conditional_statements_set_next(previous_conditional, next_conditional); + previous_conditional^.next := next_conditional; previous_conditional = next_conditional; goto elna_parser_if_statement_loop elsif token_kind = ElnaLexerKind._else then _elna_lexer_skip_token(); - - current_node := elna_parser_statements(); - _if_statement_set__else(result, current_node) + result^._else := elna_parser_statements() else - _if_statement_set__else(result, 0) + result^._else := nil end; _elna_lexer_skip_token(); @@ -2730,10 +2681,9 @@ end; proc elna_parser_statement(); var token_kind: Word; - result : Word; - temporary: Word; + result : ^ElnaTreeNode; begin - result := 0; + result := nil; _elna_lexer_read_token(@token_kind); if token_kind = ElnaLexerKind._goto then @@ -2746,9 +2696,8 @@ begin result := elna_parser_label_declaration() elsif token_kind = ElnaLexerKind.identifier then result := elna_parser_designator(); - temporary := ElnaTreeNode_get_kind(result); - if temporary <> ElnaTreeKind.call then + if result^.kind <> ElnaTreeKind.call then result := elna_parser_assign_statement(result) end end; @@ -2758,9 +2707,9 @@ end; proc elna_parser_statements(); var token_kind: Word; - previous_statement: Word; - next_statement: Word; - first_statement: Word; + previous_statement: ^_statement; + next_statement: ^_statement; + first_statement: ^_statement; begin _skip_empty_lines(); @@ -2777,7 +2726,7 @@ begin _elna_lexer_skip_token(); _skip_empty_lines(); next_statement := elna_parser_statement(); - _statement_set_next(previous_statement, next_statement); + previous_statement^.next := next_statement; previous_statement := next_statement; if previous_statement <> 0 then @@ -2792,22 +2741,22 @@ end; proc _elna_tac_statements(parser_node: Word, symbol_table: Word); var - current_statement: Word; + current_statement: ^_statement; instruction: Word; first_instruction: Word; current_instruction: Word; begin current_statement := parser_node; - first_instruction := 0; + first_instruction := nil; .elna_tac_statements_loop; - if current_statement <> 0 then + if current_statement <> nil then instruction := _elna_tac_statement(current_statement, symbol_table); - current_statement := _statement_get_next(current_statement); + current_statement := current_statement^.next; if instruction = 0 then goto elna_tac_statements_loop end; - if first_instruction = 0 then + if first_instruction = nil then first_instruction := instruction else elna_instruction_list_concatenate(current_instruction, instruction) @@ -2818,9 +2767,9 @@ begin return first_instruction end; -proc _elna_tac_if_statement(parser_node: Word, symbol_table: Word); +proc _elna_tac_if_statement(parser_node: ^_if_statement, symbol_table: Word); var - current_node: Word; + current_node: ^_conditional_statements; after_end_label: Word; condition_label: Word; first_instruction: Word; @@ -2830,22 +2779,22 @@ begin after_end_label := label_counter; label_counter := label_counter + 1; - current_node := _if_statement_get_conditionals(parser_node); + current_node := parser_node^.conditionals; first_instruction := _elna_tac_conditional_statements(current_node, after_end_label, symbol_table); current_instruction := first_instruction; .elna_tac_if_statement_loop; - current_node := _conditional_statements_get_next(current_node); - if current_node <> 0 then + 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; goto elna_tac_if_statement_loop end; - current_node := _if_statement_get__else(parser_node); + current_node := parser_node^._else; - if current_node <> 0 then - instruction := _elna_tac_statements(current_node, symbol_table); + 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 @@ -2857,27 +2806,24 @@ begin return first_instruction end; -proc _elna_tac_statement(parser_node: Word, symbol_table: Word); +proc _elna_tac_statement(parser_node: ^ElnaTreeNode, symbol_table: Word); var - statement_kind: Word; instruction: Word; begin - statement_kind := ElnaTreeNode_get_kind(parser_node); - - if statement_kind = ElnaTreeKind.goto_statement then + if parser_node^.kind = ElnaTreeKind.goto_statement then instruction := _elna_tac_goto_statement(parser_node) - elsif statement_kind = ElnaTreeKind.if_statement then + elsif parser_node^.kind = ElnaTreeKind.if_statement then instruction := _elna_tac_if_statement(parser_node, symbol_table) - elsif statement_kind = ElnaTreeKind.return_statement then + elsif parser_node^.kind = ElnaTreeKind.return_statement then instruction := _elna_tac_return_statement(parser_node, symbol_table) - elsif statement_kind = ElnaTreeKind.label_declaration then + elsif parser_node^.kind = ElnaTreeKind.label_declaration then instruction := _elna_tac_label_declaration(parser_node) - elsif statement_kind = ElnaTreeKind.call then + elsif parser_node^.kind = ElnaTreeKind.call then instruction := _elna_tac_call(parser_node, symbol_table) - elsif statement_kind = ElnaTreeKind.assign_statement then + elsif parser_node^.kind = ElnaTreeKind.assign_statement then instruction := _elna_tac_assign_statement(parser_node, symbol_table) else - instruction := 0 + instruction := nil end; return instruction end; @@ -2904,7 +2850,7 @@ var field_length: Word; field_type: Word; token_kind: Word; - result: Word; + result: ^ElnaTreeEnumerationTypeExpression; previous_entry: Word; begin _elna_lexer_skip_token(); @@ -2958,9 +2904,9 @@ begin result := malloc(ElnaTreeEnumerationTypeExpression_size()); - ElnaTreeNode_set_kind(result, ElnaTreeKind.record_type_expression); - ElnaTreeRecordTypeExpression_set_members(result, memory_start); - ElnaTreeRecordTypeExpression_set_length(result, member_count); + result^.kind := ElnaTreeKind.record_type_expression; + result^.members := memory_start; + result^.length := member_count; return result end; @@ -2972,7 +2918,7 @@ var name_length: Word; memory_start: Word; member_count: Word; - result: Word; + result: ^ElnaTreeEnumerationTypeExpression; entry: Word; previous_entry: Word; begin @@ -3020,9 +2966,9 @@ begin result := malloc(ElnaTreeEnumerationTypeExpression_size()); - ElnaTreeNode_set_kind(result, ElnaTreeKind.enumeration_type_expression); - ElnaTreeEnumerationTypeExpression_set_members(result, memory_start); - ElnaTreeEnumerationTypeExpression_set_length(result, member_count); + result^.kind := ElnaTreeKind.enumeration_type_expression; + result^.members := memory_start; + result^.length := member_count; return result end; @@ -3039,9 +2985,9 @@ end; * * Returns enumeration type description. *) -proc elna_name_enumeration_type_expression(parser_node: Word); +proc elna_name_enumeration_type_expression(parser_node: ^ElnaTreeEnumerationTypeExpression); var - result: Word; + result: ^ElnaTypeEnumeration; memory_start: Word; member_count: Word; member_array_start: Word; @@ -3049,8 +2995,8 @@ var begin result := malloc(ElnaTypeEnumeration_size()); - memory_start := ElnaTreeEnumerationTypeExpression_get_members(parser_node); - member_count := ElnaTreeEnumerationTypeExpression_get_length(parser_node); + memory_start := parser_node^.members; + member_count := parser_node^.length; (* Copy the list of enumeration members into an array of strings. *) member_array_start := malloc(member_count * 8); @@ -3070,71 +3016,64 @@ begin member_count := member_count - 1; goto elna_name_type_enumeration_loop end; - member_count := ElnaTreeEnumerationTypeExpression_get_length(parser_node); + member_count := parser_node^.length; - ElnaType_set_kind(result, ElnaTypeKind.enumeration); - ElnaType_set_size(result, 4); - ElnaTypeEnumeration_set_members(result, member_array_start); - ElnaTypeEnumeration_set_length(result, member_count); + result^.kind := ElnaTypeKind.enumeration; + result^.size := 4; + result^.members := member_array_start; + result^.length := member_count; return result end; -proc elna_name_pointer_type_expression(parser_node: Word); +proc elna_name_pointer_type_expression(parser_node: ^ElnaTreePointerTypeExpression); var - base: Word; - result: Word; + result: ^ElnaTypePointer; begin result := malloc(ElnaTypePointer_size()); - base := ElnaTreePointerTypeExpression_get_base(parser_node); - base := elna_name_type_expression(base); - ElnaType_set_kind(result, ElnaTypeKind.pointer); - ElnaType_set_size(result, 4); - ElnaTypePointer_set_base(result, base); + result^.kind := ElnaTypeKind.pointer; + result^.size := 4; + result^.base := elna_name_type_expression(parser_node^.base); return result end; -proc elna_name_array_type_expression(parser_node: Word); +proc elna_name_array_type_expression(parser_node: ^ElnaTreeArrayTypeExpression); var - base: Word; - result: Word; - length: Word; - size: Word; + base: ^ElnaType; + result: ^ElnaTypeArray; + length: ^ElnaTreeIntegerLiteral; begin result := malloc(ElnaTypeArray_size()); - base := ElnaTreeArrayTypeExpression_get_base(parser_node); - base := elna_name_type_expression(base); - (* Size of the array base. *) - size := ElnaType_get_size(base); + base := elna_name_type_expression(parser_node^.base); - length := ElnaTreeArrayTypeExpression_get_length(parser_node); (* Expected to be an integer literal for now. *) - length := ElnaTreeIntegerLiteral_get_value(length); + length := parser_node^.length; - ElnaType_set_kind(result, ElnaTypeKind.pointer); - ElnaType_set_size(result, size * length); - ElnaTypeArray_set_base(result, base); - ElnaTypeArray_set_size(result, length); + result^.kind := ElnaTypeKind.pointer; + (* Array size in bytes. *) + result^.size := base^.size * length; + result^.base := base; + result^.length := length^.value; return result end; -proc elna_name_record_type_expression(parser_node: Word); +proc elna_name_record_type_expression(parser_node: ^ElnaTreeRecordTypeExpression); var - result: Word; + result: ^ElnaTypeRecord; memory_start: Word; member_count: Word; member_array_start: Word; - member_array_current: Word; + member_array_current: ^ElnaTypeField; field_definition_size: Word; field_type: Word; begin result := malloc(ElnaTypeRecord_size()); - memory_start := ElnaTreeRecordTypeExpression_get_members(parser_node); - member_count := ElnaTreeRecordTypeExpression_get_length(parser_node); + memory_start := parser_node^.members; + member_count := parser_node^.length; field_definition_size := ElnaTypeField_size(); member_array_start := malloc(member_count * field_definition_size); @@ -3142,14 +3081,14 @@ begin .elna_name_type_record_loop; if member_count > 0 then - ElnaTypeField_set_name(member_array_current, memory_start^); + member_array_current^.name := memory_start^; memory_start := memory_start + 4; - ElnaTypeField_set_length(member_array_current, memory_start^); + member_array_current^.length := memory_start^; memory_start := memory_start + 4; field_type := elna_name_type_expression(memory_start^); - ElnaTypeField_set_field_type(member_array_current, field_type); + member_array_current^.field_type := field_type; member_array_current := member_array_current + field_definition_size; memory_start := memory_start + 4; @@ -3158,29 +3097,24 @@ begin member_count := member_count - 1; goto elna_name_type_record_loop end; - member_count := ElnaTreeRecordTypeExpression_get_length(parser_node); - ElnaType_set_kind(result, ElnaTypeKind._record); - ElnaType_set_size(result, member_count * 4); - ElnaTypeRecord_set_members(result, member_array_start); - ElnaTypeRecord_set_length(result, member_count); + result^.kind := ElnaTypeKind._record; + result^.size := parser_node^.length * 4; + result^.members := member_array_start; + result^.length := parser_node^.length; return result end; proc elna_parser_named_type_expression(); var - result: Word; - type_name: Word; - name_length: Word; + result: ^ElnaTreeNamedTypeExpression; begin result := malloc(ElnaTreeNamedTypeExpression_size()); - ElnaTreeNode_set_kind(result, ElnaTreeKind.named_type_expression); - type_name := _elna_lexer_global_get_start(); - name_length := _elna_lexer_global_get_end() - type_name; - ElnaTreeNamedTypeExpression_set_name(result, type_name); - ElnaTreeNamedTypeExpression_set_length(result, name_length); + result^.kind := ElnaTreeKind.named_type_expression; + result^.name := _elna_lexer_global_get_start(); + result^.length := _elna_lexer_global_get_end() - result^.name; _elna_lexer_skip_token(); return result @@ -3188,39 +3122,33 @@ end; proc elna_parser_pointer_type_expression(); var - result: Word; - base: Word; + result: ^ElnaTreePointerTypeExpression; begin _elna_lexer_skip_token(); - result := malloc(ElnaTreePointerTypeExpression_size()); - ElnaTreeNode_set_kind(result, ElnaTreeKind.pointer_type_expression); - base := elna_parser_type_expression(); - ElnaTreePointerTypeExpression_set_base(result, base); + result := malloc(ElnaTreePointerTypeExpression_size()); + result^.kind := ElnaTreeKind.pointer_type_expression; + result^.base := elna_parser_type_expression(); return result end; proc elna_parser_array_type_expression(); var - result: Word; - base: Word; - size: Word; + result: ^ElnaTreeArrayTypeExpression; token_kind: Word; begin _elna_lexer_skip_token(); - result := malloc(ElnaTreeArrayTypeExpression_size()); - ElnaTreeNode_set_kind(result, ElnaTreeKind.array_type_expression); - size := elna_parser_binary_expression(); - ElnaTreePointerTypeExpression_set_base(result, size); + result := malloc(ElnaTreeArrayTypeExpression_size()); + result^.kind := ElnaTreeKind.array_type_expression; + result^.base := elna_parser_binary_expression(); (* Read and skip square bracket. *) _elna_lexer_read_token(@token_kind); _elna_lexer_skip_token(); - base := elna_parser_type_expression(); - ElnaTreePointerTypeExpression_set_base(result, base); + result^.base := elna_parser_type_expression(); return result end; @@ -3230,7 +3158,7 @@ var token_kind: Word; result: Word; begin - result := 0; + result := nil; _elna_lexer_read_token(@token_kind); if token_kind = ElnaLexerKind.identifier then @@ -3247,28 +3175,24 @@ begin return result end; -proc elna_name_type_expression(parser_node: Word); +proc elna_name_type_expression(parser_node: ^ElnaTreeNode); var - token_kind: Word; - type_name: Word; - name_length: Word; + named_type_expression: ^ElnaTreeNamedTypeExpression; + type_symbol: ^_type_info; result: Word; begin - token_kind := ElnaTreeNode_get_kind(parser_node); + if parser_node^.kind = ElnaTreeKind.named_type_expression then + named_type_expression := parser_node; - if token_kind = ElnaTreeKind.named_type_expression then - type_name := ElnaTreeNamedTypeExpression_get_name(parser_node); - name_length := ElnaTreeNamedTypeExpression_get_length(parser_node); - - result := _symbol_table_lookup(@symbol_table_global, type_name, name_length); - result := _type_info_get__type(result) - elsif token_kind = ElnaTreeKind.enumeration_type_expression then + type_symbol := _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) - elsif token_kind = ElnaTreeKind.record_type_expression then + elsif parser_node^.kind = ElnaTreeKind.record_type_expression then result := elna_name_record_type_expression(parser_node) - elsif token_kind = ElnaTreeKind.pointer_type_expression then + elsif parser_node^.kind = ElnaTreeKind.pointer_type_expression then result := elna_name_pointer_type_expression(parser_node) - elsif token_kind = ElnaTreeKind.array_type_expression then + elsif parser_node^.kind = ElnaTreeKind.array_type_expression then result := elna_name_array_type_expression(parser_node) end; @@ -3283,26 +3207,26 @@ end; proc _parameter_info_create(parameter_index: Word, parameter_type: Word); var offset: Word; - result: Word; + result: ^_parameter_info; begin result := malloc(_parameter_info_size()); - _info_set_kind(result, InfoKind.parameter_info); + result^.kind := InfoKind.parameter_info; (* Calculate the stack offset: 104 - (4 * parameter_counter) *) offset := parameter_index * 4; - _parameter_info_set_offset(result, 104 - offset); - _parameter_info_set_variable_type(result, parameter_type); + result^.offset := 104 - offset; + result^.variable_type := parameter_type; return result end; proc _type_info_create(type_representation: Word); var - result: Word; + result: ^_type_info; begin result := malloc(_type_info_size()); - _info_set_kind(result, InfoKind.type_info); - _type_info_set__type(result, type_representation); + result^.kind := InfoKind.type_info; + result^._type := type_representation; return result end; @@ -3314,14 +3238,14 @@ end; *) proc _temporary_info_create(temporary_index: Word, temporary_type: Word); var - result: Word; + result: ^_temporary_info; begin result := malloc(_temporary_info_size()); - _info_set_kind(result, InfoKind.temporary_info); + result^.kind := InfoKind.temporary_info; (* Calculate the stack offset: 4 * variable_counter. *) - _temporary_info_set_offset(result, temporary_index * 4); - _parameter_info_set_variable_type(result, temporary_type); + result^.offset := temporary_index * 4; + result^.variable_type := temporary_type; return result end; @@ -3332,11 +3256,11 @@ end; *) proc _procedure_info_create(symbol_table: Word); var - result: Word; + result: ^_procedure_info; begin result := malloc(_procedure_info_size()); - _info_set_kind(result, InfoKind.procedure_info); - _procedure_info_set_symbol_table(result, symbol_table); + result^.kind := InfoKind.procedure_info; + result^.symbol_table := symbol_table; return result end; @@ -3345,101 +3269,87 @@ end; * Parameters: * parameter_index - Parameter index. *) -proc elna_name_procedure_parameter(parser_node: Word, parameter_index: Word, symbol_table: Word); +proc elna_name_procedure_parameter(parser_node: ^_variable_declaration, parameter_index: Word, symbol_table: Word); var - name_length: Word; info: Word; - name_position: Word; variable_type: Word; begin - name_position := _declaration_get_name(parser_node); - name_length := _declaration_get_length(parser_node); - - variable_type := _variable_declaration_get__type(parser_node); - variable_type := elna_name_type_expression(variable_type); + variable_type := elna_name_type_expression(parser_node^._type); info := _parameter_info_create(parameter_index, variable_type); - _symbol_table_enter(symbol_table, name_position, name_length, info) + _symbol_table_enter(symbol_table, parser_node^.name, parser_node^.length, info) end; (** * Parameters: * variable_index - Variable index. *) -proc elna_name_procedure_temporary(parser_node: Word, variable_index: Word, symbol_table: Word); +proc elna_name_procedure_temporary(parser_node: ^_variable_declaration, variable_index: Word, symbol_table: Word); var - name_length: Word; info: Word; - name_position: Word; variable_type: Word; begin - name_position := _declaration_get_name(parser_node); - name_length := _declaration_get_length(parser_node); - - variable_type := _variable_declaration_get__type(parser_node); - variable_type := elna_name_type_expression(variable_type); + variable_type := elna_name_type_expression(parser_node^._type); info := _temporary_info_create(variable_index, variable_type); - _symbol_table_enter(symbol_table, name_position, name_length, info) + _symbol_table_enter(symbol_table, parser_node^.name, parser_node^.length, info) end; -proc elna_name_procedure_temporaries(parser_node: Word, symbol_table: Word); +proc elna_name_procedure_temporaries(parser_node: ^_variable_declaration, symbol_table: Word); var temporary_counter: Word; begin temporary_counter := 0; .elna_name_procedure_temporaries_loop; - if parser_node <> 0 then + if parser_node <> nil then elna_name_procedure_temporary(parser_node, temporary_counter, symbol_table); temporary_counter := temporary_counter + 1; - parser_node := _declaration_get_next(parser_node); + parser_node := parser_node^.next; goto elna_name_procedure_temporaries_loop end end; proc elna_parser_procedure_declaration(); var - name_pointer: Word; - name_length: Word; + next_declaration: ^_declaration; + current_declaration: ^_declaration; token_kind: Word; - result: Word; - parameter_head: Word; + result: ^_procedure_declaration; + parameter_head: ^_declaration; begin result := malloc(_procedure_declaration_size()); - ElnaTreeNode_set_kind(result, ElnaTreeKind.procedure_declaration); - _declaration_set_next(result, 0); + result^.kind := ElnaTreeKind.procedure_declaration; + result^.next := nil; (* Skip "proc ". *) _elna_lexer_skip_token(); _elna_lexer_read_token(@token_kind); - name_pointer := _elna_lexer_global_get_start(); - name_length := _elna_lexer_global_get_end() - name_pointer; - _declaration_set_name(result, name_pointer); - _declaration_set_length(result, name_length); + result^.name := _elna_lexer_global_get_start(); + result^.length := _elna_lexer_global_get_end() - result^.name; (* Skip procedure name. *) _elna_lexer_skip_token(); (* Skip open paren. *) _elna_lexer_read_token(@token_kind); _elna_lexer_skip_token(); - parameter_head := 0; + parameter_head := nil; .elna_parser_procedure_declaration_parameter; _elna_lexer_read_token(@token_kind); if token_kind <> ElnaLexerKind.right_paren then - name_pointer := elna_parser_variable_declaration(); - if parameter_head = 0 then - parameter_head := name_pointer + next_declaration := elna_parser_variable_declaration(); + if parameter_head = nil then + parameter_head := next_declaration else - _declaration_set_next(name_length, name_pointer) + current_declaration^.next := next_declaration end; - name_length := name_pointer; + current_declaration := next_declaration; _elna_lexer_read_token(@token_kind); @@ -3450,14 +3360,14 @@ begin end; (* Skip close paren. *) _elna_lexer_skip_token(); - _procedure_declaration_set_parameters(result, parameter_head); + result^.parameters := parameter_head; (* Skip semicolon and newline. *) _elna_lexer_read_token(@token_kind); _elna_lexer_skip_token(); parameter_head := elna_parser_var_part(); - _procedure_declaration_set_temporaries(result, parameter_head); + result^.temporaries := parameter_head; (* Skip semicolon, "begin" and newline. *) _elna_lexer_read_token(@token_kind); @@ -3467,7 +3377,7 @@ begin elsif token_kind = ElnaLexerKind._return then parameter_head := elna_parser_return_statement() end; - _procedure_declaration_set_body(result, parameter_head); + result^.body := parameter_head; (* Skip the "end" keyword. *) _elna_lexer_read_token(@token_kind); @@ -3476,7 +3386,7 @@ begin return result end; -proc _elna_tac_parameters(current_parameter: Word, new_symbol_table: Word); +proc _elna_tac_parameters(current_parameter: ^_declaration, new_symbol_table: Word); var name_pointer: Word; name_length: Word; @@ -3484,23 +3394,19 @@ var instruction: Word; first_instruction: Word; current_instruction: Word; - symbol_info: Word; + symbol_info: ^_parameter_info; begin first_instruction := 0; parameter_counter := 0; .elna_tac_parameters_loop; if current_parameter <> 0 then - name_pointer := _declaration_get_name(current_parameter); - name_length := _declaration_get_length(current_parameter); - symbol_info := _symbol_table_lookup(new_symbol_table, name_pointer, name_length); - - symbol_info := _parameter_info_get_offset(symbol_info); + symbol_info := _symbol_table_lookup(new_symbol_table, current_parameter^.name, current_parameter^.length); instruction := _elna_tac_instruction_create(ElnaTacOperator.store); _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 11 + parameter_counter, 0); - _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, symbol_info, 0); - if first_instruction = 0 then + _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, symbol_info^.offset, 0); + if first_instruction = nil then first_instruction := instruction else elna_instruction_list_concatenate(current_instruction, instruction) @@ -3509,7 +3415,7 @@ begin parameter_counter := parameter_counter + 1; - current_parameter := _declaration_get_next(current_parameter); + current_parameter := current_parameter^.next; goto elna_tac_parameters_loop end; return first_instruction @@ -3533,14 +3439,14 @@ proc elna_rtl_procedure_declaration(tac_declaration: ^ElnaInstructionDeclaration var body: Word; result: ^ElnaInstructionDeclaration; - return_instruction: Word; + return_instruction: ^ElnaInstructionList; begin result := malloc(ElnaInstructionDeclaration_size()); body := tac_declaration^.body; body := elna_rtl_instructions(body); return_instruction := elna_rtl_instruction_create(ElnaRtlOperator.allocate_stack); - ElnaInstructionList_set_next(return_instruction, body); + return_instruction^.next := body; body := return_instruction; return_instruction := elna_rtl_instruction_create(ElnaRtlOperator.ret); elna_instruction_list_concatenate(body, return_instruction); @@ -3557,7 +3463,6 @@ end; proc _elna_tac_procedure_declaration(parser_node: _procedure_declaration); var current_parameter: Word; - body: Word; new_symbol_table: Word; symbol_info: ^_procedure_info; instruction: Word; @@ -3579,8 +3484,7 @@ begin 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); + instruction := _elna_tac_statements(parser_node^.body, new_symbol_table); first_instruction := elna_instruction_list_concatenate(first_instruction, instruction); result^.body := first_instruction; @@ -3590,12 +3494,12 @@ end; proc elna_parser_procedures(); var - parser_node: Word; - result: Word; - current_declaration: Word; + parser_node: ^_declaration; + result: ^_declaration; + current_declaration: ^_declaration; token_kind: Word; begin - result := 0; + result := nil; .elna_parser_procedures_loop; _skip_empty_lines(); @@ -3606,7 +3510,7 @@ begin if result = 0 then result := parser_node else - _declaration_set_next(current_declaration, parser_node) + current_declaration^.next := parser_node end; current_declaration := parser_node; @@ -3724,8 +3628,7 @@ var token_kind: Word; type_name: Word; name_length: Word; - parser_node: Word; - result: Word; + result: ^_type_declaration; begin _elna_lexer_read_token(@token_kind); type_name := _elna_lexer_global_get_start(); @@ -3735,14 +3638,13 @@ begin _elna_lexer_read_token(@token_kind); _elna_lexer_skip_token(); - parser_node := elna_parser_type_expression(); result := malloc(_type_declaration_size()); - ElnaTreeNode_set_kind(result, ElnaTreeKind.type_declaration); - _declaration_set_next(result, 0); - _declaration_set_name(result, type_name); - _declaration_set_length(result, name_length); - _type_declaration_set__type(result, parser_node); + result^.kind := ElnaTreeKind.type_declaration; + result^.next := nil; + result^.name := type_name; + result^.length := name_length; + result^._type := elna_parser_type_expression(); _elna_lexer_read_token(@token_kind); _elna_lexer_skip_token(); @@ -3773,11 +3675,11 @@ end; proc elna_parser_type_part(); var token_kind: Word; - parser_node: Word; - result: Word; - current_declaration: Word; + parser_node: ^_declaration; + result: ^_declaration; + current_declaration: ^_declaration; begin - result := 0; + result := nil; _skip_empty_lines(); _elna_lexer_read_token(@token_kind); @@ -3793,10 +3695,10 @@ begin if token_kind = ElnaLexerKind.identifier then parser_node := elna_parser_type_declaration(); - if result = 0 then + if result = nil then result := parser_node else - _declaration_set_next(current_declaration, parser_node) + current_declaration^.next := parser_node end; current_declaration := parser_node; goto elna_parser_type_part_loop @@ -3812,7 +3714,7 @@ var name: Word; name_length: Word; variable_type: Word; - result: Word; + result: ^_variable_declaration; begin _elna_lexer_read_token(@token_kind); @@ -3827,11 +3729,11 @@ begin variable_type := elna_parser_type_expression(); result := malloc(_variable_declaration_size()); - ElnaTreeNode_set_kind(result, ElnaTreeKind.variable_declaration); - _declaration_set_next(result, 0); - _declaration_set_name(result, name); - _declaration_set_length(result, name_length); - _variable_declaration_set__type(result, variable_type); + result^.kind := ElnaTreeKind.variable_declaration; + result^.next := nil; + result^.name := name; + result^.length := name_length; + result^._type := variable_type; return result end; @@ -3866,118 +3768,34 @@ begin return result end; -proc _elna_tac_accessor(name_pointer: Word, name_length: Word, field_pointer: Word, field_offset: Word, result: Word, method: Word); -var - instruction: Word; - new_name: Word; - name_target: Word; - new_length: Word; - field_length: Word; -begin - field_length := field_pointer + 4; - field_length := field_length^; - new_length := field_length + name_length; - new_length := new_length + 5; - - result^ := malloc(ElnaInstructionDeclaration_size()); - ElnaInstructionList_set_next(result^, 0); - ElnaInstructionDeclaration_set_stack(result^, 0); - - new_name := malloc(new_length); - - name_target := new_name; - memcpy(name_target, name_pointer, name_length); - name_target := name_target + name_length; - memcpy(name_target, method, 5); - name_target := name_target + 5; - memcpy(name_target, field_pointer^, field_length); - - ElnaInstructionDeclaration_set_name(result^, new_name); - ElnaInstructionDeclaration_set_length(result^, new_length); - - instruction := _elna_tac_instruction_create(ElnaTacOperator.add); - - _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 11, 0); - _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.temporary, 11, 0); - _elna_tac_instruction_set_operand(instruction, 3, ElnaTacOperand.immediate, field_offset, 0); - - return instruction -end; - -proc _elna_tac_type_field(name_pointer: Word, name_length: Word, field_pointer: Word, field_offset: Word); -var - first_result: Word; - second_result: Word; - instruction: Word; - next_instruction: Word; -begin - instruction := _elna_tac_accessor(name_pointer, name_length, field_pointer, field_offset, @first_result, "_get_"); - next_instruction := _elna_tac_instruction_create(ElnaTacOperator.load); - _elna_tac_instruction_set_operand(next_instruction, 1, ElnaTacOperand.temporary, 11, 0); - _elna_tac_instruction_set_operand(next_instruction, 2, ElnaTacOperand.temporary, 11, 0); - elna_instruction_list_concatenate(instruction, next_instruction); - ElnaInstructionDeclaration_set_body(first_result, instruction); - - instruction := _elna_tac_accessor(name_pointer, name_length, field_pointer, field_offset, @second_result, "_set_"); - next_instruction := _elna_tac_instruction_create(ElnaTacOperator.store); - _elna_tac_instruction_set_operand(next_instruction, 1, ElnaTacOperand.temporary, 12, 0); - _elna_tac_instruction_set_operand(next_instruction, 2, ElnaTacOperand.temporary, 11, 0); - elna_instruction_list_concatenate(instruction, next_instruction); - ElnaInstructionDeclaration_set_body(second_result, instruction); - - ElnaInstructionList_set_next(first_result, second_result); - - return first_result -end; - proc _elna_tac_type_record(name_pointer: Word, name_length: Word, type_representation: ^ElnaTypeRecord, current_result: Word); var - first_result: Word; - result: ^ElnaInstructionList; - new_name: Word; - new_length: Word; + result: ^ElnaInstructionDeclaration; instruction: Word; field_count: Word; field_offset: Word; field_pointer: Word; begin - first_result := malloc(ElnaInstructionDeclaration_size()); - result := 0; + result := malloc(ElnaInstructionDeclaration_size()); - new_length := name_length + 5; - new_name := malloc(new_length); + result^.length := name_length + 5; + result^.name := malloc(result^.length); - memcpy(new_name, name_pointer, name_length); - memcpy(new_name + name_length, "_size", 5); - - ElnaInstructionDeclaration_set_name(first_result, new_name); - ElnaInstructionDeclaration_set_length(first_result, new_length); + memcpy(result^.name, name_pointer, name_length); + memcpy(result^.name + name_length, "_size", 5); 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_representation^.size, 0); - ElnaInstructionDeclaration_set_body(first_result, instruction); + result^.body := instruction; field_count := type_representation^.length; field_pointer := type_representation^.members; field_offset := 0; - current_result^ := first_result; + current_result^ := result; - .elna_tac_type_record_fields; - if field_count > 0 then - result := _elna_tac_type_field(name_pointer, name_length, field_pointer, field_offset); - - ElnaInstructionList_set_next(current_result^, result); - current_result^ := result^.next; - - field_offset := field_offset + 4; - field_count := field_count - 1; - field_pointer := field_pointer + 12; - goto elna_tac_type_record_fields - end; - - return first_result + return result end; proc _elna_tac_type_part(parser_node: ^_declaration); @@ -4026,7 +3844,7 @@ var result: Word; token_kind: Word; variable_node: Word; - current_declaration: Word; + current_declaration: ^_declaration; begin result := 0; _elna_lexer_read_token(@token_kind); @@ -4051,7 +3869,7 @@ begin if result = 0 then result := variable_node else - _declaration_set_next(current_declaration, variable_node) + current_declaration^.next := variable_node end; current_declaration := variable_node; goto elna_parser_var_part_loop @@ -4093,12 +3911,11 @@ end; proc elna_parser_module_declaration(); var parser_node: Word; - result: Word; + result: ^_module_declaration; token_kind: Word; begin result := malloc(_module_declaration_size()); - - ElnaTreeNode_set_kind(result, ElnaTreeKind.module_declaration); + result^.kind := ElnaTreeKind.module_declaration; (* Skip "program;". *) _skip_empty_lines(); @@ -4107,14 +3924,9 @@ begin _elna_lexer_read_token(@token_kind); _elna_lexer_skip_token(); - parser_node := elna_parser_type_part(); - _module_declaration_set_types(result, parser_node); - - parser_node := elna_parser_var_part(); - _module_declaration_set_globals(result, parser_node); - - parser_node := elna_parser_procedures(); - _module_declaration_set_procedures(result, parser_node); + result^.types := elna_parser_type_part(); + result^.globals := elna_parser_var_part(); + result^.procedures := elna_parser_procedures(); return result end; @@ -4148,80 +3960,65 @@ begin return elna_instruction_module_create(data_part, code_part) end; -proc elna_name_procedure_declaration(parser_node: Word); +proc elna_name_procedure_declaration(parser_node: ^_procedure_declaration); var - name_pointer: Word; - name_length: Word; new_symbol_table: Word; parameter_counter: Word; symbol_info: Word; - current_parameter: Word; + current_parameter: ^_declaration; begin new_symbol_table := _symbol_table_create(); symbol_info := _procedure_info_create(new_symbol_table); - name_pointer := _declaration_get_name(parser_node); - name_length := _declaration_get_length(parser_node); - - current_parameter := _procedure_declaration_get_parameters(parser_node); + current_parameter := parser_node^.parameters; parameter_counter := 0; .elna_name_procedure_declaration_parameter; - if current_parameter <> 0 then + if current_parameter <> nil then elna_name_procedure_parameter(current_parameter, parameter_counter, new_symbol_table); parameter_counter := parameter_counter + 1; - current_parameter := _declaration_get_next(current_parameter); + current_parameter := current_parameter^.next; goto elna_name_procedure_declaration_parameter end; - current_parameter := _procedure_declaration_get_temporaries(parser_node); - elna_name_procedure_temporaries(current_parameter, new_symbol_table); + elna_name_procedure_temporaries(parser_node^.temporaries, new_symbol_table); - _symbol_table_enter(@symbol_table_global, name_pointer, name_length, symbol_info) + _symbol_table_enter(@symbol_table_global, parser_node^.name, parser_node^.length, symbol_info) end; -proc elna_type_conditional_statements(parser_node: Word, symbol_table: Word); -var - condition: Word; - statements: Word; +proc elna_type_conditional_statements(parser_node: ^_conditional_statements, symbol_table: Word); begin .elna_type_conditional_statements_loop; - condition := _conditional_statements_get_condition(parser_node); - elna_type_binary_expression(condition, symbol_table); + elna_type_binary_expression(parser_node^.condition, symbol_table); + elna_type_statements(parser_node^.statements, symbol_table); - statements := _conditional_statements_get_statements(parser_node); - elna_type_statements(statements, symbol_table); - - parser_node := _conditional_statements_get_next(parser_node); + parser_node := parser_node^.next; if parser_node <> nil then goto elna_type_conditional_statements_loop end end; -proc elna_type_if_statement(parser_node: Word, symbol_table: Word); +proc elna_type_if_statement(parser_node: ^_if_statement, symbol_table: Word); var - block: Word; + block: ^_conditional_statements; begin - block := _if_statement_get_conditionals(parser_node); + block := parser_node^.conditionals; .elna_type_if_statement_conditionals; elna_type_conditional_statements(block, symbol_table); - block := _conditional_statements_get_next(block); + block := block^.next; if block <> nil then goto elna_type_if_statement_conditionals end; - block := _if_statement_get__else(parser_node); + block := parser_node^._else; if block <> nil then elna_type_statements(block, symbol_table) end end; -proc elna_type_return_statement(parser_node: Word, symbol_table: Word); -var - returned_expression: Word; +proc elna_type_return_statement(parser_node: ^_return_statement, symbol_table: Word); begin - returned_expression := _return_statement_get_returned(parser_node); - elna_type_binary_expression(returned_expression, symbol_table) + elna_type_binary_expression(parser_node^.returned, symbol_table) end; proc elna_type_call(parser_node: Word, symbol_table: Word); @@ -4242,330 +4039,276 @@ begin end end; -proc elna_type_assign_statement(parser_node: Word, symbol_table: Word); -var - lhs: Word; - rhs: Word; +proc elna_type_assign_statement(parser_node: ^_assign_statement, symbol_table: Word); begin - lhs := _assign_statement_get_assignee(parser_node); - rhs := _assign_statement_get_assignment(parser_node); - - elna_type_designator(lhs, symbol_table); - elna_type_binary_expression(rhs, symbol_table) + elna_type_designator(parser_node^.assignee, symbol_table); + elna_type_binary_expression(parser_node^.assignment, symbol_table) end; -proc elna_type_statement(parser_node: Word, symbol_table: Word); -var - statement_kind: Word; +proc elna_type_statement(parser_node: ^ElnaTreeNode, symbol_table: Word); begin - statement_kind := ElnaTreeNode_get_kind(parser_node); - (* Skipping goto and label declarations. *) - if statement_kind = ElnaTreeKind.if_statement then + if parser_node^.kind = ElnaTreeKind.if_statement then elna_type_if_statement(parser_node, symbol_table) - elsif statement_kind = ElnaTreeKind.return_statement then + elsif parser_node^.kind = ElnaTreeKind.return_statement then elna_type_return_statement(parser_node, symbol_table) - elsif statement_kind = ElnaTreeKind.call then + elsif parser_node^.kind = ElnaTreeKind.call then elna_type_call(parser_node, symbol_table) - elsif statement_kind = ElnaTreeKind.assign_statement then + elsif parser_node^.kind = ElnaTreeKind.assign_statement then elna_type_assign_statement(parser_node, symbol_table) end end; -proc elna_type_statements(parser_node: Word, symbol_table: Word); +proc elna_type_statements(parser_node: ^_statement, symbol_table: Word); begin .elna_type_statements_loop; - if parser_node <> 0 then + if parser_node <> nil then elna_type_statement(parser_node, symbol_table); - parser_node := _statement_get_next(parser_node); + parser_node := parser_node^.next; goto elna_type_statements_loop end end; -proc elna_type_character_literal(parser_node: Word); +proc elna_type_character_literal(parser_node: ^ElnaTreeCharacterLiteral); var - symbol_info: Word; - symbol_type: Word; + symbol_info: ^_type_info; begin symbol_info := _symbol_table_lookup(@symbol_table_global, "Word", 4); - symbol_type := _type_info_get__type(symbol_info); - - ElnaTreeExpression_set_type_decoration(parser_node, symbol_type) + parser_node^.type_decoration := symbol_info^._type end; -proc elna_type_integer_literal(parser_node: Word); +proc elna_type_integer_literal(parser_node: ^ElnaTreeIntegerLiteral); var - symbol_info: Word; - symbol_type: Word; + symbol_info: ^_type_info; begin symbol_info := _symbol_table_lookup(@symbol_table_global, "Word", 4); - symbol_type := _type_info_get__type(symbol_info); - - ElnaTreeExpression_set_type_decoration(parser_node, symbol_type) + parser_node^.type_decoration := symbol_info^._type end; -proc elna_type_string_literal(parser_node: Word); +proc elna_type_string_literal(parser_node: ^ElnaTreeStringLiteral); var - symbol_info: Word; - symbol_type: Word; + symbol_info: ^_type_info; begin symbol_info := _symbol_table_lookup(@symbol_table_global, "Word", 4); - symbol_type := _type_info_get__type(symbol_info); - - ElnaTreeExpression_set_type_decoration(parser_node, symbol_type) + parser_node^.type_decoration := symbol_info^._type end; -proc elna_type_nil_literal(parser_node: Word); +proc elna_type_nil_literal(parser_node: ^ElnaTreeNilLiteral); var - symbol_info: Word; - symbol_type: Word; + symbol_info: ^_type_info; begin symbol_info := _symbol_table_lookup(@symbol_table_global, "Word", 4); - symbol_type := _type_info_get__type(symbol_info); - - ElnaTreeExpression_set_type_decoration(parser_node, symbol_type) + parser_node^.type_decoration := symbol_info^._type end; -proc elna_type_variable_expression(parser_node: Word, symbol_table: Word); +proc elna_type_variable_expression(parser_node: ^ElnaTreeVariableExpression, symbol_table: Word); var - variable_info: Word; - name_pointer: Word; - name_length: Word; - variable_kind: Word; - variable_type: Word; + variable_info: ^_info; + parameter_info: ^_parameter_info; + temporary_info: ^_temporary_info; begin - name_pointer := ElnaTreeVariableExpression_get_name(parser_node); - name_length := ElnaTreeVariableExpression_get_length(parser_node); - - variable_info := _symbol_table_lookup(symbol_table, name_pointer, name_length); + variable_info := _symbol_table_lookup(symbol_table, parser_node^.name, parser_node^.length); if variable_info = nil then - variable_info := _symbol_table_lookup(@symbol_table_global, name_pointer, name_length) + variable_info := _symbol_table_lookup(@symbol_table_global, parser_node^.name, parser_node^.length) end; - variable_kind := _info_get_kind(variable_info); - variable_type := nil; - if variable_kind = InfoKind.parameter_info then - variable_type := _parameter_info_get_variable_type(variable_info) - elsif variable_kind = InfoKind.temporary_info then - variable_type := _temporary_info_get_variable_type(variable_info) - end; - ElnaTreeExpression_set_type_decoration(parser_node, variable_type) + if variable_info^.kind = InfoKind.parameter_info then + parameter_info := variable_info; + parser_node^.type_decoration := parameter_info^.variable_type + elsif variable_info^.kind = InfoKind.temporary_info then + temporary_info := variable_info; + parser_node^.type_decoration := temporary_info^.variable_type + end end; -proc elna_type_simple_expression(parser_node: Word, symbol_table: Word); -var - expression_kind: Word; +proc elna_type_simple_expression(parser_node: ^ElnaTreeNode, symbol_table: Word); begin - expression_kind := ElnaTreeNode_get_kind(parser_node); - - if expression_kind = ElnaTreeKind.integer_literal then + if parser_node^.kind = ElnaTreeKind.integer_literal then elna_type_integer_literal(parser_node) - elsif expression_kind = ElnaTreeKind.character_literal then + elsif parser_node^.kind = ElnaTreeKind.character_literal then elna_type_character_literal(parser_node) - elsif expression_kind = ElnaTreeKind.string_literal then + elsif parser_node^.kind = ElnaTreeKind.string_literal then elna_type_string_literal(parser_node) - elsif expression_kind = ElnaTreeKind.null then + elsif parser_node^.kind = ElnaTreeKind.null then elna_type_nil_literal(parser_node) - elsif expression_kind = ElnaTreeKind.variable_expression then + elsif parser_node^.kind = ElnaTreeKind.variable_expression then elna_type_variable_expression(parser_node, symbol_table) end end; -proc elna_type_designator(parser_node: Word, symbol_table: Word); +proc elna_type_dereference_expression(parser_node: ^ElnaTreeDereferenceExpression, symbol_table: Word); var - expression_kind: Word; - designator_base: Word; - base_type: Word; - type_kind: Word; - name_pointer: Word; - name_length: Word; - symbol_info: Word; - aggregate_type: Word; - field_count: Word; - current_field: Word; - field_name_pointer: Word; - field_name_length: Word; + base_type: ^ElnaType; + pointer_type: ^ElnaTypePointer; + dereferenced_expression: ^ElnaTreeExpression; begin - expression_kind := ElnaTreeNode_get_kind(parser_node); + elna_type_designator(parser_node^.pointer, symbol_table); - if expression_kind = ElnaTreeKind.dereference_expression then - designator_base := ElnaTreeDereferenceExpression_get_pointer(parser_node); - elna_type_designator(designator_base, symbol_table); + dereferenced_expression := parser_node^.pointer; + base_type := dereferenced_expression^.type_decoration; - base_type := ElnaTreeExpression_get_type_decoration(designator_base); - type_kind := ElnaType_get_kind(base_type); + (* If check for compatibility, should be removed later. *) + if base_type^.kind = ElnaTypeKind.pointer then + pointer_type := base_type; + base_type := pointer_type^.base; + end; + parser_node^.type_decoration := base_type +end; - (* If check for compatibility, should be removed later. *) - if type_kind = ElnaTypeKind.pointer then - base_type := ElnaTypePointer_get_base(base_type) - end; - - ElnaTreeExpression_set_type_decoration(parser_node, base_type) - elsif expression_kind = ElnaTreeKind.field_access_expression then - base_type := nil; - designator_base := ElnaTreeFieldAccessExpression_get_aggregate(parser_node); +proc elna_type_field_access_expression(parser_node: ^ElnaTreeFieldAccessExpression, symbol_table: Word); +var + variable_expression: ^ElnaTreeVariableExpression; + base_type: Word; + type_kind: ^_type_info; + symbol_info: ^_info; + aggregate_type: ^ElnaTypeRecord; + field_count: Word; + current_field: ^ElnaTypeField; +begin + base_type := nil; + variable_expression := parser_node^.aggregate; - (* Check whether the field access is an enumeration value. *) - if ElnaTreeNode_get_kind(designator_base) = ElnaTreeKind.variable_expression then - name_pointer := ElnaTreeVariableExpression_get_name(designator_base); - name_length := ElnaTreeVariableExpression_get_length(designator_base); + (* 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); + if symbol_info <> nil then + type_kind := symbol_info; - symbol_info := _symbol_table_lookup(@symbol_table_global, name_pointer, name_length); - if symbol_info <> nil then - type_kind := _info_get_kind(symbol_info); - - if type_kind = InfoKind.type_info then - base_type := _type_info_get__type(symbol_info) - end + if symbol_info^.kind = InfoKind.type_info then + base_type := type_kind^._type end + end + end; + (* If the base_type is still nil this is record field access. *) + if base_type = nil then + elna_type_designator(parser_node^.aggregate, symbol_table); + aggregate_type := variable_expression^.type_decoration; + + field_count := aggregate_type^.length; + current_field := aggregate_type^.members; + + .elna_type_field_access_expression_field; + + if string_compare(parser_node^.field, parser_node^.length, current_field^.name, current_field^.length) = 0 then + (* Debug. Error stream output. + _syscall(2, name_pointer, name_length, 0, 0, 0, 64); + printf("# if %.*s\n\0", name_length, name_pointer); + fflush(0) *) + + field_count := field_count - 1; + current_field := current_field + ElnaTypeField_size(); + goto elna_type_field_access_expression_field end; - (* If the base_type is still nil this is record field access. *) - if base_type = nil then - 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); + base_type := current_field^.field_type + end; - field_count := ElnaTypeRecord_get_length(aggregate_type); - current_field := ElnaTypeRecord_get_members(aggregate_type); + parser_node^.type_decoration := base_type +end; - .elna_type_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 - (* Debug. Error stream output. - _syscall(2, name_pointer, name_length, 0, 0, 0, 64); - printf("# if %.*s\n\0", name_length, name_pointer); - fflush(0) *) - - field_count := field_count - 1; - current_field := current_field + ElnaTypeField_size(); - goto elna_type_designator_field - end; - base_type := ElnaTypeField_get_field_type(current_field) - end; - - ElnaTreeExpression_set_type_decoration(parser_node, base_type) - elsif expression_kind = ElnaTreeKind.call then +proc elna_type_designator(parser_node: ^ElnaTreeNode, symbol_table: Word); +begin + if parser_node^.kind = ElnaTreeKind.dereference_expression then + elna_type_dereference_expression(parser_node, symbol_table) + elsif parser_node^.kind = ElnaTreeKind.field_access_expression then + elna_type_field_access_expression(parser_node, symbol_table) + elsif parser_node^.kind = ElnaTreeKind.call then elna_type_call(parser_node, symbol_table) else elna_type_simple_expression(parser_node, symbol_table) end end; -proc elna_type_unary_expression(parser_node: Word, symbol_table: Word); +proc elna_type_unary_expression(parser_node: ^ElnaTreeUnaryExpression, symbol_table: Word); var - expression_kind: Word; - unary_operand: Word; - operand_type: Word; + unary_operand: ^ElnaTreeExpression; begin - expression_kind := ElnaTreeNode_get_kind(parser_node); - - if expression_kind = ElnaTreeKind.unary_expression then - unary_operand := ElnaTreeUnaryExpression_get_operand(parser_node); + if parser_node^.kind = ElnaTreeKind.unary_expression then + unary_operand := parser_node^.operand; elna_type_designator(unary_operand, symbol_table); - operand_type := ElnaTreeExpression_get_type_decoration(unary_operand); - ElnaTreeExpression_set_type_decoration(parser_node, operand_type) + parser_node^.type_decoration := unary_operand^.type_decoration else elna_type_designator(parser_node, symbol_table) end end; -proc elna_type_binary_expression(parser_node: Word, symbol_table: Word); +proc elna_type_binary_expression(parser_node: ^ElnaTreeBinaryExpression, symbol_table: Word); var - expression_kind: Word; - binary_operand: Word; - operand_type: Word; + binary_operand: ^ElnaTreeExpression; begin - expression_kind := ElnaTreeNode_get_kind(parser_node); + if parser_node^.kind = ElnaTreeKind.binary_expression then + elna_type_unary_expression(parser_node^.rhs, symbol_table); - if expression_kind = ElnaTreeKind.binary_expression then - binary_operand := ElnaTreeBinaryExpression_get_rhs(parser_node); + binary_operand := parser_node^.lhs; elna_type_unary_expression(binary_operand, symbol_table); - binary_operand := ElnaTreeBinaryExpression_get_lhs(parser_node); - elna_type_unary_expression(binary_operand, symbol_table); - - operand_type := ElnaTreeExpression_get_type_decoration(binary_operand); - - ElnaTreeExpression_set_type_decoration(parser_node, operand_type) + parser_node^.type_decoration := binary_operand^.type_decoration else elna_type_unary_expression(parser_node, symbol_table) end end; -proc elna_type_procedure_declaration(parser_node: Word); +proc elna_type_procedure_declaration(parser_node: ^_procedure_declaration); var - body: Word; - name_pointer: Word; - name_length: Word; - procedure_info: Word; + procedure_info: ^_procedure_info; symbol_table: Word; begin - body := _procedure_declaration_get_body(parser_node); - name_pointer := _procedure_declaration_get_name(parser_node); - name_length := _procedure_declaration_get_length(parser_node); + procedure_info := _symbol_table_lookup(@symbol_table_global, parser_node^.name, parser_node^.length); + symbol_table := procedure_info^.symbol_table; - procedure_info := _symbol_table_lookup(@symbol_table_global, name_pointer, name_length); - symbol_table := _procedure_info_get_symbol_table(procedure_info); - - elna_type_statements(body, symbol_table) + elna_type_statements(parser_node^.body, symbol_table) end; -proc elna_name_module_declaration(parser_node: Word); +proc elna_name_module_declaration(parser_node: ^_module_declaration); var - current_part: Word; - result: Word; + current_part: ^_declaration; begin - current_part := _module_declaration_get_types(parser_node); + current_part := parser_node^.types; .elna_name_module_declaration_type; if current_part <> nil then elna_name_type_declaration(current_part); - current_part := _declaration_get_next(current_part); + current_part := current_part^.next; goto elna_name_module_declaration_type end; - current_part := _module_declaration_get_globals(parser_node); + 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); - current_part := _declaration_get_next(current_part); + current_part := current_part^.next; goto elna_name_module_declaration_global end; - current_part := _module_declaration_get_procedures(parser_node); + current_part := parser_node^.procedures; .elna_name_module_declaration_procedure; if current_part <> nil then elna_name_procedure_declaration(current_part); - current_part := _declaration_get_next(current_part); + current_part := current_part^.next; goto elna_name_module_declaration_procedure end end; -proc elna_type_module_declaration(parser_node: Word); +proc elna_type_module_declaration(parser_node: ^_module_declaration); var - current_part: Word; + current_part: ^_declaration; begin - current_part := _module_declaration_get_types(parser_node); + current_part := parser_node^.types; .elna_type_module_declaration_type; if current_part <> 0 then elna_type_type_declaration(current_part); - current_part := _declaration_get_next(current_part); + current_part := current_part^.next; goto elna_type_module_declaration_type end; - current_part := _module_declaration_get_procedures(parser_node); + current_part := parser_node^.procedures; .elna_type_module_declaration_procedure; if current_part <> 0 then elna_type_procedure_declaration(current_part); - current_part := _declaration_get_next(current_part); + current_part := current_part^.next; goto elna_type_module_declaration_procedure end @@ -4713,15 +4456,15 @@ end; proc _symbol_table_build(); var - current_info: Word; - current_type: Word; + current_info: ^_type_info; + current_type: ^ElnaType; begin (* Set the table length to 0. *) symbol_table_global := 0; current_type := malloc(ElnaType_size()); - ElnaType_set_kind(current_type, ElnaTypeKind.primitive); - ElnaType_set_size(current_type, 4); + current_type^.kind := ElnaTypeKind.primitive; + current_type^.size := 4; (* Enter built-in symbols. *) current_info := _type_info_create(current_type); @@ -5534,10 +5277,3 @@ begin _exit(0) end; - -proc f(x: ElnaTreeExpression); -var - y: Word; -begin - y := x.kind -end;