summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-06-24 00:03:14 +0200
committerEugen Wissner <belka@caraus.de>2026-06-24 00:03:14 +0200
commitdd663f51bf8680f87d24569d01e2d86ed308304d (patch)
tree15bf94b3a6adbd11d7c74e31617641adc5b86fd9
parent75a44e9c3c0e92b7c9c24d2e88b092ff303b70ed (diff)
downloadelna-dd663f51bf8680f87d24569d01e2d86ed308304d.tar.gz
Add source code position to AST nodes
-rw-r--r--boot/stage24/cl.elna318
1 files changed, 214 insertions, 104 deletions
diff --git a/boot/stage24/cl.elna b/boot/stage24/cl.elna
index 8b64551..da99621 100644
--- a/boot/stage24/cl.elna
+++ b/boot/stage24/cl.elna
@@ -115,57 +115,69 @@ type
_cast
)
ElnaTreeNode = record
- kind: ElnaTreeKind
+ kind: ElnaTreeKind;
+ position: ElnaPosition
end
ElnaTreeTypeExpression = record
- kind: ElnaTreeKind
+ kind: ElnaTreeKind;
+ position: ElnaPosition
end
ElnaTreeExpression = record
kind: ElnaTreeKind;
+ position: ElnaPosition;
type_decoration: ^ElnaType
end
ElnaTreeIntegerLiteral = record
kind: ElnaTreeKind;
+ position: ElnaPosition;
type_decoration: ^ElnaType;
value: Word
end
ElnaTreeCharacterLiteral = record
kind: ElnaTreeKind;
+ position: ElnaPosition;
type_decoration: ^ElnaType;
value: Char
end
ElnaTreeNilLiteral = record
kind: ElnaTreeKind;
+ position: ElnaPosition;
type_decoration: ^ElnaType
end
ElnaTreeBooleanLiteral = record
kind: ElnaTreeKind;
+ position: ElnaPosition;
type_decoration: ^ElnaType;
value: Bool
end
ElnaTreeStringLiteral = record
kind: ElnaTreeKind;
+ position: ElnaPosition;
type_decoration: ^ElnaType;
value: String
end
ElnaTreeVariableExpression = record
kind: ElnaTreeKind;
+ position: ElnaPosition;
type_decoration: ^ElnaType;
name: String
end
ElnaTreeCastExpression = record
kind: ElnaTreeKind;
+ position: ElnaPosition;
type_decoration: ^ElnaType;
expression: ^ElnaTreeExpression;
type_expression: ^ElnaTreeTypeExpression
end
ElnaTreeDereferenceExpression = record
kind: ElnaTreeKind;
+ position: ElnaPosition;
type_decoration: ^ElnaType;
pointer: Word
end
ElnaTreeBinaryExpression = record
kind: ElnaTreeKind;
+ position: ElnaPosition;
type_decoration: ^ElnaType;
lhs: ^ElnaTreeExpression;
rhs: ^ElnaTreeExpression;
@@ -173,6 +185,7 @@ type
end
ElnaTreeUnaryExpression = record
kind: ElnaTreeKind;
+ position: ElnaPosition;
type_decoration: ^ElnaType;
operand: ^ElnaTreeExpression;
operator: Word
@@ -184,6 +197,7 @@ type
*)
ElnaTreeStatement = record
kind: ElnaTreeKind;
+ position: ElnaPosition;
next: ^ElnaTreeStatement
end
(**
@@ -197,39 +211,46 @@ type
end
ElnaTreeIfStatement = record
kind: ElnaTreeKind;
+ position: ElnaPosition;
next: ^ElnaTreeStatement;
conditionals: ^ElnaTreeConditionalStatements;
_else: ^ElnaTreeStatement
end
ElnaTreeGotoStatement = record
kind: ElnaTreeKind;
+ position: ElnaPosition;
next: ^ElnaTreeStatement;
label: String
end
ElnaTreeAssignStatement = record
kind: ElnaTreeKind;
+ position: ElnaPosition;
next: ^ElnaTreeStatement;
assignee: Word;
assignment: ^ElnaTreeExpression
end
ElnaTreeReturnStatement = record
kind: ElnaTreeKind;
+ position: ElnaPosition;
next: ^ElnaTreeStatement;
returned: ^ElnaTreeExpression
end
ElnaTreeLabelDeclaration = record
kind: ElnaTreeKind;
+ position: ElnaPosition;
next: ^ElnaTreeStatement;
label: String
end
ElnaTreeFieldAccessExpression = record
kind: ElnaTreeKind;
+ position: ElnaPosition;
type_decoration: ^ElnaType;
aggregate: Word;
field: String
end
ElnaTreeArrayAccessExpression = record
kind: ElnaTreeKind;
+ position: ElnaPosition;
type_decoration: ^ElnaType;
array: Word;
index: ^ElnaTreeExpression
@@ -240,6 +261,7 @@ type
end
ElnaTreeEnumerationTypeExpression = record
kind: ElnaTreeKind;
+ position: ElnaPosition;
members: ^ElnaTreeEnumeration;
length: Word
end
@@ -250,40 +272,48 @@ type
end
ElnaTreeRecordTypeExpression = record
kind: ElnaTreeKind;
+ position: ElnaPosition;
members: ^ElnaTreeField;
length: Word
end
ElnaTreeNamedTypeExpression = record
kind: ElnaTreeKind;
+ position: ElnaPosition;
name: String
end
ElnaTreePointerTypeExpression = record
kind: ElnaTreeKind;
+ position: ElnaPosition;
base: ^ElnaTreeTypeExpression
end
ElnaTreeArrayTypeExpression = record
kind: ElnaTreeKind;
+ position: ElnaPosition;
base: ^ElnaTreeTypeExpression;
length: ^ElnaTreeExpression
end
ElnaTreeTraitExpression = record
kind: ElnaTreeKind;
+ position: ElnaPosition;
name: String;
argument: ^ElnaTreeTypeExpression
end
ElnaTreeDeclaration = record
kind: ElnaTreeKind;
+ position: ElnaPosition;
next: ^ElnaTreeDeclaration;
name: String
end
ElnaTreeVariableDeclaration = record
kind: ElnaTreeKind;
+ position: ElnaPosition;
next: ^ElnaTreeDeclaration;
name: String;
type_expression: ^ElnaTreeTypeExpression
end
ElnaTreeProcedureDeclaration = record
kind: ElnaTreeKind;
+ position: ElnaPosition;
next: ^ElnaTreeDeclaration;
name: String;
body: ^ElnaTreeStatement;
@@ -294,6 +324,7 @@ type
end
ElnaTreeModuleDeclaration = record
kind: ElnaTreeKind;
+ position: ElnaPosition;
types: ^ElnaTreeDeclaration;
globals: ^ElnaTreeVariableDeclaration;
procedures: ^ElnaTreeProcedureDeclaration;
@@ -301,6 +332,7 @@ type
end
ElnaTreeTypeDeclaration = record
kind: ElnaTreeKind;
+ position: ElnaPosition;
next: ^ElnaTreeDeclaration;
name: String;
type_expression: ^ElnaTreeTypeExpression
@@ -311,6 +343,7 @@ type
end
ElnaTreeCall = record
kind: ElnaTreeKind;
+ position: ElnaPosition;
type_decoration: ^ElnaType;
callee: ^ElnaTreeVariableExpression;
arguments: ^ElnaTreeExpressionList;
@@ -318,6 +351,7 @@ type
end
ElnaTreeCallStatement = record
kind: ElnaTreeKind;
+ position: ElnaPosition;
next: ^ElnaTreeStatement;
call: ^ElnaTreeCall
end
@@ -507,7 +541,7 @@ type
add_ptr,
nop
)
- ElnaTacKind = (list, label, constant, variable)
+ ElnaTacKind = (list, label, constant, variable, ignore)
(*
- If value is a variable or label, length is its name length.
@@ -658,7 +692,7 @@ type
allocated: Bool
end
- ElnaErrorKind = (unexpected_token)
+ ElnaErrorKind = (unexpected_token, undefined_symbol)
ElnaError = record
next: ^ElnaListNode;
kind: ElnaErrorKind;
@@ -672,6 +706,12 @@ type
possibilities: Word;
got: ElnaLexerKind
end
+ ElnaErrorUndefinedSymbol = record
+ next: ^ElnaListNode;
+ kind: ElnaErrorKind;
+ position: ElnaPosition;
+ symbol_name: String
+ end
var
symbol_table_global: ^ElnaSymbolTable
@@ -711,13 +751,13 @@ extern
proc free(ptr: Pointer)
extern
-proc memcpy(dst: Pointer, src: Pointer, n: Word)
+proc memcpy(dst: Pointer, src: Pointer, n: Word) -> Pointer
extern
-proc memcmp(s1: Pointer, s2: Pointer, n: Word)
+proc memcmp(s1: Pointer, s2: Pointer, n: Word) -> Int
extern
-proc memset(b: Pointer, c: Int, len: Word)
+proc memset(b: Pointer, c: Int, len: Word) -> Pointer
extern
proc strlen(s: ^Char) -> Word
@@ -735,6 +775,9 @@ extern
proc atoi(str: ^Char) -> Int
extern
+proc exit(status: Int)
+extern
+
proc free_and_nil(pointer: Pointer) -> Pointer
begin
free(pointer);
@@ -956,7 +999,7 @@ begin
return result
end
-proc elna_rtl_instruction_set_operand(this: ^ElnaRtlInstruction, n: Word, operand_type: Word,
+proc elna_rtl_instruction_set_operand(this: ^ElnaRtlInstruction, n: Word, operand_type: ElnaRtlKind,
operand_value: Word, operand_length: Word, operand_offset: Word)
begin
this^.operands[n].kind := operand_type;
@@ -1276,37 +1319,39 @@ begin
tac_instruction^.operands[1].value, tac_instruction^.operands[1].length, 0);
elna_list_append(instructions, instruction);
- pseudo_symbol := elna_symbol_table_lookup(variable_map, tac_instruction^.operands[3].value, tac_instruction^.operands[3].length);
+ if tac_instruction^.operands[3].kind = ElnaTacKind.variable then
+ pseudo_symbol := elna_symbol_table_lookup(variable_map, tac_instruction^.operands[3].value, tac_instruction^.operands[3].length);
- if pseudo_symbol^.rtl_type^.kind = ElnaRtlTypeKind.byte_array then
- target_operand.kind := ElnaRtlKind.register;
- target_operand.value := ElnaRtlRegister.t0;
- target_operand.length := 0;
- target_operand.offset := 0;
- long_word_type := elna_rtl_constant_type(4);
+ if pseudo_symbol^.rtl_type^.kind = ElnaRtlTypeKind.byte_array then
+ target_operand.kind := ElnaRtlKind.register;
+ target_operand.value := ElnaRtlRegister.t0;
+ target_operand.length := 0;
+ target_operand.offset := 0;
+ long_word_type := elna_rtl_constant_type(4);
- instruction := elna_rtl_variable_address(variable_map, pseudo_symbol, @tac_instruction^.operands[3], @target_operand);
- elna_list_append(instructions, instruction);
+ instruction := elna_rtl_variable_address(variable_map, pseudo_symbol, @tac_instruction^.operands[3], @target_operand);
+ elna_list_append(instructions, instruction);
- instruction := elna_rtl_instruction_create(ElnaRtlOperator.sw);
- elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a0, 0, 0);
- elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.memory,
- target_operand.value, target_operand.length, 0);
- instruction^.types[1] := long_word_type;
- elna_list_append(instructions, instruction);
+ instruction := elna_rtl_instruction_create(ElnaRtlOperator.sw);
+ elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a0, 0, 0);
+ elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.memory,
+ target_operand.value, target_operand.length, 0);
+ instruction^.types[1] := long_word_type;
+ elna_list_append(instructions, instruction);
- instruction := elna_rtl_instruction_create(ElnaRtlOperator.sw);
- elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a1, 0, 0);
- elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.memory,
- target_operand.value, target_operand.length, 4);
- instruction^.types[1] := long_word_type;
- elna_list_append(instructions, instruction)
- else
- instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv);
- elna_rtl_instruction_set_operand(instruction, 1, tac_instruction^.operands[3].kind,
- tac_instruction^.operands[3].value, tac_instruction^.operands[3].length, 0);
- elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.a0, 0, 0);
- elna_list_append(instructions, instruction)
+ instruction := elna_rtl_instruction_create(ElnaRtlOperator.sw);
+ elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a1, 0, 0);
+ elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.memory,
+ target_operand.value, target_operand.length, 4);
+ instruction^.types[1] := long_word_type;
+ elna_list_append(instructions, instruction)
+ else
+ instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv);
+ elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo,
+ tac_instruction^.operands[3].value, tac_instruction^.operands[3].length, 0);
+ elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.a0, 0, 0);
+ elna_list_append(instructions, instruction)
+ end
end
end
@@ -2403,6 +2448,7 @@ begin
result^.kind := ElnaTreeKind.integer_literal;
result^.value := atoi(buffer);
result^.type_decoration := nil;
+ result^.position := token^.position;
free(buffer);
@@ -2411,28 +2457,31 @@ end
proc elna_parser_boolean_literal(cursor: ^ElnaLexerCursor) -> ^ElnaTreeBooleanLiteral
var
+ token: ^ElnaLexerToken
result: ^ElnaTreeBooleanLiteral
begin
+ token := elna_lexer_read(cursor);
result := malloc(#size(ElnaTreeBooleanLiteral));
result^.kind := ElnaTreeKind.boolean_literal;
- result^.value := string_compare(cursor^.start, 4, "true");
+ result^.value := string_compare(token^.start.ptr, 4, "true");
result^.type_decoration := nil;
-
- elna_lexer_read(cursor);
+ result^.position := token^.position;
return result
end
proc elna_parser_nil_literal(cursor: ^ElnaLexerCursor) -> ^ElnaTreeNilLiteral
var
+ token: ^ElnaLexerToken
result: ^ElnaTreeNilLiteral
begin
- elna_lexer_read(cursor);
+ token := elna_lexer_read(cursor);
result := malloc(#size(ElnaTreeNilLiteral));
result^.kind := ElnaTreeKind.null;
result^.type_decoration := nil;
+ result^.position := token^.position;
return result
end
@@ -2441,14 +2490,17 @@ proc elna_tac_integer_literal(integer_literal_node: ^ElnaTreeIntegerLiteral, ope
begin
operand^.kind := ElnaTacKind.constant;
operand^.value := integer_literal_node^.value;
- operand^.length := 4
+ operand^.length := word_type^.size
end
proc elna_tac_boolean_literal(boolean_literal_node: ^ElnaTreeBooleanLiteral, operand: ^ElnaTacOperand)
+var
+ current_position: Word
begin
operand^.kind := ElnaTacKind.constant;
- operand^.value := boolean_literal_node^.value;
- operand^.length := 1
+ current_position := boolean_literal_node^.value;
+ operand^.value := current_position;
+ operand^.length := bool_type^.size
end
proc elna_tac_nil_literal(nil_node: Word, operand: ^ElnaTacOperand)
@@ -2517,7 +2569,7 @@ begin
result^.kind := ElnaTreeKind.character_literal;
elna_parser_escape(token^.start.ptr + 1, @result^.value);
-
+ result^.position := token^.position;
result^.type_decoration := nil;
return result
@@ -2530,7 +2582,7 @@ begin
operand^.kind := ElnaTacKind.constant;
current_position := character_literal_node^.value;
operand^.value := current_position;
- operand^.length := 1
+ operand^.length := char_type^.size
end
proc elna_parser_variable_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeVariableExpression
@@ -2543,6 +2595,7 @@ begin
result^.kind := ElnaTreeKind.variable_expression;
result^.name := token^.start;
+ result^.position := token^.position;
result^.type_decoration := nil;
return result
@@ -2583,6 +2636,7 @@ begin
goto elna_parser_escape_loop
end;
result^.value.length := target_position - result^.value.ptr;
+ result^.position := token^.position;
result^.type_decoration := nil;
return result
@@ -2623,7 +2677,6 @@ begin
elna_tac_instruction_set_operand(instruction, 2, operand^.kind, operand^.value, operand^.length);
elna_tac_instruction_set_operand(instruction, 3, ElnaTacKind.constant, 4, 4);
elna_list_append(instructions, instruction)
-
end
proc elna_parser_trait_expression(cursor: ^ElnaLexerCursor, error_list: ^ElnaList) -> ^ElnaTreeTraitExpression
@@ -2636,6 +2689,7 @@ begin
token := elna_lexer_read(cursor);
result^.name := token^.start;
+ result^.position := token^.position;
if elna_parser_expect(cursor, ElnaLexerKind.left_paren, error_list) <> nil then
result^.argument := elna_parser_type_expression(cursor, error_list);
@@ -2660,12 +2714,13 @@ begin
result := nil;
(* Skip the cast keyword and opening paren. *)
- elna_lexer_read(cursor);
+ token := elna_lexer_read(cursor);
if elna_parser_expect(cursor, ElnaLexerKind.left_paren, error_list) = nil then
goto elna_parser_cast_expression_end
end;
result := malloc(#size(ElnaTreeCastExpression));
result^.kind := ElnaTreeKind._cast;
+ result^.position.start_location := token^.position.start_location;
result^.type_decoration := nil;
result^.expression := elna_parser_binary_expression(cursor, error_list);
@@ -2682,9 +2737,13 @@ begin
result := free_and_nil(result);
goto elna_parser_cast_expression_end
end;
- if elna_parser_expect(cursor, ElnaLexerKind.right_paren, error_list) = nil then
- result := free_and_nil(result)
+ token := elna_parser_expect(cursor, ElnaLexerKind.right_paren, error_list);
+ if token = nil then
+ result := free_and_nil(result);
+ goto elna_parser_cast_expression_end
end;
+ result^.position.end_location := token^.position.end_location;
+
.elna_parser_cast_expression_end;
return result
end
@@ -2722,13 +2781,15 @@ proc elna_parser_dereference_expression(cursor: ^ElnaLexerCursor,
simple_expression: ^ElnaTreeExpression) -> ^ElnaTreeDereferenceExpression
var
result: ^ElnaTreeDereferenceExpression
+ token: ^ElnaLexerToken
begin
+ token := elna_lexer_read(cursor);
result := malloc(#size(ElnaTreeDereferenceExpression));
result^.kind := ElnaTreeKind.dereference_expression;
result^.pointer := simple_expression;
result^.type_decoration := nil;
- elna_lexer_read(cursor);
+ result^.position := token^.position;
return result
end
@@ -2840,6 +2901,7 @@ begin
result^.kind := ElnaTreeKind.unary_expression;
result^.operand := operand;
result^.operator := operator;
+ result^.position := token^.position;
result^.type_decoration := nil
end
end;
@@ -2993,6 +3055,7 @@ begin
result^.lhs := lhs_node;
result^.rhs := rhs_node;
result^.operator := token^.kind;
+ result^.position := token^.position;
result^.type_decoration := nil
elsif elna_list_empty(error_list) then
result := lhs_node
@@ -3131,12 +3194,13 @@ begin
result^.count := 0;
result^.callee := callee;
- elna_lexer_read(cursor);
+ token := elna_lexer_read(cursor);
+ result^.position.start_location := token^.position.start_location;
token := elna_lexer_peek(cursor);
if token^.kind = ElnaLexerKind.right_paren then
- elna_lexer_read(cursor);
- goto elna_parser_call_end
+ token := elna_lexer_read(cursor);
+ goto elna_parser_call_close
end;
.elna_parser_call_loop;
@@ -3159,16 +3223,20 @@ begin
elna_lexer_read(cursor);
goto elna_parser_call_loop
elsif token^.kind = ElnaLexerKind.right_paren then
- elna_lexer_read(cursor)
+ token := elna_lexer_read(cursor)
else
parser_error := elna_error_unexpected_token_create(cursor, 2);
parser_error^.expected[1] := ElnaLexerKind.comma;
parser_error^.expected[2] := ElnaLexerKind.right_paren;
elna_list_append(error_list, parser_error);
- result := free_and_nil(result)
+ result := free_and_nil(result);
+ goto elna_parser_call_end
end
end;
+ .elna_parser_call_close;
+ result^.position.end_location := token^.position.end_location;
+
.elna_parser_call_end;
return result
end
@@ -3186,20 +3254,17 @@ begin
arguments_operand := malloc(parsed_call^.count * #size(ElnaTacOperand));
procedure_info := elna_symbol_table_lookup(symbol_table, parsed_expression^.name.ptr, parsed_expression^.name.length);
- (* TODO: procedure_info should never be nil. *)
- if procedure_info = nil then
- elna_tac_make_variable(operand, symbol_table, word_type)
- 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^.procedure_type^.return_type)
- end;
-
call_instruction := elna_tac_instruction_create(ElnaTacOperator.proc_call);
elna_tac_instruction_set_operand(call_instruction, 1, ElnaTacKind.label,
parsed_expression^.name.ptr, parsed_expression^.name.length);
elna_tac_instruction_set_operand(call_instruction, 2, ElnaTacKind.list, arguments_operand, parsed_call^.count);
- elna_tac_instruction_set_operand(call_instruction, 3, operand^.kind, operand^.value, operand^.length);
+
+ if procedure_info^.procedure_type^.return_type = nil then
+ elna_tac_instruction_set_operand(call_instruction, 3, ElnaTacKind.ignore, 0, 0)
+ else
+ elna_tac_make_variable(operand, symbol_table, procedure_info^.procedure_type^.return_type);
+ elna_tac_instruction_set_operand(call_instruction, 3, operand^.kind, operand^.value, operand^.length)
+ end;
argument_entry := parsed_call^.arguments;
.elna_tac_call_loop;
@@ -3220,15 +3285,20 @@ var
token: ^ElnaLexerToken
begin
(* Skip the goto. *)
- elna_lexer_read(cursor);
- token := elna_parser_expect(cursor, ElnaLexerKind.identifier, error_list);
+ token := elna_lexer_read(cursor);
+ result := malloc(#size(ElnaTreeGotoStatement));
+ result^.kind := ElnaTreeKind.goto_statement;
+ result^.next := nil;
+ result^.position.start_location := token^.position.start_location;
+ token := elna_parser_expect(cursor, ElnaLexerKind.identifier, error_list);
if token <> nil then
- result := malloc(#size(ElnaTreeGotoStatement));
- result^.kind := ElnaTreeKind.goto_statement;
- result^.next := nil;
- result^.label := token^.start
+ result^.label := token^.start;
+ result^.position.end_location := token^.position.end_location
+ else
+ result := free_and_nil(result)
end;
+
return result
end
@@ -3254,14 +3324,18 @@ var
result: ^ElnaTreeLabelDeclaration
token: ^ElnaLexerToken
begin
- elna_lexer_read(cursor);
+ token := elna_lexer_read(cursor);
+ result := malloc(#size(ElnaTreeLabelDeclaration));
+ result^.kind := ElnaTreeKind.label_declaration;
+ result^.next := nil;
+ result^.position.start_location := token^.position.start_location;
+
token := elna_parser_expect(cursor, ElnaLexerKind.identifier, error_list);
if token <> nil then
- result := malloc(#size(ElnaTreeLabelDeclaration));
-
- result^.kind := ElnaTreeKind.label_declaration;
- result^.next := nil;
- result^.label := token^.start
+ result^.label := token^.start;
+ result^.position.end_location := token^.position.end_location
+ else
+ result := free_and_nil(result)
end;
return result
end
@@ -3328,15 +3402,18 @@ var
token: ^ElnaLexerToken
begin
(* Skip dot. Read the enumeration value. *)
- elna_lexer_read(cursor);
token := elna_lexer_read(cursor);
result := malloc(#size(ElnaTreeFieldAccessExpression));
-
result^.kind := ElnaTreeKind.field_access_expression;
result^.type_decoration := nil;
result^.aggregate := aggregate;
+ result^.position.start_location := token^.position.start_location;
+
+ token := elna_lexer_read(cursor);
+
result^.field := token^.start;
+ result^.position.end_location := token^.position.end_location;
return result
end
@@ -3345,21 +3422,27 @@ proc elna_parser_array_access_expression(cursor: ^ElnaLexerCursor,
array: ^ElnaTreeExpression, error_list: ^ElnaList) -> ^ElnaTreeArrayAccessExpression
var
result: ^ElnaTreeArrayAccessExpression
+ token: ^ElnaLexerToken
begin
- elna_lexer_read(cursor);
-
+ token := elna_lexer_read(cursor);
result := malloc(#size(ElnaTreeArrayAccessExpression));
result^.kind := ElnaTreeKind.array_access_expression;
result^.type_decoration := nil;
result^.array := array;
+ result^.position.start_location := token^.position.start_location;
+
result^.index := elna_parser_binary_expression(cursor, error_list);
if result^.index = nil then
result := free_and_nil(result)
- elsif elna_parser_expect(cursor, ElnaLexerKind.right_square, error_list) = nil then
- result := free_and_nil(result)
+ else
+ token := elna_parser_expect(cursor, ElnaLexerKind.right_square, error_list);
+ if token = nil then
+ result := free_and_nil(result)
+ else
+ result^.position.end_location := token^.position.end_location
+ end
end;
-
return result
end
@@ -3513,6 +3596,7 @@ end
proc elna_parser_assign_statement(cursor: ^ElnaLexerCursor, assignee: ^ElnaTreeNode, error_list: ^ElnaList) -> ^ElnaTreeAssignStatement
var
+ token: ^ElnaLexerToken
result: ^ElnaTreeAssignStatement
begin
result := malloc(#size(ElnaTreeAssignStatement));
@@ -3523,8 +3607,10 @@ begin
result^.assignment := nil;
(* Skip the assignment sign (:=) with surrounding whitespaces. *)
- if elna_parser_expect(cursor, ElnaLexerKind.assignment, error_list) <> nil then
- result^.assignment := elna_parser_binary_expression(cursor, error_list);
+ token := elna_parser_expect(cursor, ElnaLexerKind.assignment, error_list);
+ if token <> nil then
+ result^.position := token^.position;
+ result^.assignment := elna_parser_binary_expression(cursor, error_list)
end;
if result^.assignment = nil then
result := free_and_nil(result)
@@ -3567,14 +3653,16 @@ end
proc elna_parser_return_statement(cursor: ^ElnaLexerCursor, error_list: ^ElnaList) -> ^ElnaTreeReturnStatement
var
+ token: ^ElnaLexerToken
result: ^ElnaTreeReturnStatement
begin
(* Skip "return" keyword. *)
- elna_lexer_read(cursor);
+ token := elna_lexer_read(cursor);
result := malloc(#size(ElnaTreeReturnStatement));
result^.kind := ElnaTreeKind.return_statement;
result^.next := nil;
+ result^.position := token^.position;
result^.returned := elna_parser_binary_expression(cursor, error_list);
if result^.returned = nil then
result := free_and_nil(result)
@@ -3657,9 +3745,11 @@ var
next_conditional: ^ElnaTreeConditionalStatements
token: ^ElnaLexerToken
begin
+ token := elna_lexer_peek(cursor);
result := malloc(#size(ElnaTreeIfStatement));
result^.kind := ElnaTreeKind.if_statement;
+ result^.position := token^.position;
result^.next := nil;
previous_conditional := elna_parser_conditional_statements(cursor, error_list, ElnaLexerKind._then);
@@ -3713,6 +3803,7 @@ begin
call_result^.kind := ElnaTreeKind.call_statement;
call_result^.next := nil;
call_result^.call := designator;
+ call_result^.position := designator^.position;
result := call_result
end
end
@@ -3836,12 +3927,13 @@ var
token: ^ElnaLexerToken
parser_error: ^ElnaErrorUnexpectedToken
begin
- elna_lexer_read(cursor);
+ token := elna_lexer_read(cursor);
result := malloc(#size(ElnaTreeRecordTypeExpression));
result^.kind := ElnaTreeKind.record_type_expression;
result^.members := nil;
result^.length := 0;
+ result^.position := token^.position;
.elna_parser_record_type_expression_loop;
token := elna_lexer_read(cursor);
@@ -3903,12 +3995,13 @@ var
token: ^ElnaLexerToken
parser_error: ^ElnaErrorUnexpectedToken
begin
- elna_lexer_read(cursor);
+ token := elna_lexer_read(cursor);
result := malloc(#size(ElnaTreeEnumerationTypeExpression));
result^.kind := ElnaTreeKind.enumeration_type_expression;
result^.members := nil;
result^.length := 0;
+ result^.position.start_location := token^.position.start_location;
.elna_parser_enumeration_type_expression_loop;
token := elna_parser_expect(cursor, ElnaLexerKind.identifier, error_list);
@@ -3931,7 +4024,8 @@ begin
elna_lexer_read(cursor);
goto elna_parser_enumeration_type_expression_loop
elsif token^.kind = ElnaLexerKind.right_paren then
- elna_lexer_read(cursor)
+ token := elna_lexer_read(cursor);
+ result^.position.end_location := token^.position.end_location
else
parser_error := elna_error_unexpected_token_create(cursor, 2);
parser_error^.expected[1] := ElnaLexerKind.comma;
@@ -4055,6 +4149,7 @@ begin
result^.kind := ElnaTreeKind.named_type_expression;
result^.name := token^.start;
+ result^.position := token^.position;
return result
end
@@ -4062,12 +4157,15 @@ end
proc elna_parser_pointer_type_expression(cursor: ^ElnaLexerCursor, error_list: ^ElnaList) -> ^ElnaTreePointerTypeExpression
var
result: ^ElnaTreePointerTypeExpression
+ token: ^ElnaLexerToken
begin
- elna_lexer_read(cursor);
+ token := elna_lexer_read(cursor);
result := malloc(#size(ElnaTreePointerTypeExpression));
result^.kind := ElnaTreeKind.pointer_type_expression;
result^.base := elna_parser_type_expression(cursor, error_list);
+ result^.position := token^.position;
+
if result^.base = nil then
result := free_and_nil(result)
end;
@@ -4078,22 +4176,28 @@ end
proc elna_parser_array_type_expression(cursor: ^ElnaLexerCursor, error_list: ^ElnaList) -> ^ElnaTreeArrayTypeExpression
var
result: ^ElnaTreeArrayTypeExpression
+ token: ^ElnaLexerToken
begin
- elna_lexer_read(cursor);
+ token := elna_lexer_read(cursor);
result := malloc(#size(ElnaTreeArrayTypeExpression));
result^.kind := ElnaTreeKind.array_type_expression;
+ result^.position.start_location := token^.position.start_location;
result^.length := elna_parser_binary_expression(cursor, error_list);
if result^.length = nil then
result := free_and_nil(result)
else
- if elna_parser_expect(cursor, ElnaLexerKind.right_square, error_list) = nil then
+ token := elna_parser_expect(cursor, ElnaLexerKind.right_square, error_list);
+
+ if token = nil then
result := free_and_nil(result)
else
result^.base := elna_parser_type_expression(cursor, error_list);
if result^.base = nil then
result := free_and_nil(result)
+ else
+ result^.position.end_location := token^.position.end_location
end
end
end;
@@ -4301,18 +4405,18 @@ var
token: ^ElnaLexerToken
begin
(* Skip "proc ". *)
- elna_lexer_read(cursor);
- result := nil;
+ token := elna_lexer_read(cursor);
+ result := malloc(#size(ElnaTreeProcedureDeclaration));
+ result^.kind := ElnaTreeKind.procedure_declaration;
+ result^.next := nil;
+ result^.position := token^.position;
(* Skip procedure name. *)
token := elna_parser_expect(cursor, ElnaLexerKind.identifier, error_list);
if token = nil then
+ result := free_and_nil(result);
goto elna_parser_procedure_declaration_end
end;
-
- result := malloc(#size(ElnaTreeProcedureDeclaration));
- result^.kind := ElnaTreeKind.procedure_declaration;
- result^.next := nil;
result^.name := token^.start;
if elna_parser_expect(cursor, ElnaLexerKind.left_paren, error_list) = nil then
@@ -4500,7 +4604,7 @@ begin
end
(* Returns whether the provided type is array or record. *)
-proc elna_type_is_aggregate(_type: ^ElnaType)
+proc elna_type_is_aggregate(_type: ^ElnaType) -> Bool
var
lhs: Word
rhs: Word
@@ -4782,6 +4886,7 @@ begin
result^.kind := ElnaTreeKind.type_declaration;
result^.next := nil;
result^.name := token^.start;
+ result^.position := token^.position;
if elna_parser_expect(cursor, ElnaLexerKind.equals, error_list) <> nil then
result^.type_expression := elna_parser_type_expression(cursor, error_list)
@@ -4869,7 +4974,8 @@ begin
result^.kind := ElnaTreeKind.variable_declaration;
result^.next := nil;
result^.name := token^.start;
- result^.type_expression := variable_type
+ result^.type_expression := variable_type;
+ result^.position := token^.position
end
end
end;
@@ -5016,6 +5122,10 @@ begin
result := malloc(#size(ElnaTreeModuleDeclaration));
result^.kind := ElnaTreeKind.module_declaration;
+ result^.position.start_location.line := 1;
+ result^.position.start_location.column := 1;
+ result^.position.end_location := result^.position.start_location;
+
result^.types := elna_parser_type_part(cursor, error_list);
if elna_list_empty(error_list) = false then
result := free_and_nil(result)
@@ -5831,7 +5941,7 @@ begin
end
end
-proc compile()
+proc compile() -> Bool
var
parser_node: Word
tac: Word
@@ -5859,7 +5969,7 @@ begin
else
current_error := error_list.first;
elna_error_print(current_error)
- ind;
+ end;
return compiled
end
@@ -5919,7 +6029,7 @@ end
*
* Returns newly allocated, empty symbol table.
*)
-proc elna_symbol_table_create(parent: ^ElnaSymbolTable)
+proc elna_symbol_table_create(parent: ^ElnaSymbolTable) -> ^ElnaSymbolTable
var
new_symbol_table: ^ElnaSymbolTable
begin
@@ -6177,7 +6287,7 @@ begin
end
end
-proc elna_lexer_get_transition(current_state: Word, character_class: Word)
+proc elna_lexer_get_transition(current_state: Word, character_class: Word) -> Word
var
column_position: Word
target: Word