aboutsummaryrefslogtreecommitdiff
path: root/source/name_analysis.elna
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-10-04 00:51:52 +0200
committerEugen Wissner <belka@caraus.de>2026-10-04 00:51:52 +0200
commit8a6ed3a4ddf9c4e16bb4ddc3b8c5094bb937598b (patch)
tree18198be391a5fd4b10421c1850f1046b3c2e12c4 /source/name_analysis.elna
parente4ce7f658741a7428597da4872435a1b0bae944c (diff)
downloadelna-8a6ed3a4ddf9c4e16bb4ddc3b8c5094bb937598b.tar.gz
Update the old compiler with the new syntax
Diffstat (limited to 'source/name_analysis.elna')
-rw-r--r--source/name_analysis.elna539
1 files changed, 539 insertions, 0 deletions
diff --git a/source/name_analysis.elna b/source/name_analysis.elna
new file mode 100644
index 0000000..75d6dbd
--- /dev/null
+++ b/source/name_analysis.elna
@@ -0,0 +1,539 @@
+(* This Source Code Form is subject to the terms of the Mozilla Public License,
+ v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ obtain one at https://mozilla.org/MPL/2.0/. *)
+module
+import common, cstdlib, lexer, ast, symbol, diagnostic
+
+proc elna_name_type_expression*(parser_node: ^ElnaTreeTypeExpression; error_list: ^ElnaList) -> ^ElnaType
+var
+ result: ^ElnaType := nil
+begin
+ if parser_node <> nil then
+ case parser_node^.kind of
+ ElnaTreeKind.named_type_expression:
+ result := elna_name_named_type_expression(cast(parser_node: ^ElnaTreeNamedTypeExpression), error_list)
+ | ElnaTreeKind.enumeration_type_expression:
+ result := malloc#[ElnaType](#size(ElnaTypeEnumeration));
+ result^.kind := ElnaTypeKind.enumeration;
+ elna_name_enumeration_type_expression(cast(parser_node: ^ElnaTreeEnumerationTypeExpression), error_list, cast(result: ^ElnaTypeEnumeration))
+ | ElnaTreeKind.record_type_expression:
+ result := malloc#[ElnaType](#size(ElnaTypeRecord));
+ result^.kind := ElnaTypeKind._record;
+ elna_name_record_type_expression(cast(parser_node: ^ElnaTreeRecordTypeExpression), error_list, cast(result: ^ElnaTypeRecord))
+ | ElnaTreeKind.pointer_type_expression:
+ result := malloc#[ElnaType](#size(ElnaTypePointer));
+ result^.kind := ElnaTypeKind.pointer;
+ elna_name_pointer_type_expression(cast(parser_node: ^ElnaTreePointerTypeExpression), error_list, cast(result: ^ElnaTypePointer))
+ | ElnaTreeKind.array_type_expression:
+ result := malloc#[ElnaType](#size(ElnaTypeArray));
+ result^.kind := ElnaTypeKind.array;
+ elna_name_array_type_expression(cast(parser_node: ^ElnaTreeArrayTypeExpression), error_list, cast(result: ^ElnaTypeArray))
+ else
+ end
+ end
+return result
+
+proc elna_name_named_type_expression*(parser_node: ^ElnaTreeNamedTypeExpression; error_list: ^ElnaList) -> ^ElnaType
+var
+ symbol_info: ^ElnaSymbolInfo
+ type_info: ^ElnaSymbolTypeInfo
+ undefined_symbol: ^ElnaErrorUndefinedSymbol
+ result: ^ElnaType := nil
+begin
+ symbol_info := elna_symbol_table_lookup(symbol_table_global, parser_node^.name);
+ if symbol_info <> nil then
+ type_info := cast(symbol_info: ^ElnaSymbolTypeInfo);
+ result := type_info^._type
+ else
+ undefined_symbol := elna_error_undefined_symbol_create(parser_node^.position, parser_node^.name);
+ elna_list_append(error_list, cast(undefined_symbol: ^ElnaListNode))
+ end
+return result
+
+proc elna_name_alias_type_expression*(parser_node: ^ElnaTreeNamedTypeExpression;
+ error_list: ^ElnaList; result: ^ElnaTypeAlias)
+var
+ base: ^ElnaType
+begin
+ base := elna_name_named_type_expression(parser_node, error_list);
+ if base <> nil then
+ result^.size := base^.size;
+ result^.alignment := base^.alignment;
+ result^.base := base
+ end
+return
+
+proc elna_name_enumeration_type_expression*(parser_node: ^ElnaTreeEnumerationTypeExpression;
+ error_list: ^ElnaList; result: ^ElnaTypeEnumeration)
+var
+ tree_member: ^ElnaTreeEnumeration
+ i: Word := 0u
+begin
+ result^.size := 8u;
+ result^.alignment := 8u;
+ result^.length := parser_node^.length;
+ result^.members := malloc#[[]const Word8](parser_node^.length * #size([]const Word8));
+
+ tree_member := parser_node^.members;
+ while i < parser_node^.length & tree_member <> nil do
+ (result^.members + i)^ := tree_member^.name;
+ tree_member := tree_member^.next;
+ i := i + 1u
+ end
+return
+
+proc elna_name_pointer_type_expression*(parser_node: ^ElnaTreePointerTypeExpression;
+ error_list: ^ElnaList; result: ^ElnaTypePointer)
+begin
+ result^.size := 8u;
+ result^.alignment := 8u;
+ result^.base := elna_name_type_expression(parser_node^.base, error_list)
+return
+
+proc elna_name_array_type_expression*(parser_node: ^ElnaTreeArrayTypeExpression;
+ error_list: ^ElnaList; result: ^ElnaTypeArray)
+var
+ base: ^ElnaType
+ len_lit: ^ElnaTreeIntegerLiteral
+begin
+ base := elna_name_type_expression(parser_node^.base, error_list);
+ len_lit := cast(parser_node^.length: ^ElnaTreeIntegerLiteral);
+ if base <> nil & len_lit <> nil then
+ result^.size := base^.size * len_lit^.value;
+ result^.alignment := base^.alignment;
+ result^.base := base;
+ result^.length := len_lit^.value
+ end
+return
+
+proc elna_name_record_type_expression*(parser_node: ^ElnaTreeRecordTypeExpression;
+ error_list: ^ElnaList; result: ^ElnaTypeRecord)
+var
+ tree_field: ^ElnaTreeField
+ member_array_current: ^ElnaTypeField
+ field_type: ^ElnaType
+begin
+ result^.size := 0u;
+ result^.alignment := 0u;
+ result^.length := 0u;
+ result^.members := malloc#[ElnaTypeField](parser_node^.length * #size(ElnaTypeField));
+
+ tree_field := parser_node^.members;
+ member_array_current := result^.members;
+
+ while result^.length < parser_node^.length & tree_field <> nil do
+ member_array_current^.name := tree_field^.name;
+ field_type := elna_name_type_expression(tree_field^.type_expression, error_list);
+ 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 + 1u;
+ tree_field := tree_field^.next;
+ result^.length := result^.length + 1u
+ else
+ tree_field := nil
+ end
+ end
+return
+
+proc elna_name_procedure_temporary*(parser_node: ^ElnaTreeVariableDeclaration; symbol_table: ^ElnaSymbolTable;
+ error_list: ^ElnaList)
+var
+ info: ^ElnaSymbolTemporaryInfo
+ variable_type: ^ElnaType
+ declaration_error: ^ElnaErrorDuplicateDeclaration
+begin
+ info := cast(elna_symbol_table_lookup(symbol_table, parser_node^.name): ^ElnaSymbolTemporaryInfo);
+ if info = nil then
+ variable_type := elna_name_type_expression(parser_node^.type_expression, error_list);
+ info := elna_symbol_temporary_info_create(0u, variable_type);
+ elna_symbol_table_enter(symbol_table, parser_node^.name, cast(info: ^ElnaSymbolInfo))
+ else
+ declaration_error := elna_error_duplicate_declaration_create(parser_node^.position, parser_node^.name);
+ elna_list_append(error_list, cast(declaration_error: ^ElnaListNode))
+ end
+return
+
+proc elna_name_procedure_temporaries*(parser_node: ^ElnaTreeVariableDeclaration; symbol_table: ^ElnaSymbolTable;
+ error_list: ^ElnaList)
+var
+ current: ^ElnaTreeVariableDeclaration
+begin
+ current := parser_node;
+ while current <> nil do
+ elna_name_procedure_temporary(current, symbol_table, error_list);
+ current := cast(current^.next: ^ElnaTreeVariableDeclaration)
+ end
+return
+
+proc elna_name_type_declaration*(parser_node: ^ElnaTreeTypeDeclaration; error_list: ^ElnaList)
+var
+ type_info: ^ElnaSymbolTypeInfo
+ type_stub: ^ElnaType
+ type_expression: ^ElnaTreeTypeExpression
+begin
+ type_info := cast(elna_symbol_table_lookup(symbol_table_global, parser_node^.name): ^ElnaSymbolTypeInfo);
+ if type_info <> nil then
+ type_stub := type_info^._type;
+ type_expression := parser_node^.type_expression;
+
+ if type_stub^.kind = ElnaTypeKind.alias then
+ elna_name_alias_type_expression(cast(type_expression: ^ElnaTreeNamedTypeExpression), error_list, cast(type_stub: ^ElnaTypeAlias))
+ elsif type_stub^.kind = ElnaTypeKind.enumeration then
+ elna_name_enumeration_type_expression(cast(type_expression: ^ElnaTreeEnumerationTypeExpression), error_list, cast(type_stub: ^ElnaTypeEnumeration))
+ elsif type_stub^.kind = ElnaTypeKind._record then
+ elna_name_record_type_expression(cast(type_expression: ^ElnaTreeRecordTypeExpression), error_list, cast(type_stub: ^ElnaTypeRecord))
+ elsif type_stub^.kind = ElnaTypeKind.pointer then
+ elna_name_pointer_type_expression(cast(type_expression: ^ElnaTreePointerTypeExpression), error_list, cast(type_stub: ^ElnaTypePointer))
+ elsif type_stub^.kind = ElnaTypeKind.array then
+ elna_name_array_type_expression(cast(type_expression: ^ElnaTreeArrayTypeExpression), error_list, cast(type_stub: ^ElnaTypeArray))
+ end
+ end
+return
+
+proc elna_name_variable_expression*(parser_node: ^ElnaTreeVariableExpression; symbol_table: ^ElnaSymbolTable;
+ error_list: ^ElnaList)
+var
+ symbol_info: ^ElnaSymbolInfo
+ undefined_symbol: ^ElnaErrorUndefinedSymbol
+begin
+ symbol_info := elna_symbol_table_lookup(symbol_table, parser_node^.name);
+ if symbol_info = nil then
+ undefined_symbol := elna_error_undefined_symbol_create(parser_node^.position, parser_node^.name);
+ elna_list_append(error_list, cast(undefined_symbol: ^ElnaListNode))
+ end
+return
+
+proc elna_name_cast_expression*(parser_node: ^ElnaTreeCastExpression; symbol_table: ^ElnaSymbolTable;
+ error_list: ^ElnaList)
+begin
+ elna_name_binary_expression(parser_node^.expression, symbol_table, error_list);
+ parser_node^.type_decoration := elna_name_type_expression(parser_node^.type_expression, error_list)
+return
+
+proc elna_name_simple_expression*(parser_node: ^ElnaTreeExpression; symbol_table: ^ElnaSymbolTable;
+ error_list: ^ElnaList)
+begin
+ if parser_node^.kind = ElnaTreeKind._cast then
+ elna_name_cast_expression(cast(parser_node: ^ElnaTreeCastExpression), symbol_table, error_list)
+ elsif parser_node^.kind = ElnaTreeKind.variable_expression then
+ elna_name_variable_expression(cast(parser_node: ^ElnaTreeVariableExpression), symbol_table, error_list)
+ end
+return
+
+proc elna_name_call*(parser_node: ^ElnaTreeCall; symbol_table: ^ElnaSymbolTable; error_list: ^ElnaList)
+var
+ argument_tree: ^ElnaTreeExpressionList
+begin
+ elna_name_variable_expression(parser_node^.callee, symbol_table, error_list);
+ argument_tree := parser_node^.arguments;
+ while argument_tree <> nil do
+ elna_name_binary_expression(argument_tree^.expression, symbol_table, error_list);
+ argument_tree := argument_tree^.next
+ end
+return
+
+proc elna_name_dereference_expression*(parser_node: ^ElnaTreeDereferenceExpression; symbol_table: ^ElnaSymbolTable;
+ error_list: ^ElnaList)
+begin
+ elna_name_designator(parser_node^.pointer, symbol_table, error_list)
+return
+
+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: ^[]const Word8
+ found: Bool := false
+begin
+ if parser_node^.aggregate^.kind = ElnaTreeKind.variable_expression then
+ variable_expression := cast(parser_node^.aggregate: ^ElnaTreeVariableExpression);
+ identifier_symbol := elna_symbol_table_lookup(symbol_table, variable_expression^.name);
+
+ if identifier_symbol <> nil & identifier_symbol^.kind = ElnaSymbolInfoKind.type_info then
+ type_info := cast(identifier_symbol: ^ElnaSymbolTypeInfo);
+ if type_info^._type^.kind = ElnaTypeKind.enumeration then
+ enumeration_type := cast(type_info^._type: ^ElnaTypeEnumeration);
+ current_member := enumeration_type^.members;
+ member_count := enumeration_type^.length;
+
+ while member_count > 0u & ~found do
+ if current_member^ = parser_node^.field then
+ found := true
+ end;
+ member_count := member_count - 1u;
+ current_member := current_member + 1u
+ end
+ end;
+ if ~found then
+ undefined_member_error := elna_error_undefined_member_create(variable_expression^.position,
+ variable_expression^.name, parser_node^.field);
+ elna_list_append(error_list, cast(undefined_member_error: ^ElnaListNode))
+ end
+ else
+ elna_name_designator(cast(variable_expression: ^ElnaTreeExpression), symbol_table, error_list)
+ end
+ else
+ elna_name_designator(parser_node^.aggregate, symbol_table, error_list)
+ end
+return
+
+proc elna_name_array_access_expression*(parser_node: ^ElnaTreeArrayAccessExpression; symbol_table: ^ElnaSymbolTable;
+ error_list: ^ElnaList)
+begin
+ elna_name_designator(parser_node^.array, symbol_table, error_list);
+ elna_name_binary_expression(parser_node^.index, symbol_table, error_list)
+return
+
+proc elna_name_designator*(parser_node: ^ElnaTreeExpression; symbol_table: ^ElnaSymbolTable; error_list: ^ElnaList)
+begin
+ if parser_node^.kind = ElnaTreeKind.dereference_expression then
+ elna_name_dereference_expression(cast(parser_node: ^ElnaTreeDereferenceExpression), symbol_table, error_list)
+ elsif parser_node^.kind = ElnaTreeKind.field_access_expression then
+ elna_name_field_access_expression(cast(parser_node: ^ElnaTreeFieldAccessExpression), symbol_table, error_list)
+ elsif parser_node^.kind = ElnaTreeKind.array_access_expression then
+ elna_name_array_access_expression(cast(parser_node: ^ElnaTreeArrayAccessExpression), symbol_table, error_list)
+ elsif parser_node^.kind = ElnaTreeKind.call then
+ elna_name_call(cast(parser_node: ^ElnaTreeCall), symbol_table, error_list)
+ else
+ elna_name_simple_expression(parser_node, symbol_table, error_list)
+ end
+return
+
+proc elna_name_unary_expression*(parser_node: ^ElnaTreeExpression; symbol_table: ^ElnaSymbolTable;
+ error_list: ^ElnaList)
+var
+ unary_node: ^ElnaTreeUnaryExpression
+begin
+ if parser_node^.kind = ElnaTreeKind.unary_expression then
+ unary_node := cast(parser_node: ^ElnaTreeUnaryExpression);
+ elna_name_designator(unary_node^.operand, symbol_table, error_list)
+ else
+ elna_name_designator(parser_node, symbol_table, error_list)
+ end
+return
+
+proc elna_name_binary_expression*(parser_node: ^ElnaTreeExpression; symbol_table: ^ElnaSymbolTable;
+ error_list: ^ElnaList)
+var
+ bin_node: ^ElnaTreeBinaryExpression
+begin
+ if parser_node^.kind = ElnaTreeKind.binary_expression then
+ bin_node := cast(parser_node: ^ElnaTreeBinaryExpression);
+ elna_name_unary_expression(bin_node^.lhs, symbol_table, error_list);
+ elna_name_unary_expression(bin_node^.rhs, symbol_table, error_list)
+ else
+ elna_name_unary_expression(parser_node, symbol_table, error_list)
+ end
+return
+
+proc elna_name_conditional_statements*(parser_node: ^ElnaTreeConditionalStatements; symbol_table: ^ElnaSymbolTable;
+ error_list: ^ElnaList)
+var
+ current: ^ElnaTreeConditionalStatements
+begin
+ current := parser_node;
+ while current <> nil do
+ elna_name_binary_expression(current^.condition, symbol_table, error_list);
+ elna_name_statements(current^.statements, symbol_table, error_list);
+ current := current^.next
+ end
+return
+
+proc elna_name_if_statement*(parser_node: ^ElnaTreeIfStatement; symbol_table: ^ElnaSymbolTable;
+ error_list: ^ElnaList)
+begin
+ elna_name_conditional_statements(parser_node^.conditionals, symbol_table, error_list);
+ if parser_node^._else <> nil then
+ elna_name_statements(parser_node^._else, symbol_table, error_list)
+ end
+return
+
+proc elna_name_return_statement*(parser_node: ^ElnaTreeReturnStatement; symbol_table: ^ElnaSymbolTable;
+ error_list: ^ElnaList)
+begin
+ elna_name_binary_expression(parser_node^.returned, symbol_table, error_list)
+return
+
+proc elna_name_assign_statement*(parser_node: ^ElnaTreeAssignStatement; symbol_table: ^ElnaSymbolTable;
+ error_list: ^ElnaList)
+begin
+ elna_name_designator(parser_node^.assignee, symbol_table, error_list);
+ elna_name_binary_expression(parser_node^.assignment, symbol_table, error_list)
+return
+
+proc elna_name_statement*(parser_node: ^ElnaTreeStatement; symbol_table: ^ElnaSymbolTable; error_list: ^ElnaList)
+var
+ call_statement: ^ElnaTreeCallStatement
+begin
+ if parser_node^.kind = ElnaTreeKind.if_statement then
+ elna_name_if_statement(cast(parser_node: ^ElnaTreeIfStatement), symbol_table, error_list)
+ elsif parser_node^.kind = ElnaTreeKind.return_statement then
+ elna_name_return_statement(cast(parser_node: ^ElnaTreeReturnStatement), symbol_table, error_list)
+ elsif parser_node^.kind = ElnaTreeKind.call_statement then
+ call_statement := cast(parser_node: ^ElnaTreeCallStatement);
+ elna_name_call(call_statement^.call, symbol_table, error_list)
+ elsif parser_node^.kind = ElnaTreeKind.assign_statement then
+ elna_name_assign_statement(cast(parser_node: ^ElnaTreeAssignStatement), symbol_table, error_list)
+ end
+return
+
+proc elna_name_statements*(parser_node: ^ElnaTreeStatement; symbol_table: ^ElnaSymbolTable;
+ error_list: ^ElnaList)
+var
+ current: ^ElnaTreeStatement
+begin
+ current := parser_node;
+ while current <> nil do
+ elna_name_statement(current, symbol_table, error_list);
+ current := current^.next
+ end
+return
+
+proc elna_name_procedure_declaration*(parser_node: ^ElnaTreeProcedureDeclaration; error_list: ^ElnaList)
+var
+ new_symbol_table: ^ElnaSymbolTable
+ symbol_info: ^ElnaSymbolProcedureInfo
+ proc_type: ^ElnaTypeProcedure
+begin
+ symbol_info := cast(elna_symbol_table_lookup(symbol_table_global, parser_node^.name): ^ElnaSymbolProcedureInfo);
+
+ proc_type := malloc#[ElnaTypeProcedure](#size(ElnaTypeProcedure));
+ proc_type^.kind := ElnaTypeKind.procedure;
+ proc_type^.size := 8u;
+ proc_type^.alignment := 8u;
+ if parser_node^.return_type = nil then
+ proc_type^.return_type := nil
+ else
+ proc_type^.return_type := elna_name_type_expression(parser_node^.return_type, error_list)
+ end;
+ symbol_info^.procedure_type := proc_type;
+
+ if ~symbol_info^.is_extern then
+ new_symbol_table := elna_symbol_table_create(symbol_table_global);
+ symbol_info^.symbol_table := 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
+return
+
+proc elna_name_program_body*(parser_node: ^ElnaTreeStatement)
+var
+ symbol_info: ^ElnaSymbolProcedureInfo
+begin
+ symbol_info := elna_symbol_procedure_info_create(false);
+ symbol_info^.symbol_table := elna_symbol_table_create(symbol_table_global);
+ elna_symbol_table_enter(symbol_table_global, "main", cast(symbol_info: ^ElnaSymbolInfo))
+return
+
+proc elna_declaration_type_declaration*(parser_node: ^ElnaTreeTypeDeclaration; error_list: ^ElnaList)
+var
+ type_info: ^ElnaSymbolTypeInfo
+ result: ^ElnaType := nil
+ type_expression: ^ElnaTreeTypeExpression
+ declaration_error: ^ElnaErrorDuplicateDeclaration
+begin
+ type_info := cast(elna_symbol_table_lookup(symbol_table_global, parser_node^.name): ^ElnaSymbolTypeInfo);
+
+ if type_info = nil then
+ type_expression := parser_node^.type_expression;
+
+ if type_expression^.kind = ElnaTreeKind.named_type_expression then
+ result := malloc#[ElnaType](#size(ElnaTypeAlias));
+ result^.kind := ElnaTypeKind.alias
+ elsif type_expression^.kind = ElnaTreeKind.enumeration_type_expression then
+ result := malloc#[ElnaType](#size(ElnaTypeEnumeration));
+ result^.kind := ElnaTypeKind.enumeration
+ elsif type_expression^.kind = ElnaTreeKind.record_type_expression then
+ result := malloc#[ElnaType](#size(ElnaTypeRecord));
+ result^.kind := ElnaTypeKind._record
+ elsif type_expression^.kind = ElnaTreeKind.pointer_type_expression then
+ result := malloc#[ElnaType](#size(ElnaTypePointer));
+ result^.kind := ElnaTypeKind.pointer
+ elsif type_expression^.kind = ElnaTreeKind.array_type_expression then
+ result := malloc#[ElnaType](#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, cast(type_info: ^ElnaSymbolInfo))
+ else
+ declaration_error := elna_error_duplicate_declaration_create(parser_node^.position, parser_node^.name);
+ elna_list_append(error_list, cast(declaration_error: ^ElnaListNode))
+ end
+return
+
+proc elna_declaration_procedure_declaration*(parser_node: ^ElnaTreeProcedureDeclaration; error_list: ^ElnaList)
+var
+ symbol_info: ^ElnaSymbolProcedureInfo
+ declaration_error: ^ElnaErrorDuplicateDeclaration
+begin
+ symbol_info := cast(elna_symbol_table_lookup(symbol_table_global, parser_node^.name): ^ElnaSymbolProcedureInfo);
+
+ 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, cast(symbol_info: ^ElnaSymbolInfo))
+ else
+ declaration_error := elna_error_duplicate_declaration_create(parser_node^.position, parser_node^.name);
+ elna_list_append(error_list, cast(declaration_error: ^ElnaListNode))
+ end
+return
+
+proc elna_declaration_module_declaration*(parser_node: ^ElnaTreeModuleDeclaration; error_list: ^ElnaList)
+var
+ current_type: ^ElnaTreeDeclaration
+ current_proc: ^ElnaTreeDeclaration
+begin
+ current_type := parser_node^.types;
+ while current_type <> nil do
+ elna_declaration_type_declaration(cast(current_type: ^ElnaTreeTypeDeclaration), error_list);
+ current_type := current_type^.next
+ end;
+
+ current_proc := cast(parser_node^.procedures: ^ElnaTreeDeclaration);
+ while current_proc <> nil do
+ elna_declaration_procedure_declaration(cast(current_proc: ^ElnaTreeProcedureDeclaration), error_list);
+ current_proc := current_proc^.next
+ end
+return
+
+proc elna_name_module_declaration*(parser_node: ^ElnaTreeModuleDeclaration; error_list: ^ElnaList)
+var
+ current_type: ^ElnaTreeDeclaration
+ current_global: ^ElnaTreeVariableDeclaration
+ current_proc: ^ElnaTreeProcedureDeclaration
+begin
+ current_type := parser_node^.types;
+ while current_type <> nil do
+ elna_name_type_declaration(cast(current_type: ^ElnaTreeTypeDeclaration), error_list);
+ current_type := current_type^.next
+ end;
+
+ current_global := parser_node^.globals;
+ while current_global <> nil do
+ elna_name_procedure_temporary(current_global, symbol_table_global, error_list);
+ current_global := cast(current_global^.next: ^ElnaTreeVariableDeclaration)
+ end;
+
+ current_proc := parser_node^.procedures;
+ while current_proc <> nil do
+ elna_name_procedure_declaration(current_proc, error_list);
+ current_proc := cast(current_proc^.next: ^ElnaTreeProcedureDeclaration)
+ end;
+
+ if parser_node^.body <> nil then
+ elna_name_program_body(parser_node^.body)
+ end
+return
+
+end.