summaryrefslogtreecommitdiff
path: root/boot/stage16/cl.elna
diff options
context:
space:
mode:
Diffstat (limited to 'boot/stage16/cl.elna')
-rw-r--r--boot/stage16/cl.elna1124
1 files changed, 647 insertions, 477 deletions
diff --git a/boot/stage16/cl.elna b/boot/stage16/cl.elna
index f76edae..e7eb475 100644
--- a/boot/stage16/cl.elna
+++ b/boot/stage16/cl.elna
@@ -7,13 +7,13 @@
(* Stage 16 compiler. *)
type
- _elna_tac_declaration = record
- next: Word;
- name: Word;
- length: Word;
- body: Word
+ (**
+ * List of intermediate representation items.
+ *)
+ ElnaInstructionList = record
+ next: Word
end;
- elna_rtl_declaration = record
+ ElnaInstructionDeclaration = record
next: Word;
name: Word;
length: Word;
@@ -90,11 +90,7 @@ type
field: Word;
length: Word
end;
- _elna_tac_module = record
- data: Word;
- code: Word
- end;
- elna_rtl_module = record
+ ElnaInstructionModule = record
data: Word;
code: Word
end;
@@ -352,14 +348,12 @@ type
InfoKind = (type_info, parameter_info, temporary_info, procedure_info);
TypeKind = (primitive, enumeration, _record);
ElnaTacOperator = (
- load_immediate,
- load_address,
+ get_address,
add,
- add_immediate,
load_word,
store_word,
jal,
- move,
+ assign,
sub,
div,
rem,
@@ -367,10 +361,12 @@ type
_xor,
_or,
and,
- seqz,
- snez,
slt,
- xor_immediate,
+ sgt,
+ sle,
+ sge,
+ seq,
+ sne,
neg,
not,
jump,
@@ -407,7 +403,7 @@ type
start,
ret
);
- ElnaTacOperand = (register, immediate, symbol, offset);
+ ElnaTacOperand = (register, immediate, symbol, offset, stack);
ElnaRtlOperand = (register, immediate, symbol, offset);
ElnaRtlRegister = (
zero,
@@ -454,6 +450,7 @@ var
compiler_strings_length: Word;
label_counter: Word;
symbol_table_store: Word;
+ temporary_variable_counter: Word;
(**
* Calculates and returns the string token length between quotes, including the
@@ -662,31 +659,37 @@ proc _elna_tac_instruction_size();
end;
proc _elna_tac_instruction_get_kind(this: Word);
+begin
+ this := this + 4;
return this^
end;
proc _elna_tac_instruction_set_kind(this: Word, value: Word);
begin
- this^ := value
-end;
-
-proc _elna_tac_instruction_get_next(this: Word);
-begin
this := this + 4;
- return this^
+ this^ := value
end;
-proc _elna_tac_instruction_set_next(this: Word, value: Word);
+proc elna_instruction_list_concatenate(this: Word, value: Word);
+var
+ start: Word;
begin
- .elna_tac_instruction_set_next_loop;
- this := this + 4;
+ if this = 0 then
+ start := value;
+ goto elna_instruction_list_concatenate_end
+ else
+ start := this
+ end;
+ .elna_instruction_list_concatenate_loop;
if value <> 0 then
if this^ <> 0 then
this := this^;
- goto elna_tac_instruction_set_next_loop
+ goto elna_instruction_list_concatenate_loop
end
end;
- this^ := value
+ this^ := value;
+ .elna_instruction_list_concatenate_end;
+ return start
end;
proc _elna_tac_instruction_get_operand_type(this: Word, n: Word);
@@ -742,7 +745,19 @@ begin
result := malloc(_elna_tac_instruction_size());
_elna_tac_instruction_set_kind(result, kind);
- _elna_tac_instruction_set_next(result, 0);
+ elna_instruction_list_concatenate(result, 0);
+
+ return result
+end;
+
+proc elna_rtl_instruction_create(kind: Word);
+var
+ result: Word;
+begin
+ result := malloc(elna_rtl_instruction_size());
+
+ elna_rtl_instruction_set_kind(result, kind);
+ ElnaInstructionList_set_next(result, 0);
return result
end;
@@ -752,23 +767,14 @@ proc elna_rtl_instruction_size();
end;
proc elna_rtl_instruction_get_kind(this: Word);
- return this^
-end;
-
-proc elna_rtl_instruction_get_next(this: Word);
begin
this := this + 4;
return this^
end;
-proc elna_rtl_instruction_set_next(this: Word, value: Word);
-begin
- this := this + 4;
- this^ := value
-end;
-
proc elna_rtl_instruction_set_kind(this: Word, value: Word);
begin
+ this := this + 4;
this^ := value
end;
@@ -818,213 +824,345 @@ begin
this^ := operand_length
end;
-proc elna_rtl_instruction(tac_instruction: Word);
+proc elna_rtl_load_operand_value(tac_instruction: Word, operand_number: Word, into: Word);
var
result: Word;
+ operand_value: Word;
+ operand_length: Word;
+ operand_type: Word;
+ next_instruction: Word;
instruction_size: Word;
begin
instruction_size := elna_rtl_instruction_size();
+ operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, operand_number);
+ operand_length := _elna_tac_instruction_get_operand_length(tac_instruction, operand_number);
+ operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, operand_number);
result := malloc(instruction_size);
- memcpy(result, tac_instruction, instruction_size);
-
- return result
-end;
-
-proc _elna_tac_module_create(data: Word, code: Word);
-var
- result: Word;
-begin
- result := malloc(_elna_tac_module_size());
-
- _elna_tac_module_set_data(result, data);
- _elna_tac_module_set_code(result, code);
-
- return result
-end;
-
-proc _elna_tac_load_immediate(target_register: Word, source_immediate: Word, immediate_length: Word);
-var
- result: Word;
-begin
- result := _elna_tac_instruction_create(ElnaTacOperator.load_immediate);
-
- _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, target_register, 0);
- _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.immediate, source_immediate, immediate_length);
-
- return result
-end;
-
-proc _elna_tac_load_address(target_register: Word, source_symbol: Word, symbol_length: Word);
-var
- result: Word;
-begin
- result := _elna_tac_instruction_create(ElnaTacOperator.load_address);
-
- _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, target_register, 0);
- _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.symbol, source_symbol, symbol_length);
-
- return result
-end;
-
-proc _elna_tac_beqz(target_register: Word, source_symbol: Word, symbol_length: Word);
-var
- result: Word;
-begin
- result := _elna_tac_instruction_create(ElnaTacOperator.beqz);
-
- _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, target_register, 0);
- _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.symbol, source_symbol, symbol_length);
-
- return result
-end;
-
-proc _elna_tac_jump(source_symbol: Word, symbol_length: Word);
-var
- result: Word;
-begin
- result := _elna_tac_instruction_create(ElnaTacOperator.jump);
-
- _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.symbol, source_symbol, symbol_length);
+ if operand_type = ElnaTacOperand.immediate then
+ elna_rtl_instruction_set_kind(result, ElnaRtlOperator.load_immediate);
+ elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0);
+ elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.immediate, operand_value, operand_length);
+ ElnaInstructionList_set_next(result, 0)
+ elsif operand_type = ElnaTacOperand.stack then
+ elna_rtl_instruction_set_kind(result, ElnaRtlOperator.load_word);
+ elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0);
+ elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, operand_value);
+ ElnaInstructionList_set_next(result, 0)
+ elsif operand_type = ElnaTacOperand.symbol then
+ elna_rtl_instruction_set_kind(result, ElnaRtlOperator.load_address);
+ elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0);
+ elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.symbol, operand_value, operand_length);
+
+ next_instruction := malloc(instruction_size);
+ elna_rtl_instruction_set_kind(next_instruction, ElnaRtlOperator.load_word);
+ elna_rtl_instruction_set_operand(next_instruction, 1, ElnaRtlOperand.register, into, 0);
+ elna_rtl_instruction_set_operand(next_instruction, 2, ElnaRtlOperand.offset, into, 0);
+ ElnaInstructionList_set_next(next_instruction, 0);
+
+ ElnaInstructionList_set_next(result, next_instruction)
+ elsif operand_type = ElnaTacOperand.register then
+ elna_rtl_instruction_set_kind(result, ElnaRtlOperator.move);
+ elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0);
+ elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.register, operand_value, 0);
+ ElnaInstructionList_set_next(result, 0)
+ end;
return result
end;
-proc _elna_tac_add(destination: Word, lhs: Word, rhs: Word);
+proc elna_rtl_load_operand_address(tac_instruction: Word, operand_number: Word, into: Word);
var
result: Word;
+ operand_value: Word;
+ operand_length: Word;
+ operand_type: Word;
begin
- result := _elna_tac_instruction_create(ElnaTacOperator.add);
-
- _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0);
- _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, lhs, 0);
- _elna_tac_instruction_set_operand(result, 3, ElnaTacOperand.register, rhs, 0);
+ operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, operand_number);
+ operand_length := _elna_tac_instruction_get_operand_length(tac_instruction, operand_number);
+ operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, operand_number);
+
+ result := malloc(elna_rtl_instruction_size());
+ ElnaInstructionList_set_next(result, 0);
+
+ if operand_type = ElnaTacOperand.stack then
+ elna_rtl_instruction_set_kind(result, ElnaRtlOperator.add_immediate);
+ elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0);
+ elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, operand_value);
+ elsif operand_type = ElnaTacOperand.symbol then
+ elna_rtl_instruction_set_kind(result, ElnaRtlOperator.load_address);
+ elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0);
+ elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.symbol, operand_value, operand_length)
+ end;
return result
end;
-proc _elna_tac_mul(destination: Word, lhs: Word, rhs: Word);
+proc elna_rtl_binary_operands(tac_instruction: Word, next_instruction: Word);
var
- result: Word;
+ lhs: Word;
+ rhs: Word;
begin
- result := _elna_tac_instruction_create(ElnaTacOperator.mul);
+ lhs := elna_rtl_load_operand_value(tac_instruction, 2, ElnaRtlRegister.t2);
+ rhs := elna_rtl_load_operand_value(tac_instruction, 3, ElnaRtlRegister.t3);
- _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0);
- _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, lhs, 0);
- _elna_tac_instruction_set_operand(result, 3, ElnaTacOperand.register, rhs, 0);
+ next_instruction^ := ElnaInstructionList_get_next(lhs);
+ if next_instruction^ = 0 then
+ ElnaInstructionList_set_next(lhs, rhs)
+ else
+ ElnaInstructionList_set_next(next_instruction^, rhs)
+ end;
+ next_instruction^ := ElnaInstructionList_get_next(rhs);
+ if next_instruction^ = 0 then
+ next_instruction^ := rhs
+ end;
- return result
+ return lhs
end;
-proc _elna_tac_sub(destination: Word, lhs: Word, rhs: Word);
+proc elna_rtl_binary_arithmetic(tac_instruction: Word, binary_result: Word, next_instruction: Word);
var
- result: Word;
+ lhs: Word;
begin
- result := _elna_tac_instruction_create(ElnaTacOperator.sub);
+ lhs := elna_rtl_binary_operands(tac_instruction, next_instruction);
+ elna_rtl_instruction_set_operand(binary_result, 2, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0);
+ elna_rtl_instruction_set_operand(binary_result, 3, ElnaRtlOperand.register, ElnaRtlRegister.t3, 0);
- _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0);
- _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, lhs, 0);
- _elna_tac_instruction_set_operand(result, 3, ElnaTacOperand.register, rhs, 0);
+ ElnaInstructionList_set_next(next_instruction^, binary_result);
+ next_instruction^ := binary_result;
- return result
+ return lhs
end;
-proc _elna_tac_div(destination: Word, lhs: Word, rhs: Word);
+proc elna_rtl_binary_equality(tac_instruction: Word, binary_result: Word, next_instruction: Word);
var
- result: Word;
+ operands: Word;
+ intermediate_instruction: Word;
begin
- result := _elna_tac_instruction_create(ElnaTacOperator.div);
-
- _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0);
- _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, lhs, 0);
- _elna_tac_instruction_set_operand(result, 3, ElnaTacOperand.register, rhs, 0);
+ operands := elna_rtl_binary_operands(tac_instruction, next_instruction);
+ intermediate_instruction := elna_rtl_instruction_create(ElnaRtlOperator._xor);
- return result
-end;
-
-proc _elna_tac_rem(destination: Word, lhs: Word, rhs: Word);
-var
- result: Word;
-begin
- result := _elna_tac_instruction_create(ElnaTacOperator.rem);
+ elna_rtl_instruction_set_operand(intermediate_instruction, 1, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0);
+ elna_rtl_instruction_set_operand(intermediate_instruction, 2, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0);
+ elna_rtl_instruction_set_operand(intermediate_instruction, 3, ElnaRtlOperand.register, ElnaRtlRegister.t3, 0);
+ ElnaInstructionList_set_next(next_instruction^, intermediate_instruction);
+ next_instruction^ := intermediate_instruction;
- _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0);
- _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, lhs, 0);
- _elna_tac_instruction_set_operand(result, 3, ElnaTacOperand.register, rhs, 0);
+ elna_rtl_instruction_set_operand(binary_result, 2, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0);
+ ElnaInstructionList_set_next(next_instruction^, binary_result);
+ next_instruction^ := binary_result;
- return result
+ return operands
end;
-proc _elna_tac_xor(destination: Word, lhs: Word, rhs: Word);
+proc elna_rtl_instruction(tac_instruction: Word, next_instruction: Word);
var
result: Word;
+ instruction_size: Word;
+ instruction_kind: Word;
+ operand_type: Word;
+ operand_value: Word;
+ operands: Word;
+ intermediate_instruction: Word;
begin
- result := _elna_tac_instruction_create(ElnaTacOperator._xor);
-
- _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0);
- _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, lhs, 0);
- _elna_tac_instruction_set_operand(result, 3, ElnaTacOperand.register, rhs, 0);
-
+ instruction_size := elna_rtl_instruction_size();
+ result := malloc(instruction_size);
+ instruction_kind := _elna_tac_instruction_get_kind(tac_instruction);
+ memcpy(result + 4, tac_instruction + 4, instruction_size - 4);
+ next_instruction^ := 0;
+
+ if instruction_kind = ElnaTacOperator.get_address then
+ operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, 2);
+
+ if operand_type = ElnaTacOperand.stack then
+ operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2);
+ elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.register, ElnaRtlRegister.sp, 0);
+ elna_rtl_instruction_set_operand(result, 3, ElnaRtlOperand.immediate, operand_value, 0);
+ elna_rtl_instruction_set_kind(result, ElnaRtlOperator.add)
+ elsif operand_type = ElnaTacOperand.symbol then
+ elna_rtl_instruction_set_kind(result, ElnaRtlOperator.load_address)
+ elsif operand_type = ElnaTacOperand.register then
+ elna_rtl_instruction_set_kind(result, ElnaRtlOperator.move);
+ else
+ (* Debug. Error stream output.
+ _syscall(2, name_pointer, name_length, 0, 0, 0, 64); *)
+ printf("# here %i\n\0", operand_type);
+ fflush(0);
+ end;
+ elsif instruction_kind = ElnaTacOperator.add then
+ result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction);
+ elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.add)
+ elsif instruction_kind = ElnaTacOperator.load_word then
+ operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, 2);
+
+ if operand_type = ElnaTacOperand.stack then
+ operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 1);
+ next_instruction^ := elna_rtl_instruction_create(ElnaRtlOperator.load_word);
+ elna_rtl_instruction_set_operand(next_instruction^, 1, ElnaRtlOperand.register, operand_value, 0);
+ elna_rtl_instruction_set_operand(next_instruction^, 2, ElnaRtlOperand.offset, operand_value, 0);
+
+ operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2);
+ elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, operand_value);
+ ElnaInstructionList_set_next(result, next_instruction^)
+ end;
+ elna_rtl_instruction_set_kind(result, ElnaRtlOperator.load_word)
+ elsif instruction_kind = ElnaTacOperator.store_word then
+ elna_rtl_instruction_set_kind(result, ElnaRtlOperator.store_word)
+ elsif instruction_kind = ElnaTacOperator.jal then
+ elna_rtl_instruction_set_kind(result, ElnaRtlOperator.jal)
+ elsif instruction_kind = ElnaTacOperator.sub then
+ result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction);
+ elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.sub)
+ elsif instruction_kind = ElnaTacOperator.mul then
+ result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction);
+ elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.mul)
+ elsif instruction_kind = ElnaTacOperator.div then
+ result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction);
+ elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.div)
+ elsif instruction_kind = ElnaTacOperator.rem then
+ result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction);
+ elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.rem)
+ elsif instruction_kind = ElnaTacOperator._xor then
+ result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction);
+ elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator._xor)
+ elsif instruction_kind = ElnaTacOperator._or then
+ result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction);
+ elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator._or)
+ elsif instruction_kind = ElnaTacOperator.and then
+ result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction);
+ elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.and)
+ elsif instruction_kind = ElnaTacOperator.slt then
+ result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction);
+ elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.slt)
+ elsif instruction_kind = ElnaTacOperator.sgt then
+ operands := elna_rtl_binary_operands(tac_instruction, next_instruction);
+ elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.register, ElnaRtlRegister.t3, 0);
+ elna_rtl_instruction_set_operand(result, 3, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0);
+
+ ElnaInstructionList_set_next(next_instruction^, result);
+ next_instruction^ := result;
+
+ result := operands;
+ elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.slt)
+ elsif instruction_kind = ElnaTacOperator.sle then
+ operands := elna_rtl_binary_operands(tac_instruction, next_instruction);
+ intermediate_instruction := elna_rtl_instruction_create(ElnaRtlOperator.slt);
+
+ elna_rtl_instruction_set_operand(intermediate_instruction, 1, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0);
+ elna_rtl_instruction_set_operand(intermediate_instruction, 2, ElnaRtlOperand.register, ElnaRtlRegister.t3, 0);
+ elna_rtl_instruction_set_operand(intermediate_instruction, 3, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0);
+ ElnaInstructionList_set_next(next_instruction^, intermediate_instruction);
+ next_instruction^ := intermediate_instruction;
+
+ elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0);
+ elna_rtl_instruction_set_operand(result, 3, ElnaRtlOperand.immediate, 1, 0);
+ ElnaInstructionList_set_next(next_instruction^, result);
+ next_instruction^ := result;
+
+ result := operands;
+ elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.xor_immediate)
+ elsif instruction_kind = ElnaTacOperator.sge then
+ operands := elna_rtl_binary_operands(tac_instruction, next_instruction);
+ intermediate_instruction := elna_rtl_instruction_create(ElnaRtlOperator.slt);
+
+ elna_rtl_instruction_set_operand(intermediate_instruction, 1, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0);
+ elna_rtl_instruction_set_operand(intermediate_instruction, 2, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0);
+ elna_rtl_instruction_set_operand(intermediate_instruction, 3, ElnaRtlOperand.register, ElnaRtlRegister.t3, 0);
+ ElnaInstructionList_set_next(next_instruction^, intermediate_instruction);
+ next_instruction^ := intermediate_instruction;
+
+ elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0);
+ elna_rtl_instruction_set_operand(result, 3, ElnaRtlOperand.immediate, 1, 0);
+ ElnaInstructionList_set_next(next_instruction^, result);
+ next_instruction^ := result;
+
+ result := operands;
+ elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.xor_immediate)
+ elsif instruction_kind = ElnaTacOperator.seq then
+ result := elna_rtl_binary_equality(tac_instruction, result, next_instruction);
+ elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.seqz)
+ elsif instruction_kind = ElnaTacOperator.sne then
+ result := elna_rtl_binary_equality(tac_instruction, result, next_instruction);
+ elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.snez)
+ elsif instruction_kind = ElnaTacOperator.neg then
+ elna_rtl_instruction_set_kind(result, ElnaRtlOperator.neg)
+ elsif instruction_kind = ElnaTacOperator.not then
+ elna_rtl_instruction_set_kind(result, ElnaRtlOperator.not)
+ elsif instruction_kind = ElnaTacOperator.jump then
+ elna_rtl_instruction_set_kind(result, ElnaRtlOperator.jump)
+ elsif instruction_kind = ElnaTacOperator.beqz then
+ elna_rtl_instruction_set_kind(result, ElnaRtlOperator.beqz)
+ elsif instruction_kind = ElnaTacOperator.start then
+ elna_rtl_instruction_set_kind(result, ElnaRtlOperator.start)
+ elsif instruction_kind = ElnaTacOperator.ret then
+ elna_rtl_instruction_set_kind(result, ElnaRtlOperator.ret)
+ elsif instruction_kind = ElnaTacOperator.label then
+ elna_rtl_instruction_set_kind(result, ElnaRtlOperator.label)
+ elsif instruction_kind = ElnaTacOperator.assign then
+ free(result);
+ operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 1);
+ result := elna_rtl_load_operand_value(tac_instruction, 2, operand_value);
+ next_instruction^ := ElnaInstructionList_get_next(result)
+ end;
+ if next_instruction^ = 0 then
+ next_instruction^ := result;
+ end;
return result
end;
-proc _elna_tac_xor_immediate(destination: Word, lhs: Word, rhs: Word);
+proc elna_instruction_module_create(data: Word, code: Word);
var
result: Word;
begin
- result := _elna_tac_instruction_create(ElnaTacOperator._xor);
+ result := malloc(ElnaInstructionModule_size());
- _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0);
- _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, lhs, 0);
- _elna_tac_instruction_set_operand(result, 3, ElnaTacOperand.immediate, rhs, 0);
+ ElnaInstructionModule_set_data(result, data);
+ ElnaInstructionModule_set_code(result, code);
return result
end;
-proc _elna_tac_or(destination: Word, lhs: Word, rhs: Word);
+proc _elna_tac_load_address(target_register: Word, source_symbol: Word, symbol_length: Word);
var
result: Word;
begin
- result := _elna_tac_instruction_create(ElnaTacOperator._or);
+ result := _elna_tac_instruction_create(ElnaTacOperator.get_address);
- _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0);
- _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, lhs, 0);
- _elna_tac_instruction_set_operand(result, 3, ElnaTacOperand.register, rhs, 0);
+ _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, target_register, 0);
+ _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.symbol, source_symbol, symbol_length);
return result
end;
-proc _elna_tac_and(destination: Word, lhs: Word, rhs: Word);
+proc _elna_tac_jump(source_symbol: Word, symbol_length: Word);
var
result: Word;
begin
- result := _elna_tac_instruction_create(ElnaTacOperator.and);
+ result := _elna_tac_instruction_create(ElnaTacOperator.jump);
- _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0);
- _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, lhs, 0);
- _elna_tac_instruction_set_operand(result, 3, ElnaTacOperand.register, rhs, 0);
+ _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.symbol, source_symbol, symbol_length);
return result
end;
-proc _elna_tac_add_immediate(destination: Word, lhs: Word, rhs: Word);
+proc _elna_tac_add(destination: Word, lhs: Word, rhs_type: Word, rhs: Word);
var
result: Word;
begin
- result := _elna_tac_instruction_create(ElnaTacOperator.add_immediate);
+ result := _elna_tac_instruction_create(ElnaTacOperator.add);
_elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0);
_elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, lhs, 0);
- _elna_tac_instruction_set_operand(result, 3, ElnaTacOperand.immediate, rhs, 0);
+ _elna_tac_instruction_set_operand(result, 3, rhs_type, rhs, 0);
return result
end;
-proc _elna_tac_slt(destination: Word, lhs: Word, rhs: Word);
+proc _elna_tac_sub(destination: Word, lhs: Word, rhs: Word);
var
result: Word;
begin
- result := _elna_tac_instruction_create(ElnaTacOperator.slt);
+ result := _elna_tac_instruction_create(ElnaTacOperator.sub);
_elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0);
_elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, lhs, 0);
@@ -1068,42 +1206,6 @@ begin
return result
end;
-proc _elna_tac_move(destination: Word, source: Word);
-var
- result: Word;
-begin
- result := _elna_tac_instruction_create(ElnaTacOperator.move);
-
- _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0);
- _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, source, 0);
-
- return result
-end;
-
-proc _elna_tac_seqz(destination: Word, source: Word);
-var
- result: Word;
-begin
- result := _elna_tac_instruction_create(ElnaTacOperator.seqz);
-
- _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0);
- _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, source, 0);
-
- return result
-end;
-
-proc _elna_tac_snez(destination: Word, source: Word);
-var
- result: Word;
-begin
- result := _elna_tac_instruction_create(ElnaTacOperator.snez);
-
- _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0);
- _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, source, 0);
-
- return result
-end;
-
proc _elna_tac_neg(destination: Word, source: Word);
var
result: Word;
@@ -1214,10 +1316,10 @@ begin
_write_s("\tbeqz", 5)
elsif instruction_kind = ElnaRtlOperator.start then
argument_count := 0;
- _write_z("\taddi sp, sp, -128\n\tsw ra, 124(sp)\n\tsw s0, 120(sp)\n\taddi s0, sp, 128\0")
+ _write_z("\taddi sp, sp, -144\n\tsw ra, 140(sp)\n\tsw s0, 136(sp)\n\taddi s0, sp, 144\0")
elsif instruction_kind = ElnaRtlOperator.ret then
argument_count := 0;
- _write_z("\tlw ra, 124(sp)\n\tlw s0, 120(sp)\n\taddi sp, sp, 128\0")
+ _write_z("\tlw ra, 140(sp)\n\tlw s0, 136(sp)\n\taddi sp, sp, 144\0")
end;
return argument_count
end;
@@ -1298,23 +1400,23 @@ var
current_copy: Word;
next_copy: Word;
first_copy: Word;
+ last_copy: Word;
begin
if instruction <> 0 then
- first_copy := elna_rtl_instruction(instruction);
- instruction := _elna_tac_instruction_get_next(instruction)
+ first_copy := elna_rtl_instruction(instruction, @current_copy);
+ instruction := ElnaInstructionList_get_next(instruction)
else
first_copy := 0;
+ current_copy := 0
end;
- current_copy := first_copy;
-
.elna_rtl_instructions_start;
if instruction <> 0 then
- next_copy := elna_rtl_instruction(instruction);
+ next_copy := elna_rtl_instruction(instruction, @last_copy);
- instruction := _elna_tac_instruction_get_next(instruction);
- elna_rtl_instruction_set_next(current_copy, next_copy);
- current_copy := next_copy;
+ instruction := ElnaInstructionList_get_next(instruction);
+ ElnaInstructionList_set_next(current_copy, next_copy);
+ current_copy := last_copy;
goto elna_rtl_instructions_start
end;
@@ -1326,7 +1428,7 @@ begin
.elna_writer_instructions_start;
if instruction <> 0 then
_elna_writer_instruction(instruction);
- instruction := elna_rtl_instruction_get_next(instruction);
+ instruction := ElnaInstructionList_get_next(instruction);
goto elna_writer_instructions_start
end
end;
@@ -1338,9 +1440,9 @@ var
body_statements: Word;
begin
.elna_writer_procedure_loop;
- name_pointer := elna_rtl_declaration_get_name(procedure);
- name_length := elna_rtl_declaration_get_length(procedure);
- body_statements := elna_rtl_declaration_get_body(procedure);
+ name_pointer := ElnaInstructionDeclaration_get_name(procedure);
+ name_length := ElnaInstructionDeclaration_get_length(procedure);
+ body_statements := ElnaInstructionDeclaration_get_body(procedure);
(* Write .type _procedure_name, @function. *)
_write_z(".type \0");
@@ -1355,7 +1457,7 @@ begin
_elna_writer_instructions(body_statements);
_write_z("\tret\n\0");
- procedure := elna_rtl_declaration_get_next(procedure);
+ procedure := ElnaInstructionList_get_next(procedure);
if procedure <> 0 then
goto elna_writer_procedure_loop
end
@@ -1369,9 +1471,9 @@ var
begin
.elna_writer_variable_loop;
if variable <> 0 then
- name := elna_rtl_declaration_get_name(variable);
- name_length := elna_rtl_declaration_get_length(variable);
- size := elna_rtl_declaration_get_body(variable);
+ name := ElnaInstructionDeclaration_get_name(variable);
+ name_length := ElnaInstructionDeclaration_get_length(variable);
+ size := ElnaInstructionDeclaration_get_body(variable);
_write_z(".type \0");
_write_s(name, name_length);
@@ -1384,7 +1486,7 @@ begin
_write_i(size);
_write_c('\n');
- variable := elna_rtl_declaration_get_next(variable);
+ variable := ElnaInstructionList_get_next(variable);
goto elna_writer_variable_loop
end
@@ -1392,20 +1494,17 @@ end;
proc elna_rtl_module_declaration(tac_module: Word);
var
- result: Word;
+ code_part: Word;
+ data_part: Word;
current_part: Word;
begin
- result := malloc(elna_rtl_module_size());
+ current_part := ElnaInstructionModule_get_data(tac_module);
+ data_part := elna_rtl_globals(current_part);
- current_part := _elna_tac_module_get_data(tac_module);
- current_part := elna_rtl_globals(current_part);
- elna_rtl_module_set_data(result, current_part);
+ current_part := ElnaInstructionModule_get_code(tac_module);
+ code_part := elna_rtl_procedures(current_part);
- current_part := _elna_tac_module_get_code(tac_module);
- current_part := elna_rtl_procedures(current_part);
- elna_rtl_module_set_code(result, current_part);
-
- return result
+ return elna_instruction_module_create(data_part, code_part)
end;
proc _elna_writer_module(pair: Word);
@@ -1418,7 +1517,7 @@ begin
_write_z(".globl main\n\n\0");
_write_z(".section .data\n\0");
- current_part := elna_rtl_module_get_data(pair);
+ current_part := ElnaInstructionModule_get_data(pair);
_elna_writer_variable(current_part);
_write_z(".section .text\n\n\0");
@@ -1426,7 +1525,7 @@ begin
_write_z(".type _load_byte, @function\n_load_byte:\n\tlb a0, (a0)\nret\n\n\0");
_write_z(".type _store_byte, @function\n_store_byte:\n\tsb a0, (a1)\nret\n\n\0");
- current_part := elna_rtl_module_get_code(pair);
+ current_part := ElnaInstructionModule_get_code(pair);
_elna_writer_procedure(current_part);
_write_z(".section .rodata\n.type strings, @object\nstrings: .ascii \0");
@@ -1467,16 +1566,13 @@ begin
return result
end;
-proc _elna_tac_integer_literal(integer_literal_node: Word);
-var
- integer_token: Word;
- integer_length: Word;
- token_kind: Word;
+proc _elna_tac_integer_literal(integer_literal_node: Word, operand_type: Word, operand_value: Word, operand_length: Word);
begin
- integer_token := _integer_literal_node_get_value(integer_literal_node);
- integer_length := _integer_literal_node_get_length(integer_literal_node);
+ operand_type^ := ElnaTacOperand.immediate;
+ operand_value^ := _integer_literal_node_get_value(integer_literal_node);
+ operand_length^ := _integer_literal_node_get_length(integer_literal_node);
- return _elna_tac_load_immediate(ElnaRtlRegister.t0, integer_token, integer_length)
+ return 0
end;
proc _elna_parser_character_literal();
@@ -1499,15 +1595,13 @@ begin
return result
end;
-proc _elna_tac_character_literal(character_literal_node: Word);
-var
- character: Word;
- character_length: Word;
+proc _elna_tac_character_literal(character_literal_node: Word, operand_type: Word, operand_value: Word, operand_length: Word);
begin
- character := _character_literal_node_get_value(character_literal_node);
- character_length := _character_literal_node_get_length(character_literal_node);
+ operand_type^ := ElnaTacOperand.immediate;
+ operand_value^ :=_character_literal_node_get_value(character_literal_node);
+ operand_length^ := _character_literal_node_get_length(character_literal_node);
- return _elna_tac_load_immediate(ElnaRtlRegister.t0, character, character_length)
+ return 0
end;
proc _elna_parser_variable_expression();
@@ -1530,23 +1624,26 @@ begin
return result
end;
-proc _elna_tac_variable_expression(variable_expression: Word, symbol_table: Word);
+proc _elna_tac_variable_expression(variable_expression: Word, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word);
var
- name: Word;
- name_token: Word;
+ name_pointer: Word;
+ name_length: Word;
lookup_result: Word;
- instruction: Word;
begin
- name := _variable_expression_get_name(variable_expression);
- name_token := _variable_expression_get_length(variable_expression);
+ name_pointer := _variable_expression_get_name(variable_expression);
+ name_length := _variable_expression_get_length(variable_expression);
- lookup_result := _symbol_table_lookup(symbol_table, name, name_token);
+ lookup_result := _symbol_table_lookup(symbol_table, name_pointer, name_length);
if lookup_result <> 0 then
- instruction := _elna_tac_local_designator(lookup_result)
+ operand_type^ := ElnaTacOperand.stack;
+ operand_value^ := _parameter_info_get_offset(lookup_result);
+ operand_length^ := 0
else
- instruction := _elna_tac_global_designator(variable_expression)
+ operand_type^ := ElnaTacOperand.symbol;
+ operand_value^ := name_pointer;
+ operand_length^ := name_length
end;
- return instruction
+ return 0
end;
proc _elna_parser_string_literal();
@@ -1568,26 +1665,31 @@ begin
return result
end;
-proc _elna_tac_string_literal(string_literal_node: Word);
+proc _elna_tac_string_literal(string_literal_node: Word, operand_type: Word, operand_value: Word, operand_length: Word);
var
token_start: Word;
- length: Word;
offset: Word;
- instruction: Word;
first_instruction: Word;
next_instruction: Word;
begin
token_start := _string_literal_node_get_value(string_literal_node);
- length := _string_literal_node_get_length(string_literal_node);
offset := _add_string(token_start);
- first_instruction := _elna_tac_load_address(ElnaRtlRegister.t0, "strings", 7);
- instruction := _elna_tac_load_immediate(ElnaRtlRegister.t1, offset, 0);
- _elna_tac_instruction_set_next(first_instruction, instruction);
- next_instruction := _elna_tac_add(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1);
- _elna_tac_instruction_set_next(instruction, next_instruction);
+ first_instruction := _elna_tac_instruction_create(ElnaTacOperator.get_address);
+ _elna_tac_instruction_set_operand(first_instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0);
+ _elna_tac_instruction_set_operand(first_instruction, 2, ElnaTacOperand.symbol, "strings", 7);
- return first_instruction
+ (* Add offset to the string block pointer. *)
+ next_instruction := _elna_tac_instruction_create(ElnaTacOperator.add);
+ _elna_tac_instruction_set_operand(next_instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0);
+ _elna_tac_instruction_set_operand(next_instruction, 2, ElnaTacOperand.register, ElnaRtlRegister.t0, 0);
+ _elna_tac_instruction_set_operand(next_instruction, 3, ElnaTacOperand.immediate, offset, 0);
+
+ operand_type^ := ElnaTacOperand.register;
+ operand_value^ := ElnaRtlRegister.t0;
+ operand_length^ := 0;
+
+ return elna_instruction_list_concatenate(first_instruction, next_instruction)
end;
proc _elna_parser_simple_expression();
@@ -1643,9 +1745,8 @@ begin
return simple_expression
end;
-proc _elna_tac_simple_expression(parser_node: Word, symbol_table: Word, is_address: Word);
+proc _elna_tac_simple_expression(parser_node: Word, symbol_table: Word, is_address: Word, operand_type: Word, operand_value: Word, operand_length: Word);
var
- is_address: Word;
node_kind: Word;
instruction: Word;
begin
@@ -1653,13 +1754,13 @@ begin
node_kind := _node_get_kind(parser_node);
if node_kind = NodeKind.character_literal then
- instruction := _elna_tac_character_literal(parser_node)
+ instruction := _elna_tac_character_literal(parser_node, operand_type, operand_value, operand_length)
elsif node_kind = NodeKind.string_literal then
- instruction := _elna_tac_string_literal(parser_node)
+ instruction := _elna_tac_string_literal(parser_node, operand_type, operand_value, operand_length)
elsif node_kind = NodeKind.integer_literal then
- instruction := _elna_tac_integer_literal(parser_node)
+ instruction := _elna_tac_integer_literal(parser_node, operand_type, operand_value, operand_length)
else
- instruction := _elna_tac_variable_expression(parser_node, symbol_table);
+ instruction := _elna_tac_variable_expression(parser_node, symbol_table, operand_type, operand_value, operand_length);
is_address^ := 1
end;
return instruction
@@ -1699,7 +1800,7 @@ begin
return result
end;
-proc _elna_tac_unary_expression(parser_node: Word, symbol_table: Word);
+proc _elna_tac_unary_expression(parser_node: Word, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word);
var
current_character: Word;
token_kind: Word;
@@ -1723,20 +1824,56 @@ begin
end;
if operator = '@' then
- first_instruction := _elna_tac_designator(operand, symbol_table, @is_address)
+ first_instruction := _elna_tac_designator(operand, symbol_table, @is_address, operand_type, operand_value, operand_length);
+
+ instruction := _elna_tac_instruction_create(ElnaTacOperator.get_address);
+ _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0);
+ _elna_tac_instruction_set_operand(instruction, 2, operand_type^, operand_value^, operand_length^);
+
+ operand_type^ := ElnaTacOperand.register;
+ operand_value^ := ElnaRtlRegister.t0;
+ operand_length^ := 0;
+
+ first_instruction := elna_instruction_list_concatenate(first_instruction, instruction)
else
- first_instruction := _elna_tac_designator(operand, symbol_table, @is_address);
+ first_instruction := _elna_tac_designator(operand, symbol_table, @is_address, operand_type, operand_value, operand_length);
+
+ if operand_type^ = ElnaTacOperand.immediate then
+ first_instruction := _elna_tac_instruction_create(ElnaTacOperator.assign);
+ _elna_tac_instruction_set_operand(first_instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0);
+ _elna_tac_instruction_set_operand(first_instruction, 2, operand_type^, operand_value^, operand_length^);
+
+ operand_type^ := ElnaTacOperand.register;
+ operand_value^ := ElnaRtlRegister.t0;
+ operand_length^ := 0
+ elsif first_instruction = 0 then
+ first_instruction := _elna_tac_instruction_create(ElnaTacOperator.get_address);
+ _elna_tac_instruction_set_operand(first_instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0);
+ _elna_tac_instruction_set_operand(first_instruction, 2, operand_type^, operand_value^, operand_length^);
+
+ operand_type^ := ElnaTacOperand.register;
+ operand_value^ := ElnaRtlRegister.t0;
+ operand_length^ := 0
+ end;
+
if is_address then
- instruction := _elna_tac_load_word(ElnaRtlRegister.t0, ElnaRtlRegister.t0, 0);
- _elna_tac_instruction_set_next(first_instruction, instruction)
+ instruction := _elna_tac_instruction_create(ElnaTacOperator.load_word);
+ _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0);
+ _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.offset, ElnaRtlRegister.t0, 0);
+
+ operand_type^ := ElnaTacOperand.register;
+ operand_value^ := ElnaRtlRegister.t0;
+ operand_length^ := 0;
+
+ elna_instruction_list_concatenate(first_instruction, instruction)
end
end;
if operator = '-' then
instruction := _elna_tac_neg(ElnaRtlRegister.t0, ElnaRtlRegister.t0);
- _elna_tac_instruction_set_next(first_instruction, instruction)
+ elna_instruction_list_concatenate(first_instruction, instruction)
elsif operator = '~' then
instruction := _elna_tac_not(ElnaRtlRegister.t0, ElnaRtlRegister.t0);
- _elna_tac_instruction_set_next(first_instruction, instruction)
+ elna_instruction_list_concatenate(first_instruction, instruction)
end;
return first_instruction
end;
@@ -1808,7 +1945,7 @@ begin
return result
end;
-proc _elna_tac_binary_expression(parser_node: Word, symbol_table: Word);
+proc _elna_tac_binary_expression(parser_node: Word, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word);
var
token_kind: Word;
expression_kind: Word;
@@ -1816,91 +1953,85 @@ var
first_instruction: Word;
instruction: Word;
current_instruction: Word;
+ lhs_type: Word;
+ lhs_value: Word;
+ lhs_length: Word;
begin
expression_kind := _node_get_kind(parser_node);
if expression_kind <> NodeKind.binary_expression then
- first_instruction := _elna_tac_unary_expression(parser_node, symbol_table)
+ first_instruction := _elna_tac_unary_expression(parser_node, symbol_table, operand_type, operand_value, operand_length)
else
token_kind := _binary_expression_get_operator(parser_node);
operand_node := _binary_expression_get_lhs(parser_node);
- first_instruction := _elna_tac_unary_expression(operand_node, symbol_table);
+ lhs_type := 0;
+ lhs_value := 0;
+ lhs_length := 0;
+ first_instruction := _elna_tac_unary_expression(operand_node, symbol_table, @lhs_type, @lhs_value, @lhs_length);
(* Save the value of the left expression on the stack. *)
- instruction := _elna_tac_store_word(ElnaRtlRegister.t0, ElnaRtlRegister.sp, 64);
- _elna_tac_instruction_set_next(first_instruction, instruction);
+ instruction := _elna_tac_instruction_create(ElnaTacOperator.store_word);
+ _elna_tac_instruction_set_operand(instruction, 1, lhs_type, lhs_value, lhs_length);
+ _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.offset, ElnaRtlRegister.sp, 72);
+
+ elna_instruction_list_concatenate(first_instruction, instruction);
current_instruction := instruction;
operand_node := _binary_expression_get_rhs(parser_node);
- instruction := _elna_tac_unary_expression(operand_node, symbol_table);
- _elna_tac_instruction_set_next(current_instruction, instruction);
+ lhs_type := 0;
+ lhs_value := 0;
+ lhs_length := 0;
+ instruction := _elna_tac_unary_expression(operand_node, symbol_table, @lhs_type, @lhs_value, @lhs_length);
+ elna_instruction_list_concatenate(current_instruction, instruction);
current_instruction := instruction;
(* Load the left expression from the stack; *)
- instruction := _elna_tac_load_word(ElnaRtlRegister.t1, ElnaRtlRegister.sp, 64);
- _elna_tac_instruction_set_next(current_instruction, instruction);
+ instruction := _elna_tac_instruction_create(ElnaTacOperator.load_word);
+ _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t1, 0);
+ _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.offset, ElnaRtlRegister.sp, 72);
+
+ elna_instruction_list_concatenate(current_instruction, instruction);
current_instruction := instruction;
if token_kind = ElnaLexerKind.plus then
- instruction := _elna_tac_add(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1);
- _elna_tac_instruction_set_next(current_instruction, instruction)
+ instruction := _elna_tac_instruction_create(ElnaTacOperator.add)
elsif token_kind = ElnaLexerKind.minus then
- instruction := _elna_tac_sub(ElnaRtlRegister.t0, ElnaRtlRegister.t1, ElnaRtlRegister.t0);
- _elna_tac_instruction_set_next(current_instruction, instruction)
+ instruction := _elna_tac_instruction_create(ElnaTacOperator.sub)
elsif token_kind = ElnaLexerKind.multiplication then
- instruction := _elna_tac_mul(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1);
- _elna_tac_instruction_set_next(current_instruction, instruction)
+ instruction := _elna_tac_instruction_create(ElnaTacOperator.mul)
elsif token_kind = ElnaLexerKind.and then
- instruction := _elna_tac_and(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1);
- _elna_tac_instruction_set_next(current_instruction, instruction)
+ instruction := _elna_tac_instruction_create(ElnaTacOperator.and)
elsif token_kind = ElnaLexerKind._or then
- instruction := _elna_tac_or(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1);
- _elna_tac_instruction_set_next(current_instruction, instruction)
+ instruction := _elna_tac_instruction_create(ElnaTacOperator._or)
elsif token_kind = ElnaLexerKind._xor then
- instruction := _elna_tac_xor(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1);
- _elna_tac_instruction_set_next(current_instruction, instruction)
+ instruction := _elna_tac_instruction_create(ElnaTacOperator._xor)
elsif token_kind = ElnaLexerKind.equals then
- instruction := _elna_tac_xor(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1);
- _elna_tac_instruction_set_next(current_instruction, instruction);
- current_instruction := instruction;
-
- instruction := _elna_tac_seqz(ElnaRtlRegister.t0, ElnaRtlRegister.t0);
- _elna_tac_instruction_set_next(current_instruction, instruction)
+ instruction := _elna_tac_instruction_create(ElnaTacOperator.seq)
elsif token_kind = ElnaLexerKind.remainder then
- instruction := _elna_tac_rem(ElnaRtlRegister.t0, ElnaRtlRegister.t1, ElnaRtlRegister.t0);
- _elna_tac_instruction_set_next(current_instruction, instruction)
+ instruction := _elna_tac_instruction_create(ElnaTacOperator.rem)
elsif token_kind = ElnaLexerKind.division then
- instruction := _elna_tac_div(ElnaRtlRegister.t0, ElnaRtlRegister.t1, ElnaRtlRegister.t0);
- _elna_tac_instruction_set_next(current_instruction, instruction)
+ instruction := _elna_tac_instruction_create(ElnaTacOperator.div)
elsif token_kind = ElnaLexerKind.less_than then
- instruction := _elna_tac_slt(ElnaRtlRegister.t0, ElnaRtlRegister.t1, ElnaRtlRegister.t0);
- _elna_tac_instruction_set_next(current_instruction, instruction)
+ instruction := _elna_tac_instruction_create(ElnaTacOperator.slt)
elsif token_kind = ElnaLexerKind.greater_than then
- instruction := _elna_tac_slt(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1);
- _elna_tac_instruction_set_next(current_instruction, instruction)
+ instruction := _elna_tac_instruction_create(ElnaTacOperator.sgt)
elsif token_kind = ElnaLexerKind.less_equal then
- instruction := _elna_tac_slt(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1);
- _elna_tac_instruction_set_next(current_instruction, instruction);
- current_instruction := instruction;
-
- instruction := _elna_tac_xor_immediate(ElnaRtlRegister.t0, ElnaRtlRegister.t0, 1);
- _elna_tac_instruction_set_next(current_instruction, instruction)
+ instruction := _elna_tac_instruction_create(ElnaTacOperator.sle)
+ elsif token_kind = ElnaLexerKind.greater_equal then
+ instruction := _elna_tac_instruction_create(ElnaTacOperator.sge)
elsif token_kind = ElnaLexerKind.not_equal then
- instruction := _elna_tac_xor(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1);
- _elna_tac_instruction_set_next(current_instruction, instruction);
- current_instruction := instruction;
+ instruction := _elna_tac_instruction_create(ElnaTacOperator.sne)
+ end;
+ _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0);
+ _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, 72, 0);
+ _elna_tac_instruction_set_operand(instruction, 3, lhs_type, lhs_value, lhs_length);
- instruction := _elna_tac_snez(ElnaRtlRegister.t0, ElnaRtlRegister.t0);
- _elna_tac_instruction_set_next(current_instruction, instruction)
- elsif token_kind = ElnaLexerKind.greater_equal then
- instruction := _elna_tac_slt(ElnaRtlRegister.t0, ElnaRtlRegister.t1, ElnaRtlRegister.t0);
- _elna_tac_instruction_set_next(current_instruction, instruction);
- current_instruction := instruction;
+ elna_instruction_list_concatenate(current_instruction, instruction);
- instruction := _elna_tac_xor_immediate(ElnaRtlRegister.t0, ElnaRtlRegister.t0, 1);
- _elna_tac_instruction_set_next(current_instruction, instruction)
- end
+ operand_type^ := ElnaTacOperand.register;
+ operand_value^ := ElnaRtlRegister.t0;
+ operand_length^ := 0
end;
return first_instruction
end;
@@ -1989,6 +2120,9 @@ var
instruction: Word;
first_instruction: Word;
current_instruction: Word;
+ operand_type: Word;
+ operand_value: Word;
+ operand_length: Word;
begin
parsed_expression := _call_get_name(parsed_call);
name := _variable_expression_get_name(parsed_expression);
@@ -2002,20 +2136,25 @@ begin
if parsed_expression = 0 then
goto elna_tac_call_finalize
else
- instruction := _elna_tac_binary_expression(parsed_expression, symbol_table);
+ operand_type := 0;
+ operand_value := 0;
+ operand_length := 0;
+ instruction := _elna_tac_binary_expression(parsed_expression, symbol_table, @operand_type, @operand_value, @operand_length);
if first_instruction = 0 then
first_instruction := instruction
else
- _elna_tac_instruction_set_next(current_instruction, instruction)
+ elna_instruction_list_concatenate(current_instruction, instruction)
end;
current_instruction := instruction;
(* Save the argument on the stack. *)
stack_offset := argument_count * 4;
- instruction := _elna_tac_store_word(ElnaRtlRegister.t0,
- ElnaRtlRegister.sp, 116 - stack_offset);
- _elna_tac_instruction_set_next(current_instruction, instruction);
+ instruction := _elna_tac_instruction_create(ElnaTacOperator.store_word);
+ _elna_tac_instruction_set_operand(instruction, 1, operand_type, operand_value, operand_length);
+ _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.offset, ElnaRtlRegister.sp, 132 - stack_offset);
+
+ elna_instruction_list_concatenate(current_instruction, instruction);
current_instruction := instruction;
argument_count := argument_count + 1;
@@ -2029,10 +2168,10 @@ begin
argument_count := argument_count - 1;
stack_offset := argument_count * 4;
- (* Calculate the stack offset: 116 - (4 * argument_counter) *)
+ (* Calculate the stack offset: 132 - (4 * argument_counter) *)
instruction := _elna_tac_load_word(ElnaRtlRegister.a0 + argument_count,
- ElnaRtlRegister.sp, 116 - stack_offset);
- _elna_tac_instruction_set_next(current_instruction, instruction);
+ ElnaRtlRegister.sp, 132 - stack_offset);
+ elna_instruction_list_concatenate(current_instruction, instruction);
current_instruction := instruction;
goto elna_tac_call_finalize
@@ -2041,7 +2180,7 @@ begin
if first_instruction = 0 then
first_instruction := instruction
else
- _elna_tac_instruction_set_next(current_instruction, instruction)
+ elna_instruction_list_concatenate(current_instruction, instruction)
end;
return first_instruction
end;
@@ -2122,27 +2261,7 @@ begin
return _elna_tac_label(label_name, label_length)
end;
-proc _elna_tac_local_designator(symbol: Word);
-var
- variable_offset: Word;
-begin
- variable_offset := _parameter_info_get_offset(symbol);
-
- return _elna_tac_add_immediate(ElnaRtlRegister.t0, ElnaRtlRegister.sp, variable_offset)
-end;
-
-proc _elna_tac_global_designator(variable_expression: Word);
-var
- name: Word;
- token_length: Word;
-begin
- name := _variable_expression_get_name(variable_expression);
- token_length := _variable_expression_get_length(variable_expression);
-
- return _elna_tac_load_address(ElnaRtlRegister.t0, name, token_length)
-end;
-
-proc _elna_tac_enumeration_value(field_access_expression: Word);
+proc _elna_tac_enumeration_value(field_access_expression: Word, operand_type: Word, operand_value: Word, operand_length: Word);
var
enumeration_type: Word;
members: Word;
@@ -2154,7 +2273,6 @@ var
member_length: Word;
counter: Word;
symbol: Word;
- instruction: Word;
begin
symbol := _field_access_expression_get_aggregate(field_access_expression);
value_name := _variable_expression_get_name(symbol);
@@ -2172,7 +2290,6 @@ begin
name_length := _field_access_expression_get_length(field_access_expression);
counter := 1;
- instruction := 0;
.elna_tac_enumeration_value_members;
if members_length > 0 then
member_name := members^;
@@ -2185,9 +2302,12 @@ begin
counter := counter + 1;
goto elna_tac_enumeration_value_members
end;
- instruction := _elna_tac_load_immediate(ElnaRtlRegister.t0, counter, 0)
+ (* Found. *)
+ operand_type^ := ElnaTacOperand.immediate;
+ operand_value^ := counter;
+ operand_length^ := 0
end;
- return instruction
+ return 0
end;
proc _elna_parser_field_access_expression(aggregate: Word);
@@ -2216,33 +2336,46 @@ begin
return result
end;
-proc _elna_tac_designator(parser_node: Word, symbol_table: Word, is_address: Word);
+proc _elna_tac_designator(parser_node: Word, symbol_table: Word, is_address: Word, operand_type: Word, operand_value: Word, operand_length: Word);
var
- name_token: Word;
- lookup_result: Word;
- token_kind: Word;
parser_node: Word;
node_kind: Word;
first_instruction: Word;
- instruction: Word;
+ last_instruction: Word;
begin
node_kind := _node_get_kind(parser_node);
if node_kind = NodeKind.dereference_expression then
parser_node := _dereference_expression_get_pointer(parser_node);
- first_instruction := _elna_tac_simple_expression(parser_node, symbol_table, is_address);
- instruction := _elna_tac_load_word(ElnaRtlRegister.t0, ElnaRtlRegister.t0, 0);
- _elna_tac_instruction_set_next(first_instruction, instruction)
+ first_instruction := _elna_tac_simple_expression(parser_node, symbol_table, is_address, operand_type, operand_value, operand_length);
+
+ last_instruction := _elna_tac_instruction_create(ElnaTacOperator.assign);
+ _elna_tac_instruction_set_operand(last_instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0);
+ _elna_tac_instruction_set_operand(last_instruction, 2, operand_type^, operand_value^, operand_length^);
+
+ operand_type^ := ElnaTacOperand.register;
+ operand_value^ := ElnaRtlRegister.t0;
+ operand_length^ := 0;
+
+ first_instruction := elna_instruction_list_concatenate(first_instruction, last_instruction)
elsif node_kind = NodeKind.field_access_expression then
- first_instruction := _elna_tac_enumeration_value(parser_node);
+ _elna_tac_enumeration_value(parser_node, operand_type, operand_value, operand_length);
is_address^ := 0
elsif node_kind = NodeKind.call then
first_instruction := _elna_tac_call(parser_node, symbol_table);
- instruction := _elna_tac_move(ElnaRtlRegister.t0, ElnaRtlRegister.a0);
- _elna_tac_instruction_set_next(first_instruction, instruction);
+
+ last_instruction := _elna_tac_instruction_create(ElnaTacOperator.assign);
+ _elna_tac_instruction_set_operand(last_instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0);
+ _elna_tac_instruction_set_operand(last_instruction, 2, ElnaTacOperand.register, ElnaRtlRegister.a0, 0);
+
+ operand_type^ := ElnaTacOperand.register;
+ operand_value^ := ElnaRtlRegister.t0;
+ operand_length^ := 0;
+
+ elna_instruction_list_concatenate(first_instruction, last_instruction);
is_address^ := 0
else
- first_instruction := _elna_tac_simple_expression(parser_node, symbol_table, is_address)
+ first_instruction := _elna_tac_simple_expression(parser_node, symbol_table, is_address, operand_type, operand_value, operand_length)
end;
return first_instruction
end;
@@ -2276,24 +2409,42 @@ var
first_instruction: Word;
instruction: Word;
current_instruction: Word;
+ operand_type: Word;
+ operand_value: Word;
+ operand_length: Word;
begin
current_expression := _assign_statement_get_assignee(parser_tree);
- first_instruction := _elna_tac_designator(current_expression, symbol_table, @is_address);
+ operand_type := 0;
+ operand_value := 0;
+ operand_length := 0;
+ first_instruction := _elna_tac_designator(current_expression, symbol_table, @is_address, @operand_type, @operand_value, @operand_length);
+
+ current_instruction := _elna_tac_instruction_create(ElnaTacOperator.get_address);
+ _elna_tac_instruction_set_operand(current_instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0);
+ _elna_tac_instruction_set_operand(current_instruction, 2, operand_type, operand_value, operand_length);
+ first_instruction := elna_instruction_list_concatenate(first_instruction, current_instruction);
(* Save the assignee address on the stack. *)
- current_instruction := _elna_tac_store_word(ElnaRtlRegister.t0, ElnaRtlRegister.sp, 60);
- _elna_tac_instruction_set_next(first_instruction, current_instruction);
+ current_instruction := _elna_tac_store_word(ElnaRtlRegister.t0, ElnaRtlRegister.sp, 76);
+ elna_instruction_list_concatenate(first_instruction, current_instruction);
(* Compile the assignment. *)
current_expression := _assign_statement_get_assignment(parser_tree);
- instruction := _elna_tac_binary_expression(current_expression, symbol_table);
- _elna_tac_instruction_set_next(current_instruction, instruction);
+ operand_type := 0;
+ operand_value := 0;
+ operand_length := 0;
+ instruction := _elna_tac_binary_expression(current_expression, symbol_table, @operand_type, @operand_value, @operand_length);
- current_instruction := _elna_tac_load_word(ElnaRtlRegister.t1, ElnaRtlRegister.sp, 60);
- _elna_tac_instruction_set_next(instruction, current_instruction);
+ elna_instruction_list_concatenate(current_instruction, instruction);
- instruction := _elna_tac_store_word(ElnaRtlRegister.t0, ElnaRtlRegister.t1, 0);
- _elna_tac_instruction_set_next(current_instruction, instruction);
+ current_instruction := _elna_tac_load_word(ElnaRtlRegister.t1, ElnaRtlRegister.sp, 76);
+ elna_instruction_list_concatenate(instruction, current_instruction);
+
+ instruction := _elna_tac_instruction_create(ElnaTacOperator.store_word);
+ _elna_tac_instruction_set_operand(instruction, 1, operand_type, operand_value, operand_length);
+ _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.offset, ElnaRtlRegister.t1, 0);
+
+ elna_instruction_list_concatenate(current_instruction, instruction);
return first_instruction
end;
@@ -2324,11 +2475,21 @@ var
return_expression: Word;
first_instruction: Word;
instruction: Word;
+ operand_type: Word;
+ operand_value: Word;
+ operand_length: Word;
begin
+ operand_type := 0;
+ operand_value := 0;
+ operand_length := 0;
return_expression := _return_statement_get_returned(parser_node);
- first_instruction := _elna_tac_binary_expression(return_expression, symbol_table);
- instruction := _elna_tac_move(ElnaRtlRegister.a0, ElnaRtlRegister.t0);
- _elna_tac_instruction_set_next(first_instruction, instruction);
+ first_instruction := _elna_tac_binary_expression(return_expression, symbol_table, @operand_type, @operand_value, @operand_length);
+
+ instruction := _elna_tac_instruction_create(ElnaTacOperator.assign);
+ _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.a0, 0);
+ _elna_tac_instruction_set_operand(instruction, 2, operand_type, operand_value, operand_length);
+
+ elna_instruction_list_concatenate(first_instruction, instruction);
return first_instruction
end;
@@ -2386,30 +2547,39 @@ var
instruction: Word;
current_instruction: Word;
first_instruction: Word;
+ operand_type: Word;
+ operand_value: Word;
+ operand_length: Word;
begin
(* Compile condition. *)
+ operand_type := 0;
+ operand_value := 0;
+ operand_length := 0;
current_node := _conditional_statements_get_condition(parser_node);
- first_instruction := _elna_tac_binary_expression(current_node, symbol_table);
+ first_instruction := _elna_tac_binary_expression(current_node, symbol_table, @operand_type, @operand_value, @operand_length);
(* 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_beqz(ElnaRtlRegister.t0, condition_label, 0);
- _elna_tac_instruction_set_next(first_instruction, current_instruction);
+ current_instruction := _elna_tac_instruction_create(ElnaTacOperator.beqz);
+ _elna_tac_instruction_set_operand(current_instruction, 1, operand_type, operand_value, operand_length);
+ _elna_tac_instruction_set_operand(current_instruction, 2, ElnaTacOperand.symbol, condition_label, 0);
+
+ elna_instruction_list_concatenate(first_instruction, current_instruction);
current_node := _conditional_statements_get_statements(parser_node);
instruction := _elna_tac_statements(current_node, symbol_table);
if instruction <> 0 then
- _elna_tac_instruction_set_next(current_instruction, instruction);
+ elna_instruction_list_concatenate(current_instruction, instruction);
current_instruction := instruction
end;
instruction := _elna_tac_jump(after_end_label, 0);
- _elna_tac_instruction_set_next(current_instruction, instruction);
+ elna_instruction_list_concatenate(current_instruction, instruction);
current_instruction := _elna_tac_label(condition_label, 0);
- _elna_tac_instruction_set_next(instruction, current_instruction);
+ elna_instruction_list_concatenate(instruction, current_instruction);
return first_instruction
end;
@@ -2533,7 +2703,7 @@ begin
if first_instruction = 0 then
first_instruction := instruction
else
- _elna_tac_instruction_set_next(current_instruction, instruction)
+ elna_instruction_list_concatenate(current_instruction, instruction)
end;
current_instruction := instruction;
goto elna_tac_statements_loop
@@ -2561,7 +2731,7 @@ begin
current_node := _conditional_statements_get_next(current_node);
if current_node <> 0 then
instruction := _elna_tac_conditional_statements(current_node, after_end_label, symbol_table);
- _elna_tac_instruction_set_next(current_instruction, instruction);
+ elna_instruction_list_concatenate(current_instruction, instruction);
current_instruction := instruction;
goto elna_tac_if_statement_loop
end;
@@ -2570,12 +2740,12 @@ begin
if current_node <> 0 then
instruction := _elna_tac_statements(current_node, symbol_table);
if instruction <> 0 then
- _elna_tac_instruction_set_next(current_instruction, instruction);
+ elna_instruction_list_concatenate(current_instruction, instruction);
current_instruction := instruction
end
end;
instruction := _elna_tac_label(after_end_label, 0);
- _elna_tac_instruction_set_next(current_instruction, instruction);
+ elna_instruction_list_concatenate(current_instruction, instruction);
return first_instruction
end;
@@ -2919,9 +3089,9 @@ begin
result := malloc(_parameter_info_size());
_info_set_kind(result, InfoKind.parameter_info);
- (* Calculate the stack offset: 88 - (4 * parameter_counter) *)
+ (* Calculate the stack offset: 104 - (4 * parameter_counter) *)
offset := parameter_index * 4;
- _parameter_info_set_offset(result, 88 - offset);
+ _parameter_info_set_offset(result, 104 - offset);
return result
end;
@@ -3117,12 +3287,11 @@ begin
symbol_info := _parameter_info_get_offset(symbol_info);
- instruction := _elna_tac_store_word(ElnaRtlRegister.a0 + parameter_counter,
- ElnaRtlRegister.sp, symbol_info);
+ instruction := _elna_tac_store_word(ElnaRtlRegister.a0 + parameter_counter, ElnaRtlRegister.sp, symbol_info);
if first_instruction = 0 then
first_instruction := instruction
else
- _elna_tac_instruction_set_next(current_instruction, instruction)
+ elna_instruction_list_concatenate(current_instruction, instruction)
end;
current_instruction := instruction;
@@ -3141,15 +3310,15 @@ var
body: Word;
result: Word;
begin
- result := malloc(elna_rtl_declaration_size());
- name := _elna_tac_declaration_get_name(tac_declaration);
- length := _elna_tac_declaration_get_length(tac_declaration);
- body := _elna_tac_declaration_get_body(tac_declaration);
+ result := malloc(ElnaInstructionDeclaration_size());
+ name := ElnaInstructionDeclaration_get_name(tac_declaration);
+ length := ElnaInstructionDeclaration_get_length(tac_declaration);
+ body := ElnaInstructionDeclaration_get_body(tac_declaration);
- elna_rtl_declaration_set_next(result, 0);
- elna_rtl_declaration_set_name(result, name);
- elna_rtl_declaration_set_length(result, length);
- elna_rtl_declaration_set_body(result, body);
+ ElnaInstructionList_set_next(result, 0);
+ ElnaInstructionDeclaration_set_name(result, name);
+ ElnaInstructionDeclaration_set_length(result, length);
+ ElnaInstructionDeclaration_set_body(result, body);
return result
end;
@@ -3161,16 +3330,16 @@ var
body: Word;
result: Word;
begin
- result := malloc(elna_rtl_declaration_size());
- name := _elna_tac_declaration_get_name(tac_declaration);
- length := _elna_tac_declaration_get_length(tac_declaration);
- body := _elna_tac_declaration_get_body(tac_declaration);
+ result := malloc(ElnaInstructionDeclaration_size());
+ name := ElnaInstructionDeclaration_get_name(tac_declaration);
+ length := ElnaInstructionDeclaration_get_length(tac_declaration);
+ body := ElnaInstructionDeclaration_get_body(tac_declaration);
body := elna_rtl_instructions(body);
- elna_rtl_declaration_set_next(result, 0);
- elna_rtl_declaration_set_name(result, name);
- elna_rtl_declaration_set_length(result, length);
- elna_rtl_declaration_set_body(result, body);
+ ElnaInstructionList_set_next(result, 0);
+ ElnaInstructionDeclaration_set_name(result, name);
+ ElnaInstructionDeclaration_set_length(result, length);
+ ElnaInstructionDeclaration_set_body(result, body);
return result
end;
@@ -3188,15 +3357,15 @@ var
result: Word;
result_size: Word;
begin
- result := malloc(_elna_tac_declaration_size());
+ result := malloc(ElnaInstructionDeclaration_size());
- _elna_tac_declaration_set_next(result, 0);
+ ElnaInstructionList_set_next(result, 0);
name_pointer := _declaration_get_name(parser_node);
name_length := _declaration_get_length(parser_node);
- _elna_tac_declaration_set_name(result, name_pointer);
- _elna_tac_declaration_set_length(result, name_length);
+ ElnaInstructionDeclaration_set_name(result, name_pointer);
+ ElnaInstructionDeclaration_set_length(result, name_length);
symbol_info := _symbol_table_lookup(@symbol_table_global, name_pointer, name_length);
new_symbol_table := _procedure_info_get_symbol_table(symbol_info);
@@ -3206,17 +3375,17 @@ begin
current_parameter := _procedure_declaration_get_parameters(parser_node);
current_parameter := _elna_tac_parameters(current_parameter, new_symbol_table);
- _elna_tac_instruction_set_next(first_instruction, current_parameter);
+ elna_instruction_list_concatenate(first_instruction, current_parameter);
body := _procedure_declaration_get_body(parser_node);
instruction := _elna_tac_statements(body, new_symbol_table);
- _elna_tac_instruction_set_next(first_instruction, instruction);
+ elna_instruction_list_concatenate(first_instruction, instruction);
(* Write the epilogue. *)
instruction := _elna_tac_instruction_create(ElnaTacOperator.ret);
- _elna_tac_instruction_set_next(first_instruction, instruction);
+ elna_instruction_list_concatenate(first_instruction, instruction);
- _elna_tac_declaration_set_body(result, first_instruction);
+ ElnaInstructionDeclaration_set_body(result, first_instruction);
return result
end;
@@ -3260,7 +3429,7 @@ var
begin
if tac_procedure <> 0 then
first_copy := elna_rtl_global_declaration(tac_procedure);
- tac_procedure := _elna_tac_declaration_get_next(tac_procedure)
+ tac_procedure := ElnaInstructionList_get_next(tac_procedure)
else
first_copy := 0;
end;
@@ -3271,8 +3440,8 @@ begin
if tac_procedure <> 0 then
next_copy := elna_rtl_global_declaration(tac_procedure);
- tac_procedure := _elna_tac_declaration_get_next(tac_procedure);
- elna_rtl_declaration_set_next(current_copy, next_copy);
+ tac_procedure := ElnaInstructionList_get_next(tac_procedure);
+ ElnaInstructionList_set_next(current_copy, next_copy);
current_copy := next_copy;
goto elna_rtl_globals_start
end;
@@ -3288,7 +3457,7 @@ var
begin
if tac_procedure <> 0 then
first_copy := elna_rtl_procedure_declaration(tac_procedure);
- tac_procedure := _elna_tac_declaration_get_next(tac_procedure)
+ tac_procedure := ElnaInstructionList_get_next(tac_procedure)
else
first_copy := 0;
end;
@@ -3299,8 +3468,8 @@ begin
if tac_procedure <> 0 then
next_copy := elna_rtl_procedure_declaration(tac_procedure);
- tac_procedure := _elna_tac_declaration_get_next(tac_procedure);
- elna_rtl_declaration_set_next(current_copy, next_copy);
+ tac_procedure := ElnaInstructionList_get_next(tac_procedure);
+ ElnaInstructionList_set_next(current_copy, next_copy);
current_copy := next_copy;
goto elna_rtl_procedures_start
end;
@@ -3324,7 +3493,7 @@ begin
if first_procedure = 0 then
first_procedure := result
else
- _elna_tac_declaration_set_next(current_procedure, result)
+ ElnaInstructionList_set_next(current_procedure, result)
end;
current_procedure := result;
@@ -3475,25 +3644,25 @@ var
variable_type: Word;
result: Word;
begin
- result := malloc(_elna_tac_declaration_size());
+ result := malloc(ElnaInstructionDeclaration_size());
- _elna_tac_declaration_set_next(result, 0);
+ ElnaInstructionList_set_next(result, 0);
name := _declaration_get_name(parser_tree);
name_length := _declaration_get_length(parser_tree);
variable_type := _variable_declaration_get__type(parser_tree);
- _elna_tac_declaration_set_name(result, name);
- _elna_tac_declaration_set_length(result, name_length);
+ ElnaInstructionDeclaration_set_name(result, name);
+ ElnaInstructionDeclaration_set_length(result, name_length);
name := _named_type_expression_get_name(variable_type);
name_length := _named_type_expression_get_length(variable_type);
if string_compare("Array", 5, name, name_length) then
(* Else we assume this is a zeroed 4096 bytes big array. *)
- _elna_tac_declaration_set_body(result, 4096)
+ ElnaInstructionDeclaration_set_body(result, 4096)
else
- _elna_tac_declaration_set_body(result, 4)
+ ElnaInstructionDeclaration_set_body(result, 4)
end;
return result
end;
@@ -3514,8 +3683,8 @@ begin
new_length := field_length + name_length;
new_length := new_length + 5;
- first_result := malloc(_elna_tac_declaration_size());
- _elna_tac_declaration_set_next(first_result, 0);
+ first_result := malloc(ElnaInstructionDeclaration_size());
+ ElnaInstructionList_set_next(first_result, 0);
new_name := malloc(new_length);
@@ -3526,16 +3695,16 @@ begin
name_target := name_target + 5;
memcpy(name_target, field_pointer^, field_length);
- _elna_tac_declaration_set_name(first_result, new_name);
- _elna_tac_declaration_set_length(first_result, new_length);
+ ElnaInstructionDeclaration_set_name(first_result, new_name);
+ ElnaInstructionDeclaration_set_length(first_result, new_length);
- instruction := _elna_tac_add_immediate(ElnaRtlRegister.a0, ElnaRtlRegister.a0, field_offset, 0);
+ instruction := _elna_tac_add(ElnaRtlRegister.a0, ElnaRtlRegister.a0, ElnaTacOperand.immediate, field_offset);
next_instruction := _elna_tac_load_word(ElnaRtlRegister.a0, ElnaRtlRegister.a0, 0);
- _elna_tac_instruction_set_next(instruction, next_instruction);
- _elna_tac_declaration_set_body(first_result, instruction);
+ elna_instruction_list_concatenate(instruction, next_instruction);
+ ElnaInstructionDeclaration_set_body(first_result, instruction);
- second_result := malloc(_elna_tac_declaration_size());
- _elna_tac_declaration_set_next(second_result, 0);
+ second_result := malloc(ElnaInstructionDeclaration_size());
+ ElnaInstructionList_set_next(second_result, 0);
new_name := malloc(new_length);
@@ -3546,15 +3715,15 @@ begin
name_target := name_target + 5;
memcpy(name_target, field_pointer^, field_length);
- _elna_tac_declaration_set_name(second_result, new_name);
- _elna_tac_declaration_set_length(second_result, new_length);
+ ElnaInstructionDeclaration_set_name(second_result, new_name);
+ ElnaInstructionDeclaration_set_length(second_result, new_length);
- instruction := _elna_tac_add_immediate(ElnaRtlRegister.a0, ElnaRtlRegister.a0, field_offset, 0);
+ instruction := _elna_tac_add(ElnaRtlRegister.a0, ElnaRtlRegister.a0, ElnaTacOperand.immediate, field_offset);
next_instruction := _elna_tac_store_word(ElnaRtlRegister.a1, ElnaRtlRegister.a0, 0);
- _elna_tac_instruction_set_next(instruction, next_instruction);
- _elna_tac_declaration_set_body(second_result, instruction);
+ elna_instruction_list_concatenate(instruction, next_instruction);
+ ElnaInstructionDeclaration_set_body(second_result, instruction);
- _elna_tac_declaration_set_next(first_result, second_result);
+ ElnaInstructionList_set_next(first_result, second_result);
return first_result
end;
@@ -3571,12 +3740,9 @@ var
field_offset: Word;
field_pointer: Word;
begin
- first_result := malloc(_elna_tac_declaration_size());
+ first_result := malloc(ElnaInstructionDeclaration_size());
result := 0;
- (* Debug. Error stream output.
- _syscall(2, name_pointer, name_length, 0, 0, 0, 64); *)
-
type_size := _type_get_size(type_representation);
new_length := name_length + 5;
new_name := malloc(new_length);
@@ -3584,11 +3750,14 @@ begin
memcpy(new_name, name_pointer, name_length);
memcpy(new_name + name_length, "_size", 5);
- _elna_tac_declaration_set_name(first_result, new_name);
- _elna_tac_declaration_set_length(first_result, new_length);
+ ElnaInstructionDeclaration_set_name(first_result, new_name);
+ ElnaInstructionDeclaration_set_length(first_result, new_length);
+
+ instruction := _elna_tac_instruction_create(ElnaTacOperator.assign);
+ _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.a0, 0);
+ _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.immediate, type_size, 0);
- instruction := _elna_tac_load_immediate(ElnaRtlRegister.a0, type_size, 0);
- _elna_tac_declaration_set_body(first_result, instruction);
+ ElnaInstructionDeclaration_set_body(first_result, instruction);
field_count := _record_type_get_length(type_representation);
field_pointer := _record_type_get_members(type_representation);
@@ -3599,8 +3768,8 @@ begin
if field_count > 0 then
result := _elna_tac_type_field(name_pointer, name_length, field_pointer, field_offset);
- _elna_tac_declaration_set_next(current_result^, result);
- current_result^ := _elna_tac_declaration_get_next(result);
+ ElnaInstructionList_set_next(current_result^, result);
+ current_result^ := ElnaInstructionList_get_next(result);
field_offset := field_offset + 4;
field_count := field_count - 1;
@@ -3647,7 +3816,7 @@ begin
first_result := result;
current_result := out_result
elsif result <> 0 then
- _elna_tac_declaration_set_next(current_result, result);
+ ElnaInstructionList_set_next(current_result, result);
current_result := out_result
end;
parser_node := _declaration_get_next(parser_node);
@@ -3713,7 +3882,7 @@ begin
if first_variable = 0 then
first_variable := node
else
- _elna_tac_declaration_set_next(current_variable, node)
+ ElnaInstructionList_set_next(current_variable, node)
end;
current_variable := node;
@@ -3770,15 +3939,15 @@ begin
current_declaration := code_part;
.elna_tac_module_declaration_types;
- next_declaration := _elna_tac_declaration_get_next(current_declaration);
+ next_declaration := ElnaInstructionList_get_next(current_declaration);
if next_declaration <> 0 then
current_declaration := next_declaration;
goto elna_tac_module_declaration_types
end;
- _elna_tac_declaration_set_next(current_declaration, type_part);
+ ElnaInstructionList_set_next(current_declaration, type_part);
- return _elna_tac_module_create(data_part, code_part)
+ return elna_instruction_module_create(data_part, code_part)
end;
proc _elna_name_procedure_declaration(parser_node: Word);
@@ -4790,7 +4959,8 @@ proc _initialize_global_state();
begin
compiler_strings_position := @compiler_strings;
source_code := malloc(495616);
- symbol_table_store := malloc(4194304)
+ symbol_table_store := malloc(4194304);
+ temporary_variable_counter := 0
end;
(*