Generate pseudo variables where possible

This commit is contained in:
2026-01-25 21:22:46 +01:00
parent f0f0f431ba
commit 08b5325f58

View File

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