Lower global static array and record access

This commit is contained in:
2026-01-30 23:21:19 +01:00
parent 08b5325f58
commit a00f0d57b8
3 changed files with 323 additions and 462 deletions

View File

@@ -38,47 +38,14 @@ end
desc 'Convert previous stage language into the current stage language'
task :convert do
File.open('boot/stage19/cl.elna', 'w') do |current_stage|
File.readlines('boot/stage18/cl.elna').each do |line|
current_stage << "\tf();\n" if line.include? "if _compile() then"
File.open('boot/stage20/cl.elna', 'w') do |current_stage|
File.readlines('boot/stage19/cl.elna').each do |line|
if line.include? "_assign_at(@classification, 1, ElnaLexerClass.eof)"
current_stage << "\tclassification[1] := ElnaLexerClass.eof;\n"
else
current_stage << line
if line == "type\n"
current_stage << <<-RECORD
Pair = record
first: Word;
second: Word
end;
R1 = record
field1: Word;
field2: [4]Word;
field3: Word
end;
R2 = record
field1: Word;
field3: Word;
field4: Word;
field5: Word;
field6: Word;
field2: Word
end;
RECORD
end
end
current_stage << <<~EPILOGUE
proc f();
var
v1: Word;
r: ^R1;
begin
r := malloc(#size(R1));
v1 := r^.field2[2];
printf("# %i\\n\\0", v1)
end;
EPILOGUE
end
end

View File

@@ -7,8 +7,9 @@ program;
(* Stage 18 compiler. *)
(* - Record fields can be aggregates themselves *)
(* - Record fields can be aggregates themselves. *)
(* - Static arrays. *)
(* - Global variables can have any valid type. *)
type
(**
@@ -2799,10 +2800,21 @@ begin
field_offset := field_offset + field_type^.size;
goto elna_tac_field_access_expression_field
end;
if is_address then
last_instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
_elna_tac_instruction_set_operand(last_instruction, 1, ElnaTacOperand.pseudo, "$unary", 6);
_elna_tac_instruction_set_operand(last_instruction, 2, operand_type^, operand_value^, operand_length^)
else
last_instruction := _elna_tac_instruction_create(ElnaTacOperator.get_address);
_elna_tac_instruction_set_operand(last_instruction, 1, ElnaTacOperand.pseudo, "$unary", 6);
_elna_tac_instruction_set_operand(last_instruction, 2, operand_type^, operand_value^, operand_length^)
end;
first_instruction := elna_instruction_list_concatenate(first_instruction, last_instruction);
last_instruction := _elna_tac_instruction_create(ElnaTacOperator.add);
_elna_tac_instruction_set_operand(last_instruction, 1, ElnaTacOperand.pseudo, "$unary", 6);
_elna_tac_instruction_set_operand(last_instruction, 2, ElnaTacOperand.immediate, field_offset, 0);
_elna_tac_instruction_set_operand(last_instruction, 3, operand_type^, operand_value^, operand_length^);
_elna_tac_instruction_set_operand(last_instruction, 3, ElnaTacOperand.pseudo, "$unary", 6);
operand_type^ := ElnaTacOperand.pseudo;
operand_value^ := "$unary";
@@ -2845,14 +2857,27 @@ begin
index_instructions := elna_instruction_list_concatenate(index_instructions, add_instruction);
array_instructions := elna_tac_designator(array_access_expression^.array, symbol_table, @is_address, operand_type, operand_value, operand_length);
elna_instruction_list_concatenate(offset_instruction, array_instructions);
if is_address then
array_instructions := _elna_tac_instruction_create(ElnaTacOperator.copy);
_elna_tac_instruction_set_operand(array_instructions, 1, ElnaTacOperand.pseudo, "$unary", 6);
_elna_tac_instruction_set_operand(array_instructions, 2, operand_type^, operand_value^, operand_length^)
else
array_instructions := _elna_tac_instruction_create(ElnaTacOperator.get_address);
_elna_tac_instruction_set_operand(array_instructions, 1, ElnaTacOperand.pseudo, "$unary", 6);
_elna_tac_instruction_set_operand(array_instructions, 2, operand_type^, operand_value^, operand_length^)
end;
elna_instruction_list_concatenate(offset_instruction, array_instructions);
operand_type^ := ElnaTacOperand.pseudo;
operand_value^ := "$unary";
operand_length^ := 6;
add_instruction := _elna_tac_instruction_create(ElnaTacOperator.add);
_elna_tac_instruction_set_operand(add_instruction, 1, operand_type^, operand_value^, operand_length^);
_elna_tac_instruction_set_operand(add_instruction, 2, operand_type^, operand_value^, operand_length^);
_elna_tac_instruction_set_operand(add_instruction, 3, ElnaTacOperand.pseudo, "$lhs", 4);
elna_instruction_list_concatenate(offset_instruction, array_instructions);
return elna_instruction_list_concatenate(index_instructions, add_instruction)
end;
@@ -4171,29 +4196,21 @@ proc elna_tac_variable_declaration(parser_tree: ^ElnaTreeVariableDeclaration);
var
name: Word;
name_length: Word;
variable_type: ^ElnaTreeNamedTypeExpression;
variable_type: ^ElnaType;
result: ^ElnaInstructionDeclaration;
variable_info: ^ElnaSymbolTemporaryInfo;
begin
result := malloc(#size(ElnaInstructionDeclaration));
result^.next := nil;
name := parser_tree^.name;
name_length := parser_tree^.length;
variable_type := parser_tree^._type;
variable_info := _symbol_table_lookup(@symbol_table_global, name, name_length);
variable_type := variable_info^.variable_type;
result^.next := nil;
result^.name := name;
result^.length := name_length;
result^.body := variable_type^.size;
name := variable_type^.name;
name_length := variable_type^.length;
if string_compare("Array", 5, name, name_length) then
(* Else we assume this is a zeroed 4096 bytes big array. *)
result^.body := 4096
else
result^.body := 4
end;
return result
end;

File diff suppressed because it is too large Load Diff