diff options
| author | Eugen Wissner <belka@caraus.de> | 2026-06-24 22:39:34 +0200 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2026-06-25 22:11:19 +0200 |
| commit | 3b747ac448ddc2173affd86b9316ab8a6c5f7bd6 (patch) | |
| tree | 09df6d35a396c818a5eb71f4fc96b8af3b2e9bde /boot/stage24/cl.elna | |
| parent | dd663f51bf8680f87d24569d01e2d86ed308304d (diff) | |
| download | elna-master.tar.gz | |
Diffstat (limited to 'boot/stage24/cl.elna')
| -rw-r--r-- | boot/stage24/cl.elna | 245 |
1 files changed, 141 insertions, 104 deletions
diff --git a/boot/stage24/cl.elna b/boot/stage24/cl.elna index da99621..878b42b 100644 --- a/boot/stage24/cl.elna +++ b/boot/stage24/cl.elna @@ -4053,7 +4053,7 @@ end * Returns enumeration type description. *) proc elna_name_enumeration_type_expression(parser_node: ^ElnaTreeEnumerationTypeExpression, - result: ^ElnaTypeEnumeration) + error_list: ^ElnaList, result: ^ElnaTypeEnumeration) var memory_start: ^ElnaTreeEnumeration member_count: Word @@ -4081,20 +4081,20 @@ begin end proc elna_name_pointer_type_expression(parser_node: ^ElnaTreePointerTypeExpression, - result: ^ElnaTypePointer) + error_list: ^ElnaList, result: ^ElnaTypePointer) begin result^.size := 4; result^.alignment := 4; - result^.base := elna_name_type_expression(parser_node^.base) + result^.base := elna_name_type_expression(parser_node^.base, error_list) end proc elna_name_array_type_expression(parser_node: ^ElnaTreeArrayTypeExpression, - result: ^ElnaTypeArray) + error_list: ^ElnaList, result: ^ElnaTypeArray) var base: ^ElnaType length: ^ElnaTreeIntegerLiteral begin - base := elna_name_type_expression(parser_node^.base); + base := elna_name_type_expression(parser_node^.base, error_list); length := parser_node^.length; (* Array size in bytes. *) @@ -4105,7 +4105,7 @@ begin end proc elna_name_record_type_expression(parser_node: ^ElnaTreeRecordTypeExpression, - result: ^ElnaTypeRecord) + error_list: ^ElnaList, result: ^ElnaTypeRecord) var result: ^ElnaTypeRecord tree_field: ^ElnaTreeField @@ -4124,7 +4124,7 @@ begin if result^.length < parser_node^.length then member_array_current^.name := tree_field^.name; - field_type := elna_name_type_expression(tree_field^.type_expression); + field_type := elna_name_type_expression(tree_field^.type_expression, error_list); result^.size := result^.size + field_type^.size; if field_type^.alignment > result^.alignment then result^.alignment := field_type^.alignment @@ -4237,7 +4237,8 @@ begin return result end -proc elna_name_alias_type_expression(parser_node: ^ElnaTreeNamedTypeExpression, result: ^ElnaTypeAlias) +proc elna_name_alias_type_expression(parser_node: ^ElnaTreeNamedTypeExpression, + error_list: ^ElnaList, result: ^ElnaTypeAlias) var type_symbol: ^ElnaSymbolTypeInfo aliased_type: ^ElnaType @@ -4251,7 +4252,7 @@ begin result^.base := aliased_type end -proc elna_name_type_expression(parser_node: ^ElnaTreeTypeExpression) -> ^ElnaType +proc elna_name_type_expression(parser_node: ^ElnaTreeTypeExpression, error_list: ^ElnaList) -> ^ElnaType var named_type_expression: ^ElnaTreeNamedTypeExpression type_symbol: ^ElnaSymbolTypeInfo @@ -4267,24 +4268,23 @@ begin result := malloc(#size(ElnaTypeEnumeration)); result^.kind := ElnaTypeKind.enumeration; - elna_name_enumeration_type_expression(parser_node, result) + elna_name_enumeration_type_expression(parser_node, error_list, result) elsif parser_node^.kind = ElnaTreeKind.record_type_expression then result := malloc(#size(ElnaTypeRecord)); result^.kind := ElnaTypeKind._record; - elna_name_record_type_expression(parser_node, result) + elna_name_record_type_expression(parser_node, error_list, result) elsif parser_node^.kind = ElnaTreeKind.pointer_type_expression then result := malloc(#size(ElnaTypePointer)); result^.kind := ElnaTypeKind.pointer; - elna_name_pointer_type_expression(parser_node, result) + elna_name_pointer_type_expression(parser_node, error_list, result) elsif parser_node^.kind = ElnaTreeKind.array_type_expression then result := malloc(#size(ElnaTypeArray)); result^.kind := ElnaTypeKind.array; - elna_name_array_type_expression(parser_node, result) + elna_name_array_type_expression(parser_node, error_list, result) end; - return result end @@ -4338,22 +4338,24 @@ end * Parameters: * variable_index - Variable index. *) -proc elna_name_procedure_temporary(parser_node: ^ElnaTreeVariableDeclaration, symbol_table: ^ElnaSymbolTable) +proc elna_name_procedure_temporary(parser_node: ^ElnaTreeVariableDeclaration, symbol_table: ^ElnaSymbolTable, + error_list: ^ElnaList) var info: ^ElnaSymbolTemporaryInfo variable_type: ^ElnaType begin - variable_type := elna_name_type_expression(parser_node^.type_expression); + variable_type := elna_name_type_expression(parser_node^.type_expression, error_list); info := elna_symbol_temporary_info_create(0, variable_type); elna_symbol_table_enter(symbol_table, parser_node^.name.ptr, parser_node^.name.length, info) end -proc elna_name_procedure_temporaries(parser_node: ^ElnaTreeVariableDeclaration, symbol_table: ^ElnaSymbolTable) +proc elna_name_procedure_temporaries(parser_node: ^ElnaTreeVariableDeclaration, symbol_table: ^ElnaSymbolTable, + error_list: ^ElnaList) begin .elna_name_procedure_temporaries_loop; if parser_node <> nil then - elna_name_procedure_temporary(parser_node, symbol_table); + elna_name_procedure_temporary(parser_node, symbol_table, error_list); parser_node := parser_node^.next; goto elna_name_procedure_temporaries_loop @@ -4896,7 +4898,7 @@ begin return result end -proc elna_name_type_declaration(parser_node: ^ElnaTreeTypeDeclaration) +proc elna_name_type_declaration(parser_node: ^ElnaTreeTypeDeclaration, error_list: ^ElnaList) var type_info: ^ElnaSymbolTypeInfo type_stub: ^ElnaType @@ -4907,15 +4909,15 @@ begin type_expression := parser_node^.type_expression; if type_stub^.kind = ElnaTypeKind.alias then - elna_name_alias_type_expression(type_expression, type_stub) + elna_name_alias_type_expression(type_expression, error_list, type_stub) elsif type_stub^.kind = ElnaTypeKind.enumeration then - elna_name_enumeration_type_expression(type_expression, type_stub) + elna_name_enumeration_type_expression(type_expression, error_list, type_stub) elsif type_stub^.kind = ElnaTypeKind._record then - elna_name_record_type_expression(type_expression, type_stub) + elna_name_record_type_expression(type_expression, error_list, type_stub) elsif type_stub^.kind = ElnaTypeKind.pointer then - elna_name_pointer_type_expression(type_expression, type_stub) + elna_name_pointer_type_expression(type_expression, error_list, type_stub) elsif type_stub^.kind = ElnaTypeKind.array then - elna_name_array_type_expression(type_expression, type_stub) + elna_name_array_type_expression(type_expression, error_list, type_stub) end end @@ -5203,104 +5205,121 @@ begin return result end -proc elna_name_dereference_expression(parser_node: ^ElnaTreeDereferenceExpression, symbol_table: ^ElnaSymbolTable) +proc elna_name_dereference_expression(parser_node: ^ElnaTreeDereferenceExpression, symbol_table: ^ElnaSymbolTable, + error_list: ^ElnaList) begin - elna_name_designator(parser_node^.pointer, symbol_table) + elna_name_designator(parser_node^.pointer, symbol_table, error_list) end -proc elna_name_field_access_expression(parser_node: ^ElnaTreeFieldAccessExpression, symbol_table: ^ElnaSymbolTable) +proc elna_name_field_access_expression(parser_node: ^ElnaTreeFieldAccessExpression, symbol_table: ^ElnaSymbolTable, + error_list: ^ElnaList) begin - elna_name_designator(parser_node^.aggregate, symbol_table) + elna_name_designator(parser_node^.aggregate, symbol_table, error_list) end -proc elna_name_array_access_expression(parser_node: ^ElnaTreeArrayAccessExpression, symbol_table: ^ElnaSymbolTable) +proc elna_name_array_access_expression(parser_node: ^ElnaTreeArrayAccessExpression, symbol_table: ^ElnaSymbolTable, + error_list: ^ElnaList) begin - elna_name_designator(parser_node^.array, symbol_table); - elna_name_binary_expression(parser_node^.index, symbol_table) + elna_name_designator(parser_node^.array, symbol_table, error_list); + elna_name_binary_expression(parser_node^.index, symbol_table, error_list) end -proc elna_name_cast_expression(parser_node: ^ElnaTreeCastExpression, symbol_table: ^ElnaSymbolTable) +proc elna_name_cast_expression(parser_node: ^ElnaTreeCastExpression, symbol_table: ^ElnaSymbolTable, + error_list: ^ElnaList) begin - elna_name_binary_expression(parser_node^.expression); - parser_node^.type_decoration := elna_name_type_expression(parser_node^.type_expression) + elna_name_binary_expression(parser_node^.expression, error_list); + parser_node^.type_decoration := elna_name_type_expression(parser_node^.type_expression, error_list) end -proc elna_name_variable_expression(parser_node: ^ElnaTreeVariableExpression, symbol_table: ^ElnaSymbolTable) +proc elna_name_variable_expression(parser_node: ^ElnaTreeVariableExpression, symbol_table: ^ElnaSymbolTable, + error_list: ^ElnaList) +var + variable_symbol: ^ElnaSymbolProcedureInfo + undefined_symbol: ^ElnaErrorUndefinedSymbol begin + variable_symbol := elna_symbol_table_lookup(symbol_table_global, + parser_node^.name.ptr, parser_node^.name.length); + + if variable_symbol = nil then + undefined_symbol := malloc(#size(ElnaErrorUndefinedSymbol)); + undefined_symbol^.next := nil; + undefined_symbol^.kind := ElnaErrorKind.undefined_symbol; + undefined_symbol^.position := parser_node^.position; + undefined_symbol^.symbol_name := parser_node^.name; + + elna_list_append(error_list, undefined_symbol) + end end -proc elna_name_simple_expression(parser_node: ^ElnaTreeNode, symbol_table: ^ElnaSymbolTable) +proc elna_name_simple_expression(parser_node: ^ElnaTreeNode, symbol_table: ^ElnaSymbolTable, + error_list: ^ElnaList) begin (* Not interested in literals. *) if parser_node^.kind = ElnaTreeKind._cast then - elna_name_cast_expression(parser_node, symbol_table) + elna_name_cast_expression(parser_node, symbol_table, error_list) elsif parser_node^.kind = ElnaTreeKind.variable_expression then - elna_name_variable_expression(parser_node, symbol_table) + elna_name_variable_expression(parser_node, symbol_table, error_list) end end -proc elna_name_call(parser_node: ^ElnaTreeCall, symbol_table: ^ElnaSymbolTable) +proc elna_name_call(parser_node: ^ElnaTreeCall, symbol_table: ^ElnaSymbolTable, error_list: ^ElnaList) var argument_tree: ^ElnaTreeExpressionList - callee_symbol: ^ElnaSymbolProcedureInfo begin - callee_symbol := elna_symbol_table_lookup(symbol_table_global, parser_node^.callee^.name.ptr, parser_node^.callee^.name.length); - if callee_symbol = nil then - (* DEBUG *) - _write_s(stdout, "# Undefined symbol "); - _write_s(stdout, parser_node^.callee^.name); - _write_s(stdout, ".\n") - end; + elna_name_variable_expression(parser_node^.callee, symbol_table, error_list); argument_tree := parser_node^.arguments; .elna_name_call_argument; if argument_tree <> nil then - elna_name_binary_expression(argument_tree^.expression, symbol_table); + elna_name_binary_expression(argument_tree^.expression, symbol_table, error_list); argument_tree := argument_tree^.next; goto elna_name_call_argument end end -proc elna_name_designator(parser_node: ^ElnaTreeNode, symbol_table: ^ElnaSymbolTable) +proc elna_name_designator(parser_node: ^ElnaTreeNode, symbol_table: ^ElnaSymbolTable, error_list: ^ElnaList) begin if parser_node^.kind = ElnaTreeKind.dereference_expression then - elna_name_dereference_expression(parser_node, symbol_table) + elna_name_dereference_expression(parser_node, symbol_table, error_list) elsif parser_node^.kind = ElnaTreeKind.field_access_expression then - elna_name_field_access_expression(parser_node, symbol_table) + elna_name_field_access_expression(parser_node, symbol_table, error_list) elsif parser_node^.kind = ElnaTreeKind.array_access_expression then - elna_name_array_access_expression(parser_node, symbol_table) + elna_name_array_access_expression(parser_node, symbol_table, error_list) elsif parser_node^.kind = ElnaTreeKind.call then - elna_name_call(parser_node, symbol_table) + elna_name_call(parser_node, symbol_table, error_list) else - elna_name_simple_expression(parser_node, symbol_table) + elna_name_simple_expression(parser_node, symbol_table, error_list) end end -proc elna_name_unary_expression(parser_node: ^ElnaTreeUnaryExpression, symbol_table: ^ElnaSymbolTable) +proc elna_name_unary_expression(parser_node: ^ElnaTreeUnaryExpression, symbol_table: ^ElnaSymbolTable, + error_list: ^ElnaList) begin if parser_node^.kind = ElnaTreeKind.unary_expression then - elna_name_designator(parser_node^.operand, symbol_table) + elna_name_designator(parser_node^.operand, symbol_table, error_list) else - elna_name_designator(parser_node, symbol_table) + elna_name_designator(parser_node, symbol_table, error_list) end end -proc elna_name_binary_expression(parser_node: ^ElnaTreeBinaryExpression, symbol_table: ^ElnaSymbolTable) +proc elna_name_binary_expression(parser_node: ^ElnaTreeBinaryExpression, symbol_table: ^ElnaSymbolTable, + error_list: ^ElnaList) begin if parser_node^.kind = ElnaTreeKind.binary_expression then - elna_name_unary_expression(parser_node^.lhs, symbol_table); - elna_name_unary_expression(parser_node^.rhs, symbol_table) + elna_name_unary_expression(parser_node^.lhs, symbol_table, error_list); + elna_name_unary_expression(parser_node^.rhs, symbol_table, error_list) else - elna_name_unary_expression(parser_node, symbol_table) + elna_name_unary_expression(parser_node, symbol_table, error_list) end end -proc elna_name_conditional_statements(parser_node: ^ElnaTreeConditionalStatements, symbol_table: ^ElnaSymbolTable) +proc elna_name_conditional_statements(parser_node: ^ElnaTreeConditionalStatements, symbol_table: ^ElnaSymbolTable, + error_list: ^ElnaList) begin .elna_name_conditional_statements_loop; - elna_name_binary_expression(parser_node^.condition, symbol_table); - elna_name_statements(parser_node^.statements, symbol_table); + elna_name_binary_expression(parser_node^.condition, symbol_table, error_list); + elna_name_statements(parser_node^.statements, symbol_table, error_list); parser_node := parser_node^.next; if parser_node <> nil then @@ -5308,14 +5327,15 @@ begin end end -proc elna_name_if_statement(parser_node: ^ElnaTreeIfStatement, symbol_table: ^ElnaSymbolTable) +proc elna_name_if_statement(parser_node: ^ElnaTreeIfStatement, symbol_table: ^ElnaSymbolTable, + error_list: ^ElnaList) var block: ^ElnaTreeConditionalStatements begin block := parser_node^.conditionals; .elna_name_if_statement_conditionals; - elna_name_conditional_statements(block, symbol_table); + elna_name_conditional_statements(block, symbol_table, error_list); block := block^.next; if block <> nil then @@ -5323,50 +5343,53 @@ begin end; block := parser_node^._else; if block <> nil then - elna_name_statements(block, symbol_table) + elna_name_statements(block, symbol_table, error_list) end end -proc elna_name_return_statement(parser_node: ^ElnaTreeReturnStatement, symbol_table: ^ElnaSymbolTable) +proc elna_name_return_statement(parser_node: ^ElnaTreeReturnStatement, symbol_table: ^ElnaSymbolTable, + error_list: ^ElnaList) begin - elna_name_binary_expression(parser_node^.returned, symbol_table) + elna_name_binary_expression(parser_node^.returned, symbol_table, error_list) end -proc elna_name_assign_statement(parser_node: ^ElnaTreeAssignStatement, symbol_table: ^ElnaSymbolTable) +proc elna_name_assign_statement(parser_node: ^ElnaTreeAssignStatement, symbol_table: ^ElnaSymbolTable, + error_list: ^ElnaList) begin - elna_name_designator(parser_node^.assignee, symbol_table); - elna_name_binary_expression(parser_node^.assignment, symbol_table) + elna_name_designator(parser_node^.assignee, symbol_table, error_list); + elna_name_binary_expression(parser_node^.assignment, symbol_table, error_list) end -proc elna_name_statement(parser_node: ^ElnaTreeStatement, symbol_table: ^ElnaSymbolTable) +proc elna_name_statement(parser_node: ^ElnaTreeStatement, symbol_table: ^ElnaSymbolTable, error_list: ^ElnaList) var call_statement: ^ElnaTreeCallStatement begin (* Skipping goto and label declarations. *) if parser_node^.kind = ElnaTreeKind.if_statement then - elna_name_if_statement(parser_node, symbol_table) + elna_name_if_statement(parser_node, symbol_table, error_list) elsif parser_node^.kind = ElnaTreeKind.return_statement then - elna_name_return_statement(parser_node, symbol_table) + elna_name_return_statement(parser_node, symbol_table, error_list) elsif parser_node^.kind = ElnaTreeKind.call_statement then call_statement := parser_node; - elna_name_call(call_statement^.call, symbol_table) + elna_name_call(call_statement^.call, symbol_table, error_list) elsif parser_node^.kind = ElnaTreeKind.assign_statement then - elna_name_assign_statement(parser_node, symbol_table) + elna_name_assign_statement(parser_node, symbol_table, error_list) end end -proc elna_name_statements(parser_node: ^ElnaTreeStatement, symbol_table: ^ElnaSymbolTable) +proc elna_name_statements(parser_node: ^ElnaTreeStatement, symbol_table: ^ElnaSymbolTable, + error_list: ^ElnaList) begin .elna_name_statements_loop; if parser_node <> nil then - elna_name_statement(parser_node, symbol_table); + elna_name_statement(parser_node, symbol_table, error_list); parser_node := parser_node^.next; goto elna_name_statements_loop end end -proc elna_name_procedure_declaration(parser_node: ^ElnaTreeProcedureDeclaration) +proc elna_name_procedure_declaration(parser_node: ^ElnaTreeProcedureDeclaration, error_list: ^ElnaList) var new_symbol_table: ^ElnaSymbolTable symbol_info: ^ElnaSymbolProcedureInfo @@ -5382,7 +5405,7 @@ begin if parser_node^.return_type = nil then procedure_type^.return_type := nil else - procedure_type^.return_type := elna_name_type_expression(parser_node^.return_type) + procedure_type^.return_type := elna_name_type_expression(parser_node^.return_type, error_list) end; symbol_info^.procedure_type := procedure_type; @@ -5391,9 +5414,9 @@ begin symbol_info^.symbol_table := new_symbol_table; - elna_name_procedure_temporaries(parser_node^.parameters, new_symbol_table); - elna_name_procedure_temporaries(parser_node^.temporaries, new_symbol_table); - elna_name_statements(parser_node^.body, new_symbol_table) + elna_name_procedure_temporaries(parser_node^.parameters, new_symbol_table, error_list); + elna_name_procedure_temporaries(parser_node^.temporaries, new_symbol_table, error_list); + elna_name_statements(parser_node^.body, new_symbol_table, error_list) end end @@ -5696,14 +5719,14 @@ begin elna_type_statements(parser_node^.body, procedure_info^.symbol_table) end -proc elna_name_module_declaration(parser_node: ^ElnaTreeModuleDeclaration) +proc elna_name_module_declaration(parser_node: ^ElnaTreeModuleDeclaration, error_list: ^ElnaList) var current_part: ^ElnaTreeDeclaration begin current_part := parser_node^.types; .elna_name_module_declaration_type; if current_part <> nil then - elna_name_type_declaration(current_part); + elna_name_type_declaration(current_part, error_list); current_part := current_part^.next; goto elna_name_module_declaration_type @@ -5711,7 +5734,7 @@ begin current_part := parser_node^.globals; .elna_name_module_declaration_global; if current_part <> nil then - elna_name_procedure_temporary(current_part, symbol_table_global); + elna_name_procedure_temporary(current_part, symbol_table_global, error_list); current_part := current_part^.next; goto elna_name_module_declaration_global @@ -5719,7 +5742,7 @@ begin current_part := parser_node^.procedures; .elna_name_module_declaration_procedure; if current_part <> nil then - elna_name_procedure_declaration(current_part); + elna_name_procedure_declaration(current_part, error_list); current_part := current_part^.next; goto elna_name_module_declaration_procedure @@ -5743,7 +5766,7 @@ begin end end -proc elna_declaration_type_declaration(parser_node: ^ElnaTreeTypeDeclaration) +proc elna_declaration_type_declaration(parser_node: ^ElnaTreeTypeDeclaration, error_list: ^ElnaList) var type_info: ^ElnaSymbolTypeInfo result: ^ElnaType @@ -5772,7 +5795,7 @@ begin elna_symbol_table_enter(symbol_table_global, parser_node^.name.ptr, parser_node^.name.length, type_info) end -proc elna_declaration_procedure_declaration(parser_node: ^ElnaTreeProcedureDeclaration) +proc elna_declaration_procedure_declaration(parser_node: ^ElnaTreeProcedureDeclaration, error_list: ^ElnaList) var symbol_info: ^ElnaSymbolProcedureInfo begin @@ -5782,14 +5805,14 @@ begin elna_symbol_table_enter(symbol_table_global, parser_node^.name.ptr, parser_node^.name.length, symbol_info) end -proc elna_declaration_module_declaration(parser_node: ^ElnaTreeModuleDeclaration) +proc elna_declaration_module_declaration(parser_node: ^ElnaTreeModuleDeclaration, error_list: ^ElnaList) var current_part: ^ElnaTreeDeclaration begin current_part := parser_node^.types; .elna_declaration_module_declaration_type; if current_part <> nil then - elna_declaration_type_declaration(current_part); + elna_declaration_type_declaration(current_part, error_list); current_part := current_part^.next; goto elna_declaration_module_declaration_type @@ -5798,7 +5821,7 @@ begin current_part := parser_node^.procedures; .elna_declaration_module_declaration_procedure; if current_part <> nil then - elna_declaration_procedure_declaration(current_part); + elna_declaration_procedure_declaration(current_part, error_list); current_part := current_part^.next; goto elna_declaration_module_declaration_procedure @@ -5956,21 +5979,35 @@ begin parser_node := elna_parser_module_declaration(@lexer_state, @error_list); compiled := elna_list_empty(@error_list); + if compiled = false then + goto compile_end + end; - if compiled then - elna_declaration_module_declaration(parser_node); - 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_alloc_module(rtl); - elna_fixup_module(rtl); - elna_riscv_module(rtl) - else + elna_declaration_module_declaration(parser_node, @error_list); + compiled := elna_list_empty(@error_list); + if compiled = false then + goto compile_end + end; + + elna_name_module_declaration(parser_node, @error_list); + (* TODO + compiled := elna_list_empty(@error_list); + if compiled = false then + goto compile_end + end; *) + + elna_type_module_declaration(parser_node); + tac := elna_tac_module_declaration(parser_node); + rtl := elna_rtl_module_declaration(tac); + elna_alloc_module(rtl); + elna_fixup_module(rtl); + elna_riscv_module(rtl); + + .compile_end; + if compiled = false then current_error := error_list.first; elna_error_print(current_error) end; - return compiled end |
