From e4257b08beeb9279e02cb2a50deec4ad8a7c4135 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Mon, 5 Jan 2026 18:24:03 +0100 Subject: [PATCH] Allow enumeration field types --- Rakefile | 7 +++- boot/stage17/cl.elna | 10 ++--- boot/stage18/cl.elna | 98 +++++++++++++++++++++----------------------- 3 files changed, 56 insertions(+), 59 deletions(-) diff --git a/Rakefile b/Rakefile index 1f175f8..d35b267 100644 --- a/Rakefile +++ b/Rakefile @@ -25,11 +25,10 @@ task default: :boot desc 'Final stage' task boot: "build/valid/#{STAGES.last}/cl" -task boot: "build/valid/#{STAGES.last}/cl.s" task boot: "boot/#{STAGES.last}/cl.elna" do |t| groupped = t.prerequisites.group_by { |stage| File.extname stage }.transform_values(&:first) exe = groupped[''] - expected = groupped['.s'] + expected = groupped[''] + '.s' source = groupped['.elna'] cat_arguments = ['cat', source] @@ -46,6 +45,10 @@ task :convert do 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.open t.name, 'w' do |f| f << <<~NINJA diff --git a/boot/stage17/cl.elna b/boot/stage17/cl.elna index 6ca9ff0..e1a8e81 100644 --- a/boot/stage17/cl.elna +++ b/boot/stage17/cl.elna @@ -10,6 +10,7 @@ program; (* - true and false boolean literals. *) (* - the number of local variables is not limited. *) (* - #size(T). *) +(* - Support enumerations as record field type. *) type (** @@ -2032,9 +2033,6 @@ var result: ^ElnaTreeTraitExpression; token_kind: Word; begin - printf("# Comment\n\0"); - fflush(nil); - result := malloc(ElnaTreeTraitExpression_size()); result^.kind := ElnaTreeKind.trait_expression; @@ -2709,14 +2707,14 @@ begin elsif parser_node^.kind = ElnaTreeKind.field_access_expression then field_access_expression := parser_node; 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); is_address^ := 0 else - designator_base := field_access_expression^.aggregate; 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; current_field := aggregate_type^.members; diff --git a/boot/stage18/cl.elna b/boot/stage18/cl.elna index 44645ae..de2e944 100644 --- a/boot/stage18/cl.elna +++ b/boot/stage18/cl.elna @@ -56,59 +56,59 @@ type trait_expression ); ElnaTreeNode = record - kind: Word + kind: ElnaTreeKind end; ElnaTreeExpression = record - kind: Word; + kind: ElnaTreeKind; type_decoration: Word end; ElnaTreeIntegerLiteral = record - kind: Word; + kind: ElnaTreeKind; type_decoration: Word; value: Word; length: Word end; ElnaTreeCharacterLiteral = record - kind: Word; + kind: ElnaTreeKind; type_decoration: Word; value: Word; length: Word end; ElnaTreeNilLiteral = record - kind: Word; + kind: ElnaTreeKind; type_decoration: Word end; ElnaTreeBooleanLiteral = record - kind: Word; + kind: ElnaTreeKind; type_decoration: Word; value: Word end; ElnaTreeVariableExpression = record - kind: Word; + kind: ElnaTreeKind; type_decoration: Word; name: Word; length: Word end; ElnaTreeStringLiteral = record - kind: Word; + kind: ElnaTreeKind; type_decoration: Word; value: Word; length: Word end; ElnaTreeDereferenceExpression = record - kind: Word; + kind: ElnaTreeKind; type_decoration: Word; pointer: Word end; ElnaTreeBinaryExpression = record - kind: Word; + kind: ElnaTreeKind; type_decoration: Word; lhs: Word; rhs: Word; operator: Word end; ElnaTreeUnaryExpression = record - kind: Word; + kind: ElnaTreeKind; type_decoration: Word; operand: Word; operator: Word @@ -119,71 +119,71 @@ type * statement in the statement list. *) ElnaTreeStatement = record - kind: Word; + kind: ElnaTreeKind; next: Word end; ElnaTreeIfStatement = record - kind: Word; + kind: ElnaTreeKind; next: Word; conditionals: Word; _else: Word end; ElnaTreeGotoStatement = record - kind: Word; + kind: ElnaTreeKind; next: Word; label: Word; length: Word end; ElnaTreeAssignStatement = record - kind: Word; + kind: ElnaTreeKind; next: Word; assignee: Word; assignment: Word end; ElnaTreeReturnStatement = record - kind: Word; + kind: ElnaTreeKind; next: Word; returned: Word end; ElnaTreeLabelDeclaration = record - kind: Word; + kind: ElnaTreeKind; next: Word; label: Word; length: Word end; ElnaTreeFieldAccessExpression = record - kind: Word; + kind: ElnaTreeKind; type_decoration: Word; aggregate: Word; field: Word; length: Word end; ElnaTreeEnumerationTypeExpression = record - kind: Word; + kind: ElnaTreeKind; members: Word; length: Word end; ElnaTreeRecordTypeExpression = record - kind: Word; + kind: ElnaTreeKind; members: Word; length: Word end; ElnaTreeNamedTypeExpression = record - kind: Word; + kind: ElnaTreeKind; name: Word; length: Word end; ElnaTreePointerTypeExpression = record - kind: Word; + kind: ElnaTreeKind; base: Word end; ElnaTreeArrayTypeExpression = record - kind: Word; + kind: ElnaTreeKind; base: Word; length: Word end; ElnaTreeTraitExpression = record - kind: Word; + kind: ElnaTreeKind; name: Word; length: Word; argument: Word @@ -198,19 +198,19 @@ type next: Word end; ElnaTreeDeclaration = record - kind: Word; + kind: ElnaTreeKind; next: Word; name: Word; length: Word end; ElnaTreeModuleDeclaration = record - kind: Word; + kind: ElnaTreeKind; types: Word; globals: Word; procedures: Word end; ElnaTreeProcedureDeclaration = record - kind: Word; + kind: ElnaTreeKind; next: Word; name: Word; length: Word; @@ -219,66 +219,69 @@ type parameters: Word end; ElnaTreeTypeDeclaration = record - kind: Word; + kind: ElnaTreeKind; next: Word; name: Word; length: Word; _type: Word end; ElnaTreeVariableDeclaration = record - kind: Word; + kind: ElnaTreeKind; next: Word; name: Word; length: Word; _type: Word end; + (* Type representation. *) + ElnaSymbolInfoKind = (type_info, parameter_info, temporary_info, procedure_info); + ElnaTypeKind = (primitive, enumeration, _record, pointer, array); ElnaType = record - kind: Word; + kind: ElnaTypeKind; size: Word end; ElnaTypeEnumeration = record - kind: Word; + kind: ElnaTypeKind; size: Word; members: Word; length: Word end; ElnaTypeField = record - name: Word; + name: ElnaTypeKind; length: Word; field_type: Word end; ElnaTypeRecord = record - kind: Word; + kind: ElnaTypeKind; size: Word; members: Word; length: Word end; ElnaTypePointer = record - kind: Word; + kind: ElnaTypeKind; size: Word; base: Word end; ElnaTypeArray = record - kind: Word; + kind: ElnaTypeKind; size: Word; base: Word; length: Word end; ElnaSymbolInfo = record - kind: Word + kind: ElnaSymbolInfoKind end; ElnaSymbolTypeInfo = record - kind: Word; + kind: ElnaSymbolInfoKind; _type: Word end; ElnaSymbolTemporaryInfo = record - kind: Word; + kind: ElnaSymbolInfoKind; offset: Word; variable_type: Word end; ElnaSymbolProcedureInfo = record - kind: Word; + kind: ElnaSymbolInfoKind; symbol_table: Word end; @@ -413,8 +416,6 @@ type eof ); - ElnaSymbolInfoKind = (type_info, parameter_info, temporary_info, procedure_info); - ElnaTypeKind = (primitive, enumeration, _record, pointer, array); ElnaTacOperator = ( get_address, add, @@ -2031,9 +2032,6 @@ var result: ^ElnaTreeTraitExpression; token_kind: Word; begin - printf("# Comment\n\0"); - fflush(nil); - result := malloc(#size(ElnaTreeTraitExpression)); result^.kind := ElnaTreeKind.trait_expression; @@ -2697,14 +2695,14 @@ begin elsif parser_node^.kind = ElnaTreeKind.field_access_expression then field_access_expression := parser_node; 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); is_address^ := 0 else - designator_base := field_access_expression^.aggregate; 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; current_field := aggregate_type^.members; @@ -3390,7 +3388,6 @@ var member_count: Word; member_array_start: Word; member_array_current: ^ElnaTypeField; - field_definition_size: Word; field_type: Word; begin result := malloc(#size(ElnaTypeRecord)); @@ -3398,8 +3395,7 @@ begin memory_start := parser_node^.members; member_count := parser_node^.length; - field_definition_size := #size(ElnaTypeField); - member_array_start := malloc(member_count * field_definition_size); + member_array_start := malloc(member_count * #size(ElnaTypeField)); member_array_current := member_array_start; .elna_name_type_record_loop; @@ -3413,7 +3409,7 @@ begin field_type := elna_name_type_expression(memory_start^); 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^;