diff --git a/boot/stage16/cl.elna b/boot/stage16/cl.elna index 438c106..89399fb 100644 --- a/boot/stage16/cl.elna +++ b/boot/stage16/cl.elna @@ -163,6 +163,11 @@ type members: Word; length: Word end; + ElnaTypeField = record + name: Word; + length: Word; + field_type: Word + end; ElnaTypeRecord = record kind: Word; size: Word; @@ -389,7 +394,7 @@ type null ); InfoKind = (type_info, parameter_info, temporary_info, procedure_info); - TypeKind = (primitive, enumeration, _record, pointer, array); + ElnaTypeKind = (primitive, enumeration, _record, pointer, array); ElnaTacOperator = ( get_address, add, @@ -2408,9 +2413,7 @@ var expression_type: Word; first_instruction: Word; last_instruction: Word; - - name_pointer: Word; - name_length: Word; + type_kind: Word; begin node_kind := ElnaTreeNode_get_kind(parser_node); @@ -2430,24 +2433,18 @@ begin first_instruction := elna_instruction_list_concatenate(first_instruction, last_instruction) elsif node_kind = ElnaTreeKind.field_access_expression then expression_type := ElnaTreeExpression_get_type_decoration(parser_node); - name_pointer := ElnaTreeFieldAccessExpression_get_field(parser_node); - name_length := ElnaTreeFieldAccessExpression_get_length(parser_node); + type_kind := ElnaType_get_kind(expression_type); - if expression_type = nil then + if type_kind = ElnaTypeKind.enumeration then + first_instruction := _elna_tac_enumeration_value(parser_node, operand_type, operand_value, operand_length) + else (* Stub for record field access. Always generate nil for field access expression until it is implemented. *) - (* Debug. Error stream output. - _syscall(2, name_pointer, name_length, 0, 0, 0, 64); - printf("# there %.*s %i\n\0", name_length, name_pointer, expression_type); - fflush(0); *) - operand_type^ := ElnaTacOperand.immediate; operand_value^ := 0; operand_length^ := 0; first_instruction := nil - else - first_instruction := _elna_tac_enumeration_value(parser_node, operand_type, operand_value, operand_length) end; is_address^ := 0 elsif node_kind = ElnaTreeKind.call then @@ -3065,7 +3062,7 @@ begin end; member_count := ElnaTreeEnumerationTypeExpression_get_length(parser_node); - ElnaType_set_kind(result, TypeKind.enumeration); + ElnaType_set_kind(result, ElnaTypeKind.enumeration); ElnaType_set_size(result, 4); ElnaTypeEnumeration_set_members(result, member_array_start); ElnaTypeEnumeration_set_length(result, member_count); @@ -3082,7 +3079,7 @@ begin base := ElnaTreePointerTypeExpression_get_base(parser_node); base := elna_name_type_expression(base); - ElnaType_set_kind(result, TypeKind.pointer); + ElnaType_set_kind(result, ElnaTypeKind.pointer); ElnaType_set_size(result, 4); ElnaTypePointer_set_base(result, base); @@ -3106,7 +3103,7 @@ begin (* Expected to be an integer literal for now. *) length := ElnaTreeIntegerLiteral_get_value(length); - ElnaType_set_kind(result, TypeKind.pointer); + ElnaType_set_kind(result, ElnaTypeKind.pointer); ElnaType_set_size(result, size * length); ElnaTypeArray_set_base(result, base); ElnaTypeArray_set_size(result, length); @@ -3121,27 +3118,30 @@ var member_count: Word; member_array_start: Word; member_array_current: Word; + field_definition_size: Word; + field_type: Word; begin result := malloc(ElnaTypeRecord_size()); memory_start := ElnaTreeRecordTypeExpression_get_members(parser_node); member_count := ElnaTreeRecordTypeExpression_get_length(parser_node); - member_array_start := malloc(member_count * 12); + field_definition_size := ElnaTypeField_size(); + member_array_start := malloc(member_count * field_definition_size); member_array_current := member_array_start; .elna_name_type_record_loop; if member_count > 0 then - member_array_current^ := memory_start^; - member_array_current := member_array_current + 4; + ElnaTypeField_set_name(member_array_current, memory_start^); memory_start := memory_start + 4; - member_array_current^ := memory_start^; - member_array_current := member_array_current + 4; + ElnaTypeField_set_length(member_array_current, memory_start^); memory_start := memory_start + 4; - member_array_current^ := elna_name_type_expression(memory_start^); - member_array_current := member_array_current + 4; + field_type := elna_name_type_expression(memory_start^); + ElnaTypeField_set_field_type(member_array_current, field_type); + + member_array_current := member_array_current + field_definition_size; memory_start := memory_start + 4; memory_start := memory_start^; @@ -3150,7 +3150,7 @@ begin end; member_count := ElnaTreeRecordTypeExpression_get_length(parser_node); - ElnaType_set_kind(result, TypeKind._record); + ElnaType_set_kind(result, ElnaTypeKind._record); ElnaType_set_size(result, member_count * 4); ElnaTypeRecord_set_members(result, member_array_start); ElnaTypeRecord_set_length(result, member_count); @@ -4015,7 +4015,7 @@ begin info_type := _type_info_get__type(symbol); type_kind := ElnaType_get_kind(info_type); - if type_kind = TypeKind._record then + if type_kind = ElnaTypeKind._record then result := _elna_tac_type_record(name_pointer, name_length, info_type, @out_result) else result := 0; @@ -4401,6 +4401,11 @@ var name_pointer: Word; name_length: Word; symbol_info: Word; + aggregate_type: Word; + field_count: Word; + current_field: Word; + field_name_pointer: Word; + field_name_length: Word; begin expression_kind := ElnaTreeNode_get_kind(parser_node); @@ -4412,7 +4417,7 @@ begin type_kind := ElnaType_get_kind(base_type); (* If check for compatibility, should be removed later. *) - if type_kind = TypeKind.pointer then + if type_kind = ElnaTypeKind.pointer then base_type := ElnaTypePointer_get_base(base_type) end; @@ -4437,12 +4442,32 @@ begin end; (* If the base_type is still nil this is record field access. *) if base_type = nil then - (* elna_type_simple_expression(designator_base, symbol_table); - base_type := ElnaTreeExpression_get_type_decoration(designator_base); *) - else + elna_type_simple_expression(designator_base, symbol_table); + aggregate_type := ElnaTreeExpression_get_type_decoration(designator_base); + name_pointer := ElnaTreeFieldAccessExpression_get_field(parser_node); + name_length := ElnaTreeFieldAccessExpression_get_length(parser_node); + + field_count := ElnaTypeRecord_get_length(aggregate_type); + current_field := ElnaTypeRecord_get_members(aggregate_type); + + .elna_type_designator_field; + + field_name_pointer := ElnaTypeField_get_name(current_field); + field_name_length := ElnaTypeField_get_length(current_field); + + if string_compare(name_pointer, name_length, field_name_pointer, field_name_length) then + (* Debug. Error stream output. + _syscall(2, name_pointer, name_length, 0, 0, 0, 64); *) + printf("# if %.*s\n\0", name_length, name_pointer); + fflush(0) + else + field_count := field_count - 1; + current_field := current_field + ElnaTypeField_size(); + goto elna_type_designator_field + end; + base_type := ElnaTypeField_get_field_type(current_field) end; - (* Change my type. *) ElnaTreeExpression_set_type_decoration(parser_node, base_type) elsif expression_kind = ElnaTreeKind.call then elna_type_call(parser_node, symbol_table) @@ -4714,7 +4739,7 @@ begin symbol_table_global := 0; current_type := malloc(ElnaType_size()); - ElnaType_set_kind(current_type, TypeKind.primitive); + ElnaType_set_kind(current_type, ElnaTypeKind.primitive); ElnaType_set_size(current_type, 4); (* Enter built-in symbols. *) diff --git a/boot/stage17/cl.elna b/boot/stage17/cl.elna index 9908b3b..66f4282 100644 --- a/boot/stage17/cl.elna +++ b/boot/stage17/cl.elna @@ -163,6 +163,11 @@ type members: Word; length: Word end; + ElnaTypeField = record + name: Word; + length: Word; + field_type: Word + end; ElnaTypeRecord = record kind: Word; size: Word; @@ -389,7 +394,7 @@ type null ); InfoKind = (type_info, parameter_info, temporary_info, procedure_info); - TypeKind = (primitive, enumeration, _record, pointer, array); + ElnaTypeKind = (primitive, enumeration, _record, pointer, array); ElnaTacOperator = ( get_address, add, @@ -2408,9 +2413,7 @@ var expression_type: Word; first_instruction: Word; last_instruction: Word; - - name_pointer: Word; - name_length: Word; + type_kind: Word; begin node_kind := ElnaTreeNode_get_kind(parser_node); @@ -2430,24 +2433,18 @@ begin first_instruction := elna_instruction_list_concatenate(first_instruction, last_instruction) elsif node_kind = ElnaTreeKind.field_access_expression then expression_type := ElnaTreeExpression_get_type_decoration(parser_node); - name_pointer := ElnaTreeFieldAccessExpression_get_field(parser_node); - name_length := ElnaTreeFieldAccessExpression_get_length(parser_node); + type_kind := ElnaType_get_kind(expression_type); - if expression_type = nil then + if type_kind = ElnaTypeKind.enumeration then + first_instruction := _elna_tac_enumeration_value(parser_node, operand_type, operand_value, operand_length) + else (* Stub for record field access. Always generate nil for field access expression until it is implemented. *) - (* Debug. Error stream output. - _syscall(2, name_pointer, name_length, 0, 0, 0, 64); - printf("# there %.*s %i\n\0", name_length, name_pointer, expression_type); - fflush(0); *) - operand_type^ := ElnaTacOperand.immediate; operand_value^ := 0; operand_length^ := 0; first_instruction := nil - else - first_instruction := _elna_tac_enumeration_value(parser_node, operand_type, operand_value, operand_length) end; is_address^ := 0 elsif node_kind = ElnaTreeKind.call then @@ -3065,7 +3062,7 @@ begin end; member_count := ElnaTreeEnumerationTypeExpression_get_length(parser_node); - ElnaType_set_kind(result, TypeKind.enumeration); + ElnaType_set_kind(result, ElnaTypeKind.enumeration); ElnaType_set_size(result, 4); ElnaTypeEnumeration_set_members(result, member_array_start); ElnaTypeEnumeration_set_length(result, member_count); @@ -3082,7 +3079,7 @@ begin base := ElnaTreePointerTypeExpression_get_base(parser_node); base := elna_name_type_expression(base); - ElnaType_set_kind(result, TypeKind.pointer); + ElnaType_set_kind(result, ElnaTypeKind.pointer); ElnaType_set_size(result, 4); ElnaTypePointer_set_base(result, base); @@ -3106,7 +3103,7 @@ begin (* Expected to be an integer literal for now. *) length := ElnaTreeIntegerLiteral_get_value(length); - ElnaType_set_kind(result, TypeKind.pointer); + ElnaType_set_kind(result, ElnaTypeKind.pointer); ElnaType_set_size(result, size * length); ElnaTypeArray_set_base(result, base); ElnaTypeArray_set_size(result, length); @@ -3121,27 +3118,30 @@ var member_count: Word; member_array_start: Word; member_array_current: Word; + field_definition_size: Word; + field_type: Word; begin result := malloc(ElnaTypeRecord_size()); memory_start := ElnaTreeRecordTypeExpression_get_members(parser_node); member_count := ElnaTreeRecordTypeExpression_get_length(parser_node); - member_array_start := malloc(member_count * 12); + field_definition_size := ElnaTypeField_size(); + member_array_start := malloc(member_count * field_definition_size); member_array_current := member_array_start; .elna_name_type_record_loop; if member_count > 0 then - member_array_current^ := memory_start^; - member_array_current := member_array_current + 4; + ElnaTypeField_set_name(member_array_current, memory_start^); memory_start := memory_start + 4; - member_array_current^ := memory_start^; - member_array_current := member_array_current + 4; + ElnaTypeField_set_length(member_array_current, memory_start^); memory_start := memory_start + 4; - member_array_current^ := elna_name_type_expression(memory_start^); - member_array_current := member_array_current + 4; + field_type := elna_name_type_expression(memory_start^); + ElnaTypeField_set_field_type(member_array_current, field_type); + + member_array_current := member_array_current + field_definition_size; memory_start := memory_start + 4; memory_start := memory_start^; @@ -3150,7 +3150,7 @@ begin end; member_count := ElnaTreeRecordTypeExpression_get_length(parser_node); - ElnaType_set_kind(result, TypeKind._record); + ElnaType_set_kind(result, ElnaTypeKind._record); ElnaType_set_size(result, member_count * 4); ElnaTypeRecord_set_members(result, member_array_start); ElnaTypeRecord_set_length(result, member_count); @@ -4015,7 +4015,7 @@ begin info_type := _type_info_get__type(symbol); type_kind := ElnaType_get_kind(info_type); - if type_kind = TypeKind._record then + if type_kind = ElnaTypeKind._record then result := _elna_tac_type_record(name_pointer, name_length, info_type, @out_result) else result := 0; @@ -4401,6 +4401,11 @@ var name_pointer: Word; name_length: Word; symbol_info: Word; + aggregate_type: Word; + field_count: Word; + current_field: Word; + field_name_pointer: Word; + field_name_length: Word; begin expression_kind := ElnaTreeNode_get_kind(parser_node); @@ -4412,7 +4417,7 @@ begin type_kind := ElnaType_get_kind(base_type); (* If check for compatibility, should be removed later. *) - if type_kind = TypeKind.pointer then + if type_kind = ElnaTypeKind.pointer then base_type := ElnaTypePointer_get_base(base_type) end; @@ -4437,12 +4442,32 @@ begin end; (* If the base_type is still nil this is record field access. *) if base_type = nil then - (* elna_type_simple_expression(designator_base, symbol_table); - base_type := ElnaTreeExpression_get_type_decoration(designator_base); *) - else + elna_type_simple_expression(designator_base, symbol_table); + aggregate_type := ElnaTreeExpression_get_type_decoration(designator_base); + name_pointer := ElnaTreeFieldAccessExpression_get_field(parser_node); + name_length := ElnaTreeFieldAccessExpression_get_length(parser_node); + + field_count := ElnaTypeRecord_get_length(aggregate_type); + current_field := ElnaTypeRecord_get_members(aggregate_type); + + .elna_type_designator_field; + + field_name_pointer := ElnaTypeField_get_name(current_field); + field_name_length := ElnaTypeField_get_length(current_field); + + if string_compare(name_pointer, name_length, field_name_pointer, field_name_length) then + (* Debug. Error stream output. + _syscall(2, name_pointer, name_length, 0, 0, 0, 64); *) + printf("# if %.*s\n\0", name_length, name_pointer); + fflush(0) + else + field_count := field_count - 1; + current_field := current_field + ElnaTypeField_size(); + goto elna_type_designator_field + end; + base_type := ElnaTypeField_get_field_type(current_field) end; - (* Change my type. *) ElnaTreeExpression_set_type_decoration(parser_node, base_type) elsif expression_kind = ElnaTreeKind.call then elna_type_call(parser_node, symbol_table) @@ -4714,7 +4739,7 @@ begin symbol_table_global := 0; current_type := malloc(ElnaType_size()); - ElnaType_set_kind(current_type, TypeKind.primitive); + ElnaType_set_kind(current_type, ElnaTypeKind.primitive); ElnaType_set_size(current_type, 4); (* Enter built-in symbols. *) @@ -5533,5 +5558,5 @@ proc f(x: ElnaTreeExpression); var y: Word; begin - y := x.kind + y := x.type_decoration end;