summaryrefslogtreecommitdiff
path: root/boot/stage20/cl.elna
diff options
context:
space:
mode:
Diffstat (limited to 'boot/stage20/cl.elna')
-rw-r--r--boot/stage20/cl.elna495
1 files changed, 210 insertions, 285 deletions
diff --git a/boot/stage20/cl.elna b/boot/stage20/cl.elna
index 08d6b6c..74dee3c 100644
--- a/boot/stage20/cl.elna
+++ b/boot/stage20/cl.elna
@@ -8,12 +8,17 @@ program;
(* Stage 20 compiler. *)
type
+ ElnaListNode = record
+ next: Word
+ end;
+ ElnaList = record
+ first: ^ElnaListNode;
+ last: ^ElnaListNode
+ end;
+
(**
* List of intermediate representation items.
*)
- ElnaInstructionList = record
- next: Word
- end;
ElnaInstructionModule = record
data: Word;
code: Word
@@ -308,10 +313,6 @@ type
symbol_table: ^ElnaSymbolTable
end;
- ElnaErrorList = record
- first: Word;
- last: Word
- end;
ElnaError = record
next: Word
end;
@@ -475,8 +476,7 @@ type
ElnaTacOperand = record
kind: ElnaTacKind;
value: Word;
- length: Word;
- offset: Word
+ length: Word
end;
ElnaTacInstruction = record
next: Word;
@@ -487,7 +487,7 @@ type
next: Word;
name: Word;
length: Word;
- body: Word;
+ body: ElnaList;
parameters: Word;
count: Word;
symbol_table: ^ElnaSymbolTable
@@ -532,8 +532,7 @@ type
ElnaRtlOperand = record
kind: ElnaRtlKind;
value: Word;
- length: Word;
- offset: Word
+ length: Word
end;
ElnaRtlStaticVariable = record
next: Word;
@@ -758,6 +757,32 @@ proc _is_alnum(character: Word);
return _is_alpha(character) or isdigit(character)
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);
var
buffer: Word;
@@ -776,7 +801,7 @@ begin
elna_symbol_table_enter(symbol_table, buffer, operand_length^, temporary_info)
end;
-proc elna_instruction_list_concatenate(this: ^ElnaInstructionList, value: Word);
+proc elna_instruction_list_concatenate(this: ^ElnaListNode, value: Word);
var
start: Word;
begin
@@ -812,7 +837,7 @@ begin
result := malloc(#size(ElnaTacInstruction));
result^.operator := kind;
- elna_instruction_list_concatenate(result, nil);
+ result^.next := nil;
return result
end;
@@ -1261,15 +1286,13 @@ begin
return result
end;
-proc elna_tac_label(counter: Word, length: Word);
+proc elna_tac_label(instructions: ^ElnaList, counter: Word, length: Word);
var
result: Word;
begin
result := elna_tac_instruction_create(ElnaTacOperator.label);
-
elna_tac_instruction_set_operand(result, 1, ElnaTacKind.symbol, counter, length);
-
- return result
+ elna_list_append(instructions, result)
end;
proc elna_riscv_instruction_name(instruction_kind: Word);
@@ -1809,27 +1832,21 @@ proc elna_tac_integer_literal(integer_literal_node: ^ElnaTreeIntegerLiteral, ope
begin
operand^.kind := ElnaTacKind.immediate;
operand^.value := integer_literal_node^.value;
- operand^.length := 0;
-
- return nil
+ operand^.length := 0
end;
proc elna_tac_boolean_literal(boolean_literal_node: ^ElnaTreeBooleanLiteral, operand: ^ElnaTacOperand);
begin
operand^.kind := ElnaTacKind.immediate;
operand^.value := boolean_literal_node^.value;
- operand^.length := 0;
-
- return nil
+ operand^.length := 0
end;
proc elna_tac_nil_literal(nil_node: Word, operand: ^ElnaTacOperand);
begin
operand^.kind := ElnaTacKind.immediate;
operand^.value := 0;
- operand^.length := 0;
-
- return nil
+ operand^.length := 0
end;
proc elna_parser_character_literal();
@@ -1851,9 +1868,7 @@ proc elna_tac_character_literal(character_literal_node: ^ElnaTreeCharacterLitera
begin
operand^.kind := ElnaTacKind.immediate;
operand^.value := character_literal_node^.value;
- operand^.length := character_literal_node^.length;
-
- return nil
+ operand^.length := character_literal_node^.length
end;
proc elna_parser_variable_expression();
@@ -1887,8 +1902,7 @@ begin
operand^.kind := ElnaTacKind.symbol;
operand^.value := variable_expression^.name;
operand^.length := variable_expression^.length
- end;
- return nil
+ end
end;
proc elna_parser_string_literal();
@@ -1907,28 +1921,27 @@ begin
return result
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);
var
offset: Word;
- first_instruction: Word;
- next_instruction: Word;
+ instruction: Word;
begin
offset := _add_string(string_literal_node^.value);
elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table);
- first_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(first_instruction, 2, ElnaTacKind.symbol, "strings", 7);
+ instruction := elna_tac_instruction_create(ElnaTacOperator.get_address);
+ elna_tac_instruction_set_operand(instruction, 1, operand^.kind, operand^.value, operand^.length);
+ elna_tac_instruction_set_operand(instruction, 2, ElnaTacKind.symbol, "strings", 7);
+ elna_list_append(instructions, instruction);
(* Add offset to the string block pointer. *)
- next_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(next_instruction, 2, operand^.kind, operand^.value, operand^.length);
- elna_tac_instruction_set_operand(next_instruction, 3, ElnaTacKind.immediate, offset, 0);
-
- return elna_instruction_list_concatenate(first_instruction, next_instruction)
+ instruction := elna_tac_instruction_create(ElnaTacOperator.add);
+ elna_tac_instruction_set_operand(instruction, 1, operand^.kind, operand^.value, operand^.length);
+ elna_tac_instruction_set_operand(instruction, 2, operand^.kind, operand^.value, operand^.length);
+ elna_tac_instruction_set_operand(instruction, 3, ElnaTacKind.immediate, offset, 0);
+ elna_list_append(instructions, instruction)
end;
proc elna_parser_trait_expression();
@@ -2033,31 +2046,27 @@ begin
operand^.kind := ElnaTacKind.immediate;
operand^.value := info_type^.size;
- operand^.length := 0;
-
- return nil
+ operand^.length := 0
end;
-proc elna_tac_simple_expression(parser_node: ^ElnaTreeNode, symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand);
-var
- instruction: Word;
+proc elna_tac_simple_expression(instructions: ^ElnaList, parser_node: ^ElnaTreeNode,
+ symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand);
begin
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
- 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
- instruction := elna_tac_integer_literal(parser_node, operand)
+ elna_tac_integer_literal(parser_node, operand)
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
- instruction := elna_tac_nil_literal(parser_node, operand)
+ elna_tac_nil_literal(parser_node, operand)
elsif parser_node^.kind = ElnaTreeKind.trait_expression then
- instruction := elna_tac_trait_expression(parser_node, operand)
+ elna_tac_trait_expression(parser_node, operand)
else
- instruction := elna_tac_variable_expression(parser_node, symbol_table, operand)
- end;
- return instruction
+ elna_tac_variable_expression(parser_node, symbol_table, operand)
+ end
end;
proc elna_parser_unary_expression();
@@ -2095,7 +2104,7 @@ begin
return result
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
instruction: Word;
begin
@@ -2104,23 +2113,21 @@ begin
else
instruction := elna_tac_instruction_create(ElnaTacOperator.get_address)
end;
- elna_tac_instruction_set_operand(instruction, 1, to_type, to_value, to_length);
- elna_tac_instruction_set_operand(instruction, 2, from_type, from_value, from_length);
+ elna_tac_instruction_set_operand(instruction, 1, to^.kind, to^.value, to^.length);
+ elna_tac_instruction_set_operand(instruction, 2, from^.kind, from^.value, from^.length);
- return instruction
+ elna_list_append(instructions, instruction)
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
token_kind: Word;
operator: Word;
unary_operand: ^ElnaTreeExpression;
is_address: Word;
- first_instruction: Word;
instruction: Word;
base: ElnaTacOperand;
begin
- instruction := nil;
if parser_node^.kind = ElnaTreeKind.unary_expression then
operator := parser_node^.operator;
unary_operand := parser_node^.operand
@@ -2128,31 +2135,33 @@ begin
operator := 0;
unary_operand := parser_node
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);
if operator = '@' then
- instruction := elna_tac_copy_address(is_address, base.kind, base.value, base.length,
- operand^.kind, operand^.value, operand^.length)
+ elna_tac_copy_address(instructions, is_address, @base, operand)
elsif operator = '-' then
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, 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
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, 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
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, 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
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, 2, base.kind, base.value, base.length)
- end;
- return elna_instruction_list_concatenate(first_instruction, instruction)
+ elna_tac_instruction_set_operand(instruction, 2, base.kind, base.value, base.length);
+ elna_list_append(instructions, instruction)
+ end
end;
proc elna_parser_binary_expression();
@@ -2223,7 +2232,7 @@ begin
return result
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
first_instruction: Word;
instruction: Word;
@@ -2231,11 +2240,10 @@ var
rhs: ElnaTacOperand;
begin
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
- first_instruction := elna_tac_unary_expression(parser_node^.lhs, symbol_table, @lhs);
- instruction := elna_tac_unary_expression(parser_node^.rhs, symbol_table, @rhs);
- first_instruction := elna_instruction_list_concatenate(first_instruction, instruction);
+ elna_tac_unary_expression(instructions, parser_node^.lhs, symbol_table, @lhs);
+ elna_tac_unary_expression(instructions, parser_node^.rhs, symbol_table, @rhs);
if parser_node^.operator = ElnaLexerKind.plus then
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, 3, rhs.kind, rhs.value, rhs.length);
- first_instruction := elna_instruction_list_concatenate(first_instruction, instruction)
+ elna_list_append(instructions, instruction)
end;
- return first_instruction
+ return instructions^.first
end;
proc elna_parser_call(callee: Word);
@@ -2327,18 +2335,14 @@ begin
return result
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
parsed_expression: ^ElnaTreeVariableExpression;
- instruction: Word;
- first_instruction: Word;
- current_instruction: Word;
arguments_operand: ^ElnaTacOperand;
call_instruction: Word;
argument_entry: ^ElnaTreeExpressionList;
begin
parsed_expression := parsed_call^.callee;
- first_instruction := nil;
arguments_operand := malloc(parsed_call^.count * #size(ElnaTacOperand));
elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table);
@@ -2352,26 +2356,13 @@ begin
.elna_tac_call_loop;
if argument_entry <> nil then
- instruction := elna_tac_binary_expression(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;
+ elna_tac_binary_expression(instructions, argument_entry^.expression, symbol_table, arguments_operand);
arguments_operand := arguments_operand + #size(ElnaTacOperand);
argument_entry := argument_entry^.next;
goto elna_tac_call_loop
end;
- if first_instruction = nil then
- first_instruction := call_instruction
- else
- elna_instruction_list_concatenate(current_instruction, call_instruction)
- end;
- return first_instruction
+ elna_list_append(instructions, call_instruction)
end;
proc elna_parser_goto_statement();
@@ -2393,21 +2384,21 @@ begin
return result
end;
-proc elna_tac_goto_statement(parser_node: ^ElnaTreeGotoStatement);
+proc elna_tac_goto_statement(instructions: ^ElnaList, parser_node: ^ElnaTreeGotoStatement);
var
- label_length1: Word;
- label_with_dot1: Word;
- instruction1: Word;
+ label_length: Word;
+ label_with_dot: Word;
+ instruction: Word;
begin
- label_length1 := parser_node^.length + 1;
- label_with_dot1 := malloc(label_length1);
+ label_length := parser_node^.length + 1;
+ label_with_dot := malloc(label_length);
- _store_byte('.', label_with_dot1);
- memcpy(label_with_dot1 + 1, parser_node^.label, parser_node^.length);
+ _store_byte('.', label_with_dot);
+ memcpy(label_with_dot + 1, parser_node^.label, parser_node^.length);
- instruction1 := elna_tac_instruction_create(ElnaTacOperator.jump);
- elna_tac_instruction_set_operand(instruction1, 1, ElnaTacKind.symbol, label_with_dot1, label_length1);
- return instruction1
+ instruction := elna_tac_instruction_create(ElnaTacOperator.jump);
+ elna_tac_instruction_set_operand(instruction, 1, ElnaTacKind.symbol, label_with_dot, label_length);
+ elna_list_append(instructions, instruction)
end;
proc elna_parser_label_declaration();
@@ -2430,8 +2421,9 @@ begin
return result
end;
-proc elna_tac_label_declaration(parser_node: ^ElnaTreeLabelDeclaration);
- return elna_tac_label(parser_node^.label, parser_node^.length)
+proc elna_tac_label_declaration(instructions: ^ElnaList, parser_node: ^ElnaTreeLabelDeclaration);
+begin
+ elna_tac_label(instructions, parser_node^.label, parser_node^.length)
end;
proc elna_tac_enumeration_value(field_access_expression: ^ElnaTreeFieldAccessExpression, operand: ^ElnaTacOperand);
@@ -2473,8 +2465,7 @@ begin
operand^.kind := ElnaTacKind.immediate;
operand^.value := counter;
operand^.length := 0
- end;
- return nil
+ end
end;
proc elna_parser_field_access_expression(aggregate: Word);
@@ -2519,64 +2510,59 @@ begin
return result
end;
-proc elna_tac_dereference_expression(dereference_expression: ^ElnaTreeDereferenceExpression,
+proc elna_tac_dereference_expression(instructions: ^ElnaList, dereference_expression: ^ElnaTreeDereferenceExpression,
symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand);
var
- result_instructions: Word;
load_instruction: Word;
is_address: Word;
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
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, 2, operand^.kind, operand^.value, operand^.length);
- result_instructions := elna_instruction_list_concatenate(result_instructions, load_instruction)
- end;
- return result_instructions
+ elna_list_append(instructions, load_instruction)
+ 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
field_access_expression: ^ElnaTreeFieldAccessExpression;
- result_instructions: Word;
designator_base: ^ElnaTreeExpression;
begin
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
elsif parser_node^.kind = ElnaTreeKind.field_access_expression then
field_access_expression := parser_node;
designator_base := field_access_expression^.aggregate;
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
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
- end;
+ end
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
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
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
- 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);
var
field_type: ^ElnaType;
- first_instruction: Word;
- last_instruction: Word;
+ instruction: Word;
designator_base: ^ElnaTreeExpression;
aggregate_type: ^ElnaTypeRecord;
field_count: Word;
@@ -2588,7 +2574,7 @@ begin
designator_base := field_access_expression^.aggregate;
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;
current_field := aggregate_type^.members;
@@ -2604,25 +2590,19 @@ begin
goto elna_tac_field_access_expression_field
end;
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);
- first_instruction := elna_instruction_list_concatenate(first_instruction, last_instruction);
-
- last_instruction := elna_tac_instruction_create(ElnaTacOperator.add);
- elna_tac_instruction_set_operand(last_instruction, 1, operand^.kind, operand^.value, operand^.length);
- 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)
+ instruction := elna_tac_instruction_create(ElnaTacOperator.add);
+ 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);
+ elna_tac_instruction_set_operand(instruction, 3, operand^.kind, operand^.value, operand^.length);
+ elna_list_append(instructions, instruction)
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);
var
- array_instructions: Word;
- index_instructions: Word;
- offset_instruction: Word;
- add_instruction: Word;
+ instruction: Word;
is_address: Word;
inter_operand: ElnaTacOperand;
index_type: Word;
@@ -2636,36 +2616,32 @@ begin
aggregate_type := designator_base^.type_decoration;
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);
- add_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(add_instruction, 2, inter_operand.kind, inter_operand.value, inter_operand.length);
- elna_tac_instruction_set_operand(add_instruction, 3, ElnaTacKind.immediate, 1, 0);
+ instruction := elna_tac_instruction_create(ElnaTacOperator.subtract);
+ elna_tac_instruction_set_operand(instruction, 1, index_type, index_value, index_length);
+ elna_tac_instruction_set_operand(instruction, 2, inter_operand.kind, inter_operand.value, inter_operand.length);
+ elna_tac_instruction_set_operand(instruction, 3, ElnaTacKind.immediate, 1, 0);
+ elna_list_append(instructions, instruction);
- offset_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(offset_instruction, 2, index_type, index_value, index_length);
- elna_tac_instruction_set_operand(offset_instruction, 3, ElnaTacKind.immediate, element_type^.size, 0);
+ instruction := elna_tac_instruction_create(ElnaTacOperator.multiply);
+ elna_tac_instruction_set_operand(instruction, 1, index_type, index_value, index_length);
+ elna_tac_instruction_set_operand(instruction, 2, index_type, index_value, index_length);
+ 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);
- 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_designator(instructions, array_access_expression^.array, symbol_table, @is_address, @inter_operand);
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,
- operand^.kind, operand^.value, operand^.length);
- elna_instruction_list_concatenate(offset_instruction, array_instructions);
+ elna_tac_copy_address(instructions, is_address, @inter_operand, operand);
- 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(add_instruction, 2, operand^.kind, operand^.value, operand^.length);
- elna_tac_instruction_set_operand(add_instruction, 3, index_type, index_value, index_length);
+ instruction := elna_tac_instruction_create(ElnaTacOperator.add);
+ elna_tac_instruction_set_operand(instruction, 1, operand^.kind, operand^.value, operand^.length);
+ elna_tac_instruction_set_operand(instruction, 2, operand^.kind, operand^.value, operand^.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;
proc elna_parser_assign_statement(assignee: Word);
@@ -2688,70 +2664,60 @@ begin
return result
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
is_address: Word;
- first_instruction: Word;
instruction: Word;
- current_instruction: Word;
operand_type: Word;
operand_value: Word;
operand_length: Word;
assignment_operand: ElnaTacOperand;
assignee: ElnaTacOperand;
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. *)
- 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
- current_instruction := elna_tac_instruction_create(ElnaTacOperator.copy);
+ instruction := elna_tac_instruction_create(ElnaTacOperator.copy);
if is_address then
elna_tac_generate_pseudo(@operand_type, @operand_value, @operand_length, symbol_table);
(* 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(current_instruction, 2, assignee.kind, assignee.value, assignee.length);
- first_instruction := elna_instruction_list_concatenate(first_instruction, current_instruction);
+ elna_tac_instruction_set_operand(instruction, 1, operand_type, operand_value, operand_length);
+ elna_tac_instruction_set_operand(instruction, 2, assignee.kind, assignee.value, assignee.length);
- if instruction <> nil then
- elna_instruction_list_concatenate(current_instruction, instruction);
- current_instruction := instruction
- end;
+ elna_list_append(instructions, instruction);
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, 2, operand_type, operand_value, operand_length);
- elna_instruction_list_concatenate(current_instruction, instruction)
+ elna_list_append(instructions, instruction)
else
- elna_tac_instruction_set_operand(current_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, 1, assignee.kind, assignee.value, assignee.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
else
elna_tac_generate_pseudo(@operand_type, @operand_value, @operand_length, symbol_table);
(* Save the assignee address on the stack. *)
- current_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(current_instruction, 2, assignee.kind, assignee.value, assignee.length);
- first_instruction := elna_instruction_list_concatenate(first_instruction, current_instruction);
-
- if instruction <> nil then
- elna_instruction_list_concatenate(current_instruction, instruction);
- current_instruction := instruction
- end;
+ instruction := elna_tac_instruction_create(ElnaTacOperator.get_address);
+ elna_tac_instruction_set_operand(instruction, 1, operand_type, operand_value, operand_length);
+ elna_tac_instruction_set_operand(instruction, 2, assignee.kind, assignee.value, assignee.length);
+
+ elna_list_append(instructions, instruction);
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, 2, operand_type, operand_value, operand_length);
- elna_instruction_list_concatenate(current_instruction, instruction)
- end;
- return first_instruction
+ elna_list_append(instructions, instruction)
+ end
end;
proc elna_parser_return_statement();
@@ -2775,18 +2741,16 @@ begin
return result
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
- first_instruction: Word;
instruction: Word;
operand: ElnaTacOperand;
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);
elna_tac_instruction_set_operand(instruction, 1, operand.kind, operand.value, operand.length);
-
- return elna_instruction_list_concatenate(first_instruction, instruction)
+ elna_list_append(instructions, instruction)
end;
(**
@@ -2828,41 +2792,32 @@ begin
return result
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
condition_label: Word;
instruction: Word;
- current_instruction: Word;
- first_instruction: Word;
operand: ElnaTacOperand;
begin
(* 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 := label_counter;
label_counter := label_counter + 1;
- current_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(current_instruction, 2, ElnaTacKind.symbol, condition_label, 0);
-
- first_instruction := elna_instruction_list_concatenate(first_instruction, current_instruction);
+ instruction := elna_tac_instruction_create(ElnaTacOperator.jump_if_zero);
+ elna_tac_instruction_set_operand(instruction, 1, operand.kind, operand.value, operand.length);
+ elna_tac_instruction_set_operand(instruction, 2, ElnaTacKind.symbol, condition_label, 0);
- instruction := elna_tac_statements(parser_node^.statements, symbol_table);
- if instruction <> nil then
- elna_instruction_list_concatenate(current_instruction, instruction);
- current_instruction := instruction
- end;
+ elna_list_append(instructions, instruction);
+ elna_tac_statements(instructions, parser_node^.statements, symbol_table);
instruction := elna_tac_instruction_create(ElnaTacOperator.jump);
elna_tac_instruction_set_operand(instruction, 1, ElnaTacKind.symbol, after_end_label, 0);
- elna_instruction_list_concatenate(current_instruction, instruction);
-
- current_instruction := elna_tac_label(condition_label, 0);
- elna_instruction_list_concatenate(instruction, current_instruction);
+ elna_list_append(instructions, instruction);
- return first_instruction
+ elna_tac_label(instructions, condition_label, 0)
end;
proc elna_parser_if_statement();
@@ -2961,94 +2916,63 @@ begin
return first_statement
end;
-proc elna_tac_statements(current_statement: ^ElnaTreeStatement, symbol_table: ^ElnaSymbolTable);
-var
- instruction: Word;
- first_instruction: Word;
- current_instruction: Word;
+proc elna_tac_statements(instructions: ^ElnaList, current_statement: ^ElnaTreeStatement, symbol_table: ^ElnaSymbolTable);
begin
- first_instruction := nil;
-
.elna_tac_statements_loop;
pseudo_counter := 0;
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;
- 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
- 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
current_node: ^ElnaTreeConditionalStatements;
after_end_label: Word;
condition_label: Word;
- first_instruction: Word;
- instruction: Word;
- current_instruction: Word;
begin
after_end_label := label_counter;
label_counter := label_counter + 1;
-
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;
current_node := current_node^.next;
if current_node <> nil then
- instruction := elna_tac_conditional_statements(current_node, after_end_label, symbol_table);
- elna_instruction_list_concatenate(current_instruction, instruction);
- current_instruction := instruction;
+ elna_tac_conditional_statements(instructions, current_node, after_end_label, symbol_table);
+
goto elna_tac_if_statement_loop
end;
current_node := parser_node^._else;
if parser_node^._else <> nil then
- instruction := elna_tac_statements(parser_node^._else, symbol_table);
- if instruction <> 0 then
- elna_instruction_list_concatenate(current_instruction, instruction);
- current_instruction := instruction
- end
+ elna_tac_statements(instructions, parser_node^._else, symbol_table)
end;
- instruction := elna_tac_label(after_end_label, 0);
- elna_instruction_list_concatenate(current_instruction, instruction);
-
- return first_instruction
+ elna_tac_label(instructions, after_end_label, 0)
end;
-proc elna_tac_statement(parser_node: ^ElnaTreeNode, symbol_table: ^ElnaSymbolTable);
+proc elna_tac_statement(instructions: ElnaList, parser_node: ^ElnaTreeNode, symbol_table: ^ElnaSymbolTable);
var
- instruction: Word;
operand: ElnaTacOperand;
begin
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
- 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
- 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
- instruction := elna_tac_label_declaration(parser_node)
+ elna_tac_label_declaration(instructions, parser_node)
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
- instruction := elna_tac_assign_statement(parser_node, symbol_table)
- else
- instruction := nil
- end;
- return instruction
+ elna_tac_assign_statement(instructions, parser_node, symbol_table)
+ end
end;
(**
@@ -3738,10 +3662,13 @@ var
symbol_info: ^ElnaSymbolProcedureInfo;
result: ^ElnaTacProcedure;
parameter_count: Word;
+ body: ElnaList;
begin
result := malloc(#size(ElnaTacProcedure));
result^.next := nil;
+ elna_list_initialize(@result^.body);
+
result^.name := parser_node^.name;
result^.length := parser_node^.length;
@@ -3751,7 +3678,7 @@ begin
result^.parameters := elna_tac_parameters(parser_node^.parameters, @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
end;
@@ -4087,7 +4014,7 @@ begin
return first_variable
end;
-proc elna_parser_module_declaration(error_list: ^ElnaErrorList);
+proc elna_parser_module_declaration(error_list: ^ElnaList);
var
parser_node: Word;
result: ^ElnaTreeModuleDeclaration;
@@ -4480,15 +4407,13 @@ var
parser_node: Word;
tac: Word;
rtl: Word;
- error_list: ^ElnaErrorList;
+ error_list: ElnaList;
compiled: Word;
begin
- error_list := malloc(#size(ElnaErrorList));
- error_list^.first := nil;
- error_list^.last := nil;
+ elna_list_initialize(@error_list);
- parser_node := elna_parser_module_declaration(error_list);
- compiled := error_list^.first = nil;
+ parser_node := elna_parser_module_declaration(@error_list);
+ compiled := error_list.first = nil;
if compiled then
elna_name_module_declaration(parser_node);