diff options
| author | Eugen Wissner <belka@caraus.de> | 2026-06-27 00:39:04 +0200 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2026-06-27 00:39:04 +0200 |
| commit | 44143ee21da8725df24ddf59ed91d7b47b7092c2 (patch) | |
| tree | ad2c5fd2b7c03a635a264a7a233bd437e6b1f466 /boot/stage24 | |
| parent | 3b747ac448ddc2173affd86b9316ab8a6c5f7bd6 (diff) | |
| download | elna-44143ee21da8725df24ddf59ed91d7b47b7092c2.tar.gz | |
Diffstat (limited to 'boot/stage24')
| -rw-r--r-- | boot/stage24/cl.elna | 392 |
1 files changed, 273 insertions, 119 deletions
diff --git a/boot/stage24/cl.elna b/boot/stage24/cl.elna index 878b42b..3bc9d7d 100644 --- a/boot/stage24/cl.elna +++ b/boot/stage24/cl.elna @@ -48,7 +48,7 @@ type kind: ElnaTypeKind; size: Word; alignment: Word; - members: Word; + members: ^String; length: Word end ElnaTypeField = record @@ -245,7 +245,7 @@ type kind: ElnaTreeKind; position: ElnaPosition; type_decoration: ^ElnaType; - aggregate: Word; + aggregate: ^ElnaTreeNode; field: String end ElnaTreeArrayAccessExpression = record @@ -692,7 +692,7 @@ type allocated: Bool end - ElnaErrorKind = (unexpected_token, undefined_symbol) + ElnaErrorKind = (unexpected_token, undefined_symbol, undefined_member, duplicate_declaration) ElnaError = record next: ^ElnaListNode; kind: ElnaErrorKind; @@ -712,6 +712,19 @@ type position: ElnaPosition; symbol_name: String end + ElnaErrorUndefinedMember = record + next: ^ElnaListNode; + kind: ElnaErrorKind; + position: ElnaPosition; + aggregate_name: String; + member_name: String + end + ElnaErrorDuplicateDeclaration = record + next: ^ElnaListNode; + kind: ElnaErrorKind; + position: ElnaPosition; + symbol_name: String + end var symbol_table_global: ^ElnaSymbolTable @@ -3358,18 +3371,15 @@ end proc elna_tac_enumeration_value(field_access_expression: ^ElnaTreeFieldAccessExpression, operand: ^ElnaTacOperand) var enumeration_type: ^ElnaTypeEnumeration - members: Word + members: ^String members_length: Word - token_type: Word symbol_info: ^ElnaSymbolTypeInfo - member_length: Word - member: String counter: Word - enumeration_type_name: ^ElnaTreeVariableExpression + aggregate_tree: ^ElnaTreeVariableExpression begin - enumeration_type_name := field_access_expression^.aggregate; + aggregate_tree := field_access_expression^.aggregate; symbol_info := elna_symbol_table_lookup(symbol_table_global, - enumeration_type_name^.name.ptr, enumeration_type_name^.name.length); + aggregate_tree^.name.ptr, aggregate_tree^.name.length); enumeration_type := symbol_info^._type; members := enumeration_type^.members; @@ -3378,13 +3388,9 @@ begin .elna_tac_enumeration_value_members; if members_length > 0 then - member.ptr := members^; - member_length := members + 4; - member.length := member_length^; - - if string_compare(field_access_expression^.field.ptr, field_access_expression^.field.length, member) = false then + if string_compare(field_access_expression^.field.ptr, field_access_expression^.field.length, members^) = false then members_length := members_length - 1; - members := members + 8; + members := members + 1; counter := counter + 1; goto elna_tac_enumeration_value_members end; @@ -4063,7 +4069,7 @@ begin member_count := parser_node^.length; (* Copy the list of enumeration members into an array of strings. *) - result^.members := malloc(member_count * 8); + result^.members := malloc(member_count * #size(String)); member_array_current := result^.members; .elna_name_type_enumeration_loop; @@ -4095,19 +4101,20 @@ var length: ^ElnaTreeIntegerLiteral begin base := elna_name_type_expression(parser_node^.base, error_list); - length := parser_node^.length; + if base <> nil then + length := parser_node^.length; - (* Array size in bytes. *) - result^.size := base^.size * length^.value; - result^.alignment := base^.alignment; - result^.base := base; - result^.length := length^.value + (* Array size in bytes. *) + result^.size := base^.size * length^.value; + result^.alignment := base^.alignment; + result^.base := base; + result^.length := length^.value + end end proc elna_name_record_type_expression(parser_node: ^ElnaTreeRecordTypeExpression, error_list: ^ElnaList, result: ^ElnaTypeRecord) var - result: ^ElnaTypeRecord tree_field: ^ElnaTreeField member_array_current: ^ElnaTypeField field_type: ^ElnaType @@ -4125,17 +4132,19 @@ begin member_array_current^.name := tree_field^.name; 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 - end; - member_array_current^.field_type := field_type; + if field_type <> nil then + result^.size := result^.size + field_type^.size; + if field_type^.alignment > result^.alignment then + result^.alignment := field_type^.alignment + end; + member_array_current^.field_type := field_type; - member_array_current := member_array_current + 1; + member_array_current := member_array_current + 1; - tree_field := tree_field^.next; - result^.length := result^.length + 1; - goto elna_name_type_record_loop + tree_field := tree_field^.next; + result^.length := result^.length + 1; + goto elna_name_type_record_loop + end end end @@ -4252,18 +4261,38 @@ begin result^.base := aliased_type end +proc elna_name_named_type_expression(parser_node: ^ElnaTreeNamedTypeExpression, error_list: ^ElnaList) -> ^ElnaType +var + type_symbol: ^ElnaSymbolTypeInfo + result: ^ElnaType + undefined_symbol: ^ElnaErrorUndefinedSymbol +begin + type_symbol := elna_symbol_table_lookup(symbol_table_global, + parser_node^.name.ptr, parser_node^.name.length); + if type_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); + result := nil + else + result := type_symbol^._type + end; + return result +end + proc elna_name_type_expression(parser_node: ^ElnaTreeTypeExpression, error_list: ^ElnaList) -> ^ElnaType var named_type_expression: ^ElnaTreeNamedTypeExpression type_symbol: ^ElnaSymbolTypeInfo result: ^ElnaType + undefined_symbol: ^ElnaErrorUndefinedSymbol begin if parser_node^.kind = ElnaTreeKind.named_type_expression then - named_type_expression := parser_node; - - type_symbol := elna_symbol_table_lookup(symbol_table_global, - named_type_expression^.name.ptr, named_type_expression^.name.length); - result := type_symbol^._type + result := elna_name_named_type_expression(parser_node, error_list) elsif parser_node^.kind = ElnaTreeKind.enumeration_type_expression then result := malloc(#size(ElnaTypeEnumeration)); result^.kind := ElnaTypeKind.enumeration; @@ -4343,11 +4372,18 @@ proc elna_name_procedure_temporary(parser_node: ^ElnaTreeVariableDeclaration, sy var info: ^ElnaSymbolTemporaryInfo variable_type: ^ElnaType + declaration_error: ^ElnaErrorDuplicateDeclaration begin - variable_type := elna_name_type_expression(parser_node^.type_expression, error_list); + info := elna_symbol_table_lookup(symbol_table, parser_node^.name.ptr, parser_node^.name.length); + if info = nil then + 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) + info := elna_symbol_temporary_info_create(0, variable_type); + elna_symbol_table_enter(symbol_table, parser_node^.name.ptr, parser_node^.name.length, info) + else + declaration_error := elna_error_duplicate_declaration_create(parser_node); + elna_list_append(error_list, declaration_error) + end end proc elna_name_procedure_temporaries(parser_node: ^ElnaTreeVariableDeclaration, symbol_table: ^ElnaSymbolTable, @@ -5094,6 +5130,18 @@ begin return parser_error end +proc elna_error_duplicate_declaration_create(declaration_tree: ^ElnaTreeDeclaration) -> ^ElnaErrorDuplicateDeclaration +var + declaration_error: ^ElnaErrorDuplicateDeclaration +begin + declaration_error := malloc(#size(ElnaErrorDuplicateDeclaration)); + declaration_error^.kind := ElnaErrorKind.duplicate_declaration; + declaration_error^.position := declaration_tree^.position; + declaration_error^.symbol_name := declaration_tree^.name; + + return declaration_error +end + (* Check and return whether the next token is of the expected kind. If so the token is skipped, otherwise an error is added to the error list. *) proc elna_parser_expect(cursor: ^ElnaLexerCursor, expected: ElnaLexerKind, error_list: ^ElnaList) -> ^ElnaLexerToken @@ -5213,8 +5261,52 @@ end proc elna_name_field_access_expression(parser_node: ^ElnaTreeFieldAccessExpression, symbol_table: ^ElnaSymbolTable, error_list: ^ElnaList) +var + variable_expression: ^ElnaTreeVariableExpression + identifier_symbol: ^ElnaSymbolInfo + type_info: ^ElnaSymbolTypeInfo + undefined_member_error: ^ElnaErrorUndefinedMember + enumeration_type: ^ElnaTypeEnumeration + member_count: Word + current_member: ^String begin - elna_name_designator(parser_node^.aggregate, symbol_table, error_list) + if parser_node^.aggregate^.kind = ElnaTreeKind.variable_expression then + variable_expression := parser_node^.aggregate; + identifier_symbol := elna_symbol_table_lookup(symbol_table, + variable_expression^.name.ptr, variable_expression^.name.length); + if identifier_symbol^.kind = ElnaSymbolInfoKind.type_info then + type_info := identifier_symbol; + + if type_info^._type^.kind = ElnaTypeKind.enumeration then + enumeration_type := type_info^._type; + current_member := enumeration_type^.members; + member_count := enumeration_type^.length; + + .elna_name_field_access_expression_loop; + if member_count > 0 then + if string_compare(current_member^.ptr, current_member^.length, parser_node^.field) then + goto elna_name_field_access_expression_end + end; + + member_count := member_count - 1; + current_member := current_member + 1; + goto elna_name_field_access_expression_loop + end + end; + undefined_member_error := malloc(#size(ElnaErrorUndefinedMember)); + undefined_member_error^.kind := ElnaErrorKind.undefined_member; + undefined_member_error^.position := variable_expression^.position; + undefined_member_error^.aggregate_name := variable_expression^.name; + undefined_member_error^.member_name := parser_node^.field; + + elna_list_append(error_list, undefined_member_error) + else + elna_name_designator(variable_expression, symbol_table, error_list) + end + else + elna_name_designator(parser_node^.aggregate, symbol_table, error_list) + end; + .elna_name_field_access_expression_end end proc elna_name_array_access_expression(parser_node: ^ElnaTreeArrayAccessExpression, symbol_table: ^ElnaSymbolTable, @@ -5237,7 +5329,7 @@ var variable_symbol: ^ElnaSymbolProcedureInfo undefined_symbol: ^ElnaErrorUndefinedSymbol begin - variable_symbol := elna_symbol_table_lookup(symbol_table_global, + variable_symbol := elna_symbol_table_lookup(symbol_table, parser_node^.name.ptr, parser_node^.name.length); if variable_symbol = nil then @@ -5430,11 +5522,12 @@ begin elna_symbol_table_enter(symbol_table_global, "main".ptr, 4, symbol_info) end -proc elna_type_conditional_statements(parser_node: ^ElnaTreeConditionalStatements, symbol_table: ^ElnaSymbolTable) +proc elna_type_conditional_statements(parser_node: ^ElnaTreeConditionalStatements, symbol_table: ^ElnaSymbolTable, + error_list: ^ElnaList) begin .elna_type_conditional_statements_loop; - elna_type_binary_expression(parser_node^.condition, symbol_table); - elna_type_statements(parser_node^.statements, symbol_table); + elna_type_binary_expression(parser_node^.condition, symbol_table, error_list); + elna_type_statements(parser_node^.statements, symbol_table, error_list); parser_node := parser_node^.next; if parser_node <> nil then @@ -5442,14 +5535,14 @@ begin end end -proc elna_type_if_statement(parser_node: ^ElnaTreeIfStatement, symbol_table: ^ElnaSymbolTable) +proc elna_type_if_statement(parser_node: ^ElnaTreeIfStatement, symbol_table: ^ElnaSymbolTable, error_list: ^ElnaList) var block: ^ElnaTreeConditionalStatements begin block := parser_node^.conditionals; .elna_type_if_statement_conditionals; - elna_type_conditional_statements(block, symbol_table); + elna_type_conditional_statements(block, symbol_table, error_list); block := block^.next; if block <> nil then @@ -5457,42 +5550,43 @@ begin end; block := parser_node^._else; if block <> nil then - elna_type_statements(block, symbol_table) + elna_type_statements(block, symbol_table, error_list) end end -proc elna_type_return_statement(parser_node: ^ElnaTreeReturnStatement, symbol_table: ^ElnaSymbolTable) +proc elna_type_return_statement(parser_node: ^ElnaTreeReturnStatement, symbol_table: ^ElnaSymbolTable, error_list: ^ElnaList) begin - elna_type_binary_expression(parser_node^.returned, symbol_table) + elna_type_binary_expression(parser_node^.returned, symbol_table, error_list) end -proc elna_type_call(parser_node: ^ElnaTreeCall, symbol_table: ^ElnaSymbolTable) +proc elna_type_call(parser_node: ^ElnaTreeCall, symbol_table: ^ElnaSymbolTable, error_list: ^ElnaList) var argument_tree: ^ElnaTreeExpressionList procedure_type: ^ElnaTypeProcedure begin argument_tree := parser_node^.arguments; - elna_type_variable_expression(parser_node^.callee); + elna_type_variable_expression(parser_node^.callee, symbol_table, error_list); procedure_type := parser_node^.callee^.type_decoration; parser_node^.type_decoration := procedure_type^.return_type; .elna_type_call_argument; if argument_tree <> nil then - elna_type_binary_expression(argument_tree^.expression, symbol_table); + elna_type_binary_expression(argument_tree^.expression, symbol_table, error_list); argument_tree := argument_tree^.next; goto elna_type_call_argument end end -proc elna_type_assign_statement(parser_node: ^ElnaTreeAssignStatement, symbol_table: ^ElnaSymbolTable) +proc elna_type_assign_statement(parser_node: ^ElnaTreeAssignStatement, symbol_table: ^ElnaSymbolTable, + error_list: ^ElnaList) begin - elna_type_designator(parser_node^.assignee, symbol_table); - elna_type_binary_expression(parser_node^.assignment, symbol_table) + elna_type_designator(parser_node^.assignee, symbol_table, error_list); + elna_type_binary_expression(parser_node^.assignment, symbol_table, error_list) end -proc elna_type_statement(parser_node: ^ElnaTreeStatement, symbol_table: ^ElnaSymbolTable) +proc elna_type_statement(parser_node: ^ElnaTreeStatement, symbol_table: ^ElnaSymbolTable, error_list: ^ElnaList) var call_statement: ^ElnaTreeCallStatement begin @@ -5500,20 +5594,20 @@ begin if parser_node^.kind = ElnaTreeKind.if_statement then elna_type_if_statement(parser_node, symbol_table) elsif parser_node^.kind = ElnaTreeKind.return_statement then - elna_type_return_statement(parser_node, symbol_table) + elna_type_return_statement(parser_node, symbol_table, error_list) elsif parser_node^.kind = ElnaTreeKind.call_statement then call_statement := parser_node; - elna_type_call(call_statement^.call, symbol_table) + elna_type_call(call_statement^.call, symbol_table, error_list) elsif parser_node^.kind = ElnaTreeKind.assign_statement then - elna_type_assign_statement(parser_node, symbol_table) + elna_type_assign_statement(parser_node, symbol_table, error_list) end end -proc elna_type_statements(parser_node: ^ElnaTreeStatement, symbol_table: ^ElnaSymbolTable) +proc elna_type_statements(parser_node: ^ElnaTreeStatement, symbol_table: ^ElnaSymbolTable, error_list: ^ElnaList) begin .elna_type_statements_loop; if parser_node <> nil then - elna_type_statement(parser_node, symbol_table); + elna_type_statement(parser_node, symbol_table, error_list); parser_node := parser_node^.next; goto elna_type_statements_loop @@ -5565,12 +5659,13 @@ begin end end -proc elna_type_cast_expression(parser_node: ^ElnaTreeCastExpression, symbol_table: ^ElnaSymbolTable) +proc elna_type_cast_expression(parser_node: ^ElnaTreeCastExpression, symbol_table: ^ElnaSymbolTable, + error_list: ^ElnaList) begin - elna_type_binary_expression(parser_node^.expression, symbol_table) + elna_type_binary_expression(parser_node^.expression, symbol_table, error_list) end -proc elna_type_simple_expression(parser_node: ^ElnaTreeNode, symbol_table: ^ElnaSymbolTable) +proc elna_type_simple_expression(parser_node: ^ElnaTreeNode, symbol_table: ^ElnaSymbolTable, error_list: ^ElnaList) begin if parser_node^.kind = ElnaTreeKind.integer_literal then elna_type_integer_literal(parser_node) @@ -5583,19 +5678,20 @@ begin elsif parser_node^.kind = ElnaTreeKind.null then elna_type_nil_literal(parser_node) elsif parser_node^.kind = ElnaTreeKind._cast then - elna_type_cast_expression(parser_node) + elna_type_cast_expression(parser_node, error_list) elsif parser_node^.kind = ElnaTreeKind.variable_expression then - elna_type_variable_expression(parser_node, symbol_table) + elna_type_variable_expression(parser_node, symbol_table, error_list) end end -proc elna_type_dereference_expression(parser_node: ^ElnaTreeDereferenceExpression, symbol_table: ^ElnaSymbolTable) +proc elna_type_dereference_expression(parser_node: ^ElnaTreeDereferenceExpression, symbol_table: ^ElnaSymbolTable, + error_list: ^ElnaList) var base_type: ^ElnaType pointer_type: ^ElnaTypePointer dereferenced_expression: ^ElnaTreeExpression begin - elna_type_designator(parser_node^.pointer, symbol_table); + elna_type_designator(parser_node^.pointer, symbol_table, error_list); dereferenced_expression := parser_node^.pointer; base_type := dereferenced_expression^.type_decoration; @@ -5608,7 +5704,8 @@ begin parser_node^.type_decoration := base_type end -proc elna_type_field_access_expression(parser_node: ^ElnaTreeFieldAccessExpression, symbol_table: ^ElnaSymbolTable) +proc elna_type_field_access_expression(parser_node: ^ElnaTreeFieldAccessExpression, symbol_table: ^ElnaSymbolTable, + error_list: ^ElnaList) var variable_expression: ^ElnaTreeVariableExpression base_type: Word @@ -5635,7 +5732,7 @@ begin end; (* If the base_type is still nil this is record field access. *) if base_type = nil then - elna_type_designator(parser_node^.aggregate, symbol_table); + elna_type_designator(parser_node^.aggregate, symbol_table, error_list); aggregate_type := variable_expression^.type_decoration; field_count := aggregate_type^.length; @@ -5654,69 +5751,72 @@ begin parser_node^.type_decoration := base_type end -proc elna_type_array_access_expression(parser_node: ^ElnaTreeArrayAccessExpression, symbol_table: ^ElnaSymbolTable) +proc elna_type_array_access_expression(parser_node: ^ElnaTreeArrayAccessExpression, symbol_table: ^ElnaSymbolTable, + error_list: ^ElnaList) var aggregate_type: ^ElnaTypeArray base_expression: ^ElnaTreeExpression begin base_expression := parser_node^.array; - elna_type_designator(base_expression, symbol_table); - elna_type_binary_expression(parser_node^.index, symbol_table); + elna_type_designator(base_expression, symbol_table, error_list); + elna_type_binary_expression(parser_node^.index, symbol_table, error_list); aggregate_type := base_expression^.type_decoration; parser_node^.type_decoration := aggregate_type^.base end -proc elna_type_designator(parser_node: ^ElnaTreeNode, symbol_table: ^ElnaSymbolTable) +proc elna_type_designator(parser_node: ^ElnaTreeNode, symbol_table: ^ElnaSymbolTable, error_list: ^ElnaList) begin if parser_node^.kind = ElnaTreeKind.dereference_expression then - elna_type_dereference_expression(parser_node, symbol_table) + elna_type_dereference_expression(parser_node, symbol_table, error_list) elsif parser_node^.kind = ElnaTreeKind.field_access_expression then - elna_type_field_access_expression(parser_node, symbol_table) + elna_type_field_access_expression(parser_node, symbol_table, error_list) elsif parser_node^.kind = ElnaTreeKind.array_access_expression then - elna_type_array_access_expression(parser_node, symbol_table) + elna_type_array_access_expression(parser_node, symbol_table, error_list) elsif parser_node^.kind = ElnaTreeKind.call then - elna_type_call(parser_node, symbol_table) + elna_type_call(parser_node, symbol_table, error_list) else elna_type_simple_expression(parser_node, symbol_table) end end -proc elna_type_unary_expression(parser_node: ^ElnaTreeUnaryExpression, symbol_table: ^ElnaSymbolTable) +proc elna_type_unary_expression(parser_node: ^ElnaTreeUnaryExpression, symbol_table: ^ElnaSymbolTable, + error_list: ^ElnaList) begin if parser_node^.kind = ElnaTreeKind.unary_expression then - elna_type_designator(parser_node^.operand, symbol_table); + elna_type_designator(parser_node^.operand, symbol_table, error_list); parser_node^.type_decoration := parser_node^.operand^.type_decoration else - elna_type_designator(parser_node, symbol_table) + elna_type_designator(parser_node, symbol_table, error_list) end end -proc elna_type_binary_expression(parser_node: ^ElnaTreeBinaryExpression, symbol_table: ^ElnaSymbolTable) +proc elna_type_binary_expression(parser_node: ^ElnaTreeBinaryExpression, symbol_table: ^ElnaSymbolTable, + error_list: ^ElnaList) var binary_operand: ^ElnaTreeExpression begin if parser_node^.kind = ElnaTreeKind.binary_expression then - elna_type_unary_expression(parser_node^.rhs, symbol_table); + elna_type_unary_expression(parser_node^.rhs, symbol_table, error_list); binary_operand := parser_node^.lhs; - elna_type_unary_expression(binary_operand, symbol_table); + elna_type_unary_expression(binary_operand, symbol_table, error_list); parser_node^.type_decoration := binary_operand^.type_decoration else - elna_type_unary_expression(parser_node, symbol_table) + elna_type_unary_expression(parser_node, symbol_table, error_list) end end -proc elna_type_procedure_declaration(parser_node: ^ElnaTreeProcedureDeclaration) +proc elna_type_procedure_declaration(parser_node: ^ElnaTreeProcedureDeclaration, error_list: ^ElnaList) var procedure_info: ^ElnaSymbolProcedureInfo begin procedure_info := elna_symbol_table_lookup(symbol_table_global, parser_node^.name.ptr, parser_node^.name.length); - elna_type_statements(parser_node^.body, procedure_info^.symbol_table) + elna_type_statements(parser_node^.body, procedure_info^.symbol_table, error_list) end proc elna_name_module_declaration(parser_node: ^ElnaTreeModuleDeclaration, error_list: ^ElnaList) @@ -5752,14 +5852,14 @@ begin end end -proc elna_type_module_declaration(parser_node: ^ElnaTreeModuleDeclaration) +proc elna_type_module_declaration(parser_node: ^ElnaTreeModuleDeclaration, error_list: ^ElnaList) var current_part: ^ElnaTreeDeclaration begin current_part := parser_node^.procedures; .elna_type_module_declaration_procedure; if current_part <> nil then - elna_type_procedure_declaration(current_part); + elna_type_procedure_declaration(current_part, error_list); current_part := current_part^.next; goto elna_type_module_declaration_procedure @@ -5771,38 +5871,54 @@ var type_info: ^ElnaSymbolTypeInfo result: ^ElnaType type_expression: ^ElnaTreeTypeExpression + declaration_error: ^ElnaErrorDuplicateDeclaration begin - type_expression := parser_node^.type_expression; + type_info := elna_symbol_table_lookup(symbol_table_global, parser_node^.name.ptr, parser_node^.name.length); - if type_expression^.kind = ElnaTreeKind.named_type_expression then - result := malloc(#size(ElnaTypeAlias)); - result^.kind := ElnaTypeKind.alias - elsif type_expression^.kind = ElnaTreeKind.enumeration_type_expression then - result := malloc(#size(ElnaTypeEnumeration)); - result^.kind := ElnaTypeKind.enumeration - elsif type_expression^.kind = ElnaTreeKind.record_type_expression then - result := malloc(#size(ElnaTypeRecord)); - result^.kind := ElnaTypeKind._record - elsif type_expression^.kind = ElnaTreeKind.pointer_type_expression then - result := malloc(#size(ElnaTypePointer)); - result^.kind := ElnaTypeKind.pointer - elsif type_expression^.kind = ElnaTreeKind.array_type_expression then - result := malloc(#size(ElnaTypeArray)); - result^.kind := ElnaTypeKind.array - end; - type_info := elna_symbol_type_info_create(result); + if type_info = nil then + type_expression := parser_node^.type_expression; + + if type_expression^.kind = ElnaTreeKind.named_type_expression then + result := malloc(#size(ElnaTypeAlias)); + result^.kind := ElnaTypeKind.alias + elsif type_expression^.kind = ElnaTreeKind.enumeration_type_expression then + result := malloc(#size(ElnaTypeEnumeration)); + result^.kind := ElnaTypeKind.enumeration + elsif type_expression^.kind = ElnaTreeKind.record_type_expression then + result := malloc(#size(ElnaTypeRecord)); + result^.kind := ElnaTypeKind._record + elsif type_expression^.kind = ElnaTreeKind.pointer_type_expression then + result := malloc(#size(ElnaTypePointer)); + result^.kind := ElnaTypeKind.pointer + elsif type_expression^.kind = ElnaTreeKind.array_type_expression then + result := malloc(#size(ElnaTypeArray)); + result^.kind := ElnaTypeKind.array + end; + type_info := elna_symbol_type_info_create(result); - elna_symbol_table_enter(symbol_table_global, parser_node^.name.ptr, parser_node^.name.length, type_info) + elna_symbol_table_enter(symbol_table_global, parser_node^.name.ptr, parser_node^.name.length, type_info) + else + declaration_error := elna_error_duplicate_declaration_create(parser_node); + elna_list_append(error_list, declaration_error) + end end proc elna_declaration_procedure_declaration(parser_node: ^ElnaTreeProcedureDeclaration, error_list: ^ElnaList) var symbol_info: ^ElnaSymbolProcedureInfo + declaration_error: ^ElnaErrorDuplicateDeclaration begin - symbol_info := elna_symbol_procedure_info_create(parser_node^.is_extern); - symbol_info^.symbol_table := elna_symbol_table_create(symbol_table_global); + symbol_info := elna_symbol_table_lookup(symbol_table_global, parser_node^.name.ptr, parser_node^.name.length); + + if symbol_info = nil then + symbol_info := elna_symbol_procedure_info_create(parser_node^.is_extern); + symbol_info^.symbol_table := elna_symbol_table_create(symbol_table_global); - elna_symbol_table_enter(symbol_table_global, parser_node^.name.ptr, parser_node^.name.length, symbol_info) + elna_symbol_table_enter(symbol_table_global, parser_node^.name.ptr, parser_node^.name.length, symbol_info) + else + declaration_error := elna_error_duplicate_declaration_create(parser_node); + elna_list_append(error_list, declaration_error) + end end proc elna_declaration_module_declaration(parser_node: ^ElnaTreeModuleDeclaration, error_list: ^ElnaList) @@ -5952,16 +6068,50 @@ begin elna_error_print_token1(current_error^.expected[1]); _write_s(stderr, "; got "); elna_error_print_token1(current_error^.got); - _write_s(stderr, ".\n") + _write_s(stderr, ". ") +end + +proc elna_error_print_undefined_member(current_error: ^ElnaErrorUndefinedMember) +begin + _write_s(stderr, "Semantic error: Member \""); + _write_s(stderr, current_error^.member_name); + _write_s(stderr, "\" is not accessible on \""); + _write_s(stderr, current_error^.aggregate_name); + _write_s(stderr, "\". ") +end + +proc elna_error_print_undefined_symbol(current_error: ^ElnaErrorUndefinedSymbol) +begin + _write_s(stderr, "Semantic error: Undefined symbol \""); + _write_s(stderr, current_error^.symbol_name); + _write_s(stderr, "\". ") +end + +proc elna_error_print_duplicate_declaration(current_error: ^ElnaErrorDuplicateDeclaration) +begin + _write_s(stderr, "Semantic error: Duplicate declaration \""); + _write_s(stderr, current_error^.symbol_name); + _write_s(stderr, "\". ") end proc elna_error_print(current_error: ^ElnaError) begin if current_error^.kind = ElnaErrorKind.unexpected_token then elna_error_print_unexpected_token(current_error) + elsif current_error^.kind = ElnaErrorKind.undefined_symbol then + elna_error_print_undefined_symbol(current_error) + elsif current_error^.kind = ElnaErrorKind.undefined_member then + elna_error_print_undefined_member(current_error) + elsif current_error^.kind = ElnaErrorKind.duplicate_declaration then + elna_error_print_duplicate_declaration(current_error) else - _write_s(stderr, "Unknown error.\n") - end + _write_s(stderr, "Unknown error. ") + end; + _write_s(stderr, "Line "); + _write_i(stderr, current_error^.position.start_location.line); + _write_s(stderr, ", column "); + _write_i(stderr, current_error^.position.start_location.column); + _write_s(stderr, ".\n") end proc compile() -> Bool @@ -5990,13 +6140,17 @@ begin end; elna_name_module_declaration(parser_node, @error_list); - (* TODO compiled := elna_list_empty(@error_list); if compiled = false then goto compile_end - end; *) + end; + + elna_type_module_declaration(parser_node, @error_list); + 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); |
