Allow enumeration field types

This commit is contained in:
2026-01-05 18:24:03 +01:00
parent 955161b36e
commit e4257b08be
3 changed files with 56 additions and 59 deletions

View File

@@ -25,11 +25,10 @@ task default: :boot
desc 'Final stage' desc 'Final stage'
task boot: "build/valid/#{STAGES.last}/cl" task boot: "build/valid/#{STAGES.last}/cl"
task boot: "build/valid/#{STAGES.last}/cl.s"
task boot: "boot/#{STAGES.last}/cl.elna" do |t| task boot: "boot/#{STAGES.last}/cl.elna" do |t|
groupped = t.prerequisites.group_by { |stage| File.extname stage }.transform_values(&:first) groupped = t.prerequisites.group_by { |stage| File.extname stage }.transform_values(&:first)
exe = groupped[''] exe = groupped['']
expected = groupped['.s'] expected = groupped[''] + '.s'
source = groupped['.elna'] source = groupped['.elna']
cat_arguments = ['cat', source] cat_arguments = ['cat', source]
@@ -46,6 +45,10 @@ task :convert do
end end
end end
file "build/valid/#{STAGES.last}/cl" => 'build/build.ninja' do |t|
sh 'ninja', '-f', t.prerequisites.first
end
file 'build/build.ninja' => ['build'] do |t| file 'build/build.ninja' => ['build'] do |t|
File.open t.name, 'w' do |f| File.open t.name, 'w' do |f|
f << <<~NINJA f << <<~NINJA

View File

@@ -10,6 +10,7 @@ program;
(* - true and false boolean literals. *) (* - true and false boolean literals. *)
(* - the number of local variables is not limited. *) (* - the number of local variables is not limited. *)
(* - #size(T). *) (* - #size(T). *)
(* - Support enumerations as record field type. *)
type type
(** (**
@@ -2032,9 +2033,6 @@ var
result: ^ElnaTreeTraitExpression; result: ^ElnaTreeTraitExpression;
token_kind: Word; token_kind: Word;
begin begin
printf("# Comment\n\0");
fflush(nil);
result := malloc(ElnaTreeTraitExpression_size()); result := malloc(ElnaTreeTraitExpression_size());
result^.kind := ElnaTreeKind.trait_expression; result^.kind := ElnaTreeKind.trait_expression;
@@ -2709,14 +2707,14 @@ begin
elsif parser_node^.kind = ElnaTreeKind.field_access_expression then elsif parser_node^.kind = ElnaTreeKind.field_access_expression then
field_access_expression := parser_node; field_access_expression := parser_node;
expression_type := field_access_expression^.type_decoration; expression_type := field_access_expression^.type_decoration;
designator_base := field_access_expression^.aggregate;
aggregate_type := designator_base^.type_decoration;
if expression_type^.kind = ElnaTypeKind.enumeration then if aggregate_type = nil then
first_instruction := elna_tac_enumeration_value(field_access_expression, operand_type, operand_value, operand_length); first_instruction := elna_tac_enumeration_value(field_access_expression, operand_type, operand_value, operand_length);
is_address^ := 0 is_address^ := 0
else else
designator_base := field_access_expression^.aggregate;
first_instruction := elna_tac_designator(designator_base, symbol_table, is_address, operand_type, operand_value, operand_length); first_instruction := elna_tac_designator(designator_base, symbol_table, is_address, operand_type, operand_value, operand_length);
aggregate_type := designator_base^.type_decoration;
field_count := aggregate_type^.length; field_count := aggregate_type^.length;
current_field := aggregate_type^.members; current_field := aggregate_type^.members;

View File

@@ -56,59 +56,59 @@ type
trait_expression trait_expression
); );
ElnaTreeNode = record ElnaTreeNode = record
kind: Word kind: ElnaTreeKind
end; end;
ElnaTreeExpression = record ElnaTreeExpression = record
kind: Word; kind: ElnaTreeKind;
type_decoration: Word type_decoration: Word
end; end;
ElnaTreeIntegerLiteral = record ElnaTreeIntegerLiteral = record
kind: Word; kind: ElnaTreeKind;
type_decoration: Word; type_decoration: Word;
value: Word; value: Word;
length: Word length: Word
end; end;
ElnaTreeCharacterLiteral = record ElnaTreeCharacterLiteral = record
kind: Word; kind: ElnaTreeKind;
type_decoration: Word; type_decoration: Word;
value: Word; value: Word;
length: Word length: Word
end; end;
ElnaTreeNilLiteral = record ElnaTreeNilLiteral = record
kind: Word; kind: ElnaTreeKind;
type_decoration: Word type_decoration: Word
end; end;
ElnaTreeBooleanLiteral = record ElnaTreeBooleanLiteral = record
kind: Word; kind: ElnaTreeKind;
type_decoration: Word; type_decoration: Word;
value: Word value: Word
end; end;
ElnaTreeVariableExpression = record ElnaTreeVariableExpression = record
kind: Word; kind: ElnaTreeKind;
type_decoration: Word; type_decoration: Word;
name: Word; name: Word;
length: Word length: Word
end; end;
ElnaTreeStringLiteral = record ElnaTreeStringLiteral = record
kind: Word; kind: ElnaTreeKind;
type_decoration: Word; type_decoration: Word;
value: Word; value: Word;
length: Word length: Word
end; end;
ElnaTreeDereferenceExpression = record ElnaTreeDereferenceExpression = record
kind: Word; kind: ElnaTreeKind;
type_decoration: Word; type_decoration: Word;
pointer: Word pointer: Word
end; end;
ElnaTreeBinaryExpression = record ElnaTreeBinaryExpression = record
kind: Word; kind: ElnaTreeKind;
type_decoration: Word; type_decoration: Word;
lhs: Word; lhs: Word;
rhs: Word; rhs: Word;
operator: Word operator: Word
end; end;
ElnaTreeUnaryExpression = record ElnaTreeUnaryExpression = record
kind: Word; kind: ElnaTreeKind;
type_decoration: Word; type_decoration: Word;
operand: Word; operand: Word;
operator: Word operator: Word
@@ -119,71 +119,71 @@ type
* statement in the statement list. * statement in the statement list.
*) *)
ElnaTreeStatement = record ElnaTreeStatement = record
kind: Word; kind: ElnaTreeKind;
next: Word next: Word
end; end;
ElnaTreeIfStatement = record ElnaTreeIfStatement = record
kind: Word; kind: ElnaTreeKind;
next: Word; next: Word;
conditionals: Word; conditionals: Word;
_else: Word _else: Word
end; end;
ElnaTreeGotoStatement = record ElnaTreeGotoStatement = record
kind: Word; kind: ElnaTreeKind;
next: Word; next: Word;
label: Word; label: Word;
length: Word length: Word
end; end;
ElnaTreeAssignStatement = record ElnaTreeAssignStatement = record
kind: Word; kind: ElnaTreeKind;
next: Word; next: Word;
assignee: Word; assignee: Word;
assignment: Word assignment: Word
end; end;
ElnaTreeReturnStatement = record ElnaTreeReturnStatement = record
kind: Word; kind: ElnaTreeKind;
next: Word; next: Word;
returned: Word returned: Word
end; end;
ElnaTreeLabelDeclaration = record ElnaTreeLabelDeclaration = record
kind: Word; kind: ElnaTreeKind;
next: Word; next: Word;
label: Word; label: Word;
length: Word length: Word
end; end;
ElnaTreeFieldAccessExpression = record ElnaTreeFieldAccessExpression = record
kind: Word; kind: ElnaTreeKind;
type_decoration: Word; type_decoration: Word;
aggregate: Word; aggregate: Word;
field: Word; field: Word;
length: Word length: Word
end; end;
ElnaTreeEnumerationTypeExpression = record ElnaTreeEnumerationTypeExpression = record
kind: Word; kind: ElnaTreeKind;
members: Word; members: Word;
length: Word length: Word
end; end;
ElnaTreeRecordTypeExpression = record ElnaTreeRecordTypeExpression = record
kind: Word; kind: ElnaTreeKind;
members: Word; members: Word;
length: Word length: Word
end; end;
ElnaTreeNamedTypeExpression = record ElnaTreeNamedTypeExpression = record
kind: Word; kind: ElnaTreeKind;
name: Word; name: Word;
length: Word length: Word
end; end;
ElnaTreePointerTypeExpression = record ElnaTreePointerTypeExpression = record
kind: Word; kind: ElnaTreeKind;
base: Word base: Word
end; end;
ElnaTreeArrayTypeExpression = record ElnaTreeArrayTypeExpression = record
kind: Word; kind: ElnaTreeKind;
base: Word; base: Word;
length: Word length: Word
end; end;
ElnaTreeTraitExpression = record ElnaTreeTraitExpression = record
kind: Word; kind: ElnaTreeKind;
name: Word; name: Word;
length: Word; length: Word;
argument: Word argument: Word
@@ -198,19 +198,19 @@ type
next: Word next: Word
end; end;
ElnaTreeDeclaration = record ElnaTreeDeclaration = record
kind: Word; kind: ElnaTreeKind;
next: Word; next: Word;
name: Word; name: Word;
length: Word length: Word
end; end;
ElnaTreeModuleDeclaration = record ElnaTreeModuleDeclaration = record
kind: Word; kind: ElnaTreeKind;
types: Word; types: Word;
globals: Word; globals: Word;
procedures: Word procedures: Word
end; end;
ElnaTreeProcedureDeclaration = record ElnaTreeProcedureDeclaration = record
kind: Word; kind: ElnaTreeKind;
next: Word; next: Word;
name: Word; name: Word;
length: Word; length: Word;
@@ -219,66 +219,69 @@ type
parameters: Word parameters: Word
end; end;
ElnaTreeTypeDeclaration = record ElnaTreeTypeDeclaration = record
kind: Word; kind: ElnaTreeKind;
next: Word; next: Word;
name: Word; name: Word;
length: Word; length: Word;
_type: Word _type: Word
end; end;
ElnaTreeVariableDeclaration = record ElnaTreeVariableDeclaration = record
kind: Word; kind: ElnaTreeKind;
next: Word; next: Word;
name: Word; name: Word;
length: Word; length: Word;
_type: Word _type: Word
end; end;
(* Type representation. *)
ElnaSymbolInfoKind = (type_info, parameter_info, temporary_info, procedure_info);
ElnaTypeKind = (primitive, enumeration, _record, pointer, array);
ElnaType = record ElnaType = record
kind: Word; kind: ElnaTypeKind;
size: Word size: Word
end; end;
ElnaTypeEnumeration = record ElnaTypeEnumeration = record
kind: Word; kind: ElnaTypeKind;
size: Word; size: Word;
members: Word; members: Word;
length: Word length: Word
end; end;
ElnaTypeField = record ElnaTypeField = record
name: Word; name: ElnaTypeKind;
length: Word; length: Word;
field_type: Word field_type: Word
end; end;
ElnaTypeRecord = record ElnaTypeRecord = record
kind: Word; kind: ElnaTypeKind;
size: Word; size: Word;
members: Word; members: Word;
length: Word length: Word
end; end;
ElnaTypePointer = record ElnaTypePointer = record
kind: Word; kind: ElnaTypeKind;
size: Word; size: Word;
base: Word base: Word
end; end;
ElnaTypeArray = record ElnaTypeArray = record
kind: Word; kind: ElnaTypeKind;
size: Word; size: Word;
base: Word; base: Word;
length: Word length: Word
end; end;
ElnaSymbolInfo = record ElnaSymbolInfo = record
kind: Word kind: ElnaSymbolInfoKind
end; end;
ElnaSymbolTypeInfo = record ElnaSymbolTypeInfo = record
kind: Word; kind: ElnaSymbolInfoKind;
_type: Word _type: Word
end; end;
ElnaSymbolTemporaryInfo = record ElnaSymbolTemporaryInfo = record
kind: Word; kind: ElnaSymbolInfoKind;
offset: Word; offset: Word;
variable_type: Word variable_type: Word
end; end;
ElnaSymbolProcedureInfo = record ElnaSymbolProcedureInfo = record
kind: Word; kind: ElnaSymbolInfoKind;
symbol_table: Word symbol_table: Word
end; end;
@@ -413,8 +416,6 @@ type
eof eof
); );
ElnaSymbolInfoKind = (type_info, parameter_info, temporary_info, procedure_info);
ElnaTypeKind = (primitive, enumeration, _record, pointer, array);
ElnaTacOperator = ( ElnaTacOperator = (
get_address, get_address,
add, add,
@@ -2031,9 +2032,6 @@ var
result: ^ElnaTreeTraitExpression; result: ^ElnaTreeTraitExpression;
token_kind: Word; token_kind: Word;
begin begin
printf("# Comment\n\0");
fflush(nil);
result := malloc(#size(ElnaTreeTraitExpression)); result := malloc(#size(ElnaTreeTraitExpression));
result^.kind := ElnaTreeKind.trait_expression; result^.kind := ElnaTreeKind.trait_expression;
@@ -2697,14 +2695,14 @@ begin
elsif parser_node^.kind = ElnaTreeKind.field_access_expression then elsif parser_node^.kind = ElnaTreeKind.field_access_expression then
field_access_expression := parser_node; field_access_expression := parser_node;
expression_type := field_access_expression^.type_decoration; expression_type := field_access_expression^.type_decoration;
designator_base := field_access_expression^.aggregate;
aggregate_type := designator_base^.type_decoration;
if expression_type^.kind = ElnaTypeKind.enumeration then if aggregate_type = nil then
first_instruction := elna_tac_enumeration_value(field_access_expression, operand_type, operand_value, operand_length); first_instruction := elna_tac_enumeration_value(field_access_expression, operand_type, operand_value, operand_length);
is_address^ := 0 is_address^ := 0
else else
designator_base := field_access_expression^.aggregate;
first_instruction := elna_tac_designator(designator_base, symbol_table, is_address, operand_type, operand_value, operand_length); first_instruction := elna_tac_designator(designator_base, symbol_table, is_address, operand_type, operand_value, operand_length);
aggregate_type := designator_base^.type_decoration;
field_count := aggregate_type^.length; field_count := aggregate_type^.length;
current_field := aggregate_type^.members; current_field := aggregate_type^.members;
@@ -3390,7 +3388,6 @@ var
member_count: Word; member_count: Word;
member_array_start: Word; member_array_start: Word;
member_array_current: ^ElnaTypeField; member_array_current: ^ElnaTypeField;
field_definition_size: Word;
field_type: Word; field_type: Word;
begin begin
result := malloc(#size(ElnaTypeRecord)); result := malloc(#size(ElnaTypeRecord));
@@ -3398,8 +3395,7 @@ begin
memory_start := parser_node^.members; memory_start := parser_node^.members;
member_count := parser_node^.length; member_count := parser_node^.length;
field_definition_size := #size(ElnaTypeField); member_array_start := malloc(member_count * #size(ElnaTypeField));
member_array_start := malloc(member_count * field_definition_size);
member_array_current := member_array_start; member_array_current := member_array_start;
.elna_name_type_record_loop; .elna_name_type_record_loop;
@@ -3413,7 +3409,7 @@ begin
field_type := elna_name_type_expression(memory_start^); field_type := elna_name_type_expression(memory_start^);
member_array_current^.field_type := field_type; member_array_current^.field_type := field_type;
member_array_current := member_array_current + field_definition_size; member_array_current := member_array_current + #size(ElnaTypeField);
memory_start := memory_start + 4; memory_start := memory_start + 4;
memory_start := memory_start^; memory_start := memory_start^;