Extend ElnaErrorList to a generic ElnaList

This commit is contained in:
2026-02-22 23:39:50 +01:00
parent b987dd741a
commit c3d4449fc7

View File

@@ -8,12 +8,17 @@ program;
(* Stage 20 compiler. *) (* Stage 20 compiler. *)
type type
ElnaListNode = record
next: Word
end;
ElnaList = record
first: ^ElnaListNode;
last: ^ElnaListNode
end;
(** (**
* List of intermediate representation items. * List of intermediate representation items.
*) *)
ElnaInstructionList = record
next: Word
end;
ElnaInstructionModule = record ElnaInstructionModule = record
data: Word; data: Word;
code: Word code: Word
@@ -308,10 +313,6 @@ type
symbol_table: ^ElnaSymbolTable symbol_table: ^ElnaSymbolTable
end; end;
ElnaErrorList = record
first: Word;
last: Word
end;
ElnaError = record ElnaError = record
next: Word next: Word
end; end;
@@ -475,8 +476,7 @@ type
ElnaTacOperand = record ElnaTacOperand = record
kind: ElnaTacKind; kind: ElnaTacKind;
value: Word; value: Word;
length: Word; length: Word
offset: Word
end; end;
ElnaTacInstruction = record ElnaTacInstruction = record
next: Word; next: Word;
@@ -487,7 +487,7 @@ type
next: Word; next: Word;
name: Word; name: Word;
length: Word; length: Word;
body: Word; body: ElnaList;
parameters: Word; parameters: Word;
count: Word; count: Word;
symbol_table: ^ElnaSymbolTable symbol_table: ^ElnaSymbolTable
@@ -532,8 +532,7 @@ type
ElnaRtlOperand = record ElnaRtlOperand = record
kind: ElnaRtlKind; kind: ElnaRtlKind;
value: Word; value: Word;
length: Word; length: Word
offset: Word
end; end;
ElnaRtlStaticVariable = record ElnaRtlStaticVariable = record
next: Word; next: Word;
@@ -758,6 +757,32 @@ proc _is_alnum(character: Word);
return _is_alpha(character) or isdigit(character) return _is_alpha(character) or isdigit(character)
end; end;
proc elna_list_initialize(list: ^ElnaList);
begin
list^.first := nil;
list^.last := nil
end;
proc elna_list_append(list: ^ElnaList, element: ^ElnaListNode);
begin
if element <> nil then
if list^.first = nil then
list^.first := element
else
list^.last^.next := element
end;
(* TODO: This is a temporary solution for the migration from the old lists. *)
.elna_list_append_loop;
if element^.next = nil then
list^.last := element
else
element := element^.next;
goto elna_list_append_loop
end
end;
return element
end;
proc elna_tac_generate_pseudo(operand_type: Word, operand_value: Word, operand_length: Word, symbol_table: ^ElnaSymbolTable); proc elna_tac_generate_pseudo(operand_type: Word, operand_value: Word, operand_length: Word, symbol_table: ^ElnaSymbolTable);
var var
buffer: Word; buffer: Word;
@@ -776,7 +801,7 @@ begin
elna_symbol_table_enter(symbol_table, buffer, operand_length^, temporary_info) elna_symbol_table_enter(symbol_table, buffer, operand_length^, temporary_info)
end; end;
proc elna_instruction_list_concatenate(this: ^ElnaInstructionList, value: Word); proc elna_instruction_list_concatenate(this: ^ElnaListNode, value: Word);
var var
start: Word; start: Word;
begin begin
@@ -812,7 +837,7 @@ begin
result := malloc(#size(ElnaTacInstruction)); result := malloc(#size(ElnaTacInstruction));
result^.operator := kind; result^.operator := kind;
elna_instruction_list_concatenate(result, nil); result^.next := nil;
return result return result
end; end;
@@ -1261,15 +1286,13 @@ begin
return result return result
end; end;
proc elna_tac_label(counter: Word, length: Word); proc elna_tac_label(instructions: ^ElnaList, counter: Word, length: Word);
var var
result: Word; result: Word;
begin begin
result := elna_tac_instruction_create(ElnaTacOperator.label); result := elna_tac_instruction_create(ElnaTacOperator.label);
elna_tac_instruction_set_operand(result, 1, ElnaTacKind.symbol, counter, length); elna_tac_instruction_set_operand(result, 1, ElnaTacKind.symbol, counter, length);
elna_list_append(instructions, result)
return result
end; end;
proc elna_riscv_instruction_name(instruction_kind: Word); proc elna_riscv_instruction_name(instruction_kind: Word);
@@ -1809,27 +1832,21 @@ proc elna_tac_integer_literal(integer_literal_node: ^ElnaTreeIntegerLiteral, ope
begin begin
operand^.kind := ElnaTacKind.immediate; operand^.kind := ElnaTacKind.immediate;
operand^.value := integer_literal_node^.value; operand^.value := integer_literal_node^.value;
operand^.length := 0; operand^.length := 0
return nil
end; end;
proc elna_tac_boolean_literal(boolean_literal_node: ^ElnaTreeBooleanLiteral, operand: ^ElnaTacOperand); proc elna_tac_boolean_literal(boolean_literal_node: ^ElnaTreeBooleanLiteral, operand: ^ElnaTacOperand);
begin begin
operand^.kind := ElnaTacKind.immediate; operand^.kind := ElnaTacKind.immediate;
operand^.value := boolean_literal_node^.value; operand^.value := boolean_literal_node^.value;
operand^.length := 0; operand^.length := 0
return nil
end; end;
proc elna_tac_nil_literal(nil_node: Word, operand: ^ElnaTacOperand); proc elna_tac_nil_literal(nil_node: Word, operand: ^ElnaTacOperand);
begin begin
operand^.kind := ElnaTacKind.immediate; operand^.kind := ElnaTacKind.immediate;
operand^.value := 0; operand^.value := 0;
operand^.length := 0; operand^.length := 0
return nil
end; end;
proc elna_parser_character_literal(); proc elna_parser_character_literal();
@@ -1851,9 +1868,7 @@ proc elna_tac_character_literal(character_literal_node: ^ElnaTreeCharacterLitera
begin begin
operand^.kind := ElnaTacKind.immediate; operand^.kind := ElnaTacKind.immediate;
operand^.value := character_literal_node^.value; operand^.value := character_literal_node^.value;
operand^.length := character_literal_node^.length; operand^.length := character_literal_node^.length
return nil
end; end;
proc elna_parser_variable_expression(); proc elna_parser_variable_expression();
@@ -1887,8 +1902,7 @@ begin
operand^.kind := ElnaTacKind.symbol; operand^.kind := ElnaTacKind.symbol;
operand^.value := variable_expression^.name; operand^.value := variable_expression^.name;
operand^.length := variable_expression^.length operand^.length := variable_expression^.length
end; end
return nil
end; end;
proc elna_parser_string_literal(); proc elna_parser_string_literal();
@@ -1907,28 +1921,27 @@ begin
return result return result
end; end;
proc elna_tac_string_literal(string_literal_node: ^ElnaTreeStringLiteral, proc elna_tac_string_literal(instructions: ^ElnaList, string_literal_node: ^ElnaTreeStringLiteral,
symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand); symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand);
var var
offset: Word; offset: Word;
first_instruction: Word; instruction: Word;
next_instruction: Word;
begin begin
offset := _add_string(string_literal_node^.value); offset := _add_string(string_literal_node^.value);
elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table); elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table);
first_instruction := elna_tac_instruction_create(ElnaTacOperator.get_address); instruction := elna_tac_instruction_create(ElnaTacOperator.get_address);
elna_tac_instruction_set_operand(first_instruction, 1, operand^.kind, operand^.value, operand^.length); elna_tac_instruction_set_operand(instruction, 1, operand^.kind, operand^.value, operand^.length);
elna_tac_instruction_set_operand(first_instruction, 2, ElnaTacKind.symbol, "strings", 7); elna_tac_instruction_set_operand(instruction, 2, ElnaTacKind.symbol, "strings", 7);
elna_list_append(instructions, instruction);
(* Add offset to the string block pointer. *) (* Add offset to the string block pointer. *)
next_instruction := elna_tac_instruction_create(ElnaTacOperator.add); instruction := elna_tac_instruction_create(ElnaTacOperator.add);
elna_tac_instruction_set_operand(next_instruction, 1, operand^.kind, operand^.value, operand^.length); elna_tac_instruction_set_operand(instruction, 1, operand^.kind, operand^.value, operand^.length);
elna_tac_instruction_set_operand(next_instruction, 2, operand^.kind, operand^.value, operand^.length); elna_tac_instruction_set_operand(instruction, 2, operand^.kind, operand^.value, operand^.length);
elna_tac_instruction_set_operand(next_instruction, 3, ElnaTacKind.immediate, offset, 0); elna_tac_instruction_set_operand(instruction, 3, ElnaTacKind.immediate, offset, 0);
elna_list_append(instructions, instruction)
return elna_instruction_list_concatenate(first_instruction, next_instruction)
end; end;
proc elna_parser_trait_expression(); proc elna_parser_trait_expression();
@@ -2033,31 +2046,27 @@ begin
operand^.kind := ElnaTacKind.immediate; operand^.kind := ElnaTacKind.immediate;
operand^.value := info_type^.size; operand^.value := info_type^.size;
operand^.length := 0; operand^.length := 0
return nil
end; end;
proc elna_tac_simple_expression(parser_node: ^ElnaTreeNode, symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand); proc elna_tac_simple_expression(instructions: ^ElnaList, parser_node: ^ElnaTreeNode,
var symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand);
instruction: Word;
begin begin
if parser_node^.kind = ElnaTreeKind.character_literal then if parser_node^.kind = ElnaTreeKind.character_literal then
instruction := elna_tac_character_literal(parser_node, operand) elna_tac_character_literal(parser_node, operand)
elsif parser_node^.kind = ElnaTreeKind.string_literal then elsif parser_node^.kind = ElnaTreeKind.string_literal then
instruction := elna_tac_string_literal(parser_node, symbol_table, operand) elna_tac_string_literal(instructions, parser_node, symbol_table, operand)
elsif parser_node^.kind = ElnaTreeKind.integer_literal then elsif parser_node^.kind = ElnaTreeKind.integer_literal then
instruction := elna_tac_integer_literal(parser_node, operand) elna_tac_integer_literal(parser_node, operand)
elsif parser_node^.kind = ElnaTreeKind.boolean_literal then elsif parser_node^.kind = ElnaTreeKind.boolean_literal then
instruction := elna_tac_boolean_literal(parser_node, operand) elna_tac_boolean_literal(parser_node, operand)
elsif parser_node^.kind = ElnaTreeKind.null then elsif parser_node^.kind = ElnaTreeKind.null then
instruction := elna_tac_nil_literal(parser_node, operand) elna_tac_nil_literal(parser_node, operand)
elsif parser_node^.kind = ElnaTreeKind.trait_expression then elsif parser_node^.kind = ElnaTreeKind.trait_expression then
instruction := elna_tac_trait_expression(parser_node, operand) elna_tac_trait_expression(parser_node, operand)
else else
instruction := elna_tac_variable_expression(parser_node, symbol_table, operand) elna_tac_variable_expression(parser_node, symbol_table, operand)
end; end
return instruction
end; end;
proc elna_parser_unary_expression(); proc elna_parser_unary_expression();
@@ -2095,7 +2104,7 @@ begin
return result return result
end; end;
proc elna_tac_copy_address(is_address: Word, from_type: Word, from_value: Word, from_length: Word, to_type: Word, to_value: Word, to_length: Word); proc elna_tac_copy_address(instructions: ^ElnaList, is_address: Word, from: ^ElnaTacOperand, to: ^ElnaTacOperand);
var var
instruction: Word; instruction: Word;
begin begin
@@ -2104,23 +2113,21 @@ begin
else else
instruction := elna_tac_instruction_create(ElnaTacOperator.get_address) instruction := elna_tac_instruction_create(ElnaTacOperator.get_address)
end; end;
elna_tac_instruction_set_operand(instruction, 1, to_type, to_value, to_length); elna_tac_instruction_set_operand(instruction, 1, to^.kind, to^.value, to^.length);
elna_tac_instruction_set_operand(instruction, 2, from_type, from_value, from_length); elna_tac_instruction_set_operand(instruction, 2, from^.kind, from^.value, from^.length);
return instruction elna_list_append(instructions, instruction)
end; end;
proc elna_tac_unary_expression(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;
unary_operand: ^ElnaTreeExpression; unary_operand: ^ElnaTreeExpression;
is_address: Word; is_address: Word;
first_instruction: Word;
instruction: Word; instruction: Word;
base: ElnaTacOperand; base: ElnaTacOperand;
begin begin
instruction := nil;
if parser_node^.kind = ElnaTreeKind.unary_expression then if parser_node^.kind = ElnaTreeKind.unary_expression then
operator := parser_node^.operator; operator := parser_node^.operator;
unary_operand := parser_node^.operand unary_operand := parser_node^.operand
@@ -2128,31 +2135,33 @@ begin
operator := 0; operator := 0;
unary_operand := parser_node unary_operand := parser_node
end; end;
first_instruction := elna_tac_designator(unary_operand, symbol_table, @is_address, @base); elna_tac_designator(instructions, unary_operand, symbol_table, @is_address, @base);
elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table); elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table);
if operator = '@' then if operator = '@' then
instruction := elna_tac_copy_address(is_address, base.kind, base.value, base.length, elna_tac_copy_address(instructions, is_address, @base, operand)
operand^.kind, operand^.value, operand^.length)
elsif operator = '-' then elsif operator = '-' then
instruction := elna_tac_instruction_create(ElnaTacOperator.negate); instruction := elna_tac_instruction_create(ElnaTacOperator.negate);
elna_tac_instruction_set_operand(instruction, 1, operand^.kind, operand^.value, operand^.length); elna_tac_instruction_set_operand(instruction, 1, operand^.kind, operand^.value, operand^.length);
elna_tac_instruction_set_operand(instruction, 2, base.kind, base.value, base.length) elna_tac_instruction_set_operand(instruction, 2, base.kind, base.value, base.length);
elna_list_append(instructions, instruction)
elsif operator = '~' then elsif operator = '~' then
instruction := elna_tac_instruction_create(ElnaTacOperator.complement); instruction := elna_tac_instruction_create(ElnaTacOperator.complement);
elna_tac_instruction_set_operand(instruction, 1, operand^.kind, operand^.value, operand^.length); elna_tac_instruction_set_operand(instruction, 1, operand^.kind, operand^.value, operand^.length);
elna_tac_instruction_set_operand(instruction, 2, base.kind, base.value, base.length) elna_tac_instruction_set_operand(instruction, 2, base.kind, base.value, base.length);
elna_list_append(instructions, instruction)
elsif is_address then elsif is_address then
instruction := elna_tac_instruction_create(ElnaTacOperator.load); instruction := elna_tac_instruction_create(ElnaTacOperator.load);
elna_tac_instruction_set_operand(instruction, 1, base.kind, base.value, base.length); elna_tac_instruction_set_operand(instruction, 1, base.kind, base.value, base.length);
elna_tac_instruction_set_operand(instruction, 2, operand^.kind, operand^.value, operand^.length) elna_tac_instruction_set_operand(instruction, 2, operand^.kind, operand^.value, operand^.length);
elna_list_append(instructions, instruction)
else else
instruction := elna_tac_instruction_create(ElnaTacOperator.copy); instruction := elna_tac_instruction_create(ElnaTacOperator.copy);
elna_tac_instruction_set_operand(instruction, 1, operand^.kind, operand^.value, operand^.length); elna_tac_instruction_set_operand(instruction, 1, operand^.kind, operand^.value, operand^.length);
elna_tac_instruction_set_operand(instruction, 2, base.kind, base.value, base.length) elna_tac_instruction_set_operand(instruction, 2, base.kind, base.value, base.length);
end; elna_list_append(instructions, instruction)
return elna_instruction_list_concatenate(first_instruction, instruction) end
end; end;
proc elna_parser_binary_expression(); proc elna_parser_binary_expression();
@@ -2223,7 +2232,7 @@ begin
return result return result
end; end;
proc elna_tac_binary_expression(parser_node: ^ElnaTreeBinaryExpression, symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand); proc elna_tac_binary_expression(instructions: ^ElnaList, parser_node: ^ElnaTreeBinaryExpression, symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand);
var var
first_instruction: Word; first_instruction: Word;
instruction: Word; instruction: Word;
@@ -2231,11 +2240,10 @@ var
rhs: ElnaTacOperand; rhs: ElnaTacOperand;
begin begin
if parser_node^.kind <> ElnaTreeKind.binary_expression then if parser_node^.kind <> ElnaTreeKind.binary_expression then
first_instruction := elna_tac_unary_expression(parser_node, symbol_table, operand) elna_tac_unary_expression(instructions, parser_node, symbol_table, operand)
else else
first_instruction := elna_tac_unary_expression(parser_node^.lhs, symbol_table, @lhs); elna_tac_unary_expression(instructions, parser_node^.lhs, symbol_table, @lhs);
instruction := elna_tac_unary_expression(parser_node^.rhs, symbol_table, @rhs); elna_tac_unary_expression(instructions, parser_node^.rhs, symbol_table, @rhs);
first_instruction := elna_instruction_list_concatenate(first_instruction, instruction);
if parser_node^.operator = ElnaLexerKind.plus then if parser_node^.operator = ElnaLexerKind.plus then
instruction := elna_tac_instruction_create(ElnaTacOperator.add) instruction := elna_tac_instruction_create(ElnaTacOperator.add)
@@ -2272,9 +2280,9 @@ begin
elna_tac_instruction_set_operand(instruction, 2, lhs.kind, lhs.value, lhs.length); elna_tac_instruction_set_operand(instruction, 2, lhs.kind, lhs.value, lhs.length);
elna_tac_instruction_set_operand(instruction, 3, rhs.kind, rhs.value, rhs.length); elna_tac_instruction_set_operand(instruction, 3, rhs.kind, rhs.value, rhs.length);
first_instruction := elna_instruction_list_concatenate(first_instruction, instruction) elna_list_append(instructions, instruction)
end; end;
return first_instruction return instructions^.first
end; end;
proc elna_parser_call(callee: Word); proc elna_parser_call(callee: Word);
@@ -2327,18 +2335,14 @@ begin
return result return result
end; end;
proc elna_tac_call(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;
instruction: Word;
first_instruction: Word;
current_instruction: Word;
arguments_operand: ^ElnaTacOperand; arguments_operand: ^ElnaTacOperand;
call_instruction: Word; call_instruction: Word;
argument_entry: ^ElnaTreeExpressionList; argument_entry: ^ElnaTreeExpressionList;
begin begin
parsed_expression := parsed_call^.callee; parsed_expression := parsed_call^.callee;
first_instruction := nil;
arguments_operand := malloc(parsed_call^.count * #size(ElnaTacOperand)); arguments_operand := malloc(parsed_call^.count * #size(ElnaTacOperand));
elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table); elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table);
@@ -2352,26 +2356,13 @@ begin
.elna_tac_call_loop; .elna_tac_call_loop;
if argument_entry <> nil then if argument_entry <> nil then
instruction := elna_tac_binary_expression(argument_entry^.expression, symbol_table, arguments_operand); elna_tac_binary_expression(instructions, argument_entry^.expression, symbol_table, arguments_operand);
if first_instruction = nil then
first_instruction := instruction
else
elna_instruction_list_concatenate(current_instruction, instruction)
end;
if instruction <> nil then
current_instruction := instruction
end;
arguments_operand := arguments_operand + #size(ElnaTacOperand); arguments_operand := arguments_operand + #size(ElnaTacOperand);
argument_entry := argument_entry^.next; argument_entry := argument_entry^.next;
goto elna_tac_call_loop goto elna_tac_call_loop
end; end;
if first_instruction = nil then elna_list_append(instructions, call_instruction)
first_instruction := call_instruction
else
elna_instruction_list_concatenate(current_instruction, call_instruction)
end;
return first_instruction
end; end;
proc elna_parser_goto_statement(); proc elna_parser_goto_statement();
@@ -2393,21 +2384,21 @@ begin
return result return result
end; end;
proc elna_tac_goto_statement(parser_node: ^ElnaTreeGotoStatement); proc elna_tac_goto_statement(instructions: ^ElnaList, parser_node: ^ElnaTreeGotoStatement);
var var
label_length1: Word; label_length: Word;
label_with_dot1: Word; label_with_dot: Word;
instruction1: Word; instruction: Word;
begin begin
label_length1 := parser_node^.length + 1; label_length := parser_node^.length + 1;
label_with_dot1 := malloc(label_length1); label_with_dot := malloc(label_length);
_store_byte('.', label_with_dot1); _store_byte('.', label_with_dot);
memcpy(label_with_dot1 + 1, parser_node^.label, parser_node^.length); memcpy(label_with_dot + 1, parser_node^.label, parser_node^.length);
instruction1 := elna_tac_instruction_create(ElnaTacOperator.jump); instruction := elna_tac_instruction_create(ElnaTacOperator.jump);
elna_tac_instruction_set_operand(instruction1, 1, ElnaTacKind.symbol, label_with_dot1, label_length1); elna_tac_instruction_set_operand(instruction, 1, ElnaTacKind.symbol, label_with_dot, label_length);
return instruction1 elna_list_append(instructions, instruction)
end; end;
proc elna_parser_label_declaration(); proc elna_parser_label_declaration();
@@ -2430,8 +2421,9 @@ begin
return result return result
end; end;
proc elna_tac_label_declaration(parser_node: ^ElnaTreeLabelDeclaration); proc elna_tac_label_declaration(instructions: ^ElnaList, parser_node: ^ElnaTreeLabelDeclaration);
return elna_tac_label(parser_node^.label, parser_node^.length) begin
elna_tac_label(instructions, parser_node^.label, parser_node^.length)
end; end;
proc elna_tac_enumeration_value(field_access_expression: ^ElnaTreeFieldAccessExpression, operand: ^ElnaTacOperand); proc elna_tac_enumeration_value(field_access_expression: ^ElnaTreeFieldAccessExpression, operand: ^ElnaTacOperand);
@@ -2473,8 +2465,7 @@ begin
operand^.kind := ElnaTacKind.immediate; operand^.kind := ElnaTacKind.immediate;
operand^.value := counter; operand^.value := counter;
operand^.length := 0 operand^.length := 0
end; end
return nil
end; end;
proc elna_parser_field_access_expression(aggregate: Word); proc elna_parser_field_access_expression(aggregate: Word);
@@ -2519,64 +2510,59 @@ begin
return result return result
end; end;
proc elna_tac_dereference_expression(dereference_expression: ^ElnaTreeDereferenceExpression, proc elna_tac_dereference_expression(instructions: ^ElnaList, dereference_expression: ^ElnaTreeDereferenceExpression,
symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand); symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand);
var var
result_instructions: Word;
load_instruction: Word; load_instruction: Word;
is_address: Word; is_address: Word;
begin begin
result_instructions := elna_tac_designator(dereference_expression^.pointer, symbol_table, @is_address, operand); elna_tac_designator(instructions, dereference_expression^.pointer, symbol_table, @is_address, operand);
if is_address = true then if is_address = true then
load_instruction := elna_tac_instruction_create(ElnaTacOperator.load); load_instruction := elna_tac_instruction_create(ElnaTacOperator.load);
elna_tac_instruction_set_operand(load_instruction, 1, operand^.kind, operand^.value, operand^.length); elna_tac_instruction_set_operand(load_instruction, 1, operand^.kind, operand^.value, operand^.length);
elna_tac_instruction_set_operand(load_instruction, 2, operand^.kind, operand^.value, operand^.length); elna_tac_instruction_set_operand(load_instruction, 2, operand^.kind, operand^.value, operand^.length);
result_instructions := elna_instruction_list_concatenate(result_instructions, load_instruction) elna_list_append(instructions, load_instruction)
end; end
return result_instructions
end; end;
proc elna_tac_designator(parser_node: ^ElnaTreeExpression, symbol_table: ElnaSymbolTable, is_address: Word, operand: ^ElnaTacOperand); proc elna_tac_designator(instructions: ^ElnaList, parser_node: ^ElnaTreeExpression, symbol_table: ElnaSymbolTable, is_address: Word, operand: ^ElnaTacOperand);
var var
field_access_expression: ^ElnaTreeFieldAccessExpression; field_access_expression: ^ElnaTreeFieldAccessExpression;
result_instructions: Word;
designator_base: ^ElnaTreeExpression; designator_base: ^ElnaTreeExpression;
begin begin
if parser_node^.kind = ElnaTreeKind.dereference_expression then if parser_node^.kind = ElnaTreeKind.dereference_expression then
result_instructions := elna_tac_dereference_expression(parser_node, symbol_table, operand); elna_tac_dereference_expression(instructions, parser_node, symbol_table, operand);
is_address^ := true is_address^ := true
elsif parser_node^.kind = ElnaTreeKind.field_access_expression then elsif parser_node^.kind = ElnaTreeKind.field_access_expression then
field_access_expression := parser_node; field_access_expression := parser_node;
designator_base := field_access_expression^.aggregate; designator_base := field_access_expression^.aggregate;
if designator_base^.type_decoration = nil then if designator_base^.type_decoration = nil then
result_instructions := elna_tac_enumeration_value(field_access_expression, operand); elna_tac_enumeration_value(field_access_expression, operand);
is_address^ := false is_address^ := false
else else
result_instructions := elna_tac_field_access_expression(field_access_expression, symbol_table, operand); elna_tac_field_access_expression(instructions, field_access_expression, symbol_table, operand);
is_address^ := true is_address^ := true
end; end
elsif parser_node^.kind = ElnaTreeKind.array_access_expression then elsif parser_node^.kind = ElnaTreeKind.array_access_expression then
result_instructions := elna_tac_array_access_expression(parser_node, symbol_table, operand); elna_tac_array_access_expression(instructions, parser_node, symbol_table, operand);
is_address^ := true is_address^ := true
elsif parser_node^.kind = ElnaTreeKind.call then elsif parser_node^.kind = ElnaTreeKind.call then
result_instructions := elna_tac_call(parser_node, symbol_table, operand); elna_tac_call(instructions, parser_node, symbol_table, operand);
is_address^ := false is_address^ := false
else else
result_instructions := elna_tac_simple_expression(parser_node, symbol_table, operand); elna_tac_simple_expression(instructions, parser_node, symbol_table, operand);
is_address^ := false is_address^ := false
end; end
return result_instructions
end; end;
proc elna_tac_field_access_expression(field_access_expression: ^ElnaTreeFieldAccessExpression, proc elna_tac_field_access_expression(instructions: ^ElnaList, field_access_expression: ^ElnaTreeFieldAccessExpression,
symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand); symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand);
var var
field_type: ^ElnaType; field_type: ^ElnaType;
first_instruction: Word; instruction: Word;
last_instruction: Word;
designator_base: ^ElnaTreeExpression; designator_base: ^ElnaTreeExpression;
aggregate_type: ^ElnaTypeRecord; aggregate_type: ^ElnaTypeRecord;
field_count: Word; field_count: Word;
@@ -2588,7 +2574,7 @@ begin
designator_base := field_access_expression^.aggregate; designator_base := field_access_expression^.aggregate;
aggregate_type := designator_base^.type_decoration; aggregate_type := designator_base^.type_decoration;
first_instruction := elna_tac_designator(designator_base, symbol_table, @is_address, @base); elna_tac_designator(instructions, designator_base, symbol_table, @is_address, @base);
field_count := aggregate_type^.length; field_count := aggregate_type^.length;
current_field := aggregate_type^.members; current_field := aggregate_type^.members;
@@ -2604,25 +2590,19 @@ begin
goto elna_tac_field_access_expression_field goto elna_tac_field_access_expression_field
end; end;
elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table); elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table);
elna_tac_copy_address(instructions, is_address, @base, operand);
last_instruction := elna_tac_copy_address(is_address, base.kind, base.value, base.length, operand^.kind, operand^.value, operand^.length); instruction := elna_tac_instruction_create(ElnaTacOperator.add);
first_instruction := elna_instruction_list_concatenate(first_instruction, last_instruction); elna_tac_instruction_set_operand(instruction, 1, operand^.kind, operand^.value, operand^.length);
elna_tac_instruction_set_operand(instruction, 2, ElnaTacKind.immediate, field_offset, 0);
last_instruction := elna_tac_instruction_create(ElnaTacOperator.add); elna_tac_instruction_set_operand(instruction, 3, operand^.kind, operand^.value, operand^.length);
elna_tac_instruction_set_operand(last_instruction, 1, operand^.kind, operand^.value, operand^.length); elna_list_append(instructions, instruction)
elna_tac_instruction_set_operand(last_instruction, 2, ElnaTacKind.immediate, field_offset, 0);
elna_tac_instruction_set_operand(last_instruction, 3, operand^.kind, operand^.value, operand^.length);
return elna_instruction_list_concatenate(first_instruction, last_instruction)
end; end;
proc elna_tac_array_access_expression(array_access_expression: ^ElnaTreeArrayAccessExpression, proc elna_tac_array_access_expression(instructions: ^ElnaList, array_access_expression: ^ElnaTreeArrayAccessExpression,
symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand); symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand);
var var
array_instructions: Word; instruction: Word;
index_instructions: Word;
offset_instruction: Word;
add_instruction: Word;
is_address: Word; is_address: Word;
inter_operand: ElnaTacOperand; inter_operand: ElnaTacOperand;
index_type: Word; index_type: Word;
@@ -2636,36 +2616,32 @@ begin
aggregate_type := designator_base^.type_decoration; aggregate_type := designator_base^.type_decoration;
element_type := aggregate_type^.base; element_type := aggregate_type^.base;
index_instructions := elna_tac_binary_expression(array_access_expression^.index, symbol_table, @inter_operand); elna_tac_binary_expression(instructions, array_access_expression^.index, symbol_table, @inter_operand);
elna_tac_generate_pseudo(@index_type, @index_value, @index_length, symbol_table); elna_tac_generate_pseudo(@index_type, @index_value, @index_length, symbol_table);
add_instruction := elna_tac_instruction_create(ElnaTacOperator.subtract); instruction := elna_tac_instruction_create(ElnaTacOperator.subtract);
elna_tac_instruction_set_operand(add_instruction, 1, index_type, index_value, index_length); elna_tac_instruction_set_operand(instruction, 1, index_type, index_value, index_length);
elna_tac_instruction_set_operand(add_instruction, 2, inter_operand.kind, inter_operand.value, inter_operand.length); elna_tac_instruction_set_operand(instruction, 2, inter_operand.kind, inter_operand.value, inter_operand.length);
elna_tac_instruction_set_operand(add_instruction, 3, ElnaTacKind.immediate, 1, 0); elna_tac_instruction_set_operand(instruction, 3, ElnaTacKind.immediate, 1, 0);
elna_list_append(instructions, instruction);
offset_instruction := elna_tac_instruction_create(ElnaTacOperator.multiply); instruction := elna_tac_instruction_create(ElnaTacOperator.multiply);
elna_tac_instruction_set_operand(offset_instruction, 1, index_type, index_value, index_length); elna_tac_instruction_set_operand(instruction, 1, index_type, index_value, index_length);
elna_tac_instruction_set_operand(offset_instruction, 2, index_type, index_value, index_length); elna_tac_instruction_set_operand(instruction, 2, index_type, index_value, index_length);
elna_tac_instruction_set_operand(offset_instruction, 3, ElnaTacKind.immediate, element_type^.size, 0); elna_tac_instruction_set_operand(instruction, 3, ElnaTacKind.immediate, element_type^.size, 0);
elna_list_append(instructions, instruction);
elna_instruction_list_concatenate(add_instruction, offset_instruction); elna_tac_designator(instructions, array_access_expression^.array, symbol_table, @is_address, @inter_operand);
index_instructions := elna_instruction_list_concatenate(index_instructions, add_instruction);
array_instructions := elna_tac_designator(array_access_expression^.array, symbol_table, @is_address, @inter_operand);
elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table); elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table);
elna_instruction_list_concatenate(offset_instruction, array_instructions);
array_instructions := elna_tac_copy_address(is_address, inter_operand.kind, inter_operand.value, inter_operand.length, elna_tac_copy_address(instructions, is_address, @inter_operand, operand);
operand^.kind, operand^.value, operand^.length);
elna_instruction_list_concatenate(offset_instruction, array_instructions);
add_instruction := elna_tac_instruction_create(ElnaTacOperator.add); instruction := elna_tac_instruction_create(ElnaTacOperator.add);
elna_tac_instruction_set_operand(add_instruction, 1, operand^.kind, operand^.value, operand^.length); elna_tac_instruction_set_operand(instruction, 1, operand^.kind, operand^.value, operand^.length);
elna_tac_instruction_set_operand(add_instruction, 2, operand^.kind, operand^.value, operand^.length); elna_tac_instruction_set_operand(instruction, 2, operand^.kind, operand^.value, operand^.length);
elna_tac_instruction_set_operand(add_instruction, 3, index_type, index_value, index_length); elna_tac_instruction_set_operand(instruction, 3, index_type, index_value, index_length);
return elna_instruction_list_concatenate(index_instructions, add_instruction) elna_list_append(instructions, instruction)
end; end;
proc elna_parser_assign_statement(assignee: Word); proc elna_parser_assign_statement(assignee: Word);
@@ -2688,70 +2664,60 @@ begin
return result return result
end; end;
proc elna_tac_assign_statement(parser_tree: ^ElnaTreeAssignStatement, symbol_table: ^ElnaSymbolTable); proc elna_tac_assign_statement(instructions: ^ElnaList, parser_tree: ^ElnaTreeAssignStatement, symbol_table: ^ElnaSymbolTable);
var var
is_address: Word; is_address: Word;
first_instruction: Word;
instruction: Word; instruction: Word;
current_instruction: Word;
operand_type: Word; operand_type: Word;
operand_value: Word; operand_value: Word;
operand_length: Word; operand_length: Word;
assignment_operand: ElnaTacOperand; assignment_operand: ElnaTacOperand;
assignee: ElnaTacOperand; assignee: ElnaTacOperand;
begin begin
first_instruction := elna_tac_designator(parser_tree^.assignee, symbol_table, @is_address, @assignee); elna_tac_designator(instructions, parser_tree^.assignee, symbol_table, @is_address, @assignee);
(* Compile the assignment. *) (* Compile the assignment. *)
instruction := elna_tac_binary_expression(parser_tree^.assignment, symbol_table, @assignment_operand); instruction := elna_tac_binary_expression(instructions, parser_tree^.assignment, symbol_table, @assignment_operand);
if assignee.kind = ElnaTacKind.pseudo then if assignee.kind = ElnaTacKind.pseudo then
current_instruction := elna_tac_instruction_create(ElnaTacOperator.copy); instruction := elna_tac_instruction_create(ElnaTacOperator.copy);
if is_address then if is_address then
elna_tac_generate_pseudo(@operand_type, @operand_value, @operand_length, symbol_table); elna_tac_generate_pseudo(@operand_type, @operand_value, @operand_length, symbol_table);
(* Save the assignee address on the stack. *) (* Save the assignee address on the stack. *)
elna_tac_instruction_set_operand(current_instruction, 1, operand_type, operand_value, operand_length); elna_tac_instruction_set_operand(instruction, 1, operand_type, operand_value, operand_length);
elna_tac_instruction_set_operand(current_instruction, 2, assignee.kind, assignee.value, assignee.length); elna_tac_instruction_set_operand(instruction, 2, assignee.kind, assignee.value, assignee.length);
first_instruction := elna_instruction_list_concatenate(first_instruction, current_instruction);
if instruction <> nil then elna_list_append(instructions, instruction);
elna_instruction_list_concatenate(current_instruction, instruction);
current_instruction := instruction
end;
instruction := elna_tac_instruction_create(ElnaTacOperator.store); instruction := elna_tac_instruction_create(ElnaTacOperator.store);
elna_tac_instruction_set_operand(instruction, 1, assignment_operand.kind, assignment_operand.value, assignment_operand.length); elna_tac_instruction_set_operand(instruction, 1, assignment_operand.kind, assignment_operand.value, assignment_operand.length);
elna_tac_instruction_set_operand(instruction, 2, operand_type, operand_value, operand_length); elna_tac_instruction_set_operand(instruction, 2, operand_type, operand_value, operand_length);
elna_instruction_list_concatenate(current_instruction, instruction) elna_list_append(instructions, instruction)
else else
elna_tac_instruction_set_operand(current_instruction, 1, assignee.kind, assignee.value, assignee.length); elna_tac_instruction_set_operand(instruction, 1, assignee.kind, assignee.value, assignee.length);
elna_tac_instruction_set_operand(current_instruction, 2, assignment_operand.kind, assignment_operand.value, assignment_operand.length); elna_tac_instruction_set_operand(instruction, 2, assignment_operand.kind, assignment_operand.value, assignment_operand.length);
first_instruction := elna_instruction_list_concatenate(instruction, current_instruction) elna_list_append(instructions, instruction)
end end
else else
elna_tac_generate_pseudo(@operand_type, @operand_value, @operand_length, symbol_table); elna_tac_generate_pseudo(@operand_type, @operand_value, @operand_length, symbol_table);
(* Save the assignee address on the stack. *) (* Save the assignee address on the stack. *)
current_instruction := elna_tac_instruction_create(ElnaTacOperator.get_address); instruction := elna_tac_instruction_create(ElnaTacOperator.get_address);
elna_tac_instruction_set_operand(current_instruction, 1, operand_type, operand_value, operand_length); elna_tac_instruction_set_operand(instruction, 1, operand_type, operand_value, operand_length);
elna_tac_instruction_set_operand(current_instruction, 2, assignee.kind, assignee.value, assignee.length); elna_tac_instruction_set_operand(instruction, 2, assignee.kind, assignee.value, assignee.length);
first_instruction := elna_instruction_list_concatenate(first_instruction, current_instruction);
if instruction <> nil then elna_list_append(instructions, instruction);
elna_instruction_list_concatenate(current_instruction, instruction);
current_instruction := instruction
end;
instruction := elna_tac_instruction_create(ElnaTacOperator.store); instruction := elna_tac_instruction_create(ElnaTacOperator.store);
elna_tac_instruction_set_operand(instruction, 1, assignment_operand.kind, assignment_operand.value, assignment_operand.length); elna_tac_instruction_set_operand(instruction, 1, assignment_operand.kind, assignment_operand.value, assignment_operand.length);
elna_tac_instruction_set_operand(instruction, 2, operand_type, operand_value, operand_length); elna_tac_instruction_set_operand(instruction, 2, operand_type, operand_value, operand_length);
elna_instruction_list_concatenate(current_instruction, instruction) elna_list_append(instructions, instruction)
end; end
return first_instruction
end; end;
proc elna_parser_return_statement(); proc elna_parser_return_statement();
@@ -2775,18 +2741,16 @@ begin
return result return result
end; end;
proc elna_tac_return_statement(parser_node: ^ElnaTreeReturnStatement, symbol_table: ^ElnaSymbolTable); proc elna_tac_return_statement(instructions: ^ElnaList, parser_node: ^ElnaTreeReturnStatement, symbol_table: ^ElnaSymbolTable);
var var
first_instruction: Word;
instruction: Word; instruction: Word;
operand: ElnaTacOperand; operand: ElnaTacOperand;
begin begin
first_instruction := elna_tac_binary_expression(parser_node^.returned, symbol_table, @operand); instruction := elna_tac_binary_expression(instructions, parser_node^.returned, symbol_table, @operand);
instruction := elna_tac_instruction_create(ElnaTacOperator._return); instruction := elna_tac_instruction_create(ElnaTacOperator._return);
elna_tac_instruction_set_operand(instruction, 1, operand.kind, operand.value, operand.length); elna_tac_instruction_set_operand(instruction, 1, operand.kind, operand.value, operand.length);
elna_list_append(instructions, instruction)
return elna_instruction_list_concatenate(first_instruction, instruction)
end; end;
(** (**
@@ -2828,41 +2792,32 @@ begin
return result return result
end; end;
proc elna_tac_conditional_statements(parser_node: ^ElnaTreeConditionalStatements, after_end_label: Word, symbol_table: ^ElnaSymbolTable); proc elna_tac_conditional_statements(instructions: ^ElnaList, parser_node: ^ElnaTreeConditionalStatements,
after_end_label: Word, symbol_table: ^ElnaSymbolTable);
var var
condition_label: Word; condition_label: Word;
instruction: Word; instruction: Word;
current_instruction: Word;
first_instruction: Word;
operand: ElnaTacOperand; operand: ElnaTacOperand;
begin begin
(* Compile condition. *) (* Compile condition. *)
first_instruction := elna_tac_binary_expression(parser_node^.condition, symbol_table, @operand); instruction := elna_tac_binary_expression(instructions, parser_node^.condition, symbol_table, @operand);
(* condition_label is the label in front of the next elsif condition or end. *) (* condition_label is the label in front of the next elsif condition or end. *)
condition_label := label_counter; condition_label := label_counter;
label_counter := label_counter + 1; label_counter := label_counter + 1;
current_instruction := elna_tac_instruction_create(ElnaTacOperator.jump_if_zero); instruction := elna_tac_instruction_create(ElnaTacOperator.jump_if_zero);
elna_tac_instruction_set_operand(current_instruction, 1, operand.kind, operand.value, operand.length); elna_tac_instruction_set_operand(instruction, 1, operand.kind, operand.value, operand.length);
elna_tac_instruction_set_operand(current_instruction, 2, ElnaTacKind.symbol, condition_label, 0); elna_tac_instruction_set_operand(instruction, 2, ElnaTacKind.symbol, condition_label, 0);
first_instruction := elna_instruction_list_concatenate(first_instruction, current_instruction); elna_list_append(instructions, instruction);
elna_tac_statements(instructions, parser_node^.statements, symbol_table);
instruction := elna_tac_statements(parser_node^.statements, symbol_table);
if instruction <> nil then
elna_instruction_list_concatenate(current_instruction, instruction);
current_instruction := instruction
end;
instruction := elna_tac_instruction_create(ElnaTacOperator.jump); instruction := elna_tac_instruction_create(ElnaTacOperator.jump);
elna_tac_instruction_set_operand(instruction, 1, ElnaTacKind.symbol, after_end_label, 0); elna_tac_instruction_set_operand(instruction, 1, ElnaTacKind.symbol, after_end_label, 0);
elna_instruction_list_concatenate(current_instruction, instruction); elna_list_append(instructions, instruction);
current_instruction := elna_tac_label(condition_label, 0); elna_tac_label(instructions, condition_label, 0)
elna_instruction_list_concatenate(instruction, current_instruction);
return first_instruction
end; end;
proc elna_parser_if_statement(); proc elna_parser_if_statement();
@@ -2961,94 +2916,63 @@ begin
return first_statement return first_statement
end; end;
proc elna_tac_statements(current_statement: ^ElnaTreeStatement, symbol_table: ^ElnaSymbolTable); proc elna_tac_statements(instructions: ^ElnaList, current_statement: ^ElnaTreeStatement, symbol_table: ^ElnaSymbolTable);
var
instruction: Word;
first_instruction: Word;
current_instruction: Word;
begin begin
first_instruction := nil;
.elna_tac_statements_loop; .elna_tac_statements_loop;
pseudo_counter := 0; pseudo_counter := 0;
if current_statement <> nil then if current_statement <> nil then
instruction := elna_tac_statement(current_statement, symbol_table); elna_tac_statement(instructions, current_statement, symbol_table);
current_statement := current_statement^.next; current_statement := current_statement^.next;
if instruction = 0 then
goto elna_tac_statements_loop
end;
if first_instruction = nil then
first_instruction := instruction
else
elna_instruction_list_concatenate(current_instruction, instruction)
end;
current_instruction := instruction;
goto elna_tac_statements_loop goto elna_tac_statements_loop
end; end
return first_instruction
end; end;
proc elna_tac_if_statement(parser_node: ^ElnaTreeIfStatement, symbol_table: ^ElnaSymbolTable); proc elna_tac_if_statement(instructions: ElnaList, parser_node: ^ElnaTreeIfStatement, symbol_table: ^ElnaSymbolTable);
var var
current_node: ^ElnaTreeConditionalStatements; current_node: ^ElnaTreeConditionalStatements;
after_end_label: Word; after_end_label: Word;
condition_label: Word; condition_label: Word;
first_instruction: Word;
instruction: Word;
current_instruction: Word;
begin begin
after_end_label := label_counter; after_end_label := label_counter;
label_counter := label_counter + 1; label_counter := label_counter + 1;
current_node := parser_node^.conditionals; current_node := parser_node^.conditionals;
first_instruction := elna_tac_conditional_statements(current_node, after_end_label, symbol_table);
current_instruction := first_instruction; elna_tac_conditional_statements(instructions, current_node, after_end_label, symbol_table);
.elna_tac_if_statement_loop; .elna_tac_if_statement_loop;
current_node := current_node^.next; current_node := current_node^.next;
if current_node <> nil then if current_node <> nil then
instruction := elna_tac_conditional_statements(current_node, after_end_label, symbol_table); elna_tac_conditional_statements(instructions, current_node, after_end_label, symbol_table);
elna_instruction_list_concatenate(current_instruction, instruction);
current_instruction := instruction;
goto elna_tac_if_statement_loop goto elna_tac_if_statement_loop
end; end;
current_node := parser_node^._else; current_node := parser_node^._else;
if parser_node^._else <> nil then if parser_node^._else <> nil then
instruction := elna_tac_statements(parser_node^._else, symbol_table); elna_tac_statements(instructions, parser_node^._else, symbol_table)
if instruction <> 0 then
elna_instruction_list_concatenate(current_instruction, instruction);
current_instruction := instruction
end
end; end;
instruction := elna_tac_label(after_end_label, 0); elna_tac_label(instructions, after_end_label, 0)
elna_instruction_list_concatenate(current_instruction, instruction);
return first_instruction
end; end;
proc elna_tac_statement(parser_node: ^ElnaTreeNode, symbol_table: ^ElnaSymbolTable); proc elna_tac_statement(instructions: ElnaList, parser_node: ^ElnaTreeNode, symbol_table: ^ElnaSymbolTable);
var var
instruction: Word;
operand: ElnaTacOperand; operand: ElnaTacOperand;
begin begin
if parser_node^.kind = ElnaTreeKind.goto_statement then if parser_node^.kind = ElnaTreeKind.goto_statement then
instruction := elna_tac_goto_statement(parser_node) elna_tac_goto_statement(instructions, parser_node)
elsif parser_node^.kind = ElnaTreeKind.if_statement then elsif parser_node^.kind = ElnaTreeKind.if_statement then
instruction := elna_tac_if_statement(parser_node, symbol_table) elna_tac_if_statement(instructions, parser_node, symbol_table)
elsif parser_node^.kind = ElnaTreeKind.return_statement then elsif parser_node^.kind = ElnaTreeKind.return_statement then
instruction := elna_tac_return_statement(parser_node, symbol_table) elna_tac_return_statement(instructions, parser_node, symbol_table)
elsif parser_node^.kind = ElnaTreeKind.label_declaration then elsif parser_node^.kind = ElnaTreeKind.label_declaration then
instruction := elna_tac_label_declaration(parser_node) elna_tac_label_declaration(instructions, parser_node)
elsif parser_node^.kind = ElnaTreeKind.call then elsif parser_node^.kind = ElnaTreeKind.call then
instruction := elna_tac_call(parser_node, symbol_table, @operand) elna_tac_call(instructions, parser_node, symbol_table, @operand)
elsif parser_node^.kind = ElnaTreeKind.assign_statement then elsif parser_node^.kind = ElnaTreeKind.assign_statement then
instruction := elna_tac_assign_statement(parser_node, symbol_table) elna_tac_assign_statement(instructions, parser_node, symbol_table)
else end
instruction := nil
end;
return instruction
end; end;
(** (**
@@ -3738,10 +3662,13 @@ var
symbol_info: ^ElnaSymbolProcedureInfo; symbol_info: ^ElnaSymbolProcedureInfo;
result: ^ElnaTacProcedure; result: ^ElnaTacProcedure;
parameter_count: Word; parameter_count: Word;
body: ElnaList;
begin begin
result := malloc(#size(ElnaTacProcedure)); result := malloc(#size(ElnaTacProcedure));
result^.next := nil; result^.next := nil;
elna_list_initialize(@result^.body);
result^.name := parser_node^.name; result^.name := parser_node^.name;
result^.length := parser_node^.length; result^.length := parser_node^.length;
@@ -3751,7 +3678,7 @@ begin
result^.parameters := elna_tac_parameters(parser_node^.parameters, @parameter_count); result^.parameters := elna_tac_parameters(parser_node^.parameters, @parameter_count);
result^.count := parameter_count; result^.count := parameter_count;
result^.body := elna_tac_statements(parser_node^.body, symbol_info^.symbol_table); elna_tac_statements(@result^.body, parser_node^.body, symbol_info^.symbol_table);
return result return result
end; end;
@@ -4087,7 +4014,7 @@ begin
return first_variable return first_variable
end; end;
proc elna_parser_module_declaration(error_list: ^ElnaErrorList); proc elna_parser_module_declaration(error_list: ^ElnaList);
var var
parser_node: Word; parser_node: Word;
result: ^ElnaTreeModuleDeclaration; result: ^ElnaTreeModuleDeclaration;
@@ -4480,15 +4407,13 @@ var
parser_node: Word; parser_node: Word;
tac: Word; tac: Word;
rtl: Word; rtl: Word;
error_list: ^ElnaErrorList; error_list: ElnaList;
compiled: Word; compiled: Word;
begin begin
error_list := malloc(#size(ElnaErrorList)); elna_list_initialize(@error_list);
error_list^.first := nil;
error_list^.last := nil;
parser_node := elna_parser_module_declaration(error_list); parser_node := elna_parser_module_declaration(@error_list);
compiled := error_list^.first = nil; compiled := error_list.first = nil;
if compiled then if compiled then
elna_name_module_declaration(parser_node); elna_name_module_declaration(parser_node);