summaryrefslogtreecommitdiff
path: root/boot/stage24/cl.elna
diff options
context:
space:
mode:
Diffstat (limited to 'boot/stage24/cl.elna')
-rw-r--r--boot/stage24/cl.elna446
1 files changed, 275 insertions, 171 deletions
diff --git a/boot/stage24/cl.elna b/boot/stage24/cl.elna
index af4fb9e..8b64551 100644
--- a/boot/stage24/cl.elna
+++ b/boot/stage24/cl.elna
@@ -3,15 +3,12 @@
* 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/.
*)
-program;
-(* Stage 23 compiler. *)
-
-(* - Support extern procedure declarations. *)
+(* Stage 24 compiler. *)
type
ElnaListNode = record
- next: Word
+ next: ^ElnaListNode
end
ElnaList = record
first: ^ElnaListNode;
@@ -35,12 +32,18 @@ type
end
(* Type representation. *)
- ElnaTypeKind = (primitive, enumeration, _record, pointer, array)
+ ElnaTypeKind = (primitive, enumeration, _record, pointer, array, alias, procedure)
ElnaType = record
kind: ElnaTypeKind;
size: Word;
alignment: Word
end
+ ElnaTypeAlias = record
+ kind: ElnaTypeKind;
+ size: Word;
+ alignment: Word;
+ base: ^ElnaType
+ end
ElnaTypeEnumeration = record
kind: ElnaTypeKind;
size: Word;
@@ -72,6 +75,12 @@ type
base: ^ElnaType;
length: Word
end
+ ElnaTypeProcedure = record
+ kind: ElnaTypeKind;
+ size: Word;
+ alignment: Word;
+ return_type: ^ElnaType
+ end
(* Abstract syntax tree nodes. *)
ElnaTreeKind = (
@@ -85,6 +94,7 @@ type
unary_expression,
binary_expression,
call,
+ call_statement,
goto_statement,
label_declaration,
return_statement,
@@ -174,33 +184,42 @@ type
*)
ElnaTreeStatement = record
kind: ElnaTreeKind;
- next: Word
+ next: ^ElnaTreeStatement
+ end
+ (**
+ * Conditional statements is a list of pairs: condition and statements.
+ * Used for example to represent if and elsif blocks with beloning statements.
+ *)
+ ElnaTreeConditionalStatements = record
+ condition: ^ElnaTreeExpression;
+ statements: ^ElnaTreeStatement;
+ next: ^ElnaTreeConditionalStatements
end
ElnaTreeIfStatement = record
kind: ElnaTreeKind;
- next: Word;
- conditionals: Word;
+ next: ^ElnaTreeStatement;
+ conditionals: ^ElnaTreeConditionalStatements;
_else: ^ElnaTreeStatement
end
ElnaTreeGotoStatement = record
kind: ElnaTreeKind;
- next: Word;
+ next: ^ElnaTreeStatement;
label: String
end
ElnaTreeAssignStatement = record
kind: ElnaTreeKind;
- next: Word;
+ next: ^ElnaTreeStatement;
assignee: Word;
assignment: ^ElnaTreeExpression
end
ElnaTreeReturnStatement = record
kind: ElnaTreeKind;
- next: Word;
+ next: ^ElnaTreeStatement;
returned: ^ElnaTreeExpression
end
ElnaTreeLabelDeclaration = record
kind: ElnaTreeKind;
- next: Word;
+ next: ^ElnaTreeStatement;
label: String
end
ElnaTreeFieldAccessExpression = record
@@ -217,17 +236,17 @@ type
end
ElnaTreeEnumeration = record
name: String;
- next: Word
+ next: ^ElnaTreeEnumeration
end
ElnaTreeEnumerationTypeExpression = record
kind: ElnaTreeKind;
- members: Word;
+ members: ^ElnaTreeEnumeration;
length: Word
end
ElnaTreeField = record
name: String;
type_expression: ^ElnaTreeTypeExpression;
- next: Word
+ next: ^ElnaTreeField
end
ElnaTreeRecordTypeExpression = record
kind: ElnaTreeKind;
@@ -250,31 +269,22 @@ type
ElnaTreeTraitExpression = record
kind: ElnaTreeKind;
name: String;
- argument: Word
- end
- (**
- * Conditional statements is a list of pairs: condition and statements.
- * Used for example to represent if and elsif blocks with beloning statements.
- *)
- ElnaTreeConditionalStatements = record
- condition: ^ElnaTreeExpression;
- statements: ^ElnaTreeStatement;
- next: Word
+ argument: ^ElnaTreeTypeExpression
end
ElnaTreeDeclaration = record
kind: ElnaTreeKind;
- next: Word;
+ next: ^ElnaTreeDeclaration;
name: String
end
ElnaTreeVariableDeclaration = record
kind: ElnaTreeKind;
- next: Word;
+ next: ^ElnaTreeDeclaration;
name: String;
type_expression: ^ElnaTreeTypeExpression
end
ElnaTreeProcedureDeclaration = record
kind: ElnaTreeKind;
- next: Word;
+ next: ^ElnaTreeDeclaration;
name: String;
body: ^ElnaTreeStatement;
temporaries: ^ElnaTreeVariableDeclaration;
@@ -284,37 +294,42 @@ type
end
ElnaTreeModuleDeclaration = record
kind: ElnaTreeKind;
- types: Word;
- globals: Word;
+ types: ^ElnaTreeDeclaration;
+ globals: ^ElnaTreeVariableDeclaration;
procedures: ^ElnaTreeProcedureDeclaration;
body: ^ElnaTreeStatement
end
ElnaTreeTypeDeclaration = record
kind: ElnaTreeKind;
- next: Word;
+ next: ^ElnaTreeDeclaration;
name: String;
type_expression: ^ElnaTreeTypeExpression
end
ElnaTreeExpressionList = record
expression: ^ElnaTreeBinaryExpression;
- next: Word
+ next: ^ElnaTreeExpressionList
end
ElnaTreeCall = record
kind: ElnaTreeKind;
- next: Word;
+ type_decoration: ^ElnaType;
callee: ^ElnaTreeVariableExpression;
arguments: ^ElnaTreeExpressionList;
count: Word
end
+ ElnaTreeCallStatement = record
+ kind: ElnaTreeKind;
+ next: ^ElnaTreeStatement;
+ call: ^ElnaTreeCall
+ end
(* Symbol table information. *)
ElnaSymbolEntry = record
name: String;
- symbol_info: Word
+ symbol_info: ^ElnaSymbolInfo
end
ElnaSymbolTable = record
count: Word;
- parent: Word;
+ parent: ^ElnaSymbolTable;
symbols: ^ElnaSymbolEntry
end
ElnaSymbolInfoKind = (type_info, temporary_info, procedure_info)
@@ -333,7 +348,7 @@ type
ElnaSymbolProcedureInfo = record
kind: ElnaSymbolInfoKind;
symbol_table: ^ElnaSymbolTable;
- return_type: ^ElnaType;
+ procedure_type: ^ElnaTypeProcedure;
is_extern: Bool
end
@@ -414,7 +429,6 @@ type
_xor,
not,
_return,
- _program,
_cast,
trait,
left_paren,
@@ -506,20 +520,20 @@ type
length: Word
end
ElnaTacInstruction = record
- next: Word;
+ next: ^ElnaListNode;
operator: ElnaTacOperator;
operands: [4]ElnaTacOperand
end
ElnaTacProcedure = record
- next: Word;
+ next: ^ElnaTacProcedure;
name: String;
body: ElnaList;
- parameters: Word;
+ parameters: ^String;
count: Word;
symbol_table: ^ElnaSymbolTable
end
ElnaTacStaticVariable = record
- next: Word;
+ next: ^ElnaTacStaticVariable;
name: String;
body: Word
end
@@ -567,12 +581,12 @@ type
offset: Word
end
ElnaRtlStaticVariable = record
- next: Word;
+ next: ^ElnaRtlStaticVariable;
name: String;
body: Word
end
ElnaRtlProcedure = record
- next: Word;
+ next: ^ElnaRtlProcedure;
name: String;
body: ElnaList;
variable_map: ^ElnaSymbolTable
@@ -590,7 +604,7 @@ type
alignment: Word
end
ElnaRtlInstruction = record
- next: Word;
+ next: ^ElnaListNode;
operator: ElnaRtlOperator;
operands: [3]ElnaRtlOperand;
types: [2]^ElnaRtlType
@@ -646,12 +660,12 @@ type
ElnaErrorKind = (unexpected_token)
ElnaError = record
- next: Word;
+ next: ^ElnaListNode;
kind: ElnaErrorKind;
position: ElnaPosition
end
ElnaErrorUnexpectedToken = record
- next: Word;
+ next: ^ElnaListNode;
kind: ElnaErrorKind;
position: ElnaPosition;
expected: ^ElnaLexerKind;
@@ -905,7 +919,7 @@ begin
operand^.value := buffer;
operand^.length := strlen(buffer);
- temporary_info := temporary_info_create(1, variable_type);
+ temporary_info := elna_symbol_temporary_info_create(1, variable_type);
elna_symbol_table_enter(symbol_table, buffer, operand^.length, temporary_info)
end
@@ -3111,7 +3125,7 @@ var
begin
result := malloc(#size(ElnaTreeCall));
result^.kind := ElnaTreeKind.call;
- result^.next := nil;
+ result^.type_decoration := nil;
result^.arguments := nil;
result^.count := 0;
@@ -3175,10 +3189,10 @@ begin
(* TODO: procedure_info should never be nil. *)
if procedure_info = nil then
elna_tac_make_variable(operand, symbol_table, word_type)
- elsif procedure_info^.return_type = nil then
+ elsif procedure_info^.procedure_type^.return_type = nil then
elna_tac_make_variable(operand, symbol_table, word_type)
else
- elna_tac_make_variable(operand, symbol_table, procedure_info^.return_type)
+ elna_tac_make_variable(operand, symbol_table, procedure_info^.procedure_type^.return_type)
end;
call_instruction := elna_tac_instruction_create(ElnaTacOperator.proc_call);
@@ -3674,6 +3688,7 @@ end
proc elna_parser_statement(cursor: ^ElnaLexerCursor, error_list: ^ElnaList) -> ^ElnaTreeStatement
var
result: ^ElnaTreeStatement
+ call_result: ^ElnaTreeCallStatement
designator: ^ElnaTreeNode
token: ^ElnaLexerToken
begin
@@ -3694,7 +3709,11 @@ begin
if designator^.kind <> ElnaTreeKind.call then
result := elna_parser_assign_statement(cursor, designator, error_list)
else
- result := designator
+ call_result := malloc(#size(ElnaTreeCallStatement));
+ call_result^.kind := ElnaTreeKind.call_statement;
+ call_result^.next := nil;
+ call_result^.call := designator;
+ result := call_result
end
end
end;
@@ -3778,6 +3797,7 @@ end
proc elna_tac_statement(instructions: ^ElnaList, parser_node: ^ElnaTreeNode, symbol_table: ^ElnaSymbolTable)
var
operand: ElnaTacOperand
+ call_statement: ^ElnaTreeCallStatement
begin
if parser_node^.kind = ElnaTreeKind.goto_statement then
elna_tac_goto_statement(instructions, parser_node)
@@ -3787,8 +3807,9 @@ begin
elna_tac_return_statement(instructions, parser_node, symbol_table)
elsif parser_node^.kind = ElnaTreeKind.label_declaration then
elna_tac_label_declaration(instructions, parser_node)
- elsif parser_node^.kind = ElnaTreeKind.call then
- elna_tac_call(instructions, parser_node, symbol_table, @operand)
+ elsif parser_node^.kind = ElnaTreeKind.call_statement then
+ call_statement := parser_node;
+ elna_tac_call(instructions, call_statement^.call, symbol_table, @operand)
elsif parser_node^.kind = ElnaTreeKind.assign_statement then
elna_tac_assign_statement(instructions, parser_node, symbol_table)
end
@@ -3937,15 +3958,13 @@ end
*
* Returns enumeration type description.
*)
-proc elna_name_enumeration_type_expression(parser_node: ^ElnaTreeEnumerationTypeExpression) -> ^ElnaTypeEnumeration
+proc elna_name_enumeration_type_expression(parser_node: ^ElnaTreeEnumerationTypeExpression,
+ result: ^ElnaTypeEnumeration)
var
- result: ^ElnaTypeEnumeration
memory_start: ^ElnaTreeEnumeration
member_count: Word
member_array_current: ^String
begin
- result := malloc(#size(ElnaTypeEnumeration));
-
memory_start := parser_node^.members;
member_count := parser_node^.length;
@@ -3962,58 +3981,43 @@ begin
member_count := member_count - 1;
goto elna_name_type_enumeration_loop
end;
-
- result^.kind := ElnaTypeKind.enumeration;
result^.size := 4;
result^.alignment := 4;
- result^.length := parser_node^.length;
-
- return result
+ result^.length := parser_node^.length
end
-proc elna_name_pointer_type_expression(parser_node: ^ElnaTreePointerTypeExpression) -> ^ElnaTypePointer
-var
- result: ^ElnaTypePointer
+proc elna_name_pointer_type_expression(parser_node: ^ElnaTreePointerTypeExpression,
+ result: ^ElnaTypePointer)
begin
- result := malloc(#size(ElnaTypePointer));
-
- result^.kind := ElnaTypeKind.pointer;
result^.size := 4;
result^.alignment := 4;
- result^.base := elna_name_type_expression(parser_node^.base);
-
- return result
+ result^.base := elna_name_type_expression(parser_node^.base)
end
-proc elna_name_array_type_expression(parser_node: ^ElnaTreeArrayTypeExpression) -> ^ElnaTypeArray
+proc elna_name_array_type_expression(parser_node: ^ElnaTreeArrayTypeExpression,
+ result: ^ElnaTypeArray)
var
base: ^ElnaType
- result: ^ElnaTypeArray
length: ^ElnaTreeIntegerLiteral
begin
- result := malloc(#size(ElnaTypeArray));
base := elna_name_type_expression(parser_node^.base);
length := parser_node^.length;
- result^.kind := ElnaTypeKind.array;
(* Array size in bytes. *)
result^.size := base^.size * length^.value;
result^.alignment := base^.alignment;
result^.base := base;
- result^.length := length^.value;
-
- return result
+ result^.length := length^.value
end
-proc elna_name_record_type_expression(parser_node: ^ElnaTreeRecordTypeExpression) -> ^ElnaTypeRecord
+proc elna_name_record_type_expression(parser_node: ^ElnaTreeRecordTypeExpression,
+ result: ^ElnaTypeRecord)
var
result: ^ElnaTypeRecord
tree_field: ^ElnaTreeField
member_array_current: ^ElnaTypeField
field_type: ^ElnaType
begin
- result := malloc(#size(ElnaTypeRecord));
- result^.kind := ElnaTypeKind._record;
result^.size := 0;
result^.alignment := 0;
result^.length := 0;
@@ -4038,9 +4042,7 @@ begin
tree_field := tree_field^.next;
result^.length := result^.length + 1;
goto elna_name_type_record_loop
- end;
-
- return result
+ end
end
proc elna_parser_named_type_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeNamedTypeExpression
@@ -4131,7 +4133,21 @@ begin
return result
end
-proc elna_name_type_expression(parser_node: ^ElnaTreeNode) -> ^ElnaType
+proc elna_name_alias_type_expression(parser_node: ^ElnaTreeNamedTypeExpression, result: ^ElnaTypeAlias)
+var
+ type_symbol: ^ElnaSymbolTypeInfo
+ aliased_type: ^ElnaType
+begin
+ type_symbol := elna_symbol_table_lookup(symbol_table_global,
+ parser_node^.name.ptr, parser_node^.name.length);
+ aliased_type := type_symbol^._type;
+
+ result^.size := aliased_type^.size;
+ result^.alignment := aliased_type^.alignment;
+ result^.base := aliased_type
+end
+
+proc elna_name_type_expression(parser_node: ^ElnaTreeTypeExpression) -> ^ElnaType
var
named_type_expression: ^ElnaTreeNamedTypeExpression
type_symbol: ^ElnaSymbolTypeInfo
@@ -4144,19 +4160,31 @@ begin
named_type_expression^.name.ptr, named_type_expression^.name.length);
result := type_symbol^._type
elsif parser_node^.kind = ElnaTreeKind.enumeration_type_expression then
- result := elna_name_enumeration_type_expression(parser_node)
+ result := malloc(#size(ElnaTypeEnumeration));
+ result^.kind := ElnaTypeKind.enumeration;
+
+ elna_name_enumeration_type_expression(parser_node, result)
elsif parser_node^.kind = ElnaTreeKind.record_type_expression then
- result := elna_name_record_type_expression(parser_node)
+ result := malloc(#size(ElnaTypeRecord));
+ result^.kind := ElnaTypeKind._record;
+
+ elna_name_record_type_expression(parser_node, result)
elsif parser_node^.kind = ElnaTreeKind.pointer_type_expression then
- result := elna_name_pointer_type_expression(parser_node)
+ result := malloc(#size(ElnaTypePointer));
+ result^.kind := ElnaTypeKind.pointer;
+
+ elna_name_pointer_type_expression(parser_node, result)
elsif parser_node^.kind = ElnaTreeKind.array_type_expression then
- result := elna_name_array_type_expression(parser_node)
+ result := malloc(#size(ElnaTypeArray));
+ result^.kind := ElnaTypeKind.array;
+
+ elna_name_array_type_expression(parser_node, result)
end;
return result
end
-proc type_info_create(type_representation: ^ElnaType) -> ^ElnaSymbolTypeInfo
+proc elna_symbol_type_info_create(type_representation: ^ElnaType) -> ^ElnaSymbolTypeInfo
var
result: ^ElnaSymbolTypeInfo
begin
@@ -4172,7 +4200,7 @@ end
* attr - Local variable attributes.
* temporary_type - Local variable type.
*)
-proc temporary_info_create(attr: Word, temporary_type: ^ElnaType) -> ^ElnaSymbolTemporaryInfo
+proc elna_symbol_temporary_info_create(attr: Word, temporary_type: ^ElnaType) -> ^ElnaSymbolTemporaryInfo
var
result: ^ElnaSymbolTemporaryInfo
begin
@@ -4190,15 +4218,13 @@ end
* Parameters:
* symbol_table - Local symbol table.
*)
-proc procedure_info_create(symbol_table: ^ElnaSymbolTable, return_type: ^ElnaRtlType,
- is_extern: Bool) -> ^ElnaSymbolProcedureInfo
+proc elna_symbol_procedure_info_create(is_extern: Bool) -> ^ElnaSymbolProcedureInfo
var
result: ^ElnaSymbolProcedureInfo
begin
result := malloc(#size(ElnaSymbolProcedureInfo));
result^.kind := ElnaSymbolInfoKind.procedure_info;
- result^.symbol_table := symbol_table;
- result^.return_type := return_type;
+ result^.procedure_type := nil;
result^.is_extern := is_extern;
return result
@@ -4210,12 +4236,12 @@ end
*)
proc elna_name_procedure_temporary(parser_node: ^ElnaTreeVariableDeclaration, symbol_table: ^ElnaSymbolTable)
var
- info: Word
- variable_type: Word
+ info: ^ElnaSymbolTemporaryInfo
+ variable_type: ^ElnaType
begin
variable_type := elna_name_type_expression(parser_node^.type_expression);
- info := temporary_info_create(0, variable_type);
+ info := elna_symbol_temporary_info_create(0, variable_type);
elna_symbol_table_enter(symbol_table, parser_node^.name.ptr, parser_node^.name.length, info)
end
@@ -4767,17 +4793,25 @@ end
proc elna_name_type_declaration(parser_node: ^ElnaTreeTypeDeclaration)
var
- symbol_type: ^ElnaType
type_info: ^ElnaSymbolTypeInfo
+ type_stub: ^ElnaType
+ type_expression: ^ElnaTreeTypeExpression
begin
- symbol_type := elna_name_type_expression(parser_node^.type_expression);
- type_info := type_info_create(symbol_type);
+ type_info := elna_symbol_table_lookup(symbol_table_global, parser_node^.name.ptr, parser_node^.name.length);
+ type_stub := type_info^._type;
+ type_expression := parser_node^.type_expression;
- elna_symbol_table_enter(symbol_table_global, parser_node^.name.ptr, parser_node^.name.length, type_info)
-end
-
-proc elna_type_type_declaration(parser_node: Word)
-begin
+ if type_stub^.kind = ElnaTypeKind.alias then
+ elna_name_alias_type_expression(type_expression, type_stub)
+ elsif type_stub^.kind = ElnaTypeKind.enumeration then
+ elna_name_enumeration_type_expression(type_expression, type_stub)
+ elsif type_stub^.kind = ElnaTypeKind._record then
+ elna_name_record_type_expression(type_expression, type_stub)
+ elsif type_stub^.kind = ElnaTypeKind.pointer then
+ elna_name_pointer_type_expression(type_expression, type_stub)
+ elsif type_stub^.kind = ElnaTypeKind.array then
+ elna_name_array_type_expression(type_expression, type_stub)
+ end
end
proc elna_parser_type_part(cursor: ^ElnaLexerCursor, error_list: ^ElnaList) -> ^ElnaTreeDeclaration
@@ -4979,35 +5013,30 @@ proc elna_parser_module_declaration(cursor: ^ElnaLexerCursor, error_list: ^ElnaL
var
result: ^ElnaTreeModuleDeclaration
begin
- result := nil;
- if elna_parser_expect(cursor, ElnaLexerKind._program, error_list) <> nil then
- if elna_parser_expect(cursor, ElnaLexerKind.semicolon, error_list) <> nil then
- result := malloc(#size(ElnaTreeModuleDeclaration));
- result^.kind := ElnaTreeKind.module_declaration;
+ result := malloc(#size(ElnaTreeModuleDeclaration));
+ result^.kind := ElnaTreeKind.module_declaration;
- result^.types := elna_parser_type_part(cursor, error_list);
- if elna_list_empty(error_list) = false then
- result := free_and_nil(result)
- end;
- if result <> nil then
- result^.globals := elna_parser_var_part(cursor, error_list);
- end;
- if elna_list_empty(error_list) = false then
- result := free_and_nil(result)
- end;
- if result <> nil then
- result^.procedures := elna_parser_procedures(cursor, error_list);
- end;
- if elna_list_empty(error_list) = false then
- result := free_and_nil(result)
- end;
- if result <> nil then
- result^.body := elna_parser_program_body(cursor, error_list)
- end;
- if elna_list_empty(error_list) = false then
- result := free_and_nil(result)
- end
- end
+ result^.types := elna_parser_type_part(cursor, error_list);
+ if elna_list_empty(error_list) = false then
+ result := free_and_nil(result)
+ end;
+ if result <> nil then
+ result^.globals := elna_parser_var_part(cursor, error_list);
+ end;
+ if elna_list_empty(error_list) = false then
+ result := free_and_nil(result)
+ end;
+ if result <> nil then
+ result^.procedures := elna_parser_procedures(cursor, error_list);
+ end;
+ if elna_list_empty(error_list) = false then
+ result := free_and_nil(result)
+ end;
+ if result <> nil then
+ result^.body := elna_parser_program_body(cursor, error_list)
+ end;
+ if elna_list_empty(error_list) = false then
+ result := free_and_nil(result)
end;
return result
end
@@ -5107,6 +5136,7 @@ var
begin
callee_symbol := elna_symbol_table_lookup(symbol_table_global, parser_node^.callee^.name.ptr, parser_node^.callee^.name.length);
if callee_symbol = nil then
+ (* DEBUG *)
_write_s(stdout, "# Undefined symbol ");
_write_s(stdout, parser_node^.callee^.name);
_write_s(stdout, ".\n")
@@ -5199,14 +5229,17 @@ begin
end
proc elna_name_statement(parser_node: ^ElnaTreeStatement, symbol_table: ^ElnaSymbolTable)
+var
+ call_statement: ^ElnaTreeCallStatement
begin
(* Skipping goto and label declarations. *)
if parser_node^.kind = ElnaTreeKind.if_statement then
elna_name_if_statement(parser_node, symbol_table)
elsif parser_node^.kind = ElnaTreeKind.return_statement then
elna_name_return_statement(parser_node, symbol_table)
- elsif parser_node^.kind = ElnaTreeKind.call then
- elna_name_call(parser_node, symbol_table)
+ elsif parser_node^.kind = ElnaTreeKind.call_statement then
+ call_statement := parser_node;
+ elna_name_call(call_statement^.call, symbol_table)
elsif parser_node^.kind = ElnaTreeKind.assign_statement then
elna_name_assign_statement(parser_node, symbol_table)
end
@@ -5228,29 +5261,38 @@ var
new_symbol_table: ^ElnaSymbolTable
symbol_info: ^ElnaSymbolProcedureInfo
return_type: ^ElnaType
+ procedure_type: ^ElnaTypeProcedure
begin
+ symbol_info := elna_symbol_table_lookup(symbol_table_global, parser_node^.name.ptr, parser_node^.name.length);
+
+ procedure_type := malloc(#size(ElnaTypeProcedure));
+ procedure_type^.kind := ElnaTypeKind.procedure;
+ procedure_type^.size := 4;
+ procedure_type^.alignment := 4;
if parser_node^.return_type = nil then
- return_type := nil
+ procedure_type^.return_type := nil
else
- return_type := elna_name_type_expression(parser_node^.return_type);
+ procedure_type^.return_type := elna_name_type_expression(parser_node^.return_type)
end;
- new_symbol_table := elna_symbol_table_create(symbol_table_global);
- symbol_info := procedure_info_create(new_symbol_table, return_type, parser_node^.is_extern);
+ symbol_info^.procedure_type := procedure_type;
- elna_name_procedure_temporaries(parser_node^.parameters, new_symbol_table);
- elna_name_procedure_temporaries(parser_node^.temporaries, new_symbol_table);
- elna_name_statements(parser_node^.body, new_symbol_table);
+ if symbol_info^.is_extern = false then
+ new_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)
+ symbol_info^.symbol_table := new_symbol_table;
+
+ elna_name_procedure_temporaries(parser_node^.parameters, new_symbol_table);
+ elna_name_procedure_temporaries(parser_node^.temporaries, new_symbol_table);
+ elna_name_statements(parser_node^.body, new_symbol_table)
+ end
end
proc elna_name_program_body(parser_node: ^ElnaTreeStatement)
var
- new_symbol_table: ^ElnaSymbolTable
- symbol_info: Word
+ symbol_info: ^ElnaSymbolProcedureInfo
begin
- new_symbol_table := elna_symbol_table_create(symbol_table_global);
- symbol_info := procedure_info_create(new_symbol_table, nil, false);
+ 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".ptr, 4, symbol_info)
end
@@ -5294,9 +5336,14 @@ end
proc elna_type_call(parser_node: ^ElnaTreeCall, symbol_table: ^ElnaSymbolTable)
var
argument_tree: ^ElnaTreeExpressionList
+ procedure_type: ^ElnaTypeProcedure
begin
argument_tree := parser_node^.arguments;
+ elna_type_variable_expression(parser_node^.callee);
+ 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);
@@ -5312,15 +5359,18 @@ begin
elna_type_binary_expression(parser_node^.assignment, symbol_table)
end
-proc elna_type_statement(parser_node: ^ElnaTreeNode, symbol_table: ^ElnaSymbolTable)
+proc elna_type_statement(parser_node: ^ElnaTreeStatement, symbol_table: ^ElnaSymbolTable)
+var
+ call_statement: ^ElnaTreeCallStatement
begin
(* Skipping goto and label declarations. *)
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)
- elsif parser_node^.kind = ElnaTreeKind.call then
- elna_type_call(parser_node, symbol_table)
+ elsif parser_node^.kind = ElnaTreeKind.call_statement then
+ call_statement := parser_node;
+ elna_type_call(call_statement^.call, symbol_table)
elsif parser_node^.kind = ElnaTreeKind.assign_statement then
elna_type_assign_statement(parser_node, symbol_table)
end
@@ -5369,12 +5419,16 @@ proc elna_type_variable_expression(parser_node: ^ElnaTreeVariableExpression, sym
var
variable_info: ^ElnaSymbolInfo
temporary_info: ^ElnaSymbolTemporaryInfo
+ procedure_info: ^ElnaSymbolProcedureInfo
begin
variable_info := elna_symbol_table_lookup(symbol_table, parser_node^.name.ptr, parser_node^.name.length);
if variable_info^.kind = ElnaSymbolInfoKind.temporary_info then
temporary_info := variable_info;
parser_node^.type_decoration := temporary_info^.variable_type
+ elsif variable_info^.kind = ElnaSymbolInfoKind.procedure_info then
+ procedure_info := variable_info;
+ parser_node^.type_decoration := procedure_info^.procedure_type
end
end
@@ -5569,22 +5623,75 @@ proc elna_type_module_declaration(parser_node: ^ElnaTreeModuleDeclaration)
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);
+ current_part := current_part^.next;
+
+ goto elna_type_module_declaration_procedure
+ end
+end
+
+proc elna_declaration_type_declaration(parser_node: ^ElnaTreeTypeDeclaration)
+var
+ type_info: ^ElnaSymbolTypeInfo
+ result: ^ElnaType
+ type_expression: ^ElnaTreeTypeExpression
+begin
+ 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)
+end
+
+proc elna_declaration_procedure_declaration(parser_node: ^ElnaTreeProcedureDeclaration)
+var
+ symbol_info: ^ElnaSymbolProcedureInfo
+begin
+ 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)
+end
+
+proc elna_declaration_module_declaration(parser_node: ^ElnaTreeModuleDeclaration)
+var
+ current_part: ^ElnaTreeDeclaration
+begin
current_part := parser_node^.types;
- .elna_type_module_declaration_type;
+ .elna_declaration_module_declaration_type;
if current_part <> nil then
- elna_type_type_declaration(current_part);
+ elna_declaration_type_declaration(current_part);
current_part := current_part^.next;
- goto elna_type_module_declaration_type
+ goto elna_declaration_module_declaration_type
end;
current_part := parser_node^.procedures;
- .elna_type_module_declaration_procedure;
+ .elna_declaration_module_declaration_procedure;
if current_part <> nil then
- elna_type_procedure_declaration(current_part);
+ elna_declaration_procedure_declaration(current_part);
current_part := current_part^.next;
- goto elna_type_module_declaration_procedure
+ goto elna_declaration_module_declaration_procedure
end
end
@@ -5630,8 +5737,6 @@ begin
_write_s(stderr, "\"~\"")
elsif kind = ElnaLexerKind._return then
_write_s(stderr, "\"return\"")
- elsif kind = ElnaLexerKind._program then
- _write_s(stderr, "\"program\"")
elsif kind = ElnaLexerKind._cast then
_write_s(stderr, "\"cast\"")
elsif kind = ElnaLexerKind.trait then
@@ -5690,6 +5795,8 @@ begin
_write_s(stderr, "CHARACTER")
elsif kind = ElnaLexerKind.integer then
_write_s(stderr, "INTEGER")
+ elsif kind = ElnaLexerKind.word then
+ _write_s(stderr, "WORD")
else
elna_error_print_token2(kind)
end
@@ -5697,9 +5804,7 @@ end
proc elna_error_print_token2(kind: ElnaLexerKind)
begin
- if kind = ElnaLexerKind.word then
- _write_s(stderr, "WORD")
- elsif kind = ElnaLexerKind._goto then
+ if kind = ElnaLexerKind._goto then
_write_s(stderr, "\"goto\"")
elsif kind = ElnaLexerKind.eof then
_write_s(stderr, "EOF")
@@ -5743,6 +5848,7 @@ begin
compiled := elna_list_empty(@error_list);
if compiled then
+ elna_declaration_module_declaration(parser_node);
elna_name_module_declaration(parser_node);
elna_type_module_declaration(parser_node);
tac := elna_tac_module_declaration(parser_node);
@@ -5887,39 +5993,39 @@ begin
word_type^.kind := ElnaTypeKind.primitive;
word_type^.size := 4;
word_type^.alignment := 4;
- current_info := type_info_create(word_type);
+ current_info := elna_symbol_type_info_create(word_type);
elna_symbol_table_enter(symbol_table_global, "Word".ptr, 4, current_info);
int_type := malloc(#size(ElnaType));
int_type^.kind := ElnaTypeKind.primitive;
int_type^.size := 4;
int_type^.alignment := 4;
- current_info := type_info_create(int_type);
+ current_info := elna_symbol_type_info_create(int_type);
elna_symbol_table_enter(symbol_table_global, "Int".ptr, 3, current_info);
current_type := malloc(#size(ElnaType));
current_type^.kind := ElnaTypeKind.primitive;
current_type^.size := 4;
current_type^.alignment := 4;
- current_info := type_info_create(current_type);
+ current_info := elna_symbol_type_info_create(current_type);
elna_symbol_table_enter(symbol_table_global, "Pointer".ptr, 7, current_info);
bool_type := malloc(#size(ElnaType));
bool_type^.kind := ElnaTypeKind.primitive;
bool_type^.size := 1;
bool_type^.alignment := 1;
- current_info := type_info_create(bool_type);
+ current_info := elna_symbol_type_info_create(bool_type);
elna_symbol_table_enter(symbol_table_global, "Bool".ptr, 4, current_info);
char_type := malloc(#size(ElnaType));
char_type^.kind := ElnaTypeKind.primitive;
char_type^.size := 1;
char_type^.alignment := 1;
- current_info := type_info_create(char_type);
+ current_info := elna_symbol_type_info_create(char_type);
elna_symbol_table_enter(symbol_table_global, "Char".ptr, 4, current_info);
elna_symbol_string_build();
- current_info := type_info_create(string_type);
+ current_info := elna_symbol_type_info_create(string_type);
elna_symbol_table_enter(symbol_table_global, "String".ptr, 6, current_info)
end
@@ -6359,8 +6465,6 @@ begin
result^.kind := ElnaLexerKind._or
elsif string_compare(position_start, result_length, "xor") then
result^.kind := ElnaLexerKind._xor
- elsif string_compare(position_start, result_length, "program") then
- result^.kind := ElnaLexerKind._program
elsif string_compare(position_start, result_length, "nil") then
result^.kind := ElnaLexerKind.null
elsif string_compare(position_start, result_length, "true") then