Annotate record field access expressions

This commit is contained in:
2025-11-25 17:49:55 +01:00
parent b5b129a90c
commit f35bdd07c2
2 changed files with 115 additions and 65 deletions

View File

@@ -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;