diff options
| author | Eugen Wissner <belka@caraus.de> | 2026-10-04 00:51:52 +0200 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2026-10-04 00:51:52 +0200 |
| commit | 8a6ed3a4ddf9c4e16bb4ddc3b8c5094bb937598b (patch) | |
| tree | 18198be391a5fd4b10421c1850f1046b3c2e12c4 /source/name_analysis.elna | |
| parent | e4ce7f658741a7428597da4872435a1b0bae944c (diff) | |
| download | elna-8a6ed3a4ddf9c4e16bb4ddc3b8c5094bb937598b.tar.gz | |
Update the old compiler with the new syntax
Diffstat (limited to 'source/name_analysis.elna')
| -rw-r--r-- | source/name_analysis.elna | 539 |
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. |
