summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--boot/stage19/cl.elna409
1 files changed, 186 insertions, 223 deletions
diff --git a/boot/stage19/cl.elna b/boot/stage19/cl.elna
index 0f0b832..e035020 100644
--- a/boot/stage19/cl.elna
+++ b/boot/stage19/cl.elna
@@ -464,7 +464,7 @@ type
label,
_return
);
- ElnaTacKind = (list, immediate, symbol, pseudo);
+ ElnaTacKind = (list, immediate, symbol, pseudo, pseudo_mem);
ElnaTacOperand = record
kind: ElnaTacKind;
value: Word;
@@ -550,6 +550,9 @@ type
t5,
t6
);
+ ElnaRtlInfo = record
+ counter: Word
+ end;
var
symbol_table_global: Array;
@@ -563,6 +566,7 @@ var
label_counter: Word;
symbol_table_store: Word;
temporary_variable_counter: Word;
+ pseudo_counter: Word;
(**
* Calculates and returns the string token length between quotes, including the
@@ -575,22 +579,22 @@ var
*)
proc _string_length(string: Word);
var
- counter1: Word;
- current_byte1: Word;
+ counter: Word;
+ current_byte: Word;
begin
(* Reset the counter. *)
- counter1 := 0;
+ counter := 0;
.string_length_loop;
string := string + 1;
- current_byte1 := _load_byte(string);
- if current_byte1 <> '"' then
- counter1 := counter1 + 1;
+ current_byte := _load_byte(string);
+ if current_byte <> '"' then
+ counter := counter + 1;
goto string_length_loop
end;
- return counter1
+ return counter
end;
(**
@@ -603,27 +607,27 @@ end;
*)
proc _add_string(string: Word);
var
- contents1: Word;
- result1: Word;
- current_byte1: Word;
+ contents: Word;
+ result: Word;
+ current_byte: Word;
begin
- contents1 := string + 1;
- result1 := compiler_strings_length;
+ contents := string + 1;
+ result := compiler_strings_length;
.add_string_loop;
- current_byte1 := _load_byte(contents1);
- if current_byte1 <> '"' then
- _store_byte(current_byte1, compiler_strings_position);
+ current_byte := _load_byte(contents);
+ if current_byte <> '"' then
+ _store_byte(current_byte, compiler_strings_position);
compiler_strings_position := compiler_strings_position + 1;
- contents1 := contents1 + 1;
+ contents := contents + 1;
- if current_byte1 <> '\\' then
+ if current_byte <> '\\' then
compiler_strings_length := compiler_strings_length + 1
end;
goto add_string_loop
end;
- return result1
+ return result
end;
(**
@@ -694,6 +698,20 @@ proc _is_alnum(character: Word);
return _is_alpha(character) or isdigit(character)
end;
+proc elna_tac_generate_pseudo(operand_type: Word, operand_value: Word, operand_length: Word);
+var
+ buffer: Word;
+begin
+ pseudo_counter := pseudo_counter + 1;
+ buffer := malloc(6);
+
+ sprintf(buffer, "$%i\0", pseudo_counter);
+
+ operand_type^ := ElnaTacKind.pseudo;
+ operand_value^ := buffer;
+ operand_length^ := strlen(buffer);
+end;
+
proc elna_instruction_list_concatenate(this: ^ElnaInstructionList, value: Word);
var
start: Word;
@@ -835,7 +853,7 @@ begin
return lhs
end;
-proc elna_rtl_binary_arithmetic(tac_instruction: Word, next_instruction: ^^ElnaRtlInstruction, operation: Word);
+proc elna_rtl_binary_arithmetic(tac_instruction: ^ElnaTacInstruction, next_instruction: ^^ElnaRtlInstruction, operation: Word);
var
lhs: Word;
binary_result: ^ElnaRtlInstruction;
@@ -894,7 +912,13 @@ begin
operand_value := tac_instruction^.operands[number].value;
operand_length := tac_instruction^.operands[number].length;
- elna_rtl_instruction_set_operand(rtl_instruction, number, operand_type, operand_value, operand_length)
+ if operand_type = ElnaTacKind.immediate then
+ elna_rtl_instruction_set_operand(rtl_instruction, number, ElnaRtlKind.immediate, operand_value, operand_length)
+ elsif operand_type = ElnaTacKind.symbol then
+ elna_rtl_instruction_set_operand(rtl_instruction, number, ElnaRtlKind.symbol, operand_value, operand_length)
+ elsif operand_type = ElnaTacKind.pseudo then
+ elna_rtl_instruction_set_operand(rtl_instruction, number, ElnaRtlKind.pseudo, operand_value, operand_length)
+ end
end;
proc elna_rtl_conditional_jump(tac_instruction: Word, condition: Word);
@@ -924,7 +948,7 @@ end;
proc elna_rtl_call(tac_instruction: ^ElnaTacInstruction, next_instruction: ^^ElnaRtlInstruction);
var
argument_count: Word;
- current_argument: Word;
+ current_argument: ^ElnaTacOperand;
argument_type: Word;
argument_value: Word;
argument_length: Word;
@@ -944,12 +968,10 @@ begin
if argument_count > 0 then
argument_count := argument_count - 1;
- argument_type := current_argument^;
- current_argument := current_argument + 4;
- argument_value := current_argument^;
- current_argument := current_argument + 4;
- argument_length := current_argument^;
- current_argument := current_argument + 4;
+ argument_type := current_argument^.kind;
+ argument_value := current_argument^.value;
+ argument_length := current_argument^.length;
+ current_argument := current_argument + #size(ElnaTacOperand);
argument_move := elna_rtl_instruction_create(ElnaRtlOperator.move);
elna_rtl_instruction_set_operand(argument_move, 1, ElnaRtlKind.register, ElnaRtlRegister.a0 + current_register, 0);
@@ -1182,13 +1204,13 @@ end;
proc elna_tac_label(counter: Word, length: Word);
var
- result1: Word;
+ result: Word;
begin
- result1 := elna_tac_instruction_create(ElnaTacOperator.label);
+ result := elna_tac_instruction_create(ElnaTacOperator.label);
- elna_tac_instruction_set_operand(result1, 1, ElnaTacKind.symbol, counter, length);
+ elna_tac_instruction_set_operand(result, 1, ElnaTacKind.symbol, counter, length);
- return result1
+ return result
end;
proc elna_riscv_instruction_name(instruction_kind: Word);
@@ -1273,8 +1295,8 @@ end;
proc elna_riscv_register(register: Word);
begin
- _write_c('x');
- _write_i(register - 1)
+ printf("x%i\0", register - 1);
+ fflush(nil)
end;
proc elna_riscv_operand(instruction: ^ElnaRtlInstruction, n: Word);
@@ -1306,12 +1328,14 @@ end;
proc elna_alloc_variable(operand_value: Word, operand_length: Word);
var
- pseudo_symbol: Word;
+ pseudo_symbol: ^ElnaRtlInfo;
begin
pseudo_symbol := _symbol_table_lookup(@variable_map, operand_value, operand_length);
if pseudo_symbol = nil then
- _symbol_table_enter(@variable_map, operand_value, operand_length, temporary_variable_counter);
- pseudo_symbol := temporary_variable_counter;
+ pseudo_symbol := malloc(#size(ElnaRtlInfo));
+ pseudo_symbol^.counter := temporary_variable_counter;
+
+ _symbol_table_enter(@variable_map, operand_value, operand_length, pseudo_symbol);
temporary_variable_counter := temporary_variable_counter + 4
end;
return pseudo_symbol
@@ -1324,7 +1348,7 @@ end;
*)
proc elna_alloc_operation_target(instruction: ^ElnaRtlInstruction);
var
- pseudo_symbol: Word;
+ pseudo_symbol: ^ElnaRtlInfo;
store_instruction: ^ElnaRtlInstruction;
begin
if instruction^.operands[1].kind = ElnaRtlKind.pseudo then
@@ -1333,7 +1357,7 @@ begin
pseudo_symbol := elna_alloc_variable(instruction^.operands[1].value, instruction^.operands[1].length);
elna_rtl_instruction_set_operand(store_instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t0, 0);
- elna_rtl_instruction_set_operand(store_instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.sp, pseudo_symbol);
+ elna_rtl_instruction_set_operand(store_instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.sp, pseudo_symbol^.counter);
instruction^.next := store_instruction;
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t0, 0)
@@ -1342,14 +1366,14 @@ end;
proc elna_alloc_load_address(instruction: ^ElnaRtlInstruction);
var
- pseudo_symbol: Word;
+ pseudo_symbol: ^ElnaRtlInfo;
begin
if instruction^.operands[2].kind = ElnaRtlKind.pseudo then
pseudo_symbol := elna_alloc_variable(instruction^.operands[2].value, instruction^.operands[2].length);
instruction^.operator := ElnaRtlOperator.addi;
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.sp, 0);
- elna_rtl_instruction_set_operand(instruction, 3, ElnaRtlKind.immediate, pseudo_symbol, 0)
+ elna_rtl_instruction_set_operand(instruction, 3, ElnaRtlKind.immediate, pseudo_symbol^.counter, 0)
end;
if instruction^.operands[1].kind = ElnaRtlKind.pseudo then
elna_alloc_operation_target(instruction)
@@ -1359,7 +1383,7 @@ end;
proc elna_alloc_store(instruction: ^ElnaRtlInstruction);
var
old_instruction: ^ElnaRtlInstruction;
- pseudo_symbol: Word;
+ pseudo_symbol: ^ElnaRtlInfo;
begin
if instruction^.operands[2].kind = ElnaRtlKind.pseudo then
old_instruction := malloc(#size(ElnaRtlInstruction));
@@ -1369,7 +1393,7 @@ begin
instruction^.operator := ElnaRtlOperator.lw;
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t1, 0);
- elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.sp, pseudo_symbol);
+ elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.sp, pseudo_symbol^.counter);
instruction^.next := old_instruction;
elna_rtl_instruction_set_operand(old_instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.t1, 0)
@@ -1379,7 +1403,7 @@ end;
proc elna_alloc_load(instruction: ^ElnaRtlInstruction);
var
old_instruction: ^ElnaRtlInstruction;
- pseudo_symbol: Word;
+ pseudo_symbol: ^ElnaRtlInfo;
begin
if instruction^.operands[1].kind = ElnaRtlKind.pseudo then
old_instruction := malloc(#size(ElnaRtlInstruction));
@@ -1389,7 +1413,7 @@ begin
old_instruction^.operator := ElnaRtlOperator.sw;
elna_rtl_instruction_set_operand(old_instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t1, 0);
- elna_rtl_instruction_set_operand(old_instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.sp, pseudo_symbol);
+ elna_rtl_instruction_set_operand(old_instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.sp, pseudo_symbol^.counter);
instruction^.next := old_instruction;
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t1, 0)
@@ -1398,7 +1422,7 @@ end;
proc elna_alloc_instruction(instruction: ^ElnaRtlInstruction);
var
- pseudo_symbol: Word;
+ pseudo_symbol: ^ElnaRtlInfo;
old_instruction: ^ElnaRtlInstruction;
begin
if instruction^.operator = ElnaRtlOperator.move then
@@ -1409,14 +1433,14 @@ begin
instruction^.operands[1].kind := instruction^.operands[2].kind;
instruction^.operands[1].value := instruction^.operands[2].value;
instruction^.operands[1].length := instruction^.operands[2].length;
- elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.sp, pseudo_symbol);
+ elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.sp, pseudo_symbol^.counter);
goto elna_alloc_instruction_end
end;
if instruction^.operands[2].kind = ElnaRtlKind.pseudo then
pseudo_symbol := elna_alloc_variable(instruction^.operands[2].value, instruction^.operands[2].length);
instruction^.operator = ElnaRtlOperator.lw;
- elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.sp, pseudo_symbol);
+ elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.sp, pseudo_symbol^.counter);
goto elna_alloc_instruction_end
end
@@ -1451,7 +1475,7 @@ begin
instruction^.operator := ElnaRtlOperator.lw;
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t0, 0);
- elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.sp, pseudo_symbol);
+ elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.sp, pseudo_symbol^.counter);
instruction^.next := old_instruction;
elna_rtl_instruction_set_operand(old_instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t0, 0);
@@ -1564,7 +1588,7 @@ var
stack_instruction: ^ElnaRtlInstruction;
begin
.elna_alloc_procedure_loop;
- temporary_variable_counter := 4;
+ temporary_variable_counter := 0;
variable_map := 0;
elna_alloc_instructions(rtl_declaration^.body);
@@ -1591,14 +1615,10 @@ begin
.elna_riscv_procedure_loop;
(* Write .type _procedure_name, @function. *)
- _write_z(".type \0");
-
- _write_s(procedure^.name, procedure^.length);
- _write_z(", @function\n\0");
+ printf(".type %.*s, @function\n\0", procedure^.length, procedure^.name);
(* Write procedure label, _procedure_name: *)
- _write_s(procedure^.name, procedure^.length);
- _write_z(":\n\0");
+ printf("%.*s:\n\0", procedure^.length, procedure^.name);
elna_riscv_instructions(procedure^.body);
_write_z("\tret\n\0");
@@ -1613,17 +1633,9 @@ proc elna_riscv_variable(variable: ^ElnaInstructionDeclaration);
begin
.elna_riscv_variable_loop;
if variable <> 0 then
- _write_z(".type \0");
- _write_s(variable^.name, variable^.length);
- _write_z(", @object\n\0");
-
- _write_s(variable^.name, variable^.length);
- _write_c(':');
+ printf(".type %.*s, @object\n\0", variable^.length, variable^.name);
- _write_z(" .zero \0");
- _write_i(variable^.body);
-
- _write_c('\n');
+ printf("%.*s: .zero %i\n\0", variable^.length, variable^.name, variable^.body);
variable := variable^.next;
goto elna_riscv_variable_loop
@@ -1850,7 +1862,7 @@ begin
return result
end;
-proc _elna_tac_string_literal(string_literal_node: ^ElnaTreeStringLiteral, operand_type: Word, operand_value: Word, operand_length: Word);
+proc elna_tac_string_literal(string_literal_node: ^ElnaTreeStringLiteral, operand_type: Word, operand_value: Word, operand_length: Word);
var
offset: Word;
first_instruction: Word;
@@ -1858,20 +1870,18 @@ var
begin
offset := _add_string(string_literal_node^.value);
+ elna_tac_generate_pseudo(operand_type, operand_value, operand_length);
+
first_instruction := elna_tac_instruction_create(ElnaTacOperator.get_address);
- elna_tac_instruction_set_operand(first_instruction, 1, ElnaTacKind.pseudo, "$unary", 6);
+ elna_tac_instruction_set_operand(first_instruction, 1, operand_type^, operand_value^, operand_length^);
elna_tac_instruction_set_operand(first_instruction, 2, ElnaTacKind.symbol, "strings", 7);
(* Add offset to the string block pointer. *)
next_instruction := elna_tac_instruction_create(ElnaTacOperator.add);
- elna_tac_instruction_set_operand(next_instruction, 1, ElnaTacKind.pseudo, "$unary", 6);
- elna_tac_instruction_set_operand(next_instruction, 2, ElnaTacKind.pseudo, "$unary", 6);
+ elna_tac_instruction_set_operand(next_instruction, 1, operand_type^, operand_value^, operand_length^);
+ elna_tac_instruction_set_operand(next_instruction, 2, operand_type^, operand_value^, operand_length^);
elna_tac_instruction_set_operand(next_instruction, 3, ElnaTacKind.immediate, offset, 0);
- operand_type^ := ElnaTacKind.pseudo;
- operand_value^ := "$unary";
- operand_length^ := 6;
-
return elna_instruction_list_concatenate(first_instruction, next_instruction)
end;
@@ -1989,7 +1999,7 @@ begin
if parser_node^.kind = ElnaTreeKind.character_literal then
instruction := elna_tac_character_literal(parser_node, operand_type, operand_value, operand_length)
elsif parser_node^.kind = ElnaTreeKind.string_literal then
- instruction := _elna_tac_string_literal(parser_node, operand_type, operand_value, operand_length)
+ instruction := elna_tac_string_literal(parser_node, operand_type, operand_value, operand_length)
elsif parser_node^.kind = ElnaTreeKind.integer_literal then
instruction := elna_tac_integer_literal(parser_node, operand_type, operand_value, operand_length)
elsif parser_node^.kind = ElnaTreeKind.boolean_literal then
@@ -2047,6 +2057,9 @@ var
is_address: Word;
first_instruction: Word;
instruction: Word;
+ base_type: Word;
+ base_value: Word;
+ base_length: Word;
begin
instruction := nil;
if parser_node^.kind = ElnaTreeKind.unary_expression then
@@ -2056,39 +2069,37 @@ begin
operator := 0;
operand := parser_node
end;
- first_instruction := elna_tac_designator(operand, symbol_table, @is_address, operand_type, operand_value, operand_length);
+ first_instruction := elna_tac_designator(operand, symbol_table, @is_address, @base_type, @base_value, @base_length);
+
+ elna_tac_generate_pseudo(operand_type, operand_value, operand_length);
if operator = '@' then
if is_address then
instruction := elna_tac_instruction_create(ElnaTacOperator.copy);
- elna_tac_instruction_set_operand(instruction, 1, ElnaTacKind.pseudo, "$unary", 6);
- elna_tac_instruction_set_operand(instruction, 2, operand_type^, operand_value^, operand_length^)
+ elna_tac_instruction_set_operand(instruction, 1, operand_type^, operand_value^, operand_length^);
+ elna_tac_instruction_set_operand(instruction, 2, base_type, base_value, base_length)
else
instruction := elna_tac_instruction_create(ElnaTacOperator.get_address);
- elna_tac_instruction_set_operand(instruction, 1, ElnaTacKind.pseudo, "$unary", 6);
- elna_tac_instruction_set_operand(instruction, 2, operand_type^, operand_value^, operand_length^)
+ elna_tac_instruction_set_operand(instruction, 1, operand_type^, operand_value^, operand_length^);
+ elna_tac_instruction_set_operand(instruction, 2, base_type, base_value, base_length)
end
elsif operator = '-' then
instruction := elna_tac_instruction_create(ElnaTacOperator.negate);
- elna_tac_instruction_set_operand(instruction, 1, ElnaTacKind.pseudo, "$unary", 6);
- elna_tac_instruction_set_operand(instruction, 2, operand_type^, operand_value^, operand_length^)
+ elna_tac_instruction_set_operand(instruction, 1, operand_type^, operand_value^, operand_length^);
+ elna_tac_instruction_set_operand(instruction, 2, base_type, base_value, base_length)
elsif operator = '~' then
instruction := elna_tac_instruction_create(ElnaTacOperator.complement);
- elna_tac_instruction_set_operand(instruction, 1, ElnaTacKind.pseudo, "$unary", 6);
- elna_tac_instruction_set_operand(instruction, 2, operand_type^, operand_value^, operand_length^)
+ elna_tac_instruction_set_operand(instruction, 1, operand_type^, operand_value^, operand_length^);
+ elna_tac_instruction_set_operand(instruction, 2, base_type, base_value, base_length)
elsif is_address then
instruction := elna_tac_instruction_create(ElnaTacOperator.load);
- elna_tac_instruction_set_operand(instruction, 1, operand_type^, operand_value^, operand_length^);
- elna_tac_instruction_set_operand(instruction, 2, ElnaTacKind.pseudo, "$unary", 6)
+ elna_tac_instruction_set_operand(instruction, 1, base_type, base_value, base_length);
+ elna_tac_instruction_set_operand(instruction, 2, operand_type^, operand_value^, operand_length^)
else
instruction := elna_tac_instruction_create(ElnaTacOperator.copy);
- elna_tac_instruction_set_operand(instruction, 1, ElnaTacKind.pseudo, "$unary", 6);
- elna_tac_instruction_set_operand(instruction, 2, operand_type^, operand_value^, operand_length^)
+ elna_tac_instruction_set_operand(instruction, 1, operand_type^, operand_value^, operand_length^);
+ elna_tac_instruction_set_operand(instruction, 2, base_type, base_value, base_length)
end;
- operand_type^ := ElnaTacKind.pseudo;
- operand_value^ := "$unary";
- operand_length^ := 6;
-
return elna_instruction_list_concatenate(first_instruction, instruction)
end;
@@ -2164,36 +2175,20 @@ proc elna_tac_binary_expression(parser_node: ^ElnaTreeBinaryExpression, symbol_t
var
first_instruction: Word;
instruction: Word;
- current_instruction: Word;
lhs_type: Word;
lhs_value: Word;
lhs_length: Word;
+ rhs_type: Word;
+ rhs_value: Word;
+ rhs_length: Word;
begin
if parser_node^.kind <> ElnaTreeKind.binary_expression then
first_instruction := elna_tac_unary_expression(parser_node, symbol_table, operand_type, operand_value, operand_length)
else
- lhs_type := 0;
- lhs_value := 0;
- lhs_length := 0;
first_instruction := elna_tac_unary_expression(parser_node^.lhs, symbol_table, @lhs_type, @lhs_value, @lhs_length);
- (* Save the value of the left expression on the stack. *)
- instruction := elna_tac_instruction_create(ElnaTacOperator.copy);
- elna_tac_instruction_set_operand(instruction, 1, ElnaTacKind.pseudo, "$lhs", 4);
- elna_tac_instruction_set_operand(instruction, 2, lhs_type, lhs_value, lhs_length);
-
- if first_instruction = 0 then
- first_instruction := instruction
- else
- elna_instruction_list_concatenate(first_instruction, instruction)
- end;
- current_instruction := instruction;
-
- lhs_type := 0;
- lhs_value := 0;
- lhs_length := 0;
- instruction := elna_tac_unary_expression(parser_node^.rhs, symbol_table, @lhs_type, @lhs_value, @lhs_length);
- current_instruction := elna_instruction_list_concatenate(current_instruction, instruction);
+ instruction := elna_tac_unary_expression(parser_node^.rhs, symbol_table, @rhs_type, @rhs_value, @rhs_length);
+ first_instruction := elna_instruction_list_concatenate(first_instruction, instruction);
if parser_node^.operator = ElnaLexerKind.plus then
instruction := elna_tac_instruction_create(ElnaTacOperator.add)
@@ -2224,15 +2219,13 @@ begin
elsif parser_node^.operator = ElnaLexerKind.not_equal then
instruction := elna_tac_instruction_create(ElnaTacOperator.not_equal)
end;
- elna_tac_instruction_set_operand(instruction, 1, ElnaTacKind.pseudo, "$binary", 7);
- elna_tac_instruction_set_operand(instruction, 2, ElnaTacKind.pseudo, "$lhs", 4);
- elna_tac_instruction_set_operand(instruction, 3, lhs_type, lhs_value, lhs_length);
+ elna_tac_generate_pseudo(operand_type, operand_value, operand_length);
- operand_type^ := ElnaTacKind.pseudo;
- operand_value^ := "$binary";
- operand_length^ := 7;
+ elna_tac_instruction_set_operand(instruction, 1, operand_type^, operand_value^, operand_length^);
+ elna_tac_instruction_set_operand(instruction, 2, lhs_type, lhs_value, lhs_length);
+ elna_tac_instruction_set_operand(instruction, 3, rhs_type, rhs_value, rhs_length);
- elna_instruction_list_concatenate(current_instruction, instruction)
+ first_instruction := elna_instruction_list_concatenate(first_instruction, instruction)
end;
return first_instruction
end;
@@ -2299,30 +2292,22 @@ var
arguments_operand: ^ElnaTacOperand;
call_instruction: Word;
argument_entry: ^ElnaTreeExpressionList;
- name_buffer: Word;
- argument_count: Word;
begin
parsed_expression := parsed_call^.callee;
first_instruction := nil;
arguments_operand := malloc(parsed_call^.count * #size(ElnaTacOperand));
+ elna_tac_generate_pseudo(operand_type, operand_value, operand_length);
+
call_instruction := elna_tac_instruction_create(ElnaTacOperator.proc_call);
elna_tac_instruction_set_operand(call_instruction, 1, ElnaTacKind.symbol, parsed_expression^.name, parsed_expression^.length);
elna_tac_instruction_set_operand(call_instruction, 2, ElnaTacKind.list, arguments_operand, parsed_call^.count);
- elna_tac_instruction_set_operand(call_instruction, 3, ElnaTacKind.pseudo, "$unary", 6);
+ elna_tac_instruction_set_operand(call_instruction, 3, operand_type^, operand_value^, operand_length^);
- operand_type^ := ElnaTacKind.pseudo;
- operand_value^ := "$unary";
- operand_length^ := 6;
-
- argument_count := 0;
argument_entry := parsed_call^.arguments;
.elna_tac_call_loop;
if argument_entry <> nil then
- argument_type := 0;
- argument_value := 0;
- argument_length := 0;
instruction := elna_tac_binary_expression(argument_entry^.expression, symbol_table,
@argument_type, @argument_value, @argument_length);
if first_instruction = nil then
@@ -2333,27 +2318,12 @@ begin
if instruction <> nil then
current_instruction := instruction
end;
-
- (* Save the argument on the stack. *)
- name_buffer := malloc(4);
- sprintf(name_buffer, "$ar%i\0", argument_count);
- instruction := elna_tac_instruction_create(ElnaTacOperator.copy);
- elna_tac_instruction_set_operand(instruction, 1, ElnaTacKind.pseudo, name_buffer, 4);
- elna_tac_instruction_set_operand(instruction, 2, argument_type, argument_value, argument_length);
- if first_instruction = 0 then
- first_instruction := instruction
- else
- elna_instruction_list_concatenate(current_instruction, instruction)
- end;
- current_instruction := instruction;
-
- arguments_operand^.kind := ElnaTacKind.pseudo;
- arguments_operand^.value := name_buffer;
- arguments_operand^.length := 4;
+ arguments_operand^.kind := argument_type;
+ arguments_operand^.value := argument_value;
+ arguments_operand^.length := argument_length;
arguments_operand := arguments_operand + #size(ElnaTacOperand);
argument_entry := argument_entry^.next;
- argument_count := argument_count + 1;
goto elna_tac_call_loop
end;
if first_instruction = nil then
@@ -2573,11 +2543,14 @@ var
current_field: ^ElnaTypeField;
field_offset: Word;
is_address: Word;
+ base_type: Word;
+ base_value: Word;
+ base_length: Word;
begin
designator_base := field_access_expression^.aggregate;
aggregate_type := designator_base^.type_decoration;
- first_instruction := elna_tac_designator(designator_base, symbol_table, @is_address, operand_type, operand_value, operand_length);
+ first_instruction := elna_tac_designator(designator_base, symbol_table, @is_address, @base_type, @base_value, @base_length);
field_count := aggregate_type^.length;
current_field := aggregate_type^.members;
@@ -2592,14 +2565,12 @@ begin
field_offset := field_offset + field_type^.size;
goto elna_tac_field_access_expression_field
end;
+ elna_tac_generate_pseudo(operand_type, operand_value, operand_length);
+
last_instruction := elna_tac_instruction_create(ElnaTacOperator.add);
- elna_tac_instruction_set_operand(last_instruction, 1, ElnaTacKind.pseudo, "$unary", 6);
+ elna_tac_instruction_set_operand(last_instruction, 1, operand_type^, 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_type^, operand_value^, operand_length^);
-
- operand_type^ := ElnaTacKind.pseudo;
- operand_value^ := "$unary";
- operand_length^ := 6;
+ elna_tac_instruction_set_operand(last_instruction, 3, base_type, base_value, base_length);
return elna_instruction_list_concatenate(first_instruction, last_instruction)
end;
@@ -2611,9 +2582,9 @@ var
offset_instruction: Word;
add_instruction: Word;
is_address: Word;
- offset_type: Word;
- offset_value: Word;
- offset_length: Word;
+ inter_type: Word;
+ inter_value: Word;
+ inter_length: Word;
aggregate_type: ^ElnaTypeArray;
designator_base: ^ElnaTreeExpression;
element_type: ^ElnaType;
@@ -2622,27 +2593,28 @@ begin
aggregate_type := designator_base^.type_decoration;
element_type := aggregate_type^.base;
- index_instructions := elna_tac_binary_expression(array_access_expression^.index, symbol_table, operand_type, operand_value, operand_length);
+ index_instructions := elna_tac_binary_expression(array_access_expression^.index, symbol_table, @inter_type, @inter_value, @inter_length);
+ elna_tac_generate_pseudo(operand_type, operand_value, operand_length);
add_instruction := elna_tac_instruction_create(ElnaTacOperator.subtract);
- elna_tac_instruction_set_operand(add_instruction, 1, ElnaTacKind.pseudo, "$lhs", 4);
- elna_tac_instruction_set_operand(add_instruction, 2, operand_type^, operand_value^, operand_length^);
+ elna_tac_instruction_set_operand(add_instruction, 1, operand_type^, operand_value^, operand_length^);
+ elna_tac_instruction_set_operand(add_instruction, 2, inter_type, inter_value, inter_length);
elna_tac_instruction_set_operand(add_instruction, 3, ElnaTacKind.immediate, 1, 0);
offset_instruction := elna_tac_instruction_create(ElnaTacOperator.multiply);
- elna_tac_instruction_set_operand(offset_instruction, 1, ElnaTacKind.pseudo, "$lhs", 4);
- elna_tac_instruction_set_operand(offset_instruction, 2, ElnaTacKind.pseudo, "$lhs", 4);
+ elna_tac_instruction_set_operand(offset_instruction, 1, operand_type^, operand_value^, operand_length^);
+ elna_tac_instruction_set_operand(offset_instruction, 2, operand_type^, operand_value^, operand_length^);
elna_tac_instruction_set_operand(offset_instruction, 3, ElnaTacKind.immediate, element_type^.size, 0);
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, operand_type, operand_value, operand_length);
+ array_instructions := elna_tac_designator(array_access_expression^.array, symbol_table, @is_address, @inter_type, @inter_value, @inter_length);
add_instruction := elna_tac_instruction_create(ElnaTacOperator.add);
elna_tac_instruction_set_operand(add_instruction, 1, operand_type^, operand_value^, operand_length^);
- elna_tac_instruction_set_operand(add_instruction, 2, operand_type^, operand_value^, operand_length^);
- elna_tac_instruction_set_operand(add_instruction, 3, ElnaTacKind.pseudo, "$lhs", 4);
+ elna_tac_instruction_set_operand(add_instruction, 2, inter_type, inter_value, inter_length);
+ elna_tac_instruction_set_operand(add_instruction, 3, operand_type^, operand_value^, operand_length^);
elna_instruction_list_concatenate(offset_instruction, array_instructions);
@@ -2678,69 +2650,63 @@ var
operand_type: Word;
operand_value: Word;
operand_length: Word;
-begin
- operand_type := 0;
- operand_value := 0;
- operand_length := 0;
- first_instruction := elna_tac_designator(parser_tree^.assignee, symbol_table, @is_address, @operand_type, @operand_value, @operand_length);
+ assignment_type: Word;
+ assignment_value: Word;
+ assignment_length: Word;
+ assignee_type: Word;
+ assignee_value: Word;
+ assignee_length: Word;
+begin
+ first_instruction := elna_tac_designator(parser_tree^.assignee, symbol_table,
+ @is_address, @assignee_type, @assignee_value, @assignee_length);
+ (* Compile the assignment. *)
+ instruction := elna_tac_binary_expression(parser_tree^.assignment, symbol_table,
+ @assignment_type, @assignment_value, @assignment_length);
+
+ if assignee_type = ElnaTacKind.pseudo then
+ current_instruction := elna_tac_instruction_create(ElnaTacOperator.copy);
- if operand_type = ElnaTacKind.pseudo then
if is_address then
+ elna_tac_generate_pseudo(@operand_type, @operand_value, @operand_length);
+
(* Save the assignee address on the stack. *)
- current_instruction := elna_tac_instruction_create(ElnaTacOperator.copy);
- elna_tac_instruction_set_operand(current_instruction, 1, ElnaTacKind.pseudo, "$assign", 7);
- elna_tac_instruction_set_operand(current_instruction, 2, operand_type, operand_value, operand_length);
+ elna_tac_instruction_set_operand(current_instruction, 1, operand_type, operand_value, operand_length);
+ elna_tac_instruction_set_operand(current_instruction, 2, assignee_type, assignee_value, assignee_length);
first_instruction := elna_instruction_list_concatenate(first_instruction, current_instruction);
- (* Compile the assignment. *)
- operand_type := 0;
- operand_value := 0;
- operand_length := 0;
- instruction := elna_tac_binary_expression(parser_tree^.assignment, symbol_table, @operand_type, @operand_value, @operand_length);
-
- if instruction <> 0 then
+ if instruction <> nil then
elna_instruction_list_concatenate(current_instruction, instruction);
current_instruction := instruction
end;
instruction := elna_tac_instruction_create(ElnaTacOperator.store);
- elna_tac_instruction_set_operand(instruction, 1, operand_type, operand_value, operand_length);
- elna_tac_instruction_set_operand(instruction, 2, ElnaTacKind.pseudo, "$assign", 7);
+ elna_tac_instruction_set_operand(instruction, 1, assignment_type, assignment_value, assignment_length);
+ elna_tac_instruction_set_operand(instruction, 2, operand_type, operand_value, operand_length);
elna_instruction_list_concatenate(current_instruction, instruction)
else
- current_instruction := elna_tac_instruction_create(ElnaTacOperator.copy);
- elna_tac_instruction_set_operand(current_instruction, 1, operand_type, operand_value, operand_length);
-
- operand_type := 0;
- operand_value := 0;
- operand_length := 0;
- instruction := elna_tac_binary_expression(parser_tree^.assignment, symbol_table, @operand_type, @operand_value, @operand_length);
- elna_tac_instruction_set_operand(current_instruction, 2, operand_type, operand_value, operand_length);
+ elna_tac_instruction_set_operand(current_instruction, 1, assignee_type, assignee_value, assignee_length);
+ elna_tac_instruction_set_operand(current_instruction, 2, assignment_type, assignment_value, assignment_length);
first_instruction := elna_instruction_list_concatenate(instruction, current_instruction)
end
else
+ elna_tac_generate_pseudo(@operand_type, @operand_value, @operand_length);
+
(* Save the assignee address on the stack. *)
current_instruction := elna_tac_instruction_create(ElnaTacOperator.get_address);
- elna_tac_instruction_set_operand(current_instruction, 1, ElnaTacKind.pseudo, "$assign", 7);
- elna_tac_instruction_set_operand(current_instruction, 2, operand_type, operand_value, operand_length);
+ elna_tac_instruction_set_operand(current_instruction, 1, operand_type, operand_value, operand_length);
+ elna_tac_instruction_set_operand(current_instruction, 2, assignee_type, assignee_value, assignee_length);
first_instruction := elna_instruction_list_concatenate(first_instruction, current_instruction);
- (* Compile the assignment. *)
- operand_type := 0;
- operand_value := 0;
- operand_length := 0;
- instruction := elna_tac_binary_expression(parser_tree^.assignment, symbol_table, @operand_type, @operand_value, @operand_length);
-
- if instruction <> 0 then
+ if instruction <> nil then
elna_instruction_list_concatenate(current_instruction, instruction);
current_instruction := instruction
end;
instruction := elna_tac_instruction_create(ElnaTacOperator.store);
- elna_tac_instruction_set_operand(instruction, 1, operand_type, operand_value, operand_length);
- elna_tac_instruction_set_operand(instruction, 2, ElnaTacKind.pseudo, "$assign", 7);
+ elna_tac_instruction_set_operand(instruction, 1, assignment_type, assignment_value, assignment_length);
+ elna_tac_instruction_set_operand(instruction, 2, operand_type, operand_value, operand_length);
elna_instruction_list_concatenate(current_instruction, instruction)
end;
@@ -2798,15 +2764,11 @@ var
first_byte: Word;
begin
if length = 0 then
- _write_s(".L", 2);
- _write_i(counter)
+ printf(".L%i\0", counter)
else
- first_byte := _load_byte(counter);
- if first_byte <> '.' then
- _write_c('.')
- end;
- _write_s(counter, length)
- end
+ printf(".%.*s\0", length, counter);
+ end;
+ fflush(nil)
end;
proc elna_parser_conditional_statements();
@@ -2979,6 +2941,8 @@ begin
first_instruction := nil;
.elna_tac_statements_loop;
+ pseudo_counter := 0;
+
if current_statement <> nil then
instruction := elna_tac_statement(current_statement, symbol_table);
current_statement := current_statement^.next;
@@ -3962,26 +3926,18 @@ end;
proc elna_tac_variable_declaration(parser_tree: ^ElnaTreeVariableDeclaration);
var
- name: Word;
- name_length: Word;
variable_type: ^ElnaTreeNamedTypeExpression;
result: ^ElnaInstructionDeclaration;
begin
result := malloc(#size(ElnaInstructionDeclaration));
result^.next := nil;
-
- name := parser_tree^.name;
- name_length := parser_tree^.length;
variable_type := parser_tree^._type;
- result^.name := name;
- result^.length := name_length;
-
- name := variable_type^.name;
- name_length := variable_type^.length;
+ result^.name := parser_tree^.name;
+ result^.length := parser_tree^.length;
- if string_compare("Array", 5, name, name_length) then
+ if string_compare("Array", 5, variable_type^.name, variable_type^.length) then
(* Else we assume this is a zeroed 4096 bytes big array. *)
result^.body := 4096
else
@@ -5467,3 +5423,10 @@ begin
exit(4)
end;
end;
+
+proc f();
+var
+ a: Word;
+begin
+ return a
+end;