Start stage 21

This commit is contained in:
2026-04-07 21:38:14 +02:00
parent 7c37f7f1c7
commit 4fb6b702b4
3 changed files with 5558 additions and 45 deletions

View File

@@ -8,6 +8,7 @@ program;
(* Stage 20 compiler. *)
(* - Allow program module body. *)
(* - Addition handles adding a number to the pointer by adding multiple of the pointer size. *)
type
ElnaListNode = record
@@ -2067,7 +2068,7 @@ begin
operand^.length := character_literal_node^.length
end;
proc elna_parser_variable_expression(cursor: ^ElnaLexerCursor);
proc elna_parser_variable_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeVariableExpression;
var
result: ^ElnaTreeVariableExpression;
token: ^ElnaLexerToken;
@@ -2448,16 +2449,28 @@ proc elna_tac_sum_create(parser_node: ^ElnaTreeBinaryExpression, lhs: ^ElnaTacOp
var
instruction: ^ElnaTacInstruction;
pointer_type: ^ElnaTypePointer;
variable_expression: ^ElnaTreeVariableExpression;
begin
pointer_type := parser_node^.lhs^.type_decoration;
instruction := elna_tac_instruction_create(ElnaTacOperator.add_ptr);
if parser_node^.operator = ElnaLexerKind.pipe then
instruction := elna_tac_instruction_create(ElnaTacOperator.add_ptr);
elna_tac_make_variable(@operand^.kind, @operand^.value, @operand^.length, symbol_table);
elna_tac_instruction_set_operand(instruction, 1, lhs^.kind, lhs^.value, lhs^.length);
elna_tac_instruction_set_operand(instruction, 2, rhs^.kind, rhs^.value, rhs^.length);
elna_tac_instruction_set_operand(instruction, 3, ElnaTacKind.constant, pointer_type^.base^.size, 0);
elna_tac_instruction_set_operand(instruction, 4, operand^.kind, operand^.value, operand^.length);
elna_tac_make_variable(@operand^.kind, @operand^.value, @operand^.length, symbol_table);
elna_tac_instruction_set_operand(instruction, 1, lhs^.kind, lhs^.value, lhs^.length);
elna_tac_instruction_set_operand(instruction, 2, rhs^.kind, rhs^.value, rhs^.length);
elna_tac_instruction_set_operand(instruction, 3, ElnaTacKind.constant, pointer_type^.base^.size, 0);
elna_tac_instruction_set_operand(instruction, 4, operand^.kind, operand^.value, operand^.length)
elsif pointer_type^.kind = ElnaTypeKind.pointer then
instruction := elna_tac_instruction_create(ElnaTacOperator.add_ptr);
elna_tac_make_variable(@operand^.kind, @operand^.value, @operand^.length, symbol_table);
elna_tac_instruction_set_operand(instruction, 1, lhs^.kind, lhs^.value, lhs^.length);
elna_tac_instruction_set_operand(instruction, 2, rhs^.kind, rhs^.value, rhs^.length);
elna_tac_instruction_set_operand(instruction, 3, ElnaTacKind.constant, pointer_type^.base^.size, 0);
elna_tac_instruction_set_operand(instruction, 4, operand^.kind, operand^.value, operand^.length)
else
instruction := elna_tac_binary_create(ElnaTacOperator.add, lhs, rhs, symbol_table, operand)
end;
return instruction
end;
@@ -2490,7 +2503,7 @@ begin
elna_tac_unary_expression(instructions, parser_node^.rhs, symbol_table, @rhs);
if parser_node^.operator = ElnaLexerKind.plus then
instruction := elna_tac_binary_create(ElnaTacOperator.add, @lhs, @rhs, symbol_table, operand)
instruction := elna_tac_sum_create(parser_node, @lhs, @rhs, symbol_table, operand)
elsif parser_node^.operator = ElnaLexerKind.minus then
instruction := elna_tac_binary_create(ElnaTacOperator.subtract, @lhs, @rhs, symbol_table, operand)
elsif parser_node^.operator = ElnaLexerKind.pipe then
@@ -2594,7 +2607,7 @@ begin
if argument_entry <> nil then
elna_tac_binary_expression(instructions, argument_entry^.expression, symbol_table, arguments_operand);
arguments_operand := arguments_operand + #size(ElnaTacOperand);
arguments_operand := arguments_operand | 1;
argument_entry := argument_entry^.next;
goto elna_tac_call_loop
@@ -2818,7 +2831,7 @@ begin
if string_compare(field_access_expression^.field, field_access_expression^.length, current_field^.name, current_field^.length) = 0 then
field_type := current_field^.field_type;
field_count := field_count - 1;
current_field := current_field + #size(ElnaTypeField);
current_field := current_field | 1;
field_offset := field_offset + field_type^.size;
goto elna_tac_field_access_expression_field
end;
@@ -3421,7 +3434,7 @@ begin
end;
member_array_current^.field_type := field_type;
member_array_current := member_array_current + #size(ElnaTypeField);
member_array_current := member_array_current | 1;
memory_start := memory_start + 4;
memory_start := memory_start^;
@@ -3812,7 +3825,7 @@ begin
variable_map^.count := 0;
count := symbol_table^.count;
current_entry := symbol_table + 4;
current_entry := @symbol_table^.symbols;
.elna_rtl_symbol_table_loop;
if count > 0 then
@@ -3837,7 +3850,7 @@ begin
elna_symbol_table_enter(variable_map, current_entry^.name, current_entry^.length, pseudo_symbol);
count := count - 1;
current_entry := current_entry + #size(ElnaSymbolEntry);
current_entry := current_entry | 1;
goto elna_rtl_symbol_table_loop
end;
@@ -4531,7 +4544,7 @@ begin
if string_compare(parser_node^.field, parser_node^.length, current_field^.name, current_field^.length) = 0 then
field_count := field_count - 1;
current_field := current_field + #size(ElnaTypeField);
current_field := current_field | 1;
goto elna_type_field_access_expression_field
end;
base_type := current_field^.field_type
@@ -4700,7 +4713,7 @@ end;
* symbol_name - Symbol name pointer.
* name_length - Symbol name length.
*
* Returns the symbol pointer or 0 in a0.
* Returns the symbol pointer or nil.
*)
proc elna_symbol_table_lookup(symbol_table: ^ElnaSymbolTable, symbol_name: Word, name_length: Word);
var
@@ -4708,12 +4721,13 @@ var
symbol_table_length: Word;
current_name: Word;
current_length: Word;
current_entry: ^ElnaSymbolEntry;
begin
result := 0;
symbol_table_length := symbol_table^.count;
(* Go to the first symbol position. *)
symbol_table := symbol_table + 4;
current_entry := @symbol_table^.symbols;
.symbol_table_lookup_loop;
if symbol_table_length = 0 then
@@ -4721,9 +4735,8 @@ begin
end;
(* Symbol name pointer and length. *)
current_name := symbol_table^;
current_length := symbol_table + 4;
current_length := current_length^;
current_name := current_entry^.name;
current_length := current_entry^.length;
(* If lengths don't match, exit and return nil. *)
if name_length <> current_length then
@@ -4734,12 +4747,11 @@ begin
goto symbol_table_lookup_repeat
end;
(* Otherwise, the symbol is found. *)
result := symbol_table + 8;
result := result^;
result := current_entry^.symbol_info;
goto symbol_table_lookup_end;
.symbol_table_lookup_repeat;
symbol_table := symbol_table + 12;
current_entry := current_entry | 1;
symbol_table_length := symbol_table_length - 1;
goto symbol_table_lookup_loop;
@@ -4772,26 +4784,18 @@ end;
*)
proc elna_symbol_table_enter(symbol_table: ^ElnaSymbolTable, symbol_name: Word, name_length: Word, symbol: Word);
var
table_length: Word;
symbol_pointer: Word;
symbol_pointer: ^ElnaSymbolEntry;
begin
(* The first word in the symbol table is its length, get it. *)
table_length := symbol_table^;
(* Calculate the offset for the new symbol. *)
symbol_pointer := table_length * 12;
symbol_pointer := symbol_pointer + 4;
symbol_pointer := symbol_table + symbol_pointer;
symbol_pointer := @symbol_table^.symbols;
symbol_pointer := symbol_pointer | symbol_table^.count;
symbol_pointer^ := symbol_name;
symbol_pointer := symbol_pointer + 4;
symbol_pointer^ := name_length;
symbol_pointer := symbol_pointer + 4;
symbol_pointer^ := symbol;
symbol_pointer^.name := symbol_name;
symbol_pointer^.length := name_length;
symbol_pointer^.symbol_info := symbol;
(* Increment the symbol table length. *)
table_length := table_length + 1;
symbol_table^ := table_length
symbol_table^.count := symbol_table^.count + 1
end;
proc elna_symbol_table_build();
@@ -5531,11 +5535,3 @@ begin
exit(4)
end
end;
proc f();
var
x: Word;
y: Word;
begin
x := y
end;

5517
boot/stage21/cl.elna Normal file

File diff suppressed because it is too large Load Diff

0
boot/stage21/linker.arg Normal file
View File