Implement aggregate assignment

This commit is contained in:
2026-04-15 22:19:17 +02:00
parent a54285c71c
commit 928a87d544
2 changed files with 166 additions and 141 deletions
+7 -1
View File
@@ -49,12 +49,18 @@ task :convert do
x: ElnaLocation; x: ElnaLocation;
y: ElnaLocation; y: ElnaLocation;
begin begin
y.line := 1;
y.column := 3;
x := y; x := y;
printf("# %i %i %i %i\\n\\0", x.line, x.column, y.line, y.column)
end; end;
begin
f();
FUN FUN
else
current_stage << line
end end
current_stage << line
end end
end end
end end
+159 -140
View File
@@ -210,6 +210,11 @@ type
array: Word; array: Word;
index: ^ElnaTreeExpression index: ^ElnaTreeExpression
end; end;
ElnaTreeEnumeration = record
name: Word;
length: Word;
next: Word
end;
ElnaTreeEnumerationTypeExpression = record ElnaTreeEnumerationTypeExpression = record
kind: ElnaTreeKind; kind: ElnaTreeKind;
members: Word; members: Word;
@@ -672,7 +677,7 @@ var
* *
* Returns the length in a0. * Returns the length in a0.
*) *)
proc _string_length(string: Word); proc _string_length(string: Word) -> Word;
var var
counter: Word; counter: Word;
current_byte: Word; current_byte: Word;
@@ -802,7 +807,7 @@ end;
(** (**
* Appends a new element to the end of the list. * Appends a new element to the end of the list.
*) *)
proc elna_list_append(list: ^ElnaList, element: ^ElnaListNode); proc elna_list_append(list: ^ElnaList, element: ^ElnaListNode) -> ^ElnaListNode;
begin begin
if element <> nil then if element <> nil then
if list^.first = nil then if list^.first = nil then
@@ -877,13 +882,13 @@ begin
return result return result
end; end;
proc elna_rtl_instruction_create(kind: Word); proc elna_rtl_instruction_create(operator: ElnaRtlOperator) -> ^ElnaRtlInstruction;
var var
result: ^ElnaRtlInstruction; result: ^ElnaRtlInstruction;
begin begin
result := malloc(#size(ElnaRtlInstruction)); result := malloc(#size(ElnaRtlInstruction));
result^.operator := kind; result^.operator := operator;
result^.next := nil; result^.next := nil;
return result return result
@@ -1097,8 +1102,6 @@ begin
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo_mem, elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo_mem,
addressable^.value, addressable^.length, 0) addressable^.value, addressable^.length, 0)
else else
(* Debug
printf("# %.*s, %i\n\0", addressable^.length, addressable^.value, pseudo_symbol^.rtl_type^.kind); *)
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo, elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo,
addressable^.value, addressable^.length, 0) addressable^.value, addressable^.length, 0)
end; end;
@@ -1255,6 +1258,7 @@ var
source_operand: ElnaRtlOperand; source_operand: ElnaRtlOperand;
target_operand: ElnaRtlOperand; target_operand: ElnaRtlOperand;
pseudo_symbol: ^ElnaRtlInfo; pseudo_symbol: ^ElnaRtlInfo;
byte_array: ^ElnaRtlTypeByteArray;
begin begin
elna_rtl_operand_value(instructions, @tac_instruction^.operands[1], variable_map, @source_operand); elna_rtl_operand_value(instructions, @tac_instruction^.operands[1], variable_map, @source_operand);
pseudo_symbol := elna_symbol_table_lookup(variable_map, pseudo_symbol := elna_symbol_table_lookup(variable_map,
@@ -1262,8 +1266,8 @@ begin
if pseudo_symbol = nil then if pseudo_symbol = nil then
elna_rtl_generate_pseudo(@target_operand, variable_map); elna_rtl_generate_pseudo(@target_operand, variable_map);
instruction := elna_rtl_instruction_create(ElnaRtlOperator.la);
instruction := elna_rtl_instruction_create(ElnaRtlOperator.la);
elna_rtl_instruction_set_operand(instruction, 1, target_operand.kind, target_operand.value, target_operand.length, 0); elna_rtl_instruction_set_operand(instruction, 1, target_operand.kind, target_operand.value, target_operand.length, 0);
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.data, elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.data,
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length, 0); tac_instruction^.operands[2].value, tac_instruction^.operands[2].length, 0);
@@ -1273,12 +1277,34 @@ begin
elna_rtl_instruction_set_operand(instruction, 1, source_operand.kind, source_operand.value, source_operand.length, 0); elna_rtl_instruction_set_operand(instruction, 1, source_operand.kind, source_operand.value, source_operand.length, 0);
elna_rtl_instruction_set_operand(instruction, 2, target_operand.kind, target_operand.value, target_operand.length, 0); elna_rtl_instruction_set_operand(instruction, 2, target_operand.kind, target_operand.value, target_operand.length, 0);
elna_list_append(instructions, instruction) elna_list_append(instructions, instruction)
else elsif source_operand.kind = ElnaRtlKind.pseudo then
instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv); instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv);
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo, elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo,
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length, 0); tac_instruction^.operands[2].value, tac_instruction^.operands[2].length, 0);
elna_rtl_instruction_set_operand(instruction, 2, source_operand.kind, source_operand.value, source_operand.length, 0); elna_rtl_instruction_set_operand(instruction, 2, source_operand.kind, source_operand.value, source_operand.length, 0);
elna_list_append(instructions, instruction); elna_list_append(instructions, instruction);
else
byte_array := pseudo_symbol^.rtl_type;
instruction := elna_rtl_instruction_create(ElnaRtlOperator.la);
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a0, 0, 0);
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo,
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length, 0);
elna_list_append(instructions, instruction);
instruction := elna_rtl_instruction_create(ElnaRtlOperator.la);
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a1, 0, 0);
elna_rtl_instruction_set_operand(instruction, 2, source_operand.kind, source_operand.value, source_operand.length, 0);
elna_list_append(instructions, instruction);
instruction := elna_rtl_instruction_create(ElnaRtlOperator.li);
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a2, 0, 0);
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.immediate, byte_array^.size, 0, 0);
elna_list_append(instructions, instruction);
instruction := elna_rtl_instruction_create(ElnaRtlOperator.jal);
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.data, "memcpy", 6, 0);
elna_list_append(instructions, instruction)
end end
end; end;
@@ -1370,7 +1396,7 @@ begin
elna_list_append(instructions, result) elna_list_append(instructions, result)
end; end;
proc elna_riscv_instruction_name(instruction_kind: Word); proc elna_riscv_instruction_name(instruction_kind: ElnaRtlOperator) -> Word;
var var
argument_count: Word; argument_count: Word;
begin begin
@@ -1483,7 +1509,8 @@ begin
end end
end; end;
proc elna_alloc_variable(operand_value: Word, operand_length: Word, variable_map: ^ElnaSymbolTable); proc elna_alloc_variable(operand_value: Word, operand_length: Word,
variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInfo;
var var
pseudo_symbol: ^ElnaRtlInfo; pseudo_symbol: ^ElnaRtlInfo;
pseudo_type: ^ElnaRtlTypeByteArray; pseudo_type: ^ElnaRtlTypeByteArray;
@@ -1553,7 +1580,8 @@ begin
end end
end; end;
proc elna_alloc_store(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable); proc elna_alloc_store(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction,
variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction;
var var
store_instruction: ^ElnaRtlInstruction; store_instruction: ^ElnaRtlInstruction;
pseudo_symbol: ^ElnaRtlInfo; pseudo_symbol: ^ElnaRtlInfo;
@@ -1580,7 +1608,8 @@ begin
return instruction return instruction
end; end;
proc elna_alloc_load(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable); proc elna_alloc_load(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction,
variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction;
var var
new_instruction: ^ElnaRtlInstruction; new_instruction: ^ElnaRtlInstruction;
pseudo_symbol: ^ElnaRtlInfo; pseudo_symbol: ^ElnaRtlInfo;
@@ -1606,7 +1635,8 @@ begin
return elna_alloc_operation_target(instructions, instruction, variable_map) return elna_alloc_operation_target(instructions, instruction, variable_map)
end; end;
proc elna_alloc_move(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable); proc elna_alloc_move(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction,
variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction;
var var
pseudo_symbol: ^ElnaRtlInfo; pseudo_symbol: ^ElnaRtlInfo;
destination_pseudo: Word; destination_pseudo: Word;
@@ -1674,7 +1704,8 @@ begin
return instruction return instruction
end; end;
proc elna_alloc_binary(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction; proc elna_alloc_binary(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction,
variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction;
var var
new_instruction: ^ElnaRtlInstruction; new_instruction: ^ElnaRtlInstruction;
pseudo_symbol: ^ElnaRtlInfo; pseudo_symbol: ^ElnaRtlInfo;
@@ -1684,7 +1715,8 @@ begin
return elna_alloc_operation_target(instructions, instruction, variable_map) return elna_alloc_operation_target(instructions, instruction, variable_map)
end; end;
proc elna_alloc_unary(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction; proc elna_alloc_unary(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction,
variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction;
var var
new_instruction: ^ElnaRtlInstruction; new_instruction: ^ElnaRtlInstruction;
pseudo_symbol: ^ElnaRtlInfo; pseudo_symbol: ^ElnaRtlInfo;
@@ -1693,7 +1725,8 @@ begin
return elna_alloc_operation_target(instructions, instruction, variable_map) return elna_alloc_operation_target(instructions, instruction, variable_map)
end; end;
proc elna_alloc_instruction(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction; proc elna_alloc_instruction(instructions: ^ElnaList, instruction: ^ElnaRtlInstruction,
variable_map: ^ElnaSymbolTable) -> ^ElnaRtlInstruction;
var var
pseudo_symbol: ^ElnaRtlInfo; pseudo_symbol: ^ElnaRtlInfo;
new_instruction: ^ElnaRtlInstruction; new_instruction: ^ElnaRtlInstruction;
@@ -1896,7 +1929,7 @@ begin
end end
end; end;
proc elna_rtl_module_declaration(tac_module: ^ElnaInstructionModule); proc elna_rtl_module_declaration(tac_module: ^ElnaInstructionModule) -> ^ElnaInstructionModule;
var var
result: ^ElnaInstructionModule; result: ^ElnaInstructionModule;
begin begin
@@ -2020,7 +2053,7 @@ begin
return result return result
end; end;
proc elna_parser_nil_literal(cursor: ^ElnaLexerCursor); proc elna_parser_nil_literal(cursor: ^ElnaLexerCursor) -> ^ElnaTreeNilLiteral;
var var
result: ^ElnaTreeNilLiteral; result: ^ElnaTreeNilLiteral;
begin begin
@@ -2166,7 +2199,7 @@ var
parser_node: ^ElnaTreeExpression; parser_node: ^ElnaTreeExpression;
token: ^ElnaLexerToken; token: ^ElnaLexerToken;
begin begin
parser_node := 0; parser_node := nil;
token := elna_lexer_peek(cursor); token := elna_lexer_peek(cursor);
if token^.kind = ElnaLexerKind.character then if token^.kind = ElnaLexerKind.character then
@@ -2187,7 +2220,8 @@ begin
return parser_node return parser_node
end; end;
proc elna_parser_dereference_expression(cursor: ^ElnaLexerCursor, simple_expression: Word); proc elna_parser_dereference_expression(cursor: ^ElnaLexerCursor,
simple_expression: ^ElnaTreeExpression) -> ^ElnaTreeDereferenceExpression;
var var
result: ^ElnaTreeDereferenceExpression; result: ^ElnaTreeDereferenceExpression;
begin begin
@@ -2201,9 +2235,9 @@ begin
return result return result
end; end;
proc elna_parser_designator(cursor: ^ElnaLexerCursor); proc elna_parser_designator(cursor: ^ElnaLexerCursor) -> ^ElnaTreeExpression;
var var
simple_expression: Word; simple_expression: ^ElnaTreeExpression;
token: ^ElnaLexerToken; token: ^ElnaLexerToken;
begin begin
simple_expression := elna_parser_simple_expression(cursor); simple_expression := elna_parser_simple_expression(cursor);
@@ -2262,7 +2296,7 @@ begin
end end
end; end;
proc elna_parser_unary_expression(cursor: ^ElnaLexerCursor); proc elna_parser_unary_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeExpression;
var var
result: ^ElnaTreeUnaryExpression; result: ^ElnaTreeUnaryExpression;
operand: Word; operand: Word;
@@ -2322,7 +2356,8 @@ begin
end end
end; end;
proc elna_tac_unary_expression(instructions: ^ElnaList, parser_node: ^ElnaTreeUnaryExpression, symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand); proc elna_tac_unary_expression(instructions: ^ElnaList, parser_node: ^ElnaTreeUnaryExpression,
symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand);
var var
token_kind: Word; token_kind: Word;
operator: Word; operator: Word;
@@ -2379,10 +2414,10 @@ begin
end end
end; end;
proc elna_parser_binary_expression(cursor: ^ElnaLexerCursor); proc elna_parser_binary_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeExpression;
var var
lhs_node: Word; lhs_node: ^ElnaTreeExpression;
rhs_node: Word; rhs_node: ^ElnaTreeExpression;
result: ^ElnaTreeBinaryExpression; result: ^ElnaTreeBinaryExpression;
token: ^ElnaLexerToken; token: ^ElnaLexerToken;
begin begin
@@ -2433,7 +2468,7 @@ begin
elna_lexer_read(cursor); elna_lexer_read(cursor);
rhs_node := elna_parser_unary_expression(cursor) rhs_node := elna_parser_unary_expression(cursor)
end; end;
if rhs_node <> 0 then if rhs_node <> nil then
result := malloc(#size(ElnaTreeBinaryExpression)); result := malloc(#size(ElnaTreeBinaryExpression));
result^.kind := ElnaTreeKind.binary_expression; result^.kind := ElnaTreeKind.binary_expression;
@@ -2555,7 +2590,7 @@ begin
end end
end; end;
proc elna_parser_call(cursor: ^ElnaLexerCursor, callee: Word); proc elna_parser_call(cursor: ^ElnaLexerCursor, callee: ^ElnaTreeExpression) -> ^ElnaTreeCall;
var var
result: ^ElnaTreeCall; result: ^ElnaTreeCall;
argument_number: Word; argument_number: Word;
@@ -2603,7 +2638,8 @@ begin
return result return result
end; end;
proc elna_tac_call(instructions: ^ElnaList, parsed_call: ^ElnaTreeCall, symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand); proc elna_tac_call(instructions: ^ElnaList, parsed_call: ^ElnaTreeCall, symbol_table: ^ElnaSymbolTable,
operand: ^ElnaTacOperand);
var var
parsed_expression: ^ElnaTreeVariableExpression; parsed_expression: ^ElnaTreeVariableExpression;
arguments_operand: ^ElnaTacOperand; arguments_operand: ^ElnaTacOperand;
@@ -2633,7 +2669,7 @@ begin
elna_list_append(instructions, call_instruction) elna_list_append(instructions, call_instruction)
end; end;
proc elna_parser_goto_statement(cursor: ^ElnaLexerCursor); proc elna_parser_goto_statement(cursor: ^ElnaLexerCursor) -> ^ElnaTreeGotoStatement;
var var
result: ^ElnaTreeGotoStatement; result: ^ElnaTreeGotoStatement;
token: ^ElnaLexerToken; token: ^ElnaLexerToken;
@@ -2667,9 +2703,9 @@ begin
elna_list_append(instructions, instruction) elna_list_append(instructions, instruction)
end; end;
proc elna_parser_label_declaration(cursor: ^ElnaLexerCursor); proc elna_parser_label_declaration(cursor: ^ElnaLexerCursor) -> ^ElnaTreeLabelDeclaration;
var var
result: ^ElnaTreeGotoStatement; result: ^ElnaTreeLabelDeclaration;
token: ^ElnaLexerToken; token: ^ElnaLexerToken;
begin begin
elna_lexer_read(cursor); elna_lexer_read(cursor);
@@ -2730,7 +2766,8 @@ begin
end end
end; end;
proc elna_parser_field_access_expression(cursor: ^ElnaLexerCursor, aggregate: Word); proc elna_parser_field_access_expression(cursor: ^ElnaLexerCursor,
aggregate: ^ElnaTreeExpression) -> ^ElnaTreeFieldAccessExpression;
var var
result: ^ElnaTreeFieldAccessExpression; result: ^ElnaTreeFieldAccessExpression;
token: ^ElnaLexerToken; token: ^ElnaLexerToken;
@@ -2750,7 +2787,8 @@ begin
return result return result
end; end;
proc elna_parser_array_access_expression(cursor: ^ElnaLexerCursor, array: Word); proc elna_parser_array_access_expression(cursor: ^ElnaLexerCursor,
array: ^ElnaTreeExpression) -> ^ElnaTreeArrayAccessExpression;
var var
result: ^ElnaTreeArrayAccessExpression; result: ^ElnaTreeArrayAccessExpression;
begin begin
@@ -2909,7 +2947,7 @@ begin
elna_list_append(instructions, instruction) elna_list_append(instructions, instruction)
end; end;
proc elna_parser_assign_statement(cursor: ^ElnaLexerCursor, assignee: Word); proc elna_parser_assign_statement(cursor: ^ElnaLexerCursor, assignee: ^ElnaTreeNode) -> ^ElnaTreeAssignStatement;
var var
result: ^ElnaTreeAssignStatement; result: ^ElnaTreeAssignStatement;
begin begin
@@ -2960,9 +2998,9 @@ begin
elna_list_append(instructions, instruction) elna_list_append(instructions, instruction)
end; end;
proc elna_parser_return_statement(cursor: ^ElnaLexerCursor); proc elna_parser_return_statement(cursor: ^ElnaLexerCursor) -> ^ElnaTreeReturnStatement;
var var
returned: Word; returned: ^ElnaTreeExpression;
label_length: Word; label_length: Word;
result: ^ElnaTreeReturnStatement; result: ^ElnaTreeReturnStatement;
begin begin
@@ -3009,7 +3047,7 @@ begin
fflush(nil) fflush(nil)
end; end;
proc elna_parser_conditional_statements(cursor: ^ElnaLexerCursor); proc elna_parser_conditional_statements(cursor: ^ElnaLexerCursor) -> ^ElnaTreeConditionalStatements;
var var
result: ^ElnaTreeConditionalStatements; result: ^ElnaTreeConditionalStatements;
begin begin
@@ -3056,7 +3094,7 @@ begin
elna_tac_label(instructions, condition_label, 0) elna_tac_label(instructions, condition_label, 0)
end; end;
proc elna_parser_if_statement(cursor: ^ElnaLexerCursor); proc elna_parser_if_statement(cursor: ^ElnaLexerCursor) -> ^ElnaTreeIfStatement;
var var
result: ^ElnaTreeIfStatement; result: ^ElnaTreeIfStatement;
previous_conditional: ^ElnaTreeConditionalStatements; previous_conditional: ^ElnaTreeConditionalStatements;
@@ -3091,9 +3129,10 @@ begin
return result return result
end; end;
proc elna_parser_statement(cursor: ^ElnaLexerCursor); proc elna_parser_statement(cursor: ^ElnaLexerCursor) -> ^ElnaTreeStatement;
var var
result : ^ElnaTreeNode; result: ^ElnaTreeStatement;
designator: ^ElnaTreeNode;
token: ^ElnaLexerToken; token: ^ElnaLexerToken;
begin begin
result := nil; result := nil;
@@ -3108,10 +3147,12 @@ begin
elsif token^.kind = ElnaLexerKind.dot then elsif token^.kind = ElnaLexerKind.dot then
result := elna_parser_label_declaration(cursor) result := elna_parser_label_declaration(cursor)
elsif token^.kind = ElnaLexerKind.identifier then elsif token^.kind = ElnaLexerKind.identifier then
result := elna_parser_designator(cursor); designator := elna_parser_designator(cursor);
if result^.kind <> ElnaTreeKind.call then if designator^.kind <> ElnaTreeKind.call then
result := elna_parser_assign_statement(cursor, result) result := elna_parser_assign_statement(cursor, designator)
else
result := designator
end end
end; end;
return result return result
@@ -3224,7 +3265,7 @@ begin
_write_c(register_number + '0') _write_c(register_number + '0')
end; end;
proc elna_parser_record_type_expression(cursor: ^ElnaLexerCursor); proc elna_parser_record_type_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeRecordTypeExpression;
var var
entry: ^ElnaTreeField; entry: ^ElnaTreeField;
result: ^ElnaTreeRecordTypeExpression; result: ^ElnaTreeRecordTypeExpression;
@@ -3273,35 +3314,33 @@ begin
return result return result
end; end;
proc elna_parser_enumeration_type_expression(cursor: ^ElnaLexerCursor); proc elna_parser_enumeration_type_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeEnumerationTypeExpression;
var var
memory_start: Word;
member_count: Word;
result: ^ElnaTreeEnumerationTypeExpression; result: ^ElnaTreeEnumerationTypeExpression;
entry: Word; entry: ^ElnaTreeEnumeration;
previous_entry: Word; previous_entry: ^ElnaTreeEnumeration;
token: ^ElnaLexerToken; token: ^ElnaLexerToken;
begin begin
elna_lexer_read(cursor); elna_lexer_read(cursor);
memory_start := 0;
member_count := 0; result := malloc(#size(ElnaTreeEnumerationTypeExpression));
result^.kind := ElnaTreeKind.enumeration_type_expression;
result^.members := nil;
result^.length := 0;
.elna_parser_enumeration_type_expression_loop; .elna_parser_enumeration_type_expression_loop;
token := elna_lexer_read(cursor); token := elna_lexer_read(cursor);
entry := malloc(12); entry := malloc(#size(ElnaTreeEnumeration));
member_count := member_count + 1; result^.length := result^.length + 1;
entry^ := token^.start; entry^.name := token^.start;
entry := entry + 4; entry^.length := token^.length;
entry^.next := nil;
entry^ := token^.length; if result^.members = nil then
entry := entry + 4; result^.members := entry
entry^ := 0;
if memory_start = 0 then
memory_start := entry - 8
else else
previous_entry^ := entry - 8 previous_entry^.next := entry
end; end;
previous_entry := entry; previous_entry := entry;
@@ -3310,12 +3349,6 @@ begin
if token^.kind = ElnaLexerKind.comma then if token^.kind = ElnaLexerKind.comma then
goto elna_parser_enumeration_type_expression_loop goto elna_parser_enumeration_type_expression_loop
end; end;
result := malloc(#size(ElnaTreeEnumerationTypeExpression));
result^.kind := ElnaTreeKind.enumeration_type_expression;
result^.members := memory_start;
result^.length := member_count;
return result return result
end; end;
@@ -3331,7 +3364,7 @@ end;
* *
* Returns enumeration type description. * Returns enumeration type description.
*) *)
proc elna_name_enumeration_type_expression(parser_node: ^ElnaTreeEnumerationTypeExpression); proc elna_name_enumeration_type_expression(parser_node: ^ElnaTreeEnumerationTypeExpression) -> ^ElnaTypeEnumeration;
var var
result: ^ElnaTypeEnumeration; result: ^ElnaTypeEnumeration;
memory_start: Word; memory_start: Word;
@@ -3373,7 +3406,7 @@ begin
return result return result
end; end;
proc elna_name_pointer_type_expression(parser_node: ^ElnaTreePointerTypeExpression); proc elna_name_pointer_type_expression(parser_node: ^ElnaTreePointerTypeExpression) -> ^ElnaTypePointer;
var var
result: ^ElnaTypePointer; result: ^ElnaTypePointer;
begin begin
@@ -3387,7 +3420,7 @@ begin
return result return result
end; end;
proc elna_name_array_type_expression(parser_node: ^ElnaTreeArrayTypeExpression); proc elna_name_array_type_expression(parser_node: ^ElnaTreeArrayTypeExpression) -> ^ElnaTypeArray;
var var
base: ^ElnaType; base: ^ElnaType;
result: ^ElnaTypeArray; result: ^ElnaTypeArray;
@@ -3409,34 +3442,30 @@ begin
return result return result
end; end;
proc elna_name_record_type_expression(parser_node: ^ElnaTreeRecordTypeExpression); proc elna_name_record_type_expression(parser_node: ^ElnaTreeRecordTypeExpression) -> ^ElnaTypeRecord;
var var
result: ^ElnaTypeRecord; result: ^ElnaTypeRecord;
memory_start: Word; tree_field: ^ElnaTreeField;
member_count: Word; member_array_start: ^ElnaTypeField;
member_array_start: Word;
member_array_current: ^ElnaTypeField; member_array_current: ^ElnaTypeField;
field_type: ^ElnaType; field_type: ^ElnaType;
begin begin
result := malloc(#size(ElnaTypeRecord)); result := malloc(#size(ElnaTypeRecord));
result^.kind := ElnaTypeKind._record;
result^.size := 0; result^.size := 0;
result^.alignment := 0; result^.alignment := 0;
result^.length := 0;
result^.members := malloc(parser_node^.length * #size(ElnaTypeField));
memory_start := parser_node^.members; tree_field := parser_node^.members;
member_count := parser_node^.length; member_array_current := result^.members;
member_array_start := malloc(member_count * #size(ElnaTypeField));
member_array_current := member_array_start;
.elna_name_type_record_loop; .elna_name_type_record_loop;
if member_count > 0 then if result^.length < parser_node^.length then
member_array_current^.name := memory_start^; member_array_current^.name := tree_field^.name;
memory_start := memory_start + 4; member_array_current^.length := tree_field^.length;
member_array_current^.length := memory_start^; field_type := elna_name_type_expression(tree_field^.type_expression);
memory_start := memory_start + 4;
field_type := elna_name_type_expression(memory_start^);
result^.size := result^.size + field_type^.size; result^.size := result^.size + field_type^.size;
if field_type^.alignment > result^.alignment then if field_type^.alignment > result^.alignment then
result^.alignment := field_type^.alignment result^.alignment := field_type^.alignment
@@ -3444,21 +3473,16 @@ begin
member_array_current^.field_type := field_type; member_array_current^.field_type := field_type;
member_array_current := member_array_current + 1; member_array_current := member_array_current + 1;
memory_start := memory_start + 4;
memory_start := memory_start^; tree_field := tree_field^.next;
member_count := member_count - 1; result^.length := result^.length + 1;
goto elna_name_type_record_loop goto elna_name_type_record_loop
end; end;
result^.kind := ElnaTypeKind._record;
result^.members := member_array_start;
result^.length := parser_node^.length;
return result return result
end; end;
proc elna_parser_named_type_expression(cursor: ^ElnaLexerCursor); proc elna_parser_named_type_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeNamedTypeExpression;
var var
result: ^ElnaTreeNamedTypeExpression; result: ^ElnaTreeNamedTypeExpression;
token: ^ElnaLexerToken; token: ^ElnaLexerToken;
@@ -3473,7 +3497,7 @@ begin
return result return result
end; end;
proc elna_parser_pointer_type_expression(cursor: ^ElnaLexerCursor); proc elna_parser_pointer_type_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreePointerTypeExpression;
var var
result: ^ElnaTreePointerTypeExpression; result: ^ElnaTreePointerTypeExpression;
begin begin
@@ -3486,7 +3510,7 @@ begin
return result return result
end; end;
proc elna_parser_array_type_expression(cursor: ^ElnaLexerCursor); proc elna_parser_array_type_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeArrayTypeExpression;
var var
result: ^ElnaTreeArrayTypeExpression; result: ^ElnaTreeArrayTypeExpression;
begin begin
@@ -3504,9 +3528,9 @@ begin
return result return result
end; end;
proc elna_parser_type_expression(cursor: ^ElnaLexerCursor); proc elna_parser_type_expression(cursor: ^ElnaLexerCursor) -> ^ElnaTreeNode;
var var
result: Word; result: ^ElnaTreeNode;
token: ^ElnaLexerToken; token: ^ElnaLexerToken;
begin begin
result := nil; result := nil;
@@ -3526,11 +3550,11 @@ begin
return result return result
end; end;
proc elna_name_type_expression(parser_node: ^ElnaTreeNode); proc elna_name_type_expression(parser_node: ^ElnaTreeNode) -> ^ElnaType;
var var
named_type_expression: ^ElnaTreeNamedTypeExpression; named_type_expression: ^ElnaTreeNamedTypeExpression;
type_symbol: ^ElnaSymbolTypeInfo; type_symbol: ^ElnaSymbolTypeInfo;
result: Word; result: ^ElnaType;
begin begin
if parser_node^.kind = ElnaTreeKind.named_type_expression then if parser_node^.kind = ElnaTreeKind.named_type_expression then
named_type_expression := parser_node; named_type_expression := parser_node;
@@ -3551,7 +3575,7 @@ begin
return result return result
end; end;
proc type_info_create(type_representation: Word); proc type_info_create(type_representation: Word) -> ^ElnaSymbolTypeInfo;
var var
result: ^ElnaSymbolTypeInfo; result: ^ElnaSymbolTypeInfo;
begin begin
@@ -3567,7 +3591,7 @@ end;
* attr - Local variable attributes. * attr - Local variable attributes.
* temporary_type - Local variable type. * temporary_type - Local variable type.
*) *)
proc temporary_info_create(attr: Word, temporary_type: Word); proc temporary_info_create(attr: Word, temporary_type: ^ElnaType) -> ^ElnaSymbolTemporaryInfo;
var var
result: ^ElnaSymbolTemporaryInfo; result: ^ElnaSymbolTemporaryInfo;
begin begin
@@ -3585,7 +3609,7 @@ end;
* Parameters: * Parameters:
* symbol_table - Local symbol table. * symbol_table - Local symbol table.
*) *)
proc procedure_info_create(symbol_table: ^ElnaSymbolTable); proc procedure_info_create(symbol_table: ^ElnaSymbolTable) -> ^ElnaSymbolProcedureInfo;
var var
result: ^ElnaSymbolProcedureInfo; result: ^ElnaSymbolProcedureInfo;
begin begin
@@ -3699,7 +3723,7 @@ begin
return result return result
end; end;
proc elna_tac_parameters(ast_list: ^ElnaTreeDeclaration, parameter_count: ^Word); proc elna_tac_parameters(ast_list: ^ElnaTreeDeclaration, parameter_count: ^Word) -> ^Word;
var var
ast_parameter: ^ElnaTreeDeclaration; ast_parameter: ^ElnaTreeDeclaration;
parameter_index: Word; parameter_index: Word;
@@ -3738,7 +3762,7 @@ begin
return parameter_list return parameter_list
end; end;
proc elna_rtl_global_declaration(tac_declaration: ^ElnaTacStaticVariable); proc elna_rtl_global_declaration(tac_declaration: ^ElnaTacStaticVariable) -> ^ElnaRtlStaticVariable;
var var
result: ^ElnaRtlStaticVariable; result: ^ElnaRtlStaticVariable;
begin begin
@@ -3752,7 +3776,7 @@ begin
return result return result
end; end;
proc elna_rtl_parameters(instructions: ^ElnaList, parameters: Word, count: Word); proc elna_rtl_parameters(instructions: ^ElnaList, parameters: Word, count: Word) -> ^ElnaRtlInstruction;
var var
result: ^ElnaRtlInstruction; result: ^ElnaRtlInstruction;
instruction: ^ElnaRtlInstruction; instruction: ^ElnaRtlInstruction;
@@ -3820,7 +3844,7 @@ begin
return pseudo_symbol return pseudo_symbol
end; end;
proc elna_rtl_symbol_table(symbol_table: ^ElnaSymbolTable); proc elna_rtl_symbol_table(symbol_table: ^ElnaSymbolTable) -> ^ElnaSymbolTable;
var var
variable_map: ^ElnaSymbolTable; variable_map: ^ElnaSymbolTable;
count: Word; count: Word;
@@ -3867,7 +3891,7 @@ begin
return variable_map; return variable_map;
end; end;
proc elna_rtl_procedure_declaration(tac_declaration: ^ElnaTacProcedure); proc elna_rtl_procedure_declaration(tac_declaration: ^ElnaTacProcedure) -> ^ElnaRtlProcedure;
var var
result: ^ElnaRtlProcedure; result: ^ElnaRtlProcedure;
begin begin
@@ -3887,7 +3911,7 @@ begin
return result return result
end; end;
proc elna_tac_procedure_declaration(parser_node: ^ElnaTreeProcedureDeclaration); proc elna_tac_procedure_declaration(parser_node: ^ElnaTreeProcedureDeclaration) -> ^ElnaTacProcedure;
var var
symbol_info: ^ElnaSymbolProcedureInfo; symbol_info: ^ElnaSymbolProcedureInfo;
result: ^ElnaTacProcedure; result: ^ElnaTacProcedure;
@@ -3943,7 +3967,7 @@ begin
return result return result
end; end;
proc elna_rtl_globals(tac_procedure: ^ElnaTacStaticVariable); proc elna_rtl_globals(tac_procedure: ^ElnaTacStaticVariable) -> ^ElnaRtlStaticVariable;
var var
current_copy: ^ElnaRtlStaticVariable; current_copy: ^ElnaRtlStaticVariable;
next_copy: ^ElnaRtlStaticVariable; next_copy: ^ElnaRtlStaticVariable;
@@ -3971,7 +3995,7 @@ begin
return first_copy return first_copy
end; end;
proc elna_rtl_procedures(tac_procedure: ^ElnaTacProcedure); proc elna_rtl_procedures(tac_procedure: ^ElnaTacProcedure) -> ^ElnaRtlProcedure;
var var
current_copy: ^ElnaRtlProcedure; current_copy: ^ElnaRtlProcedure;
next_copy: ^ElnaRtlProcedure; next_copy: ^ElnaRtlProcedure;
@@ -4043,7 +4067,7 @@ begin
end end
end; end;
proc elna_parser_type_declaration(cursor: ^ElnaLexerCursor); proc elna_parser_type_declaration(cursor: ^ElnaLexerCursor) -> ^ElnaTreeTypeDeclaration;
var var
result: ^ElnaTreeTypeDeclaration; result: ^ElnaTreeTypeDeclaration;
token: ^ElnaLexerToken; token: ^ElnaLexerToken;
@@ -4066,25 +4090,20 @@ end;
proc elna_name_type_declaration(parser_node: ^ElnaTreeTypeDeclaration); proc elna_name_type_declaration(parser_node: ^ElnaTreeTypeDeclaration);
var var
type_name: Word; symbol_type: ^ElnaType;
name_length: Word; type_info: ^ElnaSymbolTypeInfo;
type_info: Word;
begin begin
type_name := parser_node^.name; symbol_type := elna_name_type_expression(parser_node^._type);
name_length := parser_node^.length; type_info := type_info_create(symbol_type);
parser_node := parser_node^._type; elna_symbol_table_enter(@symbol_table_global, parser_node^.name, parser_node^.length, type_info)
type_info := elna_name_type_expression(parser_node);
type_info := type_info_create(type_info);
elna_symbol_table_enter(@symbol_table_global, type_name, name_length, type_info)
end; end;
proc elna_type_type_declaration(parser_node: Word); proc elna_type_type_declaration(parser_node: Word);
begin begin
end; end;
proc elna_parser_type_part(cursor: ^ElnaLexerCursor); proc elna_parser_type_part(cursor: ^ElnaLexerCursor) -> ^ElnaTreeDeclaration;
var var
parser_node: ^ElnaTreeDeclaration; parser_node: ^ElnaTreeDeclaration;
result: ^ElnaTreeDeclaration; result: ^ElnaTreeDeclaration;
@@ -4120,7 +4139,7 @@ begin
return result return result
end; end;
proc elna_parser_variable_declaration(cursor: ^ElnaLexerCursor); proc elna_parser_variable_declaration(cursor: ^ElnaLexerCursor) -> ^ElnaTreeVariableDeclaration;
var var
variable_type: Word; variable_type: Word;
result: ^ElnaTreeVariableDeclaration; result: ^ElnaTreeVariableDeclaration;
@@ -4143,7 +4162,7 @@ begin
return result return result
end; end;
proc elna_tac_variable_declaration(parser_tree: ^ElnaTreeVariableDeclaration); proc elna_tac_variable_declaration(parser_tree: ^ElnaTreeVariableDeclaration) -> ^ElnaTacStaticVariable;
var var
result: ^ElnaTacStaticVariable; result: ^ElnaTacStaticVariable;
variable_info: ^ElnaSymbolTemporaryInfo; variable_info: ^ElnaSymbolTemporaryInfo;
@@ -4159,14 +4178,14 @@ begin
return result return result
end; end;
proc elna_parser_var_part(cursor: ^ElnaLexerCursor); proc elna_parser_var_part(cursor: ^ElnaLexerCursor) -> ^ElnaTreeDeclaration;
var var
result: Word; result: ^ElnaTreeDeclaration;
variable_node: Word; variable_node: ^ElnaTreeDeclaration;
current_declaration: ^ElnaTreeDeclaration; current_declaration: ^ElnaTreeDeclaration;
token: ^ElnaLexerToken; token: ^ElnaLexerToken;
begin begin
result := 0; result := nil;
token := elna_lexer_peek(cursor); token := elna_lexer_peek(cursor);
if token^.kind <> ElnaLexerKind._var then if token^.kind <> ElnaLexerKind._var then
@@ -4185,7 +4204,7 @@ begin
(* Skip semicolon. *) (* Skip semicolon. *)
elna_lexer_read(cursor); elna_lexer_read(cursor);
if result = 0 then if result = nil then
result := variable_node result := variable_node
else else
current_declaration^.next := variable_node current_declaration^.next := variable_node
@@ -4198,20 +4217,20 @@ begin
return result return result
end; end;
proc elna_tac_var_part(parser_node: ^ElnaTreeDeclaration); proc elna_tac_var_part(parser_node: ^ElnaTreeDeclaration) -> ^ElnaTacStaticVariable;
var var
node: ^ElnaTacStaticVariable; node: ^ElnaTacStaticVariable;
current_variable: ^ElnaTacStaticVariable; current_variable: ^ElnaTacStaticVariable;
first_variable: ^ElnaTacStaticVariable; first_variable: ^ElnaTacStaticVariable;
begin begin
first_variable := 0; first_variable := nil;
if parser_node = 0 then if parser_node = nil then
goto elna_tac_var_part_end goto elna_tac_var_part_end
end; end;
.elna_tac_var_part_loop; .elna_tac_var_part_loop;
node := elna_tac_variable_declaration(parser_node); node := elna_tac_variable_declaration(parser_node);
if first_variable = 0 then if first_variable = nil then
first_variable := node first_variable := node
else else
current_variable^.next := node current_variable^.next := node
@@ -4219,7 +4238,7 @@ begin
current_variable := node; current_variable := node;
parser_node := parser_node^.next; parser_node := parser_node^.next;
if parser_node <> 0 then if parser_node <> nil then
goto elna_tac_var_part_loop goto elna_tac_var_part_loop
end; end;
@@ -4273,7 +4292,7 @@ begin
return result return result
end; end;
proc elna_tac_program_body(parser_node: ^ElnaTreeStatement); proc elna_tac_program_body(parser_node: ^ElnaTreeStatement) -> ^ElnaTacProcedure;
var var
result: ^ElnaTacProcedure; result: ^ElnaTacProcedure;
symbol_info: ^ElnaSymbolProcedureInfo; symbol_info: ^ElnaSymbolProcedureInfo;
@@ -4298,7 +4317,7 @@ begin
return result return result
end; end;
proc elna_tac_module_declaration(parser_node: ^ElnaTreeModuleDeclaration); proc elna_tac_module_declaration(parser_node: ^ElnaTreeModuleDeclaration) -> ^ElnaInstructionModule;
var var
result: ^ElnaInstructionModule; result: ^ElnaInstructionModule;
code: ^ElnaTacProcedure; code: ^ElnaTacProcedure;