Add jump_if_not_zero and bnez instructions

This commit is contained in:
2025-11-19 10:25:41 +01:00
parent 76f55d0796
commit fd9e8a36b5
2 changed files with 120 additions and 74 deletions

View File

@@ -4317,12 +4317,21 @@ var
parser_node: Word; parser_node: Word;
declaration_size: Word; declaration_size: Word;
result: Word; result: Word;
token_kind: Word;
begin begin
declaration_size := _module_declaration_size(); declaration_size := _module_declaration_size();
result := _allocate(declaration_size); result := _allocate(declaration_size);
_node_set_kind(result, NodeKind.module_declaration); _node_set_kind(result, NodeKind.module_declaration);
_skip_empty_lines();
_elna_lexer_read_token(@token_kind);
if token_kind = ElnaLexerKind._program then
_elna_lexer_skip_token();
_elna_lexer_read_token(@token_kind);
_elna_lexer_skip_token()
end;
parser_node := _elna_parser_type_part(); parser_node := _elna_parser_type_part();
_module_declaration_set_types(result, parser_node); _module_declaration_set_types(result, parser_node);
@@ -5161,8 +5170,14 @@ begin
result := ElnaLexerKind._record result := ElnaLexerKind._record
elsif _string_compare(position_start, token_length, "or", 2) then elsif _string_compare(position_start, token_length, "or", 2) then
result := ElnaLexerKind._or result := ElnaLexerKind._or
elsif _string_compare(position_start, token_length, "xor", 2) then elsif _string_compare(position_start, token_length, "xor", 3) then
result := ElnaLexerKind._xor result := ElnaLexerKind._xor
elsif _string_compare(position_start, token_length, "program", 7) then
result := ElnaLexerKind._program
elsif _string_compare(position_start, token_length, "module", 6) then
result := ElnaLexerKind._module
elsif _string_compare(position_start, token_length, "nil", 3) then
result := ElnaLexerKind.null
end; end;
return result return result
end; end;

View File

@@ -3,6 +3,7 @@
* v. 2.0. If a copy of the MPL was not distributed with this file, You can * v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/. * obtain one at https://mozilla.org/MPL/2.0/.
*) *)
program;
(* Stage 16 compiler. *) (* Stage 16 compiler. *)
@@ -351,29 +352,30 @@ type
ElnaTacOperator = ( ElnaTacOperator = (
get_address, get_address,
add, add,
load_word, load,
store_word, store,
jal, proc_call,
assign, copy,
sub, subtract,
div, divide,
rem, remainder,
mul, multiply,
_xor, _xor,
_or, _or,
and, and,
slt, less_than,
sgt, greater_than,
sle, less_or_equal,
sge, greater_or_equal,
seq, equal,
sne, not_equal,
neg, negate,
not, complement,
jump, jump,
beqz, jump_if_zero,
jump_if_not_zero,
label, label,
ret _return
); );
ElnaRtlOperator = ( ElnaRtlOperator = (
li, li,
@@ -397,8 +399,9 @@ type
xori, xori,
neg, neg,
not, not,
jump, j,
beqz, beqz,
bnez,
label, label,
allocate_stack, allocate_stack,
ret ret
@@ -965,6 +968,17 @@ begin
elna_rtl_instruction_set_operand(rtl_instruction, number, operand_type, operand_value, operand_length) elna_rtl_instruction_set_operand(rtl_instruction, number, operand_type, operand_value, operand_length)
end; end;
proc elna_rtl_conditional_jump(tac_instruction: Word, condition: Word);
var
result: Word;
begin
result := elna_rtl_instruction_create(condition);
elna_rtl_copy_operand(tac_instruction, 1, result);
elna_rtl_copy_operand(tac_instruction, 2, result);
return result
end;
proc elna_rtl_instruction(tac_instruction: Word, next_instruction: Word); proc elna_rtl_instruction(tac_instruction: Word, next_instruction: Word);
var var
result: Word; result: Word;
@@ -1003,7 +1017,7 @@ begin
end end
elsif instruction_kind = ElnaTacOperator.add then elsif instruction_kind = ElnaTacOperator.add then
result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.add) result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.add)
elsif instruction_kind = ElnaTacOperator.load_word then elsif instruction_kind = ElnaTacOperator.load then
operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, 2); operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, 2);
if operand_type = ElnaTacOperand.stack then if operand_type = ElnaTacOperand.stack then
@@ -1024,7 +1038,7 @@ begin
operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2); operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2);
elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.offset, operand_value, 0) elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.offset, operand_value, 0)
end end
elsif instruction_kind = ElnaTacOperator.store_word then elsif instruction_kind = ElnaTacOperator.store then
operands := elna_rtl_load_operand_value(tac_instruction, 1, ElnaRtlRegister.t0); operands := elna_rtl_load_operand_value(tac_instruction, 1, ElnaRtlRegister.t0);
next_instruction^ := elna_rtl_instruction_create(ElnaRtlOperator.sw); next_instruction^ := elna_rtl_instruction_create(ElnaRtlOperator.sw);
result := operands; result := operands;
@@ -1045,16 +1059,16 @@ begin
else else
ElnaInstructionList_set_next(operands, next_instruction^) ElnaInstructionList_set_next(operands, next_instruction^)
end end
elsif instruction_kind = ElnaTacOperator.jal then elsif instruction_kind = ElnaTacOperator.proc_call then
result := elna_rtl_instruction_create(ElnaRtlOperator.jal); result := elna_rtl_instruction_create(ElnaRtlOperator.jal);
elna_rtl_copy_operand(tac_instruction, 1, result) elna_rtl_copy_operand(tac_instruction, 1, result)
elsif instruction_kind = ElnaTacOperator.sub then elsif instruction_kind = ElnaTacOperator.subtract then
result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.sub) result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.sub)
elsif instruction_kind = ElnaTacOperator.mul then elsif instruction_kind = ElnaTacOperator.multiply then
result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.mul) result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.mul)
elsif instruction_kind = ElnaTacOperator.div then elsif instruction_kind = ElnaTacOperator.divide then
result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.div) result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.div)
elsif instruction_kind = ElnaTacOperator.rem then elsif instruction_kind = ElnaTacOperator.remainder then
result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.rem) result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.rem)
elsif instruction_kind = ElnaTacOperator._xor then elsif instruction_kind = ElnaTacOperator._xor then
result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator._xor) result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator._xor)
@@ -1062,9 +1076,9 @@ begin
result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator._or) result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator._or)
elsif instruction_kind = ElnaTacOperator.and then elsif instruction_kind = ElnaTacOperator.and then
result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.and) result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.and)
elsif instruction_kind = ElnaTacOperator.slt then elsif instruction_kind = ElnaTacOperator.less_than then
result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.slt) result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.slt)
elsif instruction_kind = ElnaTacOperator.sgt then elsif instruction_kind = ElnaTacOperator.greater_than then
operands := elna_rtl_binary_operands(tac_instruction, next_instruction); operands := elna_rtl_binary_operands(tac_instruction, next_instruction);
result := elna_rtl_instruction_create(ElnaRtlOperator.slt); result := elna_rtl_instruction_create(ElnaRtlOperator.slt);
@@ -1077,7 +1091,7 @@ begin
result := operands; result := operands;
elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.slt) elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.slt)
elsif instruction_kind = ElnaTacOperator.sle then elsif instruction_kind = ElnaTacOperator.less_or_equal then
operands := elna_rtl_binary_operands(tac_instruction, next_instruction); operands := elna_rtl_binary_operands(tac_instruction, next_instruction);
intermediate_instruction := elna_rtl_instruction_create(ElnaRtlOperator.slt); intermediate_instruction := elna_rtl_instruction_create(ElnaRtlOperator.slt);
@@ -1096,7 +1110,7 @@ begin
result := operands; result := operands;
elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.xori) elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.xori)
elsif instruction_kind = ElnaTacOperator.sge then elsif instruction_kind = ElnaTacOperator.greater_or_equal then
operands := elna_rtl_binary_operands(tac_instruction, next_instruction); operands := elna_rtl_binary_operands(tac_instruction, next_instruction);
intermediate_instruction := elna_rtl_instruction_create(ElnaRtlOperator.slt); intermediate_instruction := elna_rtl_instruction_create(ElnaRtlOperator.slt);
@@ -1115,31 +1129,31 @@ begin
result := operands; result := operands;
elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.xori) elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.xori)
elsif instruction_kind = ElnaTacOperator.seq then elsif instruction_kind = ElnaTacOperator.equal then
result := elna_rtl_binary_equality(tac_instruction, ElnaRtlOperator.seqz, next_instruction) result := elna_rtl_binary_equality(tac_instruction, ElnaRtlOperator.seqz, next_instruction)
elsif instruction_kind = ElnaTacOperator.sne then elsif instruction_kind = ElnaTacOperator.not_equal then
result := elna_rtl_binary_equality(tac_instruction, ElnaRtlOperator.snez, next_instruction) result := elna_rtl_binary_equality(tac_instruction, ElnaRtlOperator.snez, next_instruction)
elsif instruction_kind = ElnaTacOperator.neg then elsif instruction_kind = ElnaTacOperator.negate then
result := elna_rtl_instruction_create(ElnaRtlOperator.neg); result := elna_rtl_instruction_create(ElnaRtlOperator.neg);
elna_rtl_copy_operand(tac_instruction, 1, result); elna_rtl_copy_operand(tac_instruction, 1, result);
elna_rtl_copy_operand(tac_instruction, 2, result) elna_rtl_copy_operand(tac_instruction, 2, result)
elsif instruction_kind = ElnaTacOperator.not then elsif instruction_kind = ElnaTacOperator.complement then
result := elna_rtl_instruction_create(ElnaRtlOperator.not); result := elna_rtl_instruction_create(ElnaRtlOperator.not);
elna_rtl_copy_operand(tac_instruction, 1, result); elna_rtl_copy_operand(tac_instruction, 1, result);
elna_rtl_copy_operand(tac_instruction, 2, result) elna_rtl_copy_operand(tac_instruction, 2, result)
elsif instruction_kind = ElnaTacOperator.jump then elsif instruction_kind = ElnaTacOperator.jump then
result := elna_rtl_instruction_create(ElnaRtlOperator.jump); result := elna_rtl_instruction_create(ElnaRtlOperator.j);
elna_rtl_copy_operand(tac_instruction, 1, result) elna_rtl_copy_operand(tac_instruction, 1, result)
elsif instruction_kind = ElnaTacOperator.beqz then elsif instruction_kind = ElnaTacOperator.jump_if_zero then
result := elna_rtl_instruction_create(ElnaRtlOperator.beqz); result := elna_rtl_conditional_jump(tac_instruction, ElnaRtlOperator.beqz)
elna_rtl_copy_operand(tac_instruction, 1, result); elsif instruction_kind = ElnaTacOperator.jump_if_not_zero then
elna_rtl_copy_operand(tac_instruction, 2, result) result := elna_rtl_conditional_jump(tac_instruction, ElnaRtlOperator.bnez)
elsif instruction_kind = ElnaTacOperator.ret then elsif instruction_kind = ElnaTacOperator._return then
result := elna_rtl_load_operand_value(tac_instruction, 1, ElnaRtlRegister.a0) result := elna_rtl_load_operand_value(tac_instruction, 1, ElnaRtlRegister.a0)
elsif instruction_kind = ElnaTacOperator.label then elsif instruction_kind = ElnaTacOperator.label then
result := elna_rtl_instruction_create(ElnaRtlOperator.label); result := elna_rtl_instruction_create(ElnaRtlOperator.label);
elna_rtl_copy_operand(tac_instruction, 1, result) elna_rtl_copy_operand(tac_instruction, 1, result)
elsif instruction_kind = ElnaTacOperator.assign then elsif instruction_kind = ElnaTacOperator.copy then
operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, 1); operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, 1);
operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 1); operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 1);
@@ -1262,12 +1276,15 @@ begin
elsif instruction_kind = ElnaRtlOperator.not then elsif instruction_kind = ElnaRtlOperator.not then
argument_count := 2; argument_count := 2;
_write_s("\tnot", 4) _write_s("\tnot", 4)
elsif instruction_kind = ElnaRtlOperator.jump then elsif instruction_kind = ElnaRtlOperator.j then
argument_count := 1; argument_count := 1;
_write_s("\tj", 2) _write_s("\tj", 2)
elsif instruction_kind = ElnaRtlOperator.beqz then elsif instruction_kind = ElnaRtlOperator.beqz then
argument_count := 2; argument_count := 2;
_write_s("\tbeqz", 5) _write_s("\tbeqz", 5)
elsif instruction_kind = ElnaRtlOperator.bnez then
argument_count := 2;
_write_s("\tbnez", 5)
else (* ElnaRtlOperator.allocate_stack or ElnaRtlOperator.ret *) else (* ElnaRtlOperator.allocate_stack or ElnaRtlOperator.ret *)
argument_count := 0 argument_count := 0
end; end;
@@ -1800,7 +1817,7 @@ begin
operand := operand_type^; operand := operand_type^;
if is_address then if is_address then
instruction := _elna_tac_instruction_create(ElnaTacOperator.load_word); instruction := _elna_tac_instruction_create(ElnaTacOperator.load);
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 6, 0); _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 6, 0);
_elna_tac_instruction_set_operand(instruction, 2, operand_type^, operand_value^, operand_length^); _elna_tac_instruction_set_operand(instruction, 2, operand_type^, operand_value^, operand_length^);
@@ -1810,7 +1827,7 @@ begin
elna_instruction_list_concatenate(first_instruction, instruction) elna_instruction_list_concatenate(first_instruction, instruction)
else else
instruction := _elna_tac_instruction_create(ElnaTacOperator.assign); instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 6, 0); _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 6, 0);
_elna_tac_instruction_set_operand(instruction, 2, operand_type^, operand_value^, operand_length^); _elna_tac_instruction_set_operand(instruction, 2, operand_type^, operand_value^, operand_length^);
@@ -1822,12 +1839,12 @@ begin
end end
end; end;
if operator = '-' then if operator = '-' then
instruction := _elna_tac_instruction_create(ElnaTacOperator.neg); instruction := _elna_tac_instruction_create(ElnaTacOperator.negate);
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 6, 0); _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 6, 0);
_elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.temporary, 6, 0); _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.temporary, 6, 0);
elna_instruction_list_concatenate(first_instruction, instruction) elna_instruction_list_concatenate(first_instruction, instruction)
elsif operator = '~' then elsif operator = '~' then
instruction := _elna_tac_instruction_create(ElnaTacOperator.not); instruction := _elna_tac_instruction_create(ElnaTacOperator.complement);
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 6, 0); _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 6, 0);
_elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.temporary, 6, 0); _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.temporary, 6, 0);
elna_instruction_list_concatenate(first_instruction, instruction) elna_instruction_list_concatenate(first_instruction, instruction)
@@ -1928,7 +1945,7 @@ begin
first_instruction := _elna_tac_unary_expression(operand_node, symbol_table, @lhs_type, @lhs_value, @lhs_length); 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. *) (* Save the value of the left expression on the stack. *)
instruction := _elna_tac_instruction_create(ElnaTacOperator.assign); instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.stack, 72, 0); _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.stack, 72, 0);
_elna_tac_instruction_set_operand(instruction, 2, lhs_type, lhs_value, lhs_length); _elna_tac_instruction_set_operand(instruction, 2, lhs_type, lhs_value, lhs_length);
@@ -1948,7 +1965,7 @@ begin
current_instruction := elna_instruction_list_concatenate(current_instruction, instruction); current_instruction := elna_instruction_list_concatenate(current_instruction, instruction);
(* Load the left expression from the stack; *) (* Load the left expression from the stack; *)
instruction := _elna_tac_instruction_create(ElnaTacOperator.assign); instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 7, 0); _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 7, 0);
_elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, 72, 0); _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, 72, 0);
@@ -1958,9 +1975,9 @@ begin
if token_kind = ElnaLexerKind.plus then if token_kind = ElnaLexerKind.plus then
instruction := _elna_tac_instruction_create(ElnaTacOperator.add) instruction := _elna_tac_instruction_create(ElnaTacOperator.add)
elsif token_kind = ElnaLexerKind.minus then elsif token_kind = ElnaLexerKind.minus then
instruction := _elna_tac_instruction_create(ElnaTacOperator.sub) instruction := _elna_tac_instruction_create(ElnaTacOperator.subtract)
elsif token_kind = ElnaLexerKind.multiplication then elsif token_kind = ElnaLexerKind.multiplication then
instruction := _elna_tac_instruction_create(ElnaTacOperator.mul) instruction := _elna_tac_instruction_create(ElnaTacOperator.multiply)
elsif token_kind = ElnaLexerKind.and then elsif token_kind = ElnaLexerKind.and then
instruction := _elna_tac_instruction_create(ElnaTacOperator.and) instruction := _elna_tac_instruction_create(ElnaTacOperator.and)
elsif token_kind = ElnaLexerKind._or then elsif token_kind = ElnaLexerKind._or then
@@ -1968,21 +1985,21 @@ begin
elsif token_kind = ElnaLexerKind._xor then elsif token_kind = ElnaLexerKind._xor then
instruction := _elna_tac_instruction_create(ElnaTacOperator._xor) instruction := _elna_tac_instruction_create(ElnaTacOperator._xor)
elsif token_kind = ElnaLexerKind.equals then elsif token_kind = ElnaLexerKind.equals then
instruction := _elna_tac_instruction_create(ElnaTacOperator.seq) instruction := _elna_tac_instruction_create(ElnaTacOperator.equal)
elsif token_kind = ElnaLexerKind.remainder then elsif token_kind = ElnaLexerKind.remainder then
instruction := _elna_tac_instruction_create(ElnaTacOperator.rem) instruction := _elna_tac_instruction_create(ElnaTacOperator.remainder)
elsif token_kind = ElnaLexerKind.division then elsif token_kind = ElnaLexerKind.division then
instruction := _elna_tac_instruction_create(ElnaTacOperator.div) instruction := _elna_tac_instruction_create(ElnaTacOperator.divide)
elsif token_kind = ElnaLexerKind.less_than then elsif token_kind = ElnaLexerKind.less_than then
instruction := _elna_tac_instruction_create(ElnaTacOperator.slt) instruction := _elna_tac_instruction_create(ElnaTacOperator.less_than)
elsif token_kind = ElnaLexerKind.greater_than then elsif token_kind = ElnaLexerKind.greater_than then
instruction := _elna_tac_instruction_create(ElnaTacOperator.sgt) instruction := _elna_tac_instruction_create(ElnaTacOperator.greater_than)
elsif token_kind = ElnaLexerKind.less_equal then elsif token_kind = ElnaLexerKind.less_equal then
instruction := _elna_tac_instruction_create(ElnaTacOperator.sle) instruction := _elna_tac_instruction_create(ElnaTacOperator.less_or_equal)
elsif token_kind = ElnaLexerKind.greater_equal then elsif token_kind = ElnaLexerKind.greater_equal then
instruction := _elna_tac_instruction_create(ElnaTacOperator.sge) instruction := _elna_tac_instruction_create(ElnaTacOperator.greater_or_equal)
elsif token_kind = ElnaLexerKind.not_equal then elsif token_kind = ElnaLexerKind.not_equal then
instruction := _elna_tac_instruction_create(ElnaTacOperator.sne) instruction := _elna_tac_instruction_create(ElnaTacOperator.not_equal)
end; end;
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 6, 0); _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 6, 0);
_elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, 72, 0); _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, 72, 0);
@@ -2113,7 +2130,7 @@ begin
(* Save the argument on the stack. *) (* Save the argument on the stack. *)
stack_offset := argument_count * 4; stack_offset := argument_count * 4;
instruction := _elna_tac_instruction_create(ElnaTacOperator.store_word); 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, operand_type, operand_value, operand_length);
_elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, 132 - stack_offset, 0); _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, 132 - stack_offset, 0);
if first_instruction = 0 then if first_instruction = 0 then
@@ -2135,7 +2152,7 @@ begin
stack_offset := argument_count * 4; stack_offset := argument_count * 4;
(* Calculate the stack offset: 132 - (4 * argument_counter) *) (* Calculate the stack offset: 132 - (4 * argument_counter) *)
instruction := _elna_tac_instruction_create(ElnaTacOperator.assign); instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 11 + argument_count, 0); _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 11 + argument_count, 0);
_elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, 132 - stack_offset, 0); _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, 132 - stack_offset, 0);
elna_instruction_list_concatenate(current_instruction, instruction); elna_instruction_list_concatenate(current_instruction, instruction);
@@ -2143,7 +2160,7 @@ begin
goto elna_tac_call_finalize goto elna_tac_call_finalize
end; end;
instruction := _elna_tac_instruction_create(ElnaTacOperator.jal); instruction := _elna_tac_instruction_create(ElnaTacOperator.proc_call);
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.symbol, name, name_length); _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.symbol, name, name_length);
if first_instruction = 0 then if first_instruction = 0 then
first_instruction := instruction first_instruction := instruction
@@ -2319,7 +2336,7 @@ begin
parser_node := _dereference_expression_get_pointer(parser_node); parser_node := _dereference_expression_get_pointer(parser_node);
first_instruction := _elna_tac_simple_expression(parser_node, symbol_table, operand_type, operand_value, operand_length); first_instruction := _elna_tac_simple_expression(parser_node, symbol_table, operand_type, operand_value, operand_length);
last_instruction := _elna_tac_instruction_create(ElnaTacOperator.assign); last_instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
_elna_tac_instruction_set_operand(last_instruction, 1, ElnaTacOperand.temporary, 6, 0); _elna_tac_instruction_set_operand(last_instruction, 1, ElnaTacOperand.temporary, 6, 0);
_elna_tac_instruction_set_operand(last_instruction, 2, operand_type^, operand_value^, operand_length^); _elna_tac_instruction_set_operand(last_instruction, 2, operand_type^, operand_value^, operand_length^);
@@ -2335,7 +2352,7 @@ begin
elsif node_kind = NodeKind.call then elsif node_kind = NodeKind.call then
first_instruction := _elna_tac_call(parser_node, symbol_table); first_instruction := _elna_tac_call(parser_node, symbol_table);
last_instruction := _elna_tac_instruction_create(ElnaTacOperator.assign); last_instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
_elna_tac_instruction_set_operand(last_instruction, 1, ElnaTacOperand.temporary, 6, 0); _elna_tac_instruction_set_operand(last_instruction, 1, ElnaTacOperand.temporary, 6, 0);
_elna_tac_instruction_set_operand(last_instruction, 2, ElnaTacOperand.temporary, 11, 0); _elna_tac_instruction_set_operand(last_instruction, 2, ElnaTacOperand.temporary, 11, 0);
@@ -2397,7 +2414,7 @@ begin
first_instruction := elna_instruction_list_concatenate(first_instruction, current_instruction); first_instruction := elna_instruction_list_concatenate(first_instruction, current_instruction);
(* Save the assignee address on the stack. *) (* Save the assignee address on the stack. *)
current_instruction := _elna_tac_instruction_create(ElnaTacOperator.store_word); current_instruction := _elna_tac_instruction_create(ElnaTacOperator.store);
_elna_tac_instruction_set_operand(current_instruction, 1, ElnaTacOperand.temporary, 6, 0); _elna_tac_instruction_set_operand(current_instruction, 1, ElnaTacOperand.temporary, 6, 0);
_elna_tac_instruction_set_operand(current_instruction, 2, ElnaTacOperand.stack, 76, 0); _elna_tac_instruction_set_operand(current_instruction, 2, ElnaTacOperand.stack, 76, 0);
elna_instruction_list_concatenate(first_instruction, current_instruction); elna_instruction_list_concatenate(first_instruction, current_instruction);
@@ -2414,14 +2431,14 @@ begin
current_instruction := instruction current_instruction := instruction
end; end;
instruction := _elna_tac_instruction_create(ElnaTacOperator.assign); instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 7, 0); _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 7, 0);
_elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, 76, 0); _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, 76, 0);
elna_instruction_list_concatenate(current_instruction, instruction); elna_instruction_list_concatenate(current_instruction, instruction);
current_instruction := instruction; current_instruction := instruction;
instruction := _elna_tac_instruction_create(ElnaTacOperator.store_word); 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, operand_type, operand_value, operand_length);
_elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.temporary, 7, 0); _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.temporary, 7, 0);
@@ -2466,7 +2483,7 @@ begin
return_expression := _return_statement_get_returned(parser_node); return_expression := _return_statement_get_returned(parser_node);
first_instruction := _elna_tac_binary_expression(return_expression, symbol_table, @operand_type, @operand_value, @operand_length); first_instruction := _elna_tac_binary_expression(return_expression, symbol_table, @operand_type, @operand_value, @operand_length);
instruction := _elna_tac_instruction_create(ElnaTacOperator.ret); instruction := _elna_tac_instruction_create(ElnaTacOperator._return);
_elna_tac_instruction_set_operand(instruction, 1, operand_type, operand_value, operand_length); _elna_tac_instruction_set_operand(instruction, 1, operand_type, operand_value, operand_length);
return elna_instruction_list_concatenate(first_instruction, instruction) return elna_instruction_list_concatenate(first_instruction, instruction)
@@ -2541,7 +2558,7 @@ begin
condition_label := label_counter; condition_label := label_counter;
label_counter := label_counter + 1; label_counter := label_counter + 1;
current_instruction := _elna_tac_instruction_create(ElnaTacOperator.beqz); current_instruction := _elna_tac_instruction_create(ElnaTacOperator.jump_if_zero);
_elna_tac_instruction_set_operand(current_instruction, 1, 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, ElnaTacOperand.symbol, condition_label, 0); _elna_tac_instruction_set_operand(current_instruction, 2, ElnaTacOperand.symbol, condition_label, 0);
@@ -3269,7 +3286,7 @@ begin
symbol_info := _parameter_info_get_offset(symbol_info); symbol_info := _parameter_info_get_offset(symbol_info);
instruction := _elna_tac_instruction_create(ElnaTacOperator.store_word); instruction := _elna_tac_instruction_create(ElnaTacOperator.store);
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 11 + parameter_counter, 0); _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 11 + parameter_counter, 0);
_elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, symbol_info, 0); _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, symbol_info, 0);
if first_instruction = 0 then if first_instruction = 0 then
@@ -3700,14 +3717,14 @@ var
next_instruction: Word; next_instruction: Word;
begin begin
instruction := _elna_tac_accessor(name_pointer, name_length, field_pointer, field_offset, @first_result, "_get_"); instruction := _elna_tac_accessor(name_pointer, name_length, field_pointer, field_offset, @first_result, "_get_");
next_instruction := _elna_tac_instruction_create(ElnaTacOperator.load_word); next_instruction := _elna_tac_instruction_create(ElnaTacOperator.load);
_elna_tac_instruction_set_operand(next_instruction, 1, ElnaTacOperand.temporary, 11, 0); _elna_tac_instruction_set_operand(next_instruction, 1, ElnaTacOperand.temporary, 11, 0);
_elna_tac_instruction_set_operand(next_instruction, 2, ElnaTacOperand.temporary, 11, 0); _elna_tac_instruction_set_operand(next_instruction, 2, ElnaTacOperand.temporary, 11, 0);
elna_instruction_list_concatenate(instruction, next_instruction); elna_instruction_list_concatenate(instruction, next_instruction);
ElnaInstructionDeclaration_set_body(first_result, instruction); ElnaInstructionDeclaration_set_body(first_result, instruction);
instruction := _elna_tac_accessor(name_pointer, name_length, field_pointer, field_offset, @second_result, "_set_"); instruction := _elna_tac_accessor(name_pointer, name_length, field_pointer, field_offset, @second_result, "_set_");
next_instruction := _elna_tac_instruction_create(ElnaTacOperator.store_word); next_instruction := _elna_tac_instruction_create(ElnaTacOperator.store);
_elna_tac_instruction_set_operand(next_instruction, 1, ElnaTacOperand.temporary, 12, 0); _elna_tac_instruction_set_operand(next_instruction, 1, ElnaTacOperand.temporary, 12, 0);
_elna_tac_instruction_set_operand(next_instruction, 2, ElnaTacOperand.temporary, 11, 0); _elna_tac_instruction_set_operand(next_instruction, 2, ElnaTacOperand.temporary, 11, 0);
elna_instruction_list_concatenate(instruction, next_instruction); elna_instruction_list_concatenate(instruction, next_instruction);
@@ -3743,7 +3760,7 @@ begin
ElnaInstructionDeclaration_set_name(first_result, new_name); ElnaInstructionDeclaration_set_name(first_result, new_name);
ElnaInstructionDeclaration_set_length(first_result, new_length); ElnaInstructionDeclaration_set_length(first_result, new_length);
instruction := _elna_tac_instruction_create(ElnaTacOperator.assign); instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 11, 0); _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 11, 0);
_elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.immediate, type_size, 0); _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.immediate, type_size, 0);
@@ -3889,11 +3906,19 @@ proc _elna_parser_module_declaration();
var var
parser_node: Word; parser_node: Word;
result: Word; result: Word;
token_kind: Word;
begin begin
result := malloc(_module_declaration_size()); result := malloc(_module_declaration_size());
_node_set_kind(result, NodeKind.module_declaration); _node_set_kind(result, NodeKind.module_declaration);
(* Skip "program;". *)
_skip_empty_lines();
_elna_lexer_read_token(@token_kind);
_elna_lexer_skip_token();
_elna_lexer_read_token(@token_kind);
_elna_lexer_skip_token();
parser_node := _elna_parser_type_part(); parser_node := _elna_parser_type_part();
_module_declaration_set_types(result, parser_node); _module_declaration_set_types(result, parser_node);
@@ -4734,8 +4759,14 @@ begin
result := ElnaLexerKind._record result := ElnaLexerKind._record
elsif string_compare(position_start, token_length, "or", 2) then elsif string_compare(position_start, token_length, "or", 2) then
result := ElnaLexerKind._or result := ElnaLexerKind._or
elsif string_compare(position_start, token_length, "xor", 2) then elsif string_compare(position_start, token_length, "xor", 3) then
result := ElnaLexerKind._xor result := ElnaLexerKind._xor
elsif string_compare(position_start, token_length, "program", 7) then
result := ElnaLexerKind._program
elsif string_compare(position_start, token_length, "module", 6) then
result := ElnaLexerKind._module
elsif string_compare(position_start, token_length, "nil", 3) then
result := ElnaLexerKind.null
end; end;
return result return result
end; end;