summaryrefslogtreecommitdiff
path: root/boot/stage24
diff options
context:
space:
mode:
Diffstat (limited to 'boot/stage24')
-rw-r--r--boot/stage24/cl.elna392
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);