Extend ElnaErrorList to a generic ElnaList
This commit is contained in:
@@ -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);
|
||||
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);
|
||||
|
||||
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)
|
||||
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);
|
||||
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);
|
||||
|
||||
first_instruction := elna_instruction_list_concatenate(first_instruction, current_instruction);
|
||||
|
||||
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);
|
||||
elna_list_append(instructions, instruction);
|
||||
|
||||
current_instruction := elna_tac_label(condition_label, 0);
|
||||
elna_instruction_list_concatenate(instruction, current_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);
|
||||
|
||||
Reference in New Issue
Block a user