Allow parsing multiple designator expressions in a row
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user