diff options
| author | Eugen Wissner <belka@caraus.de> | 2025-11-25 08:03:05 +0100 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2025-11-25 08:03:05 +0100 |
| commit | c20d9b7240033b462b33030ba4946135bc7d7fef (patch) | |
| tree | 1ef1f96a42999bebd8b9eb00d3480f776f591a04 /boot/stage16 | |
| parent | c3eff02f8d610b6bd259eee672c044731df43d65 (diff) | |
| download | elna-c20d9b7240033b462b33030ba4946135bc7d7fef.tar.gz | |
Set expression type for enumeration values
Diffstat (limited to 'boot/stage16')
| -rw-r--r-- | boot/stage16/cl.elna | 175 |
1 files changed, 144 insertions, 31 deletions
diff --git a/boot/stage16/cl.elna b/boot/stage16/cl.elna index 0a6d454..438c106 100644 --- a/boot/stage16/cl.elna +++ b/boot/stage16/cl.elna @@ -24,6 +24,10 @@ type ElnaTreeNode = record kind: Word end; + ElnaTreeExpression = record + kind: Word; + type_decoration: Word + end; ElnaTreeIntegerLiteral = record kind: Word; type_decoration: Word; @@ -1581,7 +1585,7 @@ begin 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); + ElnaTreeExpression_set_type_decoration(result, nil); return result end; @@ -1594,7 +1598,7 @@ begin result := malloc(ElnaTreeNilLiteral_size()); ElnaTreeNode_set_kind(result, ElnaTreeKind.null); - ElnaTreeIntegerLiteral_set_type_decoration(result, nil); + ElnaTreeExpression_set_type_decoration(result, nil); return result end; @@ -1633,7 +1637,7 @@ begin ElnaTreeNode_set_kind(result, ElnaTreeKind.character_literal); ElnaTreeIntegerLiteral_set_value(result, character); ElnaTreeIntegerLiteral_set_length(result, character_length); - ElnaTreeIntegerLiteral_set_type_decoration(result, nil); + ElnaTreeExpression_set_type_decoration(result, nil); return result end; @@ -1662,7 +1666,7 @@ begin 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); + ElnaTreeExpression_set_type_decoration(result, nil); return result end; @@ -1704,7 +1708,7 @@ begin ElnaTreeNode_set_kind(result, ElnaTreeKind.string_literal); ElnaTreeStringLiteral_set_value(result, token_start); ElnaTreeStringLiteral_set_length(result, length); - ElnaTreeIntegerLiteral_set_type_decoration(result, nil); + ElnaTreeExpression_set_type_decoration(result, nil); return result end; @@ -1767,7 +1771,7 @@ begin ElnaTreeNode_set_kind(result, ElnaTreeKind.dereference_expression); ElnaTreeDereferenceExpression_set_pointer(result, simple_expression); - ElnaTreeDereferenceExpression_set_type_decoration(result, nil); + ElnaTreeExpression_set_type_decoration(result, nil); _elna_lexer_skip_token(); return result @@ -1842,7 +1846,7 @@ begin ElnaTreeNode_set_kind(result, ElnaTreeKind.unary_expression); ElnaTreeUnaryExpression_set_operand(result, operand); ElnaTreeUnaryExpression_set_operator(result, operator); - ElnaTreeUnaryExpression_set_type_decoration(result, nil) + ElnaTreeExpression_set_type_decoration(result, nil) end; return result @@ -1986,7 +1990,7 @@ begin ElnaTreeBinaryExpression_set_lhs(result, lhs_node); ElnaTreeBinaryExpression_set_rhs(result, rhs_node); ElnaTreeBinaryExpression_set_operator(result, token_kind); - ElnaTreeBinaryExpression_set_type_decoration(result, nil) + ElnaTreeExpression_set_type_decoration(result, nil) else result := lhs_node end; @@ -2368,7 +2372,7 @@ begin operand_value^ := counter; operand_length^ := 0 end; - return 0 + return nil end; proc elna_parser_field_access_expression(aggregate: Word); @@ -2392,7 +2396,7 @@ begin ElnaTreeFieldAccessExpression_set_aggregate(result, aggregate); ElnaTreeFieldAccessExpression_set_field(result, name_pointer); ElnaTreeFieldAccessExpression_set_length(result, name_length); - ElnaTreeFieldAccessExpression_set_type_decoration(result, nil); + ElnaTreeExpression_set_type_decoration(result, nil); return result end; @@ -2401,8 +2405,12 @@ proc _elna_tac_designator(parser_node: Word, symbol_table: Word, is_address: Wor var parser_node: Word; node_kind: Word; + expression_type: Word; first_instruction: Word; last_instruction: Word; + + name_pointer: Word; + name_length: Word; begin node_kind := ElnaTreeNode_get_kind(parser_node); @@ -2421,7 +2429,26 @@ begin is_address^ := 2; first_instruction := elna_instruction_list_concatenate(first_instruction, last_instruction) elsif node_kind = ElnaTreeKind.field_access_expression then - first_instruction := _elna_tac_enumeration_value(parser_node, operand_type, operand_value, operand_length); + expression_type := ElnaTreeExpression_get_type_decoration(parser_node); + name_pointer := ElnaTreeFieldAccessExpression_get_field(parser_node); + name_length := ElnaTreeFieldAccessExpression_get_length(parser_node); + + if expression_type = nil then + (* Stub for record field access. Always generate nil for field access expression until it is implemented. *) + + (* Debug. Error stream output. + _syscall(2, name_pointer, name_length, 0, 0, 0, 64); + printf("# there %.*s %i\n\0", name_length, name_pointer, expression_type); + fflush(0); *) + + operand_type^ := ElnaTacOperand.immediate; + operand_value^ := 0; + operand_length^ := 0; + + first_instruction := nil + else + first_instruction := _elna_tac_enumeration_value(parser_node, operand_type, operand_value, operand_length) + end; is_address^ := 0 elsif node_kind = ElnaTreeKind.call then first_instruction := _elna_tac_call(parser_node, symbol_table); @@ -3241,8 +3268,9 @@ end; (** * Parameters: * parameter_index - Parameter index. + * parameter_type - Parameter type. *) -proc _parameter_info_create(parameter_index: Word); +proc _parameter_info_create(parameter_index: Word, parameter_type: Word); var offset: Word; result: Word; @@ -3253,6 +3281,7 @@ begin (* 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); return result end; @@ -3270,9 +3299,10 @@ end; (** * Parameters: - * temporary_index - Parameter index. + * temporary_index - Local variable index. + * temporary_type - Local variable type. *) -proc _temporary_info_create(temporary_index: Word); +proc _temporary_info_create(temporary_index: Word, temporary_type: Word); var result: Word; begin @@ -3281,6 +3311,7 @@ begin (* Calculate the stack offset: 4 * variable_counter. *) _temporary_info_set_offset(result, temporary_index * 4); + _parameter_info_set_variable_type(result, temporary_type); return result end; @@ -3309,11 +3340,15 @@ 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); - info := _parameter_info_create(parameter_index); + variable_type := _variable_declaration_get__type(parser_node); + variable_type := elna_name_type_expression(variable_type); + + info := _parameter_info_create(parameter_index, variable_type); _symbol_table_enter(symbol_table, name_position, name_length, info) end; @@ -3326,11 +3361,15 @@ 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); - info := _temporary_info_create(variable_index); + variable_type := _variable_declaration_get__type(parser_node); + variable_type := elna_name_type_expression(variable_type); + + info := _temporary_info_create(variable_index, variable_type); _symbol_table_enter(symbol_table, name_position, name_length, info) end; @@ -4191,7 +4230,7 @@ begin goto elna_type_if_statement_conditionals end; block := _if_statement_get__else(parser_node); - if block <> 0 then + if block <> nil then elna_type_statements(block, symbol_table) end end; @@ -4230,8 +4269,8 @@ 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) + elna_type_designator(lhs, symbol_table); + elna_type_binary_expression(rhs, symbol_table) end; proc elna_type_statement(parser_node: Word, symbol_table: Word); @@ -4271,7 +4310,7 @@ 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) + ElnaTreeExpression_set_type_decoration(parser_node, symbol_type) end; proc elna_type_integer_literal(parser_node: Word); @@ -4282,7 +4321,7 @@ 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) + ElnaTreeExpression_set_type_decoration(parser_node, symbol_type) end; proc elna_type_string_literal(parser_node: Word); @@ -4293,7 +4332,7 @@ 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) + ElnaTreeExpression_set_type_decoration(parser_node, symbol_type) end; proc elna_type_nil_literal(parser_node: Word); @@ -4304,7 +4343,7 @@ 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) + ElnaTreeExpression_set_type_decoration(parser_node, symbol_type) end; proc elna_type_variable_expression(parser_node: Word, symbol_table: Word); @@ -4313,6 +4352,7 @@ var name_pointer: Word; name_length: Word; variable_kind: Word; + variable_type: Word; begin name_pointer := ElnaTreeVariableExpression_get_name(parser_node); name_length := ElnaTreeVariableExpression_get_length(parser_node); @@ -4322,13 +4362,15 @@ begin if variable_info = nil then variable_info := _symbol_table_lookup(@symbol_table_global, name_pointer, name_length) end; + variable_kind := _info_get_kind(variable_info); + variable_type := nil; - (* 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) *) + 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) end; proc elna_type_simple_expression(parser_node: Word, symbol_table: Word); @@ -4353,11 +4395,57 @@ end; proc elna_type_designator(parser_node: Word, 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; begin expression_kind := ElnaTreeNode_get_kind(parser_node); if expression_kind = ElnaTreeKind.dereference_expression then + designator_base := ElnaTreeDereferenceExpression_get_pointer(parser_node); + elna_type_simple_expression(designator_base, symbol_table); + + base_type := ElnaTreeExpression_get_type_decoration(designator_base); + type_kind := ElnaType_get_kind(base_type); + + (* If check for compatibility, should be removed later. *) + if type_kind = TypeKind.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); + + (* 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); + + 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 + end + end; + (* If the base_type is still nil this is record field access. *) + if base_type = nil then + (* elna_type_simple_expression(designator_base, symbol_table); + base_type := ElnaTreeExpression_get_type_decoration(designator_base); *) + else + end; + + (* Change my type. *) + ElnaTreeExpression_set_type_decoration(parser_node, base_type) + elsif expression_kind = ElnaTreeKind.call then + elna_type_call(parser_node, symbol_table) else elna_type_simple_expression(parser_node, symbol_table) end @@ -4366,10 +4454,17 @@ end; proc elna_type_unary_expression(parser_node: Word, symbol_table: Word); var expression_kind: Word; + unary_operand: Word; + operand_type: Word; begin expression_kind := ElnaTreeNode_get_kind(parser_node); if expression_kind = ElnaTreeKind.unary_expression then + unary_operand := ElnaTreeUnaryExpression_get_operand(parser_node); + elna_type_designator(unary_operand, symbol_table); + + operand_type := ElnaTreeExpression_get_type_decoration(unary_operand); + ElnaTreeExpression_set_type_decoration(parser_node, operand_type) else elna_type_designator(parser_node, symbol_table) end @@ -4378,10 +4473,21 @@ end; proc elna_type_binary_expression(parser_node: Word, symbol_table: Word); var expression_kind: Word; + binary_operand: Word; + operand_type: Word; begin expression_kind := ElnaTreeNode_get_kind(parser_node); if expression_kind = ElnaTreeKind.binary_expression then + binary_operand := ElnaTreeBinaryExpression_get_rhs(parser_node); + 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) else elna_type_unary_expression(parser_node, symbol_table) end @@ -4412,16 +4518,23 @@ var begin current_part := _module_declaration_get_types(parser_node); .elna_name_module_declaration_type; - if current_part <> 0 then + if current_part <> nil then elna_name_type_declaration(current_part); current_part := _declaration_get_next(current_part); goto elna_name_module_declaration_type end; + current_part := _module_declaration_get_globals(parser_node); + .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); + goto elna_name_module_declaration_global + end; current_part := _module_declaration_get_procedures(parser_node); .elna_name_module_declaration_procedure; - if current_part <> 0 then + if current_part <> nil then elna_name_procedure_declaration(current_part); current_part := _declaration_get_next(current_part); |
