From c3eff02f8d610b6bd259eee672c044731df43d65 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Sat, 22 Nov 2025 23:27:00 +0100 Subject: [PATCH] Visit expressions in the type checker --- boot/stage16/cl.elna | 955 ++++++++++++++++++++++++++++++------------- 1 file changed, 661 insertions(+), 294 deletions(-) diff --git a/boot/stage16/cl.elna b/boot/stage16/cl.elna index 32bedfb..0a6d454 100644 --- a/boot/stage16/cl.elna +++ b/boot/stage16/cl.elna @@ -21,44 +21,52 @@ type body: Word; stack: Word end; - _node = record + ElnaTreeNode = record kind: Word end; - _integer_literal_node = record + ElnaTreeIntegerLiteral = record kind: Word; + type_decoration: Word; value: Word; length: Word end; - _character_literal_node = record + ElnaTreeCharacterLiteral = record kind: Word; + type_decoration: Word; value: Word; length: Word end; - _nil_node = record - kind: Word - end; - _variable_expression = record + ElnaTreeNilLiteral = record kind: Word; + type_decoration: Word + end; + ElnaTreeVariableExpression = record + kind: Word; + type_decoration: Word; name: Word; length: Word end; - _string_literal_node = record + ElnaTreeStringLiteral = record kind: Word; + type_decoration: Word; value: Word; length: Word end; - _dereference_expression = record + ElnaTreeDereferenceExpression = record kind: Word; + type_decoration: Word; pointer: Word end; - _binary_expression = record + ElnaTreeBinaryExpression = record kind: Word; + type_decoration: Word; lhs: Word; rhs: Word; operator: Word end; - _unary_expression = record + ElnaTreeUnaryExpression = record kind: Word; + type_decoration: Word; operand: Word; operator: Word end; @@ -89,12 +97,18 @@ type label: Word; length: Word end; - _field_access_expression = record + ElnaTreeFieldAccessExpression = record kind: Word; + type_decoration: Word; aggregate: Word; field: Word; length: Word end; + ElnaTreeEnumerationTypeExpression = record + kind: Word; + members: Word; + length: Word + end; ElnaInstructionModule = record data: Word; code: Word @@ -116,35 +130,50 @@ type next: Word; returned: Word end; - _type = record + ElnaTreeRecordTypeExpression = record + kind: Word; + members: Word; + length: Word + end; + ElnaTreeNamedTypeExpression = record + kind: Word; + name: Word; + length: Word + end; + ElnaTreePointerTypeExpression = record + kind: Word; + base: Word + end; + ElnaTreeArrayTypeExpression = record + kind: Word; + base: Word; + length: Word + end; + ElnaType = record kind: Word; size: Word end; - _enumeration_type = record + ElnaTypeEnumeration = record kind: Word; size: Word; members: Word; length: Word end; - _enumeration_type_expression = record - kind: Word; - members: Word; - length: Word - end; - _record_type = record + ElnaTypeRecord = record kind: Word; size: Word; members: Word; length: Word end; - _record_type_expression = record + ElnaTypePointer = record kind: Word; - members: Word; - length: Word + size: Word; + base: Word end; - _named_type_expression = record + ElnaTypeArray = record kind: Word; - name: Word; + size: Word; + base: Word; length: Word end; _info = record @@ -156,11 +185,13 @@ type end; _parameter_info = record kind: Word; - offset: Word + offset: Word; + variable_type: Word end; _temporary_info = record kind: Word; - offset: Word + offset: Word; + variable_type: Word end; _procedure_info = record kind: Word; @@ -327,7 +358,7 @@ type _goto, eof ); - NodeKind = ( + ElnaTreeKind = ( integer_literal, string_literal, character_literal, @@ -349,10 +380,12 @@ type type_declaration, module_declaration, record_type_expression, + pointer_type_expression, + array_type_expression, null ); InfoKind = (type_info, parameter_info, temporary_info, procedure_info); - TypeKind = (primitive, enumeration, _record); + TypeKind = (primitive, enumeration, _record, pointer, array); ElnaTacOperator = ( get_address, add, @@ -1187,10 +1220,6 @@ begin else ElnaInstructionList_set_next(operands, next_instruction^) end - (* Debug. Error stream output. - _syscall(2, name_pointer, name_length, 0, 0, 0, 64); - printf("# here\n\0"); - fflush(0); *) end end; if next_instruction^ = 0 then @@ -1536,34 +1565,36 @@ begin _write_c('\n'); end; -proc _elna_parser_integer_literal(); +proc elna_parser_integer_literal(); var integer_token: Word; integer_length: Word; result: Word; begin - result := malloc(_integer_literal_node_size()); + result := malloc(ElnaTreeIntegerLiteral_size()); integer_token := _elna_lexer_global_get_start(); integer_length := _elna_lexer_global_get_end(); integer_length := integer_length - integer_token; _elna_lexer_skip_token(); - _node_set_kind(result, NodeKind.integer_literal); - _integer_literal_node_set_value(result, integer_token); - _integer_literal_node_set_length(result, integer_length); + ElnaTreeNode_set_kind(result, ElnaTreeKind.integer_literal); + ElnaTreeIntegerLiteral_set_value(result, integer_token); + ElnaTreeIntegerLiteral_set_length(result, integer_length); + ElnaTreeIntegerLiteral_set_type_decoration(result, nil); return result end; -proc _elna_parser_nil(); +proc elna_parser_nil_literal(); var result: Word; begin _elna_lexer_skip_token(); - result := malloc(_nil_node_size()); - _nil_node_set_kind(result, NodeKind.null); + result := malloc(ElnaTreeNilLiteral_size()); + ElnaTreeNode_set_kind(result, ElnaTreeKind.null); + ElnaTreeIntegerLiteral_set_type_decoration(result, nil); return result end; @@ -1571,13 +1602,13 @@ end; proc _elna_tac_integer_literal(integer_literal_node: Word, operand_type: Word, operand_value: Word, operand_length: Word); begin operand_type^ := ElnaTacOperand.immediate; - operand_value^ := _integer_literal_node_get_value(integer_literal_node); - operand_length^ := _integer_literal_node_get_length(integer_literal_node); + operand_value^ := ElnaTreeIntegerLiteral_get_value(integer_literal_node); + operand_length^ := ElnaTreeIntegerLiteral_get_length(integer_literal_node); return 0 end; -proc _elna_tac_nil(nil_node: Word, operand_type: Word, operand_value: Word, operand_length: Word); +proc _elna_tac_nil_literal(nil_node: Word, operand_type: Word, operand_value: Word, operand_length: Word); begin operand_type^ := ElnaTacOperand.immediate; operand_value^ := 0; @@ -1586,22 +1617,23 @@ begin return 0 end; -proc _elna_parser_character_literal(); +proc elna_parser_character_literal(); var character: Word; character_length: Word; result: Word; begin - result := malloc(_character_literal_node_size()); + result := malloc(ElnaTreeCharacterLiteral_size()); character := _elna_lexer_global_get_start(); character_length := _elna_lexer_global_get_end(); character_length := character_length - character; _elna_lexer_skip_token(); - _node_set_kind(result, NodeKind.character_literal); - _integer_literal_node_set_value(result, character); - _integer_literal_node_set_length(result, character_length); + ElnaTreeNode_set_kind(result, ElnaTreeKind.character_literal); + ElnaTreeIntegerLiteral_set_value(result, character); + ElnaTreeIntegerLiteral_set_length(result, character_length); + ElnaTreeIntegerLiteral_set_type_decoration(result, nil); return result end; @@ -1609,28 +1641,28 @@ end; proc _elna_tac_character_literal(character_literal_node: Word, operand_type: Word, operand_value: Word, operand_length: Word); begin operand_type^ := ElnaTacOperand.immediate; - operand_value^ :=_character_literal_node_get_value(character_literal_node); - operand_length^ := _character_literal_node_get_length(character_literal_node); + operand_value^ :=ElnaTreeCharacterLiteral_get_value(character_literal_node); + operand_length^ := ElnaTreeCharacterLiteral_get_length(character_literal_node); return 0 end; -proc _elna_parser_variable_expression(); +proc elna_parser_variable_expression(); var - name: Word; - name_token: Word; + name_pointer: Word; + name_length: Word; result: Word; begin - name := _elna_lexer_global_get_start(); - name_token := _elna_lexer_global_get_end(); - name_token := name_token - name; + name_pointer := _elna_lexer_global_get_start(); + name_length := _elna_lexer_global_get_end() - name_pointer; _elna_lexer_skip_token(); - result := malloc(_variable_expression_size()); + result := malloc(ElnaTreeVariableExpression_size()); - _node_set_kind(result, NodeKind.variable_expression); - _variable_expression_set_name(result, name); - _variable_expression_set_length(result, name_token); + ElnaTreeNode_set_kind(result, ElnaTreeKind.variable_expression); + ElnaTreeVariableExpression_set_name(result, name_pointer); + ElnaTreeVariableExpression_set_length(result, name_length); + ElnaTreeVariableExpression_set_type_decoration(result, nil); return result end; @@ -1641,8 +1673,8 @@ var name_length: Word; lookup_result: Word; begin - name_pointer := _variable_expression_get_name(variable_expression); - name_length := _variable_expression_get_length(variable_expression); + 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 @@ -1657,21 +1689,22 @@ begin return 0 end; -proc _elna_parser_string_literal(); +proc elna_parser_string_literal(); var length: Word; token_start: Word; result: Word; begin - result := malloc(_string_literal_node_size()); + result := malloc(ElnaTreeStringLiteral_size()); token_start := _elna_lexer_global_get_start(); length := _string_length(token_start); _elna_lexer_skip_token(); - _node_set_kind(result, NodeKind.string_literal); - _string_literal_node_set_value(result, token_start); - _string_literal_node_set_length(result, length); + ElnaTreeNode_set_kind(result, ElnaTreeKind.string_literal); + ElnaTreeStringLiteral_set_value(result, token_start); + ElnaTreeStringLiteral_set_length(result, length); + ElnaTreeIntegerLiteral_set_type_decoration(result, nil); return result end; @@ -1683,7 +1716,7 @@ var first_instruction: Word; next_instruction: Word; begin - token_start := _string_literal_node_get_value(string_literal_node); + token_start := ElnaTreeStringLiteral_get_value(string_literal_node); offset := _add_string(token_start); first_instruction := _elna_tac_instruction_create(ElnaTacOperator.get_address); @@ -1703,7 +1736,7 @@ begin return elna_instruction_list_concatenate(first_instruction, next_instruction) end; -proc _elna_parser_simple_expression(); +proc elna_parser_simple_expression(); var current_character: Word; parser_node: Word; @@ -1713,47 +1746,48 @@ begin _elna_lexer_read_token(@token_kind); if token_kind = ElnaLexerKind.character then - parser_node := _elna_parser_character_literal() + parser_node := elna_parser_character_literal() elsif token_kind = ElnaLexerKind.integer then - parser_node := _elna_parser_integer_literal() + parser_node := elna_parser_integer_literal() elsif token_kind = ElnaLexerKind.string then - parser_node := _elna_parser_string_literal() + parser_node := elna_parser_string_literal() elsif token_kind = ElnaLexerKind.null then - parser_node := _elna_parser_nil() + parser_node := elna_parser_nil_literal() elsif token_kind = ElnaLexerKind.identifier then - parser_node := _elna_parser_variable_expression() + parser_node := elna_parser_variable_expression() end; return parser_node end; -proc _elna_parser_dereference_expression(simple_expression: Word); +proc elna_parser_dereference_expression(simple_expression: Word); var result: Word; begin - result := malloc(_dereference_expression_size()); + result := malloc(ElnaTreeDereferenceExpression_size()); - _node_set_kind(result, NodeKind.dereference_expression); - _dereference_expression_set_pointer(result, simple_expression); + ElnaTreeNode_set_kind(result, ElnaTreeKind.dereference_expression); + ElnaTreeDereferenceExpression_set_pointer(result, simple_expression); + ElnaTreeDereferenceExpression_set_type_decoration(result, nil); _elna_lexer_skip_token(); return result end; -proc _elna_parser_designator(); +proc elna_parser_designator(); var simple_expression: Word; token_kind: Word; begin - simple_expression := _elna_parser_simple_expression(); + simple_expression := elna_parser_simple_expression(); _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) elsif token_kind = ElnaLexerKind.dot then - simple_expression := _elna_parser_field_access_expression(simple_expression) + simple_expression := elna_parser_field_access_expression(simple_expression) elsif token_kind = ElnaLexerKind.left_paren then - simple_expression := _elna_parser_call(simple_expression) + simple_expression := elna_parser_call(simple_expression) end; return simple_expression end; @@ -1763,23 +1797,23 @@ var node_kind: Word; instruction: Word; begin - node_kind := _node_get_kind(parser_node); + node_kind := ElnaTreeNode_get_kind(parser_node); - if node_kind = NodeKind.character_literal then + if node_kind = ElnaTreeKind.character_literal then instruction := _elna_tac_character_literal(parser_node, operand_type, operand_value, operand_length) - elsif node_kind = NodeKind.string_literal then + elsif node_kind = ElnaTreeKind.string_literal then instruction := _elna_tac_string_literal(parser_node, operand_type, operand_value, operand_length) - elsif node_kind = NodeKind.integer_literal then + elsif node_kind = ElnaTreeKind.integer_literal then instruction := _elna_tac_integer_literal(parser_node, operand_type, operand_value, operand_length) - elsif node_kind = NodeKind.null then - instruction := _elna_tac_nil(parser_node, operand_type, operand_value, operand_length) + elsif 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) end; return instruction end; -proc _elna_parser_unary_expression(); +proc elna_parser_unary_expression(); var token_kind: Word; result: Word; @@ -1799,15 +1833,16 @@ begin if operator <> 0 then _elna_lexer_skip_token() end; - result := _elna_parser_designator(); + result := elna_parser_designator(); if operator <> 0 then operand := result; - result := malloc(_unary_expression_size()); + result := malloc(ElnaTreeUnaryExpression_size()); - _node_set_kind(result, NodeKind.unary_expression); - _unary_expression_set_operand(result, operand); - _unary_expression_set_operator(result, operator) + ElnaTreeNode_set_kind(result, ElnaTreeKind.unary_expression); + ElnaTreeUnaryExpression_set_operand(result, operand); + ElnaTreeUnaryExpression_set_operator(result, operator); + ElnaTreeUnaryExpression_set_type_decoration(result, nil) end; return result @@ -1828,11 +1863,11 @@ begin operator := 0; operand := 0; - expression_kind := _node_get_kind(parser_node); + expression_kind := ElnaTreeNode_get_kind(parser_node); - if expression_kind = NodeKind.unary_expression then - operator := _unary_expression_get_operator(parser_node); - operand := _unary_expression_get_operand(parser_node) + if expression_kind = ElnaTreeKind.unary_expression then + operator := ElnaTreeUnaryExpression_get_operator(parser_node); + operand := ElnaTreeUnaryExpression_get_operand(parser_node) else operand := parser_node end; @@ -1890,67 +1925,68 @@ begin return first_instruction end; -proc _elna_parser_binary_expression(); +proc elna_parser_binary_expression(); var lhs_node: Word; rhs_node: Word; token_kind: Word; result: Word; begin - lhs_node := _elna_parser_unary_expression(); + lhs_node := elna_parser_unary_expression(); rhs_node := 0; _elna_lexer_read_token(@token_kind); if token_kind = ElnaLexerKind.plus then _elna_lexer_skip_token(); - rhs_node := _elna_parser_unary_expression() + rhs_node := elna_parser_unary_expression() elsif token_kind = ElnaLexerKind.minus then _elna_lexer_skip_token(); - rhs_node := _elna_parser_unary_expression() + rhs_node := elna_parser_unary_expression() elsif token_kind = ElnaLexerKind.multiplication then _elna_lexer_skip_token(); - rhs_node := _elna_parser_unary_expression() + rhs_node := elna_parser_unary_expression() elsif token_kind = ElnaLexerKind.and then _elna_lexer_skip_token(); - rhs_node := _elna_parser_unary_expression() + rhs_node := elna_parser_unary_expression() elsif token_kind = ElnaLexerKind._or then _elna_lexer_skip_token(); - rhs_node := _elna_parser_unary_expression() + rhs_node := elna_parser_unary_expression() elsif token_kind = ElnaLexerKind._xor then _elna_lexer_skip_token(); - rhs_node := _elna_parser_unary_expression() + rhs_node := elna_parser_unary_expression() elsif token_kind = ElnaLexerKind.equals then _elna_lexer_skip_token(); - rhs_node := _elna_parser_unary_expression() + rhs_node := elna_parser_unary_expression() elsif token_kind = ElnaLexerKind.remainder then _elna_lexer_skip_token(); - rhs_node := _elna_parser_unary_expression() + rhs_node := elna_parser_unary_expression() elsif token_kind = ElnaLexerKind.division then _elna_lexer_skip_token(); - rhs_node := _elna_parser_unary_expression() + rhs_node := elna_parser_unary_expression() elsif token_kind = ElnaLexerKind.less_than then _elna_lexer_skip_token(); - rhs_node := _elna_parser_unary_expression() + rhs_node := elna_parser_unary_expression() elsif token_kind = ElnaLexerKind.greater_than then _elna_lexer_skip_token(); - rhs_node := _elna_parser_unary_expression() + rhs_node := elna_parser_unary_expression() elsif token_kind = ElnaLexerKind.less_equal then _elna_lexer_skip_token(); - rhs_node := _elna_parser_unary_expression() + rhs_node := elna_parser_unary_expression() elsif token_kind = ElnaLexerKind.not_equal then _elna_lexer_skip_token(); - rhs_node := _elna_parser_unary_expression() + rhs_node := elna_parser_unary_expression() elsif token_kind = ElnaLexerKind.greater_equal then _elna_lexer_skip_token(); - rhs_node := _elna_parser_unary_expression() + rhs_node := elna_parser_unary_expression() end; if rhs_node <> 0 then - result := malloc(_binary_expression_size()); + result := malloc(ElnaTreeBinaryExpression_size()); - _node_set_kind(result, NodeKind.binary_expression); - _binary_expression_set_lhs(result, lhs_node); - _binary_expression_set_rhs(result, rhs_node); - _binary_expression_set_operator(result, token_kind) + 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); + ElnaTreeBinaryExpression_set_type_decoration(result, nil) else result := lhs_node end; @@ -1969,14 +2005,14 @@ var lhs_value: Word; lhs_length: Word; begin - expression_kind := _node_get_kind(parser_node); + expression_kind := ElnaTreeNode_get_kind(parser_node); - if expression_kind <> NodeKind.binary_expression then + if expression_kind <> ElnaTreeKind.binary_expression then first_instruction := _elna_tac_unary_expression(parser_node, symbol_table, operand_type, operand_value, operand_length) else - token_kind := _binary_expression_get_operator(parser_node); + token_kind := ElnaTreeBinaryExpression_get_operator(parser_node); - operand_node := _binary_expression_get_lhs(parser_node); + operand_node := ElnaTreeBinaryExpression_get_lhs(parser_node); lhs_type := 0; lhs_value := 0; lhs_length := 0; @@ -1994,7 +2030,7 @@ begin end; current_instruction := instruction; - operand_node := _binary_expression_get_rhs(parser_node); + operand_node := ElnaTreeBinaryExpression_get_rhs(parser_node); lhs_type := 0; lhs_value := 0; lhs_length := 0; @@ -2085,7 +2121,7 @@ begin this^ := value end; -proc _elna_parser_call(callee: Word); +proc elna_parser_call(callee: Word); var parsed_expression: Word; result: Word; @@ -2093,7 +2129,7 @@ var token_kind: Word; begin result := malloc(_call_size()); - _node_set_kind(result, NodeKind.call); + ElnaTreeNode_set_kind(result, ElnaTreeKind.call); _statement_set_next(result, 0); argument_number := 1; @@ -2109,7 +2145,7 @@ begin end; .elna_parser_call_loop; - parsed_expression := _elna_parser_binary_expression(); + parsed_expression := elna_parser_binary_expression(); _call_set_argument(result, argument_number, parsed_expression); argument_number := argument_number + 1; _elna_lexer_read_token(@token_kind); @@ -2121,7 +2157,7 @@ begin .elna_parser_call_end; (* Set the trailing argument to nil. *) - _call_set_argument(result, argument_number, 0); + _call_set_argument(result, argument_number, nil); return result end; @@ -2141,8 +2177,8 @@ var operand_length: Word; begin parsed_expression := _call_get_name(parsed_call); - name := _variable_expression_get_name(parsed_expression); - name_length := _variable_expression_get_length(parsed_expression); + name := ElnaTreeVariableExpression_get_name(parsed_expression); + name_length := ElnaTreeVariableExpression_get_length(parsed_expression); argument_count := 0; first_instruction := 0; @@ -2208,7 +2244,7 @@ begin return first_instruction end; -proc _elna_parser_goto_statement(); +proc elna_parser_goto_statement(); var token_kind: Word; label_name: Word; @@ -2224,7 +2260,7 @@ begin result := malloc(_goto_statement_size()); - _node_set_kind(result, NodeKind.goto_statement); + 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); @@ -2251,7 +2287,7 @@ begin return instruction end; -proc _elna_parser_label_declaration(); +proc elna_parser_label_declaration(); var token_kind: Word; label_name: Word; @@ -2267,7 +2303,7 @@ begin result := malloc(_label_declaration_size()); - _node_set_kind(result, NodeKind.label_declaration); + 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); @@ -2299,20 +2335,20 @@ var counter: Word; symbol: Word; begin - symbol := _field_access_expression_get_aggregate(field_access_expression); - value_name := _variable_expression_get_name(symbol); - name_length := _variable_expression_get_length(symbol); + symbol := ElnaTreeFieldAccessExpression_get_aggregate(field_access_expression); + value_name := ElnaTreeVariableExpression_get_name(symbol); + name_length := ElnaTreeVariableExpression_get_length(symbol); symbol := _symbol_table_lookup(@symbol_table_global, value_name, name_length); enumeration_type := _type_info_get__type(symbol); - members := _enumeration_type_get_members(enumeration_type); - members_length := _enumeration_type_get_length(enumeration_type); + members := ElnaTypeEnumeration_get_members(enumeration_type); + members_length := ElnaTypeEnumeration_get_length(enumeration_type); _elna_lexer_read_token(@token_type); - value_name := _field_access_expression_get_field(field_access_expression); - name_length := _field_access_expression_get_length(field_access_expression); + value_name := ElnaTreeFieldAccessExpression_get_field(field_access_expression); + name_length := ElnaTreeFieldAccessExpression_get_length(field_access_expression); counter := 1; .elna_tac_enumeration_value_members; @@ -2335,28 +2371,28 @@ begin return 0 end; -proc _elna_parser_field_access_expression(aggregate: Word); +proc elna_parser_field_access_expression(aggregate: Word); var token_kind: Word; - name: Word; - name_token: Word; + name_pointer: Word; + name_length: Word; result: Word; begin (* Skip dot. Read the enumeration value. *) _elna_lexer_skip_token(); _elna_lexer_read_token(@token_kind); - name := _elna_lexer_global_get_start(); - name_token := _elna_lexer_global_get_end(); - name_token := name_token - name; + name_pointer := _elna_lexer_global_get_start(); + name_length := _elna_lexer_global_get_end() - name_pointer; _elna_lexer_skip_token(); - result := malloc(_field_access_expression_size()); + result := malloc(ElnaTreeFieldAccessExpression_size()); - _node_set_kind(result, NodeKind.field_access_expression); - _field_access_expression_set_aggregate(result, aggregate); - _field_access_expression_set_field(result, name); - _field_access_expression_set_length(result, name_token); + 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); + ElnaTreeFieldAccessExpression_set_type_decoration(result, nil); return result end; @@ -2368,10 +2404,10 @@ var first_instruction: Word; last_instruction: Word; begin - node_kind := _node_get_kind(parser_node); + node_kind := ElnaTreeNode_get_kind(parser_node); - if node_kind = NodeKind.dereference_expression then - parser_node := _dereference_expression_get_pointer(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); last_instruction := _elna_tac_instruction_create(ElnaTacOperator.copy); @@ -2384,10 +2420,10 @@ begin is_address^ := 2; first_instruction := elna_instruction_list_concatenate(first_instruction, last_instruction) - elsif node_kind = NodeKind.field_access_expression then + elsif node_kind = ElnaTreeKind.field_access_expression then first_instruction := _elna_tac_enumeration_value(parser_node, operand_type, operand_value, operand_length); is_address^ := 0 - elsif node_kind = NodeKind.call then + elsif node_kind = ElnaTreeKind.call then first_instruction := _elna_tac_call(parser_node, symbol_table); last_instruction := _elna_tac_instruction_create(ElnaTacOperator.copy); @@ -2407,7 +2443,7 @@ begin return first_instruction end; -proc _elna_parser_assign_statement(assignee: Word); +proc elna_parser_assign_statement(assignee: Word); var result: Word; token_kind: Word; @@ -2415,7 +2451,7 @@ var begin result := malloc(_assign_statement_size()); - _node_set_kind(result, NodeKind.assign_statement); + ElnaTreeNode_set_kind(result, ElnaTreeKind.assign_statement); _statement_set_next(result, 0); _assign_statement_set_assignee(result, assignee); @@ -2423,7 +2459,7 @@ begin _elna_lexer_read_token(@token_kind); _elna_lexer_skip_token(); - assignment_node := _elna_parser_binary_expression(); + assignment_node := elna_parser_binary_expression(); _assign_statement_set_assignment(result, assignment_node); return result @@ -2485,7 +2521,7 @@ begin return first_instruction end; -proc _elna_parser_return_statement(); +proc elna_parser_return_statement(); var token_kind: Word; returned: Word; @@ -2496,10 +2532,10 @@ begin _elna_lexer_skip_token(); _elna_lexer_read_token(@token_kind); - returned := _elna_parser_binary_expression(); + returned := elna_parser_binary_expression(); result := malloc(_return_statement_size()); - _node_set_kind(result, NodeKind.return_statement); + ElnaTreeNode_set_kind(result, ElnaTreeKind.return_statement); _statement_set_next(result, 0); _return_statement_set_returned(result, returned); @@ -2549,7 +2585,7 @@ begin end end; -proc _elna_parser_conditional_statements(); +proc elna_parser_conditional_statements(); var token_kind: Word; current_node: Word; @@ -2560,14 +2596,14 @@ begin (* Skip "if", "while" or "elsif". *) _elna_lexer_skip_token(); - current_node := _elna_parser_binary_expression(); + current_node := elna_parser_binary_expression(); _conditional_statements_set_condition(result, current_node); (* Skip "then" or "do". *) _elna_lexer_read_token(@token_kind); _elna_lexer_skip_token(); - current_node := _elna_parser_statements(); + current_node := elna_parser_statements(); _conditional_statements_set_statements(result, current_node); _conditional_statements_set_next(result, 0); @@ -2619,7 +2655,7 @@ begin return first_instruction end; -proc _elna_parser_if_statement(); +proc elna_parser_if_statement(); var current_node: Word; result: Word; @@ -2629,17 +2665,17 @@ var begin result := malloc(_if_statement_size()); - _node_set_kind(result, NodeKind.if_statement); + ElnaTreeNode_set_kind(result, ElnaTreeKind.if_statement); _statement_set_next(result, 0); - previous_conditional := _elna_parser_conditional_statements(); + previous_conditional := elna_parser_conditional_statements(); _if_statement_set_conditionals(result, 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(); + next_conditional := elna_parser_conditional_statements(); _conditional_statements_set_next(previous_conditional, next_conditional); previous_conditional = next_conditional; @@ -2647,7 +2683,7 @@ begin elsif token_kind = ElnaLexerKind._else then _elna_lexer_skip_token(); - current_node := _elna_parser_statements(); + current_node := elna_parser_statements(); _if_statement_set__else(result, current_node) else _if_statement_set__else(result, 0) @@ -2657,7 +2693,7 @@ begin return result end; -proc _elna_parser_statement(); +proc elna_parser_statement(); var token_kind: Word; result : Word; @@ -2667,25 +2703,25 @@ begin _elna_lexer_read_token(@token_kind); if token_kind = ElnaLexerKind._goto then - result := _elna_parser_goto_statement() + result := elna_parser_goto_statement() elsif token_kind = ElnaLexerKind._if then - result := _elna_parser_if_statement() + result := elna_parser_if_statement() elsif token_kind = ElnaLexerKind._return then - result := _elna_parser_return_statement() + result := elna_parser_return_statement() elsif token_kind = ElnaLexerKind.dot then - result := _elna_parser_label_declaration() + result := elna_parser_label_declaration() elsif token_kind = ElnaLexerKind.identifier then - result := _elna_parser_designator(); - temporary := _node_get_kind(result); + result := elna_parser_designator(); + temporary := ElnaTreeNode_get_kind(result); - if temporary <> NodeKind.call then - result := _elna_parser_assign_statement(result) + if temporary <> ElnaTreeKind.call then + result := elna_parser_assign_statement(result) end end; return result end; -proc _elna_parser_statements(); +proc elna_parser_statements(); var token_kind: Word; previous_statement: Word; @@ -2694,7 +2730,7 @@ var begin _skip_empty_lines(); - first_statement := _elna_parser_statement(); + first_statement := elna_parser_statement(); previous_statement := first_statement; if previous_statement = 0 then goto elna_parser_statements_end @@ -2706,7 +2742,7 @@ begin if token_kind = ElnaLexerKind.semicolon then _elna_lexer_skip_token(); _skip_empty_lines(); - next_statement := _elna_parser_statement(); + next_statement := elna_parser_statement(); _statement_set_next(previous_statement, next_statement); previous_statement := next_statement; @@ -2792,19 +2828,19 @@ var statement_kind: Word; instruction: Word; begin - statement_kind := _node_get_kind(parser_node); + statement_kind := ElnaTreeNode_get_kind(parser_node); - if statement_kind = NodeKind.goto_statement then + if statement_kind = ElnaTreeKind.goto_statement then instruction := _elna_tac_goto_statement(parser_node) - elsif statement_kind = NodeKind.if_statement then + elsif statement_kind = ElnaTreeKind.if_statement then instruction := _elna_tac_if_statement(parser_node, symbol_table) - elsif statement_kind = NodeKind.return_statement then + elsif statement_kind = ElnaTreeKind.return_statement then instruction := _elna_tac_return_statement(parser_node, symbol_table) - elsif statement_kind = NodeKind.label_declaration then + elsif statement_kind = ElnaTreeKind.label_declaration then instruction := _elna_tac_label_declaration(parser_node) - elsif statement_kind = NodeKind.call then + elsif statement_kind = ElnaTreeKind.call then instruction := _elna_tac_call(parser_node, symbol_table) - elsif statement_kind = NodeKind.assign_statement then + elsif statement_kind = ElnaTreeKind.assign_statement then instruction := _elna_tac_assign_statement(parser_node, symbol_table) else instruction := 0 @@ -2825,7 +2861,7 @@ begin _write_c(register_number + '0') end; -proc _elna_parser_record_type_expression(); +proc elna_parser_record_type_expression(); var entry: Word; member_count: Word; @@ -2863,7 +2899,7 @@ begin _elna_lexer_read_token(@token_kind); _elna_lexer_skip_token(); - field_type := _elna_parser_type_expression(); + field_type := elna_parser_type_expression(); entry^ := field_type; entry := entry + 4; @@ -2886,16 +2922,16 @@ begin .elna_parser_record_type_expression_end; _elna_lexer_skip_token(); - result := malloc(_enumeration_type_expression_size()); + result := malloc(ElnaTreeEnumerationTypeExpression_size()); - _node_set_kind(result, NodeKind.record_type_expression); - _record_type_expression_set_members(result, memory_start); - _record_type_expression_set_length(result, member_count); + ElnaTreeNode_set_kind(result, ElnaTreeKind.record_type_expression); + ElnaTreeRecordTypeExpression_set_members(result, memory_start); + ElnaTreeRecordTypeExpression_set_length(result, member_count); return result end; -proc _elna_parser_enumeration_type_expression(); +proc elna_parser_enumeration_type_expression(); var token_kind: Word; enumeration_name: Word; @@ -2948,11 +2984,11 @@ begin .elna_parser_enumeration_type_expression_end; _elna_lexer_skip_token(); - result := malloc(_enumeration_type_expression_size()); + result := malloc(ElnaTreeEnumerationTypeExpression_size()); - _node_set_kind(result, NodeKind.enumeration_type_expression); - _enumeration_type_expression_set_members(result, memory_start); - _enumeration_type_expression_set_length(result, member_count); + ElnaTreeNode_set_kind(result, ElnaTreeKind.enumeration_type_expression); + ElnaTreeEnumerationTypeExpression_set_members(result, memory_start); + ElnaTreeEnumerationTypeExpression_set_length(result, member_count); return result end; @@ -2969,7 +3005,7 @@ end; * * Returns enumeration type description. *) -proc _elna_name_type_enumeration(parser_node: Word); +proc elna_name_enumeration_type_expression(parser_node: Word); var result: Word; memory_start: Word; @@ -2977,10 +3013,10 @@ var member_array_start: Word; member_array_current: Word; begin - result := malloc(_enumeration_type_size()); + result := malloc(ElnaTypeEnumeration_size()); - memory_start := _enumeration_type_expression_get_members(parser_node); - member_count := _enumeration_type_expression_get_length(parser_node); + memory_start := ElnaTreeEnumerationTypeExpression_get_members(parser_node); + member_count := ElnaTreeEnumerationTypeExpression_get_length(parser_node); (* Copy the list of enumeration members into an array of strings. *) member_array_start := malloc(member_count * 8); @@ -3000,17 +3036,58 @@ begin member_count := member_count - 1; goto elna_name_type_enumeration_loop end; - member_count := _enumeration_type_expression_get_length(parser_node); + member_count := ElnaTreeEnumerationTypeExpression_get_length(parser_node); - _type_set_kind(result, TypeKind.enumeration); - _type_set_size(result, 4); - _enumeration_type_set_members(result, member_array_start); - _enumeration_type_set_length(result, member_count); + ElnaType_set_kind(result, TypeKind.enumeration); + ElnaType_set_size(result, 4); + ElnaTypeEnumeration_set_members(result, member_array_start); + ElnaTypeEnumeration_set_length(result, member_count); - return _type_info_create(result) + return result end; -proc _elna_name_type_record(parser_node: Word); +proc elna_name_pointer_type_expression(parser_node: Word); +var + base: Word; + result: Word; +begin + result := malloc(ElnaTypePointer_size()); + base := ElnaTreePointerTypeExpression_get_base(parser_node); + base := elna_name_type_expression(base); + + ElnaType_set_kind(result, TypeKind.pointer); + ElnaType_set_size(result, 4); + ElnaTypePointer_set_base(result, base); + + return result +end; + +proc elna_name_array_type_expression(parser_node: Word); +var + base: Word; + result: Word; + length: Word; + size: Word; +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); + + length := ElnaTreeArrayTypeExpression_get_length(parser_node); + (* Expected to be an integer literal for now. *) + length := ElnaTreeIntegerLiteral_get_value(length); + + ElnaType_set_kind(result, TypeKind.pointer); + ElnaType_set_size(result, size * length); + ElnaTypeArray_set_base(result, base); + ElnaTypeArray_set_size(result, length); + + return result +end; + +proc elna_name_record_type_expression(parser_node: Word); var result: Word; memory_start: Word; @@ -3018,10 +3095,10 @@ var member_array_start: Word; member_array_current: Word; begin - result := malloc(_record_type_size()); + result := malloc(ElnaTypeRecord_size()); - memory_start := _record_type_expression_get_members(parser_node); - member_count := _record_type_expression_get_length(parser_node); + memory_start := ElnaTreeRecordTypeExpression_get_members(parser_node); + member_count := ElnaTreeRecordTypeExpression_get_length(parser_node); member_array_start := malloc(member_count * 12); member_array_current := member_array_start; @@ -3036,7 +3113,7 @@ begin member_array_current := member_array_current + 4; memory_start := memory_start + 4; - member_array_current^ := _elna_name_type_expression(memory_start^); + member_array_current^ := elna_name_type_expression(memory_start^); member_array_current := member_array_current + 4; memory_start := memory_start + 4; @@ -3044,35 +3121,74 @@ begin member_count := member_count - 1; goto elna_name_type_record_loop end; - member_count := _record_type_expression_get_length(parser_node); + member_count := ElnaTreeRecordTypeExpression_get_length(parser_node); - _type_set_kind(result, TypeKind._record); - _type_set_size(result, member_count * 4); - _record_type_set_members(result, member_array_start); - _record_type_set_length(result, member_count); + ElnaType_set_kind(result, TypeKind._record); + ElnaType_set_size(result, member_count * 4); + ElnaTypeRecord_set_members(result, member_array_start); + ElnaTypeRecord_set_length(result, member_count); - return _type_info_create(result) + return result end; -proc _elna_parser_named_type_expression(); +proc elna_parser_named_type_expression(); var result: Word; type_name: Word; name_length: Word; begin - result := malloc(_named_type_expression_size()); + result := malloc(ElnaTreeNamedTypeExpression_size()); - _node_set_kind(result, NodeKind.named_type_expression); + ElnaTreeNode_set_kind(result, ElnaTreeKind.named_type_expression); type_name := _elna_lexer_global_get_start(); name_length := _elna_lexer_global_get_end() - type_name; - _named_type_expression_set_name(result, type_name); - _named_type_expression_set_length(result, name_length); + ElnaTreeNamedTypeExpression_set_name(result, type_name); + ElnaTreeNamedTypeExpression_set_length(result, name_length); _elna_lexer_skip_token(); return result end; -proc _elna_parser_type_expression(); +proc elna_parser_pointer_type_expression(); +var + result: Word; + base: Word; +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); + + return result +end; + +proc elna_parser_array_type_expression(); +var + result: Word; + base: Word; + size: Word; + 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); + + (* 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); + + return result +end; + +proc elna_parser_type_expression(); var token_kind: Word; result: Word; @@ -3081,34 +3197,42 @@ begin _elna_lexer_read_token(@token_kind); if token_kind = ElnaLexerKind.identifier then - result := _elna_parser_named_type_expression() + result := elna_parser_named_type_expression() elsif token_kind = ElnaLexerKind.left_paren then - result := _elna_parser_enumeration_type_expression() + result := elna_parser_enumeration_type_expression() elsif token_kind = ElnaLexerKind._record then - result := _elna_parser_record_type_expression() + result := elna_parser_record_type_expression() + elsif token_kind = ElnaLexerKind.hat then + result := elna_parser_pointer_type_expression() + elsif token_kind = ElnaLexerKind.left_square then + result := elna_parser_array_type_expression() end; return result end; -proc _elna_name_type_expression(parser_node: Word); +proc elna_name_type_expression(parser_node: Word); var token_kind: Word; type_name: Word; name_length: Word; result: Word; begin - token_kind := _node_get_kind(parser_node); + token_kind := ElnaTreeNode_get_kind(parser_node); - if token_kind = NodeKind.named_type_expression then - type_name := _named_type_expression_get_name(parser_node); - name_length := _named_type_expression_get_length(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 = NodeKind.enumeration_type_expression then - result := _elna_name_type_enumeration(parser_node) - elsif token_kind = NodeKind.record_type_expression then - result := _elna_name_type_record(parser_node) + elsif token_kind = ElnaTreeKind.enumeration_type_expression then + result := elna_name_enumeration_type_expression(parser_node) + elsif token_kind = ElnaTreeKind.record_type_expression then + result := elna_name_record_type_expression(parser_node) + elsif token_kind = ElnaTreeKind.pointer_type_expression then + result := elna_name_pointer_type_expression(parser_node) + elsif token_kind = ElnaTreeKind.array_type_expression then + result := elna_name_array_type_expression(parser_node) end; return result @@ -3180,7 +3304,7 @@ 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: Word, parameter_index: Word, symbol_table: Word); var name_length: Word; info: Word; @@ -3197,7 +3321,7 @@ 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: Word, variable_index: Word, symbol_table: Word); var name_length: Word; info: Word; @@ -3210,7 +3334,7 @@ begin _symbol_table_enter(symbol_table, name_position, name_length, info) end; -proc _elna_name_procedure_temporaries(parser_node: Word, symbol_table: Word); +proc elna_name_procedure_temporaries(parser_node: Word, symbol_table: Word); var temporary_counter: Word; begin @@ -3218,7 +3342,7 @@ begin .elna_name_procedure_temporaries_loop; if parser_node <> 0 then - _elna_name_procedure_temporary(parser_node, temporary_counter, symbol_table); + elna_name_procedure_temporary(parser_node, temporary_counter, symbol_table); temporary_counter := temporary_counter + 1; parser_node := _declaration_get_next(parser_node); @@ -3226,7 +3350,7 @@ begin end end; -proc _elna_parser_procedure_declaration(); +proc elna_parser_procedure_declaration(); var name_pointer: Word; name_length: Word; @@ -3236,7 +3360,7 @@ var begin result := malloc(_procedure_declaration_size()); - _node_set_kind(result, NodeKind.procedure_declaration); + ElnaTreeNode_set_kind(result, ElnaTreeKind.procedure_declaration); _declaration_set_next(result, 0); (* Skip "proc ". *) @@ -3260,7 +3384,7 @@ begin _elna_lexer_read_token(@token_kind); if token_kind <> ElnaLexerKind.right_paren then - name_pointer := _elna_parser_variable_declaration(); + name_pointer := elna_parser_variable_declaration(); if parameter_head = 0 then parameter_head := name_pointer else @@ -3283,16 +3407,16 @@ begin _elna_lexer_read_token(@token_kind); _elna_lexer_skip_token(); - parameter_head := _elna_parser_var_part(); + parameter_head := elna_parser_var_part(); _procedure_declaration_set_temporaries(result, parameter_head); (* Skip semicolon, "begin" and newline. *) _elna_lexer_read_token(@token_kind); if token_kind = ElnaLexerKind._begin then _elna_lexer_skip_token(); - parameter_head := _elna_parser_statements() + parameter_head := elna_parser_statements() elsif token_kind = ElnaLexerKind._return then - parameter_head := _elna_parser_return_statement() + parameter_head := elna_parser_return_statement() end; _procedure_declaration_set_body(result, parameter_head); @@ -3432,7 +3556,7 @@ begin return result end; -proc _elna_parser_procedures(); +proc elna_parser_procedures(); var parser_node: Word; result: Word; @@ -3446,7 +3570,7 @@ begin _elna_lexer_read_token(@token_kind); if token_kind = ElnaLexerKind._proc then - parser_node := _elna_parser_procedure_declaration(); + parser_node := elna_parser_procedure_declaration(); if result = 0 then result := parser_node else @@ -3563,7 +3687,7 @@ begin end end; -proc _elna_parser_type_declaration(); +proc elna_parser_type_declaration(); var token_kind: Word; type_name: Word; @@ -3579,10 +3703,10 @@ begin _elna_lexer_read_token(@token_kind); _elna_lexer_skip_token(); - parser_node := _elna_parser_type_expression(); + parser_node := elna_parser_type_expression(); result := malloc(_type_declaration_size()); - _node_set_kind(result, NodeKind.type_declaration); + ElnaTreeNode_set_kind(result, ElnaTreeKind.type_declaration); _declaration_set_next(result, 0); _declaration_set_name(result, type_name); _declaration_set_length(result, name_length); @@ -3594,7 +3718,7 @@ begin return result end; -proc _elna_name_type_declaration(parser_node: Word); +proc elna_name_type_declaration(parser_node: Word); var type_name: Word; name_length: Word; @@ -3604,16 +3728,17 @@ begin name_length := _declaration_get_length(parser_node); parser_node := _type_declaration_get__type(parser_node); - type_info := _elna_name_type_expression(parser_node); + type_info := elna_name_type_expression(parser_node); + type_info := _type_info_create(type_info); _symbol_table_enter(@symbol_table_global, type_name, name_length, type_info) end; -proc _elna_type_type_declaration(parser_node: Word); +proc elna_type_type_declaration(parser_node: Word); begin end; -proc _elna_parser_type_part(); +proc elna_parser_type_part(); var token_kind: Word; parser_node: Word; @@ -3634,7 +3759,7 @@ begin _elna_lexer_read_token(@token_kind); if token_kind = ElnaLexerKind.identifier then - parser_node := _elna_parser_type_declaration(); + parser_node := elna_parser_type_declaration(); if result = 0 then result := parser_node @@ -3649,7 +3774,7 @@ begin return result end; -proc _elna_parser_variable_declaration(); +proc elna_parser_variable_declaration(); var token_kind: Word; name: Word; @@ -3667,10 +3792,10 @@ begin _elna_lexer_read_token(@token_kind); _elna_lexer_skip_token(); - variable_type := _elna_parser_type_expression(); + variable_type := elna_parser_type_expression(); result := malloc(_variable_declaration_size()); - _node_set_kind(result, NodeKind.variable_declaration); + ElnaTreeNode_set_kind(result, ElnaTreeKind.variable_declaration); _declaration_set_next(result, 0); _declaration_set_name(result, name); _declaration_set_length(result, name_length); @@ -3697,8 +3822,8 @@ begin ElnaInstructionDeclaration_set_name(result, name); ElnaInstructionDeclaration_set_length(result, name_length); - name := _named_type_expression_get_name(variable_type); - name_length := _named_type_expression_get_length(variable_type); + name := ElnaTreeNamedTypeExpression_get_name(variable_type); + name_length := ElnaTreeNamedTypeExpression_get_length(variable_type); if string_compare("Array", 5, name, name_length) then (* Else we assume this is a zeroed 4096 bytes big array. *) @@ -3788,7 +3913,7 @@ begin first_result := malloc(ElnaInstructionDeclaration_size()); result := 0; - type_size := _type_get_size(type_representation); + type_size := ElnaType_get_size(type_representation); new_length := name_length + 5; new_name := malloc(new_length); @@ -3804,8 +3929,8 @@ begin ElnaInstructionDeclaration_set_body(first_result, instruction); - field_count := _record_type_get_length(type_representation); - field_pointer := _record_type_get_members(type_representation); + field_count := ElnaTypeRecord_get_length(type_representation); + field_pointer := ElnaTypeRecord_get_members(type_representation); field_offset := 0; current_result^ := first_result; @@ -3849,7 +3974,7 @@ begin symbol := _symbol_table_lookup(@symbol_table_global, name_pointer, name_length); info_type := _type_info_get__type(symbol); - type_kind := _type_get_kind(info_type); + type_kind := ElnaType_get_kind(info_type); if type_kind = TypeKind._record then result := _elna_tac_type_record(name_pointer, name_length, info_type, @out_result) @@ -3871,7 +3996,7 @@ begin return first_result end; -proc _elna_parser_var_part(); +proc elna_parser_var_part(); var result: Word; token_kind: Word; @@ -3892,7 +4017,7 @@ begin _elna_lexer_read_token(@token_kind); if token_kind = ElnaLexerKind.identifier then - variable_node := _elna_parser_variable_declaration(); + variable_node := elna_parser_variable_declaration(); (* Skip semicolon. *) _elna_lexer_read_token(@token_kind); @@ -3940,7 +4065,7 @@ begin return first_variable end; -proc _elna_parser_module_declaration(); +proc elna_parser_module_declaration(); var parser_node: Word; result: Word; @@ -3948,7 +4073,7 @@ var begin result := malloc(_module_declaration_size()); - _node_set_kind(result, NodeKind.module_declaration); + ElnaTreeNode_set_kind(result, ElnaTreeKind.module_declaration); (* Skip "program;". *) _skip_empty_lines(); @@ -3957,13 +4082,13 @@ begin _elna_lexer_read_token(@token_kind); _elna_lexer_skip_token(); - parser_node := _elna_parser_type_part(); + parser_node := elna_parser_type_part(); _module_declaration_set_types(result, parser_node); - parser_node := _elna_parser_var_part(); + parser_node := elna_parser_var_part(); _module_declaration_set_globals(result, parser_node); - parser_node := _elna_parser_procedures(); + parser_node := elna_parser_procedures(); _module_declaration_set_procedures(result, parser_node); return result @@ -4003,7 +4128,7 @@ 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: Word); var name_pointer: Word; name_length: Word; @@ -4022,23 +4147,265 @@ begin parameter_counter := 0; .elna_name_procedure_declaration_parameter; if current_parameter <> 0 then - _elna_name_procedure_parameter(current_parameter, parameter_counter, new_symbol_table); + elna_name_procedure_parameter(current_parameter, parameter_counter, new_symbol_table); parameter_counter := parameter_counter + 1; current_parameter := _declaration_get_next(current_parameter); 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(current_parameter, new_symbol_table); _symbol_table_enter(@symbol_table_global, name_pointer, name_length, symbol_info) end; -proc _elna_type_procedure_declaration(parser_node: Word); +proc elna_type_conditional_statements(parser_node: Word, symbol_table: Word); +var + condition: Word; + statements: Word; begin + .elna_type_conditional_statements_loop; + condition := _conditional_statements_get_condition(parser_node); + elna_type_binary_expression(condition, symbol_table); + + statements := _conditional_statements_get_statements(parser_node); + elna_type_statements(statements, symbol_table); + + parser_node := _conditional_statements_get_next(parser_node); + if parser_node <> nil then + goto elna_type_conditional_statements_loop + end end; -proc _elna_name_module_declaration(parser_node: Word); +proc elna_type_if_statement(parser_node: Word, symbol_table: Word); +var + block: Word; +begin + block := _if_statement_get_conditionals(parser_node); + + .elna_type_if_statement_conditionals; + elna_type_conditional_statements(block, symbol_table); + + block := _conditional_statements_get_next(block); + if block <> nil then + goto elna_type_if_statement_conditionals + end; + block := _if_statement_get__else(parser_node); + if block <> 0 then + elna_type_statements(block, symbol_table) + end +end; + +proc elna_type_return_statement(parser_node: Word, symbol_table: Word); +var + returned_expression: Word; +begin + returned_expression := _return_statement_get_returned(parser_node); + elna_type_binary_expression(returned_expression, symbol_table) +end; + +proc elna_type_call(parser_node: Word, symbol_table: Word); +var + current_argument: Word; + argument_tree: Word; +begin + current_argument := 1; + + .elna_type_call_argument; + argument_tree := _call_get_argument(parser_node, current_argument); + + if argument_tree <> nil then + elna_type_binary_expression(argument_tree, symbol_table); + current_argument := current_argument + 1; + + goto elna_type_call_argument + end +end; + +proc elna_type_assign_statement(parser_node: Word, symbol_table: Word); +var + lhs: Word; + rhs: Word; +begin + lhs := _assign_statement_get_assignee(parser_node); + rhs := _assign_statement_get_assignment(parser_node); + + elna_type_designator(parser_node, symbol_table); + elna_type_binary_expression(parser_node, symbol_table) +end; + +proc elna_type_statement(parser_node: Word, symbol_table: Word); +var + statement_kind: Word; +begin + statement_kind := ElnaTreeNode_get_kind(parser_node); + + (* Skipping goto and label declarations. *) + if statement_kind = ElnaTreeKind.if_statement then + elna_type_if_statement(parser_node, symbol_table) + elsif statement_kind = ElnaTreeKind.return_statement then + elna_type_return_statement(parser_node, symbol_table) + elsif statement_kind = ElnaTreeKind.call then + elna_type_call(parser_node, symbol_table) + elsif statement_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); +begin + .elna_type_statements_loop; + if parser_node <> 0 then + elna_type_statement(parser_node, symbol_table); + + parser_node := _statement_get_next(parser_node); + goto elna_type_statements_loop + end +end; + +proc elna_type_character_literal(parser_node: Word); +var + symbol_info: Word; + symbol_type: Word; +begin + symbol_info := _symbol_table_lookup(@symbol_table_global, "Word", 4); + symbol_type := _type_info_get__type(symbol_info); + + ElnaTreeCharacterLiteral_set_type_decoration(parser_node, symbol_type) +end; + +proc elna_type_integer_literal(parser_node: Word); +var + symbol_info: Word; + symbol_type: Word; +begin + symbol_info := _symbol_table_lookup(@symbol_table_global, "Word", 4); + symbol_type := _type_info_get__type(symbol_info); + + ElnaTreeIntegerLiteral_set_type_decoration(parser_node, symbol_type) +end; + +proc elna_type_string_literal(parser_node: Word); +var + symbol_info: Word; + symbol_type: Word; +begin + symbol_info := _symbol_table_lookup(@symbol_table_global, "Word", 4); + symbol_type := _type_info_get__type(symbol_info); + + ElnaTreeStringLiteral_set_type_decoration(parser_node, symbol_type) +end; + +proc elna_type_nil_literal(parser_node: Word); +var + symbol_info: Word; + symbol_type: Word; +begin + symbol_info := _symbol_table_lookup(@symbol_table_global, "Word", 4); + symbol_type := _type_info_get__type(symbol_info); + + ElnaTreeNilLiteral_set_type_decoration(parser_node, symbol_type) +end; + +proc elna_type_variable_expression(parser_node: Word, symbol_table: Word); +var + variable_info: Word; + name_pointer: Word; + name_length: Word; + variable_kind: Word; +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); + + if variable_info = nil then + variable_info := _symbol_table_lookup(@symbol_table_global, name_pointer, name_length) + end; + + (* Debug. Error stream output. + _syscall(2, name_pointer, name_length, 0, 0, 0, 64); + printf("# here %p %.*s\n\0", variable_info, name_length, name_pointer); + fflush(0) + + variable_kind := _info_get_kind(variable_info) *) +end; + +proc elna_type_simple_expression(parser_node: Word, symbol_table: Word); +var + expression_kind: Word; +begin + expression_kind := ElnaTreeNode_get_kind(parser_node); + + if expression_kind = ElnaTreeKind.integer_literal then + elna_type_integer_literal(parser_node) + elsif expression_kind = ElnaTreeKind.character_literal then + elna_type_character_literal(parser_node) + elsif expression_kind = ElnaTreeKind.string_literal then + elna_type_string_literal(parser_node) + elsif expression_kind = ElnaTreeKind.null then + elna_type_nil_literal(parser_node) + elsif expression_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); +var + expression_kind: Word; +begin + expression_kind := ElnaTreeNode_get_kind(parser_node); + + if expression_kind = ElnaTreeKind.dereference_expression then + elsif expression_kind = ElnaTreeKind.field_access_expression then + else + elna_type_simple_expression(parser_node, symbol_table) + end +end; + +proc elna_type_unary_expression(parser_node: Word, symbol_table: Word); +var + expression_kind: Word; +begin + expression_kind := ElnaTreeNode_get_kind(parser_node); + + if expression_kind = ElnaTreeKind.unary_expression then + else + elna_type_designator(parser_node, symbol_table) + end +end; + +proc elna_type_binary_expression(parser_node: Word, symbol_table: Word); +var + expression_kind: Word; +begin + expression_kind := ElnaTreeNode_get_kind(parser_node); + + if expression_kind = ElnaTreeKind.binary_expression then + else + elna_type_unary_expression(parser_node, symbol_table) + end +end; + +proc elna_type_procedure_declaration(parser_node: Word); +var + body: Word; + name_pointer: Word; + name_length: Word; + procedure_info: Word; + 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, name_pointer, name_length); + symbol_table := _procedure_info_get_symbol_table(procedure_info); + + elna_type_statements(body, symbol_table) +end; + +proc elna_name_module_declaration(parser_node: Word); var current_part: Word; result: Word; @@ -4046,7 +4413,7 @@ begin current_part := _module_declaration_get_types(parser_node); .elna_name_module_declaration_type; if current_part <> 0 then - _elna_name_type_declaration(current_part); + elna_name_type_declaration(current_part); current_part := _declaration_get_next(current_part); goto elna_name_module_declaration_type @@ -4055,21 +4422,21 @@ begin current_part := _module_declaration_get_procedures(parser_node); .elna_name_module_declaration_procedure; if current_part <> 0 then - _elna_name_procedure_declaration(current_part); + elna_name_procedure_declaration(current_part); current_part := _declaration_get_next(current_part); goto elna_name_module_declaration_procedure end end; -proc _elna_type_module_declaration(parser_node: Word); +proc elna_type_module_declaration(parser_node: Word); var current_part: Word; begin current_part := _module_declaration_get_types(parser_node); .elna_type_module_declaration_type; if current_part <> 0 then - _elna_type_type_declaration(current_part); + elna_type_type_declaration(current_part); current_part := _declaration_get_next(current_part); goto elna_type_module_declaration_type @@ -4078,7 +4445,7 @@ begin current_part := _module_declaration_get_procedures(parser_node); .elna_type_module_declaration_procedure; if current_part <> 0 then - _elna_type_procedure_declaration(current_part); + elna_type_procedure_declaration(current_part); current_part := _declaration_get_next(current_part); goto elna_type_module_declaration_procedure @@ -4091,9 +4458,9 @@ var tac: Word; rtl: Word; begin - parser_node := _elna_parser_module_declaration(); - _elna_name_module_declaration(parser_node); - _elna_type_module_declaration(parser_node); + parser_node := elna_parser_module_declaration(); + elna_name_module_declaration(parser_node); + elna_type_module_declaration(parser_node); tac := _elna_tac_module_declaration(parser_node); rtl := elna_rtl_module_declaration(tac); _elna_writer_module(rtl) @@ -4233,9 +4600,9 @@ begin (* Set the table length to 0. *) symbol_table_global := 0; - current_type := malloc(_type_size()); - _type_set_kind(current_type, TypeKind.primitive); - _type_set_size(current_type, 4); + current_type := malloc(ElnaType_size()); + ElnaType_set_kind(current_type, TypeKind.primitive); + ElnaType_set_size(current_type, 4); (* Enter built-in symbols. *) current_info := _type_info_create(current_type);