diff options
| author | Eugen Wissner <belka@caraus.de> | 2025-11-28 12:42:51 +0100 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2025-11-28 12:42:51 +0100 |
| commit | eb691db24aaaa43eca03d82a5075b3eba52beedc (patch) | |
| tree | bfc7d7dc85435f519626f0c3cc883620c2fa92f7 /boot/stage16 | |
| parent | f35bdd07c2c34129364e5a1ba17569d949670648 (diff) | |
| download | elna-eb691db24aaaa43eca03d82a5075b3eba52beedc.tar.gz | |
Allow parsing multiple designator expressions in a row
Diffstat (limited to 'boot/stage16')
| -rw-r--r-- | boot/stage16/cl.elna | 70 |
1 files changed, 54 insertions, 16 deletions
diff --git a/boot/stage16/cl.elna b/boot/stage16/cl.elna index 89399fb..fc44bc7 100644 --- a/boot/stage16/cl.elna +++ b/boot/stage16/cl.elna @@ -1789,14 +1789,18 @@ var begin simple_expression := elna_parser_simple_expression(); + .elna_parser_designator_loop; _elna_lexer_read_token(@token_kind); if token_kind = ElnaLexerKind.hat then - simple_expression := elna_parser_dereference_expression(simple_expression) + simple_expression := elna_parser_dereference_expression(simple_expression); + goto elna_parser_designator_loop elsif token_kind = ElnaLexerKind.dot then - simple_expression := elna_parser_field_access_expression(simple_expression) + simple_expression := elna_parser_field_access_expression(simple_expression); + goto elna_parser_designator_loop elsif token_kind = ElnaLexerKind.left_paren then - simple_expression := elna_parser_call(simple_expression) + simple_expression := elna_parser_call(simple_expression); + goto elna_parser_designator_loop end; return simple_expression end; @@ -2414,12 +2418,21 @@ var first_instruction: Word; last_instruction: Word; type_kind: Word; + designator_base: Word; + aggregate_type: Word; + name_pointer: Word; + name_length: Word; + field_name_pointer: Word; + field_name_length: Word; + field_count: Word; + current_field: Word; + field_offset: Word; begin node_kind := ElnaTreeNode_get_kind(parser_node); if node_kind = ElnaTreeKind.dereference_expression then parser_node := ElnaTreeDereferenceExpression_get_pointer(parser_node); - first_instruction := _elna_tac_simple_expression(parser_node, symbol_table, operand_type, operand_value, operand_length); + first_instruction := _elna_tac_designator(parser_node, symbol_table, is_address, operand_type, operand_value, operand_length); last_instruction := _elna_tac_instruction_create(ElnaTacOperator.copy); _elna_tac_instruction_set_operand(last_instruction, 1, ElnaTacOperand.temporary, 6, 0); @@ -2436,17 +2449,42 @@ begin type_kind := ElnaType_get_kind(expression_type); if type_kind = ElnaTypeKind.enumeration then - first_instruction := _elna_tac_enumeration_value(parser_node, operand_type, operand_value, operand_length) + first_instruction := _elna_tac_enumeration_value(parser_node, operand_type, operand_value, operand_length); + is_address^ := 0 else - (* Stub for record field access. Always generate nil for field access expression until it is implemented. *) + designator_base := ElnaTreeFieldAccessExpression_get_aggregate(parser_node); + first_instruction := _elna_tac_designator(designator_base, symbol_table, is_address, operand_type, operand_value, operand_length); + aggregate_type := ElnaTreeExpression_get_type_decoration(designator_base); + name_pointer := ElnaTreeFieldAccessExpression_get_field(parser_node); + name_length := ElnaTreeFieldAccessExpression_get_length(parser_node); - operand_type^ := ElnaTacOperand.immediate; - operand_value^ := 0; + field_count := ElnaTypeRecord_get_length(aggregate_type); + current_field := ElnaTypeRecord_get_members(aggregate_type); + field_offset := 0; + + .elna_tac_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) = 0 then + field_count := field_count - 1; + current_field := current_field + ElnaTypeField_size(); + field_offset := field_offset + 4; + goto elna_tac_designator_field + end; + last_instruction := _elna_tac_instruction_create(ElnaTacOperator.add); + _elna_tac_instruction_set_operand(last_instruction, 1, ElnaTacOperand.temporary, 6, 0); + _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^); + + operand_type^ := ElnaTacOperand.temporary; + operand_value^ := 6; operand_length^ := 0; - first_instruction := nil + is_address^ := 1; + first_instruction := elna_instruction_list_concatenate(first_instruction, last_instruction) end; - is_address^ := 0 elsif node_kind = ElnaTreeKind.call then first_instruction := _elna_tac_call(parser_node, symbol_table); @@ -4411,7 +4449,7 @@ begin if expression_kind = ElnaTreeKind.dereference_expression then designator_base := ElnaTreeDereferenceExpression_get_pointer(parser_node); - elna_type_simple_expression(designator_base, symbol_table); + elna_type_designator(designator_base, symbol_table); base_type := ElnaTreeExpression_get_type_decoration(designator_base); type_kind := ElnaType_get_kind(base_type); @@ -4442,7 +4480,7 @@ 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); + elna_type_designator(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); @@ -4455,12 +4493,12 @@ begin 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 + if string_compare(name_pointer, name_length, field_name_pointer, field_name_length) = 0 then (* Debug. Error stream output. - _syscall(2, name_pointer, name_length, 0, 0, 0, 64); *) + _syscall(2, name_pointer, name_length, 0, 0, 0, 64); printf("# if %.*s\n\0", name_length, name_pointer); - fflush(0) - else + fflush(0) *) + field_count := field_count - 1; current_field := current_field + ElnaTypeField_size(); goto elna_type_designator_field |
