Provide binary and unary TAC operations
This commit is contained in:
@@ -155,9 +155,27 @@ type
|
|||||||
ElnaGeneratorKind = (
|
ElnaGeneratorKind = (
|
||||||
load_immediate,
|
load_immediate,
|
||||||
load_address,
|
load_address,
|
||||||
add
|
add,
|
||||||
|
add_immediate,
|
||||||
|
load_word,
|
||||||
|
store_word,
|
||||||
|
call,
|
||||||
|
move,
|
||||||
|
sub,
|
||||||
|
div,
|
||||||
|
rem,
|
||||||
|
mul,
|
||||||
|
_xor,
|
||||||
|
_or,
|
||||||
|
and,
|
||||||
|
seqz,
|
||||||
|
snez,
|
||||||
|
slt,
|
||||||
|
xor_immediate,
|
||||||
|
neg,
|
||||||
|
not
|
||||||
);
|
);
|
||||||
ElnaGeneratorOperand = (register, immediate, symbol);
|
ElnaGeneratorOperand = (register, immediate, symbol, offset);
|
||||||
ElnaGeneratorRegister = (
|
ElnaGeneratorRegister = (
|
||||||
zero,
|
zero,
|
||||||
ra,
|
ra,
|
||||||
@@ -615,7 +633,7 @@ begin
|
|||||||
this^ := operand_length
|
this^ := operand_length
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_generator_load_immediate(target_register: Word, source_immediate: Word, immediate_length: Word);
|
proc _elna_generator_instruction_create(kind: Word);
|
||||||
var
|
var
|
||||||
result: Word;
|
result: Word;
|
||||||
instruction_size: Word;
|
instruction_size: Word;
|
||||||
@@ -623,8 +641,18 @@ begin
|
|||||||
instruction_size := _elna_generator_instruction_size();
|
instruction_size := _elna_generator_instruction_size();
|
||||||
result := _allocate(instruction_size);
|
result := _allocate(instruction_size);
|
||||||
|
|
||||||
_elna_generator_instruction_set_kind(result, ElnaGeneratorKind.load_immediate);
|
_elna_generator_instruction_set_kind(result, kind);
|
||||||
_elna_generator_instruction_set_next(result, 0);
|
_elna_generator_instruction_set_next(result, 0);
|
||||||
|
|
||||||
|
return result
|
||||||
|
end;
|
||||||
|
|
||||||
|
proc _elna_generator_load_immediate(target_register: Word, source_immediate: Word, immediate_length: Word);
|
||||||
|
var
|
||||||
|
result: Word;
|
||||||
|
begin
|
||||||
|
result := _elna_generator_instruction_create(ElnaGeneratorKind.load_immediate);
|
||||||
|
|
||||||
_elna_generator_instruction_set_operand(result, 1, ElnaGeneratorOperand.register, target_register, 0);
|
_elna_generator_instruction_set_operand(result, 1, ElnaGeneratorOperand.register, target_register, 0);
|
||||||
_elna_generator_instruction_set_operand(result, 2, ElnaGeneratorOperand.immediate, source_immediate, immediate_length);
|
_elna_generator_instruction_set_operand(result, 2, ElnaGeneratorOperand.immediate, source_immediate, immediate_length);
|
||||||
|
|
||||||
@@ -634,19 +662,253 @@ end;
|
|||||||
proc _elna_generator_load_address(target_register: Word, source_symbol: Word, symbol_length: Word);
|
proc _elna_generator_load_address(target_register: Word, source_symbol: Word, symbol_length: Word);
|
||||||
var
|
var
|
||||||
result: Word;
|
result: Word;
|
||||||
instruction_size: Word;
|
|
||||||
begin
|
begin
|
||||||
instruction_size := _elna_generator_instruction_size();
|
result := _elna_generator_instruction_create(ElnaGeneratorKind.load_address);
|
||||||
result := _allocate(instruction_size);
|
|
||||||
|
|
||||||
_elna_generator_instruction_set_kind(result, ElnaGeneratorKind.load_address);
|
|
||||||
_elna_generator_instruction_set_next(result, 0);
|
|
||||||
_elna_generator_instruction_set_operand(result, 1, ElnaGeneratorOperand.register, target_register, 0);
|
_elna_generator_instruction_set_operand(result, 1, ElnaGeneratorOperand.register, target_register, 0);
|
||||||
_elna_generator_instruction_set_operand(result, 2, ElnaGeneratorOperand.symbol, source_symbol, symbol_length);
|
_elna_generator_instruction_set_operand(result, 2, ElnaGeneratorOperand.symbol, source_symbol, symbol_length);
|
||||||
|
|
||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
proc _elna_generator_add(destination: Word, lhs: Word, rhs: Word);
|
||||||
|
var
|
||||||
|
result: Word;
|
||||||
|
begin
|
||||||
|
result := _elna_generator_instruction_create(ElnaGeneratorKind.add);
|
||||||
|
|
||||||
|
_elna_generator_instruction_set_operand(result, 1, ElnaGeneratorOperand.register, destination, 0);
|
||||||
|
_elna_generator_instruction_set_operand(result, 2, ElnaGeneratorOperand.register, lhs, 0);
|
||||||
|
_elna_generator_instruction_set_operand(result, 3, ElnaGeneratorOperand.register, rhs, 0);
|
||||||
|
|
||||||
|
return result
|
||||||
|
end;
|
||||||
|
|
||||||
|
proc _elna_generator_mul(destination: Word, lhs: Word, rhs: Word);
|
||||||
|
var
|
||||||
|
result: Word;
|
||||||
|
begin
|
||||||
|
result := _elna_generator_instruction_create(ElnaGeneratorKind.mul);
|
||||||
|
|
||||||
|
_elna_generator_instruction_set_operand(result, 1, ElnaGeneratorOperand.register, destination, 0);
|
||||||
|
_elna_generator_instruction_set_operand(result, 2, ElnaGeneratorOperand.register, lhs, 0);
|
||||||
|
_elna_generator_instruction_set_operand(result, 3, ElnaGeneratorOperand.register, rhs, 0);
|
||||||
|
|
||||||
|
return result
|
||||||
|
end;
|
||||||
|
|
||||||
|
proc _elna_generator_sub(destination: Word, lhs: Word, rhs: Word);
|
||||||
|
var
|
||||||
|
result: Word;
|
||||||
|
begin
|
||||||
|
result := _elna_generator_instruction_create(ElnaGeneratorKind.sub);
|
||||||
|
|
||||||
|
_elna_generator_instruction_set_operand(result, 1, ElnaGeneratorOperand.register, destination, 0);
|
||||||
|
_elna_generator_instruction_set_operand(result, 2, ElnaGeneratorOperand.register, lhs, 0);
|
||||||
|
_elna_generator_instruction_set_operand(result, 3, ElnaGeneratorOperand.register, rhs, 0);
|
||||||
|
|
||||||
|
return result
|
||||||
|
end;
|
||||||
|
|
||||||
|
proc _elna_generator_div(destination: Word, lhs: Word, rhs: Word);
|
||||||
|
var
|
||||||
|
result: Word;
|
||||||
|
begin
|
||||||
|
result := _elna_generator_instruction_create(ElnaGeneratorKind.div);
|
||||||
|
|
||||||
|
_elna_generator_instruction_set_operand(result, 1, ElnaGeneratorOperand.register, destination, 0);
|
||||||
|
_elna_generator_instruction_set_operand(result, 2, ElnaGeneratorOperand.register, lhs, 0);
|
||||||
|
_elna_generator_instruction_set_operand(result, 3, ElnaGeneratorOperand.register, rhs, 0);
|
||||||
|
|
||||||
|
return result
|
||||||
|
end;
|
||||||
|
|
||||||
|
proc _elna_generator_rem(destination: Word, lhs: Word, rhs: Word);
|
||||||
|
var
|
||||||
|
result: Word;
|
||||||
|
begin
|
||||||
|
result := _elna_generator_instruction_create(ElnaGeneratorKind.rem);
|
||||||
|
|
||||||
|
_elna_generator_instruction_set_operand(result, 1, ElnaGeneratorOperand.register, destination, 0);
|
||||||
|
_elna_generator_instruction_set_operand(result, 2, ElnaGeneratorOperand.register, lhs, 0);
|
||||||
|
_elna_generator_instruction_set_operand(result, 3, ElnaGeneratorOperand.register, rhs, 0);
|
||||||
|
|
||||||
|
return result
|
||||||
|
end;
|
||||||
|
|
||||||
|
proc _elna_generator_xor(destination: Word, lhs: Word, rhs: Word);
|
||||||
|
var
|
||||||
|
result: Word;
|
||||||
|
begin
|
||||||
|
result := _elna_generator_instruction_create(ElnaGeneratorKind._xor);
|
||||||
|
|
||||||
|
_elna_generator_instruction_set_operand(result, 1, ElnaGeneratorOperand.register, destination, 0);
|
||||||
|
_elna_generator_instruction_set_operand(result, 2, ElnaGeneratorOperand.register, lhs, 0);
|
||||||
|
_elna_generator_instruction_set_operand(result, 3, ElnaGeneratorOperand.register, rhs, 0);
|
||||||
|
|
||||||
|
return result
|
||||||
|
end;
|
||||||
|
|
||||||
|
proc _elna_generator_xor_immediate(destination: Word, lhs: Word, rhs: Word);
|
||||||
|
var
|
||||||
|
result: Word;
|
||||||
|
begin
|
||||||
|
result := _elna_generator_instruction_create(ElnaGeneratorKind._xor);
|
||||||
|
|
||||||
|
_elna_generator_instruction_set_operand(result, 1, ElnaGeneratorOperand.register, destination, 0);
|
||||||
|
_elna_generator_instruction_set_operand(result, 2, ElnaGeneratorOperand.register, lhs, 0);
|
||||||
|
_elna_generator_instruction_set_operand(result, 3, ElnaGeneratorOperand.immediate, rhs, 0);
|
||||||
|
|
||||||
|
return result
|
||||||
|
end;
|
||||||
|
|
||||||
|
proc _elna_generator_or(destination: Word, lhs: Word, rhs: Word);
|
||||||
|
var
|
||||||
|
result: Word;
|
||||||
|
begin
|
||||||
|
result := _elna_generator_instruction_create(ElnaGeneratorKind._or);
|
||||||
|
|
||||||
|
_elna_generator_instruction_set_operand(result, 1, ElnaGeneratorOperand.register, destination, 0);
|
||||||
|
_elna_generator_instruction_set_operand(result, 2, ElnaGeneratorOperand.register, lhs, 0);
|
||||||
|
_elna_generator_instruction_set_operand(result, 3, ElnaGeneratorOperand.register, rhs, 0);
|
||||||
|
|
||||||
|
return result
|
||||||
|
end;
|
||||||
|
|
||||||
|
proc _elna_generator_and(destination: Word, lhs: Word, rhs: Word);
|
||||||
|
var
|
||||||
|
result: Word;
|
||||||
|
begin
|
||||||
|
result := _elna_generator_instruction_create(ElnaGeneratorKind.and);
|
||||||
|
|
||||||
|
_elna_generator_instruction_set_operand(result, 1, ElnaGeneratorOperand.register, destination, 0);
|
||||||
|
_elna_generator_instruction_set_operand(result, 2, ElnaGeneratorOperand.register, lhs, 0);
|
||||||
|
_elna_generator_instruction_set_operand(result, 3, ElnaGeneratorOperand.register, rhs, 0);
|
||||||
|
|
||||||
|
return result
|
||||||
|
end;
|
||||||
|
|
||||||
|
proc _elna_generator_add_immediate(destination: Word, lhs: Word, rhs: Word);
|
||||||
|
var
|
||||||
|
result: Word;
|
||||||
|
begin
|
||||||
|
result := _elna_generator_instruction_create(ElnaGeneratorKind.add_immediate);
|
||||||
|
|
||||||
|
_elna_generator_instruction_set_operand(result, 1, ElnaGeneratorOperand.register, destination, 0);
|
||||||
|
_elna_generator_instruction_set_operand(result, 2, ElnaGeneratorOperand.register, lhs, 0);
|
||||||
|
_elna_generator_instruction_set_operand(result, 3, ElnaGeneratorOperand.immediate, rhs, 0);
|
||||||
|
|
||||||
|
return result
|
||||||
|
end;
|
||||||
|
|
||||||
|
proc _elna_generator_slt(destination: Word, lhs: Word, rhs: Word);
|
||||||
|
var
|
||||||
|
result: Word;
|
||||||
|
begin
|
||||||
|
result := _elna_generator_instruction_create(ElnaGeneratorKind.slt);
|
||||||
|
|
||||||
|
_elna_generator_instruction_set_operand(result, 1, ElnaGeneratorOperand.register, destination, 0);
|
||||||
|
_elna_generator_instruction_set_operand(result, 2, ElnaGeneratorOperand.register, lhs, 0);
|
||||||
|
_elna_generator_instruction_set_operand(result, 3, ElnaGeneratorOperand.register, rhs, 0);
|
||||||
|
|
||||||
|
return result
|
||||||
|
end;
|
||||||
|
|
||||||
|
proc _elna_generator_call(symbol: Word, length: Word);
|
||||||
|
var
|
||||||
|
result: Word;
|
||||||
|
begin
|
||||||
|
result := _elna_generator_instruction_create(ElnaGeneratorKind.call);
|
||||||
|
|
||||||
|
_elna_generator_instruction_set_operand(result, 1, ElnaGeneratorOperand.symbol, symbol, length);
|
||||||
|
|
||||||
|
return result
|
||||||
|
end;
|
||||||
|
|
||||||
|
proc _elna_generator_load_word(target: Word, register: Word, offset: Word);
|
||||||
|
var
|
||||||
|
result: Word;
|
||||||
|
begin
|
||||||
|
result := _elna_generator_instruction_create(ElnaGeneratorKind.load_word);
|
||||||
|
|
||||||
|
_elna_generator_instruction_set_operand(result, 1, ElnaGeneratorOperand.register, target, 0);
|
||||||
|
_elna_generator_instruction_set_operand(result, 2, ElnaGeneratorOperand.offset, register, offset);
|
||||||
|
|
||||||
|
return result
|
||||||
|
end;
|
||||||
|
|
||||||
|
proc _elna_generator_store_word(target: Word, register: Word, offset: Word);
|
||||||
|
var
|
||||||
|
result: Word;
|
||||||
|
begin
|
||||||
|
result := _elna_generator_instruction_create(ElnaGeneratorKind.store_word);
|
||||||
|
|
||||||
|
_elna_generator_instruction_set_operand(result, 1, ElnaGeneratorOperand.register, target, 0);
|
||||||
|
_elna_generator_instruction_set_operand(result, 2, ElnaGeneratorOperand.offset, register, offset);
|
||||||
|
|
||||||
|
return result
|
||||||
|
end;
|
||||||
|
|
||||||
|
proc _elna_generator_move(destination: Word, source: Word);
|
||||||
|
var
|
||||||
|
result: Word;
|
||||||
|
begin
|
||||||
|
result := _elna_generator_instruction_create(ElnaGeneratorKind.move);
|
||||||
|
|
||||||
|
_elna_generator_instruction_set_operand(result, 1, ElnaGeneratorOperand.register, destination, 0);
|
||||||
|
_elna_generator_instruction_set_operand(result, 2, ElnaGeneratorOperand.register, source, 0);
|
||||||
|
|
||||||
|
return result
|
||||||
|
end;
|
||||||
|
|
||||||
|
proc _elna_generator_seqz(destination: Word, source: Word);
|
||||||
|
var
|
||||||
|
result: Word;
|
||||||
|
begin
|
||||||
|
result := _elna_generator_instruction_create(ElnaGeneratorKind.seqz);
|
||||||
|
|
||||||
|
_elna_generator_instruction_set_operand(result, 1, ElnaGeneratorOperand.register, destination, 0);
|
||||||
|
_elna_generator_instruction_set_operand(result, 2, ElnaGeneratorOperand.register, source, 0);
|
||||||
|
|
||||||
|
return result
|
||||||
|
end;
|
||||||
|
|
||||||
|
proc _elna_generator_snez(destination: Word, source: Word);
|
||||||
|
var
|
||||||
|
result: Word;
|
||||||
|
begin
|
||||||
|
result := _elna_generator_instruction_create(ElnaGeneratorKind.snez);
|
||||||
|
|
||||||
|
_elna_generator_instruction_set_operand(result, 1, ElnaGeneratorOperand.register, destination, 0);
|
||||||
|
_elna_generator_instruction_set_operand(result, 2, ElnaGeneratorOperand.register, source, 0);
|
||||||
|
|
||||||
|
return result
|
||||||
|
end;
|
||||||
|
|
||||||
|
proc _elna_generator_neg(destination: Word, source: Word);
|
||||||
|
var
|
||||||
|
result: Word;
|
||||||
|
begin
|
||||||
|
result := _elna_generator_instruction_create(ElnaGeneratorKind.neg);
|
||||||
|
|
||||||
|
_elna_generator_instruction_set_operand(result, 1, ElnaGeneratorOperand.register, destination, 0);
|
||||||
|
_elna_generator_instruction_set_operand(result, 2, ElnaGeneratorOperand.register, source, 0);
|
||||||
|
|
||||||
|
return result
|
||||||
|
end;
|
||||||
|
|
||||||
|
proc _elna_generator_not(destination: Word, source: Word);
|
||||||
|
var
|
||||||
|
result: Word;
|
||||||
|
begin
|
||||||
|
result := _elna_generator_instruction_create(ElnaGeneratorKind.not);
|
||||||
|
|
||||||
|
_elna_generator_instruction_set_operand(result, 1, ElnaGeneratorOperand.register, destination, 0);
|
||||||
|
_elna_generator_instruction_set_operand(result, 2, ElnaGeneratorOperand.register, source, 0);
|
||||||
|
|
||||||
|
return result
|
||||||
|
end;
|
||||||
|
|
||||||
proc _elna_writer_instruction_name(instruction_kind: Word);
|
proc _elna_writer_instruction_name(instruction_kind: Word);
|
||||||
var
|
var
|
||||||
argument_count: Word;
|
argument_count: Word;
|
||||||
@@ -660,6 +922,60 @@ begin
|
|||||||
elsif instruction_kind = ElnaGeneratorKind.add then
|
elsif instruction_kind = ElnaGeneratorKind.add then
|
||||||
argument_count := 3;
|
argument_count := 3;
|
||||||
_write_s("\tadd", 4)
|
_write_s("\tadd", 4)
|
||||||
|
elsif instruction_kind = ElnaGeneratorKind.add_immediate then
|
||||||
|
argument_count := 3;
|
||||||
|
_write_s("\taddi", 5)
|
||||||
|
elsif instruction_kind = ElnaGeneratorKind.load_word then
|
||||||
|
argument_count := 2;
|
||||||
|
_write_s("\tlw", 3)
|
||||||
|
elsif instruction_kind = ElnaGeneratorKind.store_word then
|
||||||
|
argument_count := 2;
|
||||||
|
_write_s("\tsw", 3)
|
||||||
|
elsif instruction_kind = ElnaGeneratorKind.call then
|
||||||
|
argument_count := 1;
|
||||||
|
_write_s("\tcall", 5)
|
||||||
|
elsif instruction_kind = ElnaGeneratorKind.move then
|
||||||
|
argument_count := 2;
|
||||||
|
_write_s("\tmv", 3)
|
||||||
|
elsif instruction_kind = ElnaGeneratorKind.sub then
|
||||||
|
argument_count := 3;
|
||||||
|
_write_s("\tsub", 4)
|
||||||
|
elsif instruction_kind = ElnaGeneratorKind.mul then
|
||||||
|
argument_count := 3;
|
||||||
|
_write_s("\tmul", 4)
|
||||||
|
elsif instruction_kind = ElnaGeneratorKind.div then
|
||||||
|
argument_count := 3;
|
||||||
|
_write_s("\tdiv", 4)
|
||||||
|
elsif instruction_kind = ElnaGeneratorKind.rem then
|
||||||
|
argument_count := 3;
|
||||||
|
_write_s("\trem", 4)
|
||||||
|
elsif instruction_kind = ElnaGeneratorKind._xor then
|
||||||
|
argument_count := 3;
|
||||||
|
_write_s("\txor", 4)
|
||||||
|
elsif instruction_kind = ElnaGeneratorKind.xor_immediate then
|
||||||
|
argument_count := 3;
|
||||||
|
_write_s("\txori", 5)
|
||||||
|
elsif instruction_kind = ElnaGeneratorKind._or then
|
||||||
|
argument_count := 3;
|
||||||
|
_write_s("\tor", 3)
|
||||||
|
elsif instruction_kind = ElnaGeneratorKind.and then
|
||||||
|
argument_count := 3;
|
||||||
|
_write_s("\tand", 4)
|
||||||
|
elsif instruction_kind = ElnaGeneratorKind.seqz then
|
||||||
|
argument_count := 2;
|
||||||
|
_write_s("\tseqz", 5)
|
||||||
|
elsif instruction_kind = ElnaGeneratorKind.snez then
|
||||||
|
argument_count := 2;
|
||||||
|
_write_s("\tsnez", 5)
|
||||||
|
elsif instruction_kind = ElnaGeneratorKind.slt then
|
||||||
|
argument_count := 3;
|
||||||
|
_write_s("\tslt", 4)
|
||||||
|
elsif instruction_kind = ElnaGeneratorKind.neg then
|
||||||
|
argument_count := 2;
|
||||||
|
_write_s("\tneg", 4)
|
||||||
|
elsif instruction_kind = ElnaGeneratorKind.not then
|
||||||
|
argument_count := 2;
|
||||||
|
_write_s("\tnot", 4)
|
||||||
end;
|
end;
|
||||||
return argument_count
|
return argument_count
|
||||||
end;
|
end;
|
||||||
@@ -686,6 +1002,11 @@ begin
|
|||||||
_write_c(' ');
|
_write_c(' ');
|
||||||
if operand_type = ElnaGeneratorOperand.register then
|
if operand_type = ElnaGeneratorOperand.register then
|
||||||
_elna_writer_register(operand_value)
|
_elna_writer_register(operand_value)
|
||||||
|
elsif operand_type = ElnaGeneratorOperand.offset then
|
||||||
|
_write_i(operand_length);
|
||||||
|
_write_c('(');
|
||||||
|
_elna_writer_register(operand_value);
|
||||||
|
_write_c(')')
|
||||||
elsif operand_length = 0 then
|
elsif operand_length = 0 then
|
||||||
_write_i(operand_value)
|
_write_i(operand_value)
|
||||||
else
|
else
|
||||||
@@ -696,13 +1017,22 @@ end;
|
|||||||
proc _elna_writer_instruction(instruction: Word);
|
proc _elna_writer_instruction(instruction: Word);
|
||||||
var
|
var
|
||||||
instruction_kind: Word;
|
instruction_kind: Word;
|
||||||
|
argument_count: Word;
|
||||||
|
current_argument: Word;
|
||||||
begin
|
begin
|
||||||
instruction_kind := _elna_generator_instruction_get_kind(instruction);
|
instruction_kind := _elna_generator_instruction_get_kind(instruction);
|
||||||
_elna_writer_instruction_name(instruction_kind);
|
argument_count := _elna_writer_instruction_name(instruction_kind);
|
||||||
|
current_argument := 1;
|
||||||
|
|
||||||
_elna_writer_operand(instruction, 1);
|
.elna_writer_instruction_loop;
|
||||||
|
if current_argument <= argument_count then
|
||||||
|
_elna_writer_operand(instruction, current_argument);
|
||||||
|
current_argument := current_argument + 1
|
||||||
|
end;
|
||||||
|
if current_argument <= argument_count then
|
||||||
_write_c(',');
|
_write_c(',');
|
||||||
_elna_writer_operand(instruction, 2);
|
goto elna_writer_instruction_loop
|
||||||
|
end;
|
||||||
|
|
||||||
_write_c('\n')
|
_write_c('\n')
|
||||||
end;
|
end;
|
||||||
@@ -776,13 +1106,11 @@ var
|
|||||||
integer_token: Word;
|
integer_token: Word;
|
||||||
integer_length: Word;
|
integer_length: Word;
|
||||||
token_kind: Word;
|
token_kind: Word;
|
||||||
instruction: Word;
|
|
||||||
begin
|
begin
|
||||||
integer_token := _integer_literal_node_get_value(integer_literal_node);
|
integer_token := _integer_literal_node_get_value(integer_literal_node);
|
||||||
integer_length := _integer_literal_node_get_length(integer_literal_node);
|
integer_length := _integer_literal_node_get_length(integer_literal_node);
|
||||||
|
|
||||||
instruction := _elna_generator_load_immediate(ElnaGeneratorRegister.t0, integer_token, integer_length);
|
return _elna_generator_load_immediate(ElnaGeneratorRegister.t0, integer_token, integer_length)
|
||||||
_elna_writer_instructions(instruction)
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _character_literal_node_size();
|
proc _character_literal_node_size();
|
||||||
@@ -839,13 +1167,11 @@ proc _compile_character_literal(character_literal_node: Word);
|
|||||||
var
|
var
|
||||||
character: Word;
|
character: Word;
|
||||||
character_length: Word;
|
character_length: Word;
|
||||||
instruction: Word;
|
|
||||||
begin
|
begin
|
||||||
character := _character_literal_node_get_value(character_literal_node);
|
character := _character_literal_node_get_value(character_literal_node);
|
||||||
character_length := _character_literal_node_get_length(character_literal_node);
|
character_length := _character_literal_node_get_length(character_literal_node);
|
||||||
|
|
||||||
instruction := _elna_generator_load_immediate(ElnaGeneratorRegister.t0, character, character_length);
|
return _elna_generator_load_immediate(ElnaGeneratorRegister.t0, character, character_length)
|
||||||
_elna_writer_instructions(instruction)
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _variable_expression_size();
|
proc _variable_expression_size();
|
||||||
@@ -912,16 +1238,18 @@ var
|
|||||||
name: Word;
|
name: Word;
|
||||||
name_token: Word;
|
name_token: Word;
|
||||||
lookup_result: Word;
|
lookup_result: Word;
|
||||||
|
instruction: Word;
|
||||||
begin
|
begin
|
||||||
name := _variable_expression_get_name(variable_expression);
|
name := _variable_expression_get_name(variable_expression);
|
||||||
name_token := _variable_expression_get_length(variable_expression);
|
name_token := _variable_expression_get_length(variable_expression);
|
||||||
|
|
||||||
lookup_result := _symbol_table_lookup(symbol_table, name, name_token);
|
lookup_result := _symbol_table_lookup(symbol_table, name, name_token);
|
||||||
if lookup_result <> 0 then
|
if lookup_result <> 0 then
|
||||||
_compile_local_designator(lookup_result)
|
instruction := _compile_local_designator(lookup_result)
|
||||||
else
|
else
|
||||||
_compile_global_designator(variable_expression)
|
instruction := _compile_global_designator(variable_expression)
|
||||||
end
|
end;
|
||||||
|
return instruction
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _string_literal_node_size();
|
proc _string_literal_node_size();
|
||||||
@@ -980,6 +1308,7 @@ var
|
|||||||
offset: Word;
|
offset: Word;
|
||||||
instruction: Word;
|
instruction: Word;
|
||||||
first_instruction: Word;
|
first_instruction: Word;
|
||||||
|
next_instruction: Word;
|
||||||
begin
|
begin
|
||||||
token_start := _string_literal_node_get_value(string_literal_node);
|
token_start := _string_literal_node_get_value(string_literal_node);
|
||||||
length := _string_literal_node_get_length(string_literal_node);
|
length := _string_literal_node_get_length(string_literal_node);
|
||||||
@@ -988,10 +1317,10 @@ begin
|
|||||||
first_instruction := _elna_generator_load_address(ElnaGeneratorRegister.t0, "strings", 7);
|
first_instruction := _elna_generator_load_address(ElnaGeneratorRegister.t0, "strings", 7);
|
||||||
instruction := _elna_generator_load_immediate(ElnaGeneratorRegister.t1, offset, 0);
|
instruction := _elna_generator_load_immediate(ElnaGeneratorRegister.t1, offset, 0);
|
||||||
_elna_generator_instruction_set_next(first_instruction, instruction);
|
_elna_generator_instruction_set_next(first_instruction, instruction);
|
||||||
|
next_instruction := _elna_generator_add(ElnaGeneratorRegister.t0, ElnaGeneratorRegister.t0, ElnaGeneratorRegister.t1);
|
||||||
|
_elna_generator_instruction_set_next(instruction, next_instruction);
|
||||||
|
|
||||||
_elna_writer_instructions(first_instruction);
|
return first_instruction
|
||||||
|
|
||||||
_write_z("\tadd t0, t0, t1\n\0")
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _parse_simple_expression();
|
proc _parse_simple_expression();
|
||||||
@@ -1065,25 +1394,26 @@ begin
|
|||||||
return simple_expression
|
return simple_expression
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _compile_simple_expression(parser_node: Word, symbol_table: Word);
|
proc _compile_simple_expression(parser_node: Word, symbol_table: Word, is_address: Word);
|
||||||
var
|
var
|
||||||
is_address: Word;
|
is_address: Word;
|
||||||
node_kind: Word;
|
node_kind: Word;
|
||||||
|
instruction: Word;
|
||||||
begin
|
begin
|
||||||
is_address := 0;
|
is_address^ := 0;
|
||||||
node_kind := _node_get_kind(parser_node);
|
node_kind := _node_get_kind(parser_node);
|
||||||
|
|
||||||
if node_kind = NodeKind.character_literal then
|
if node_kind = NodeKind.character_literal then
|
||||||
_compile_character_literal(parser_node)
|
instruction := _compile_character_literal(parser_node)
|
||||||
elsif node_kind = NodeKind.string_literal then
|
elsif node_kind = NodeKind.string_literal then
|
||||||
_compile_string_literal(parser_node)
|
instruction := _compile_string_literal(parser_node)
|
||||||
elsif node_kind = NodeKind.integer_literal then
|
elsif node_kind = NodeKind.integer_literal then
|
||||||
_compile_integer_literal(parser_node)
|
instruction := _compile_integer_literal(parser_node)
|
||||||
else
|
else
|
||||||
_compile_variable_expression(parser_node, symbol_table);
|
instruction := _compile_variable_expression(parser_node, symbol_table);
|
||||||
is_address := 1
|
is_address^ := 1
|
||||||
end;
|
end;
|
||||||
return is_address
|
_elna_writer_instructions(instruction)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _unary_expression_size();
|
proc _unary_expression_size();
|
||||||
@@ -1157,6 +1487,8 @@ var
|
|||||||
expression_kind: Word;
|
expression_kind: Word;
|
||||||
operator: Word;
|
operator: Word;
|
||||||
operand: Word;
|
operand: Word;
|
||||||
|
is_address: Word;
|
||||||
|
instruction: Word;
|
||||||
begin
|
begin
|
||||||
operator := 0;
|
operator := 0;
|
||||||
operand := 0;
|
operand := 0;
|
||||||
@@ -1171,14 +1503,20 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
if operator = '@' then
|
if operator = '@' then
|
||||||
_compile_designator(operand, symbol_table)
|
_compile_designator(operand, symbol_table, @is_address)
|
||||||
elsif _compile_designator(operand, symbol_table) then
|
else
|
||||||
_write_z("\tlw t0, (t0) # Designator is an address.\n\0")
|
_compile_designator(operand, symbol_table, @is_address);
|
||||||
|
if is_address then
|
||||||
|
instruction := _elna_generator_load_word(ElnaGeneratorRegister.t0, ElnaGeneratorRegister.t0, 0);
|
||||||
|
_elna_writer_instruction(instruction)
|
||||||
|
end
|
||||||
end;
|
end;
|
||||||
if operator = '-' then
|
if operator = '-' then
|
||||||
_write_z("\tneg t0, t0\n\0")
|
instruction := _elna_generator_neg(ElnaGeneratorRegister.t0, ElnaGeneratorRegister.t0);
|
||||||
|
_elna_writer_instruction(instruction)
|
||||||
elsif operator = '~' then
|
elsif operator = '~' then
|
||||||
_write_z("\tnot t0, t0\n\0")
|
instruction := _elna_generator_not(ElnaGeneratorRegister.t0, ElnaGeneratorRegister.t0);
|
||||||
|
_elna_writer_instruction(instruction)
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@@ -1296,6 +1634,8 @@ var
|
|||||||
token_kind: Word;
|
token_kind: Word;
|
||||||
expression_kind: Word;
|
expression_kind: Word;
|
||||||
operand_node: Word;
|
operand_node: Word;
|
||||||
|
first_instruction: Word;
|
||||||
|
instruction: Word;
|
||||||
begin
|
begin
|
||||||
expression_kind := _node_get_kind(parser_node);
|
expression_kind := _node_get_kind(parser_node);
|
||||||
|
|
||||||
@@ -1307,42 +1647,53 @@ begin
|
|||||||
operand_node := _binary_expression_get_lhs(parser_node);
|
operand_node := _binary_expression_get_lhs(parser_node);
|
||||||
_compile_unary_expression(operand_node, symbol_table);
|
_compile_unary_expression(operand_node, symbol_table);
|
||||||
(* Save the value of the left expression on the stack. *)
|
(* Save the value of the left expression on the stack. *)
|
||||||
_write_z("\tsw t0, 64(sp)\n\0");
|
instruction := _elna_generator_store_word(ElnaGeneratorRegister.t0, ElnaGeneratorRegister.sp, 64);
|
||||||
|
_elna_writer_instruction(instruction);
|
||||||
|
|
||||||
operand_node := _binary_expression_get_rhs(parser_node);
|
operand_node := _binary_expression_get_rhs(parser_node);
|
||||||
_compile_unary_expression(operand_node, symbol_table);
|
_compile_unary_expression(operand_node, symbol_table);
|
||||||
(* Load the left expression from the stack; *)
|
(* Load the left expression from the stack; *)
|
||||||
_write_z("\tlw t1, 64(sp)\n\0");
|
instruction := _elna_generator_load_word(ElnaGeneratorRegister.t1, ElnaGeneratorRegister.sp, 64);
|
||||||
|
_elna_writer_instruction(instruction);
|
||||||
|
|
||||||
if token_kind = LexerTokenKind.plus then
|
if token_kind = LexerTokenKind.plus then
|
||||||
_write_z("\tadd t0, t0, t1\n\0")
|
first_instruction := _elna_generator_add(ElnaGeneratorRegister.t0, ElnaGeneratorRegister.t0, ElnaGeneratorRegister.t1)
|
||||||
elsif token_kind = LexerTokenKind.minus then
|
elsif token_kind = LexerTokenKind.minus then
|
||||||
_write_z("\tsub t0, t1, t0\n\0");
|
first_instruction := _elna_generator_sub(ElnaGeneratorRegister.t0, ElnaGeneratorRegister.t1, ElnaGeneratorRegister.t0)
|
||||||
elsif token_kind = LexerTokenKind.multiplication then
|
elsif token_kind = LexerTokenKind.multiplication then
|
||||||
_write_z("\tmul t0, t0, t1\n\0")
|
first_instruction := _elna_generator_mul(ElnaGeneratorRegister.t0, ElnaGeneratorRegister.t0, ElnaGeneratorRegister.t1)
|
||||||
elsif token_kind = LexerTokenKind.and then
|
elsif token_kind = LexerTokenKind.and then
|
||||||
_write_z("\tand t0, t0, t1\n\0")
|
first_instruction := _elna_generator_and(ElnaGeneratorRegister.t0, ElnaGeneratorRegister.t0, ElnaGeneratorRegister.t1)
|
||||||
elsif token_kind = LexerTokenKind._or then
|
elsif token_kind = LexerTokenKind._or then
|
||||||
_write_z("\tor t0, t0, t1\n\0")
|
first_instruction := _elna_generator_or(ElnaGeneratorRegister.t0, ElnaGeneratorRegister.t0, ElnaGeneratorRegister.t1)
|
||||||
elsif token_kind = LexerTokenKind._xor then
|
elsif token_kind = LexerTokenKind._xor then
|
||||||
_write_z("\txor t0, t0, t1\n\0")
|
first_instruction := _elna_generator_xor(ElnaGeneratorRegister.t0, ElnaGeneratorRegister.t0, ElnaGeneratorRegister.t1)
|
||||||
elsif token_kind = LexerTokenKind.equals then
|
elsif token_kind = LexerTokenKind.equals then
|
||||||
_write_z("\txor t0, t0, t1\n\tseqz t0, t0\n\0")
|
first_instruction := _elna_generator_xor(ElnaGeneratorRegister.t0, ElnaGeneratorRegister.t0, ElnaGeneratorRegister.t1);
|
||||||
|
instruction := _elna_generator_seqz(ElnaGeneratorRegister.t0, ElnaGeneratorRegister.t0);
|
||||||
|
_elna_generator_instruction_set_next(first_instruction, instruction)
|
||||||
elsif token_kind = LexerTokenKind.remainder then
|
elsif token_kind = LexerTokenKind.remainder then
|
||||||
_write_z("\trem t0, t1, t0\n\0")
|
first_instruction := _elna_generator_rem(ElnaGeneratorRegister.t0, ElnaGeneratorRegister.t1, ElnaGeneratorRegister.t0)
|
||||||
elsif token_kind = LexerTokenKind.division then
|
elsif token_kind = LexerTokenKind.division then
|
||||||
_write_z("\tdiv t0, t1, t0\n\0")
|
first_instruction := _elna_generator_div(ElnaGeneratorRegister.t0, ElnaGeneratorRegister.t1, ElnaGeneratorRegister.t0)
|
||||||
elsif token_kind = LexerTokenKind.less_than then
|
elsif token_kind = LexerTokenKind.less_than then
|
||||||
_write_z("\tslt t0, t1, t0\n\0")
|
first_instruction := _elna_generator_slt(ElnaGeneratorRegister.t0, ElnaGeneratorRegister.t1, ElnaGeneratorRegister.t0)
|
||||||
elsif token_kind = LexerTokenKind.greater_than then
|
elsif token_kind = LexerTokenKind.greater_than then
|
||||||
_write_z("\tslt t0, t0, t1\n\0")
|
first_instruction := _elna_generator_slt(ElnaGeneratorRegister.t0, ElnaGeneratorRegister.t0, ElnaGeneratorRegister.t1)
|
||||||
elsif token_kind = LexerTokenKind.less_equal then
|
elsif token_kind = LexerTokenKind.less_equal then
|
||||||
_write_z("\tslt t0, t0, t1\n\txori t0, t0, 1\n\0")
|
first_instruction := _elna_generator_slt(ElnaGeneratorRegister.t0, ElnaGeneratorRegister.t0, ElnaGeneratorRegister.t1);
|
||||||
|
instruction := _elna_generator_xor_immediate(ElnaGeneratorRegister.t0, ElnaGeneratorRegister.t0, 1);
|
||||||
|
_elna_generator_instruction_set_next(first_instruction, instruction)
|
||||||
elsif token_kind = LexerTokenKind.not_equal then
|
elsif token_kind = LexerTokenKind.not_equal then
|
||||||
_write_z("\txor t0, t0, t1\n\tsnez t0, t0\n\0")
|
first_instruction := _elna_generator_xor(ElnaGeneratorRegister.t0, ElnaGeneratorRegister.t0, ElnaGeneratorRegister.t1);
|
||||||
|
instruction := _elna_generator_snez(ElnaGeneratorRegister.t0, ElnaGeneratorRegister.t0);
|
||||||
|
_elna_generator_instruction_set_next(first_instruction, instruction)
|
||||||
elsif token_kind = LexerTokenKind.greater_equal then
|
elsif token_kind = LexerTokenKind.greater_equal then
|
||||||
_write_z("\tslt t0, t1, t0\n\txori t0, t0, 1\n\0")
|
first_instruction := _elna_generator_slt(ElnaGeneratorRegister.t0, ElnaGeneratorRegister.t1, ElnaGeneratorRegister.t0);
|
||||||
end
|
instruction := _elna_generator_xor_immediate(ElnaGeneratorRegister.t0, ElnaGeneratorRegister.t0, 1);
|
||||||
|
_elna_generator_instruction_set_next(first_instruction, instruction)
|
||||||
|
end;
|
||||||
|
_elna_writer_instructions(first_instruction)
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@@ -1429,11 +1780,15 @@ var
|
|||||||
argument_count: Word;
|
argument_count: Word;
|
||||||
stack_offset: Word;
|
stack_offset: Word;
|
||||||
parsed_expression: Word;
|
parsed_expression: Word;
|
||||||
|
instruction: Word;
|
||||||
|
first_instruction: Word;
|
||||||
|
current_instruction: Word;
|
||||||
begin
|
begin
|
||||||
parsed_expression := _call_get_name(parsed_call);
|
parsed_expression := _call_get_name(parsed_call);
|
||||||
name := _variable_expression_get_name(parsed_expression);
|
name := _variable_expression_get_name(parsed_expression);
|
||||||
name_length := _variable_expression_get_length(parsed_expression);
|
name_length := _variable_expression_get_length(parsed_expression);
|
||||||
argument_count := 0;
|
argument_count := 0;
|
||||||
|
first_instruction := 0;
|
||||||
|
|
||||||
.compile_call_loop;
|
.compile_call_loop;
|
||||||
|
|
||||||
@@ -1444,11 +1799,11 @@ begin
|
|||||||
_compile_binary_expression(parsed_expression, symbol_table);
|
_compile_binary_expression(parsed_expression, symbol_table);
|
||||||
|
|
||||||
(* Save the argument on the stack. *)
|
(* Save the argument on the stack. *)
|
||||||
_write_z("\tsw t0, \0");
|
|
||||||
|
|
||||||
stack_offset := argument_count * 4;
|
stack_offset := argument_count * 4;
|
||||||
_write_i(116 - stack_offset);
|
|
||||||
_write_z("(sp)\n\0");
|
instruction := _elna_generator_store_word(ElnaGeneratorRegister.t0,
|
||||||
|
ElnaGeneratorRegister.sp, 116 - stack_offset);
|
||||||
|
_elna_writer_instruction(instruction);
|
||||||
|
|
||||||
argument_count := argument_count + 1;
|
argument_count := argument_count + 1;
|
||||||
goto compile_call_loop
|
goto compile_call_loop
|
||||||
@@ -1460,24 +1815,27 @@ begin
|
|||||||
if argument_count <> 0 then
|
if argument_count <> 0 then
|
||||||
(* Decrement the argument counter. *)
|
(* Decrement the argument counter. *)
|
||||||
argument_count := argument_count - 1;
|
argument_count := argument_count - 1;
|
||||||
|
stack_offset := argument_count * 4;
|
||||||
_write_z("\tlw a\0");
|
|
||||||
_write_i(argument_count);
|
|
||||||
|
|
||||||
_write_z(", \0");
|
|
||||||
|
|
||||||
(* Calculate the stack offset: 116 - (4 * argument_counter) *)
|
(* Calculate the stack offset: 116 - (4 * argument_counter) *)
|
||||||
stack_offset := argument_count * 4;
|
instruction := _elna_generator_load_word(ElnaGeneratorRegister.a0 + argument_count,
|
||||||
_write_i(116 - stack_offset);
|
ElnaGeneratorRegister.sp, 116 - stack_offset);
|
||||||
|
if first_instruction = 0 then
|
||||||
_write_z("(sp)\n\0");
|
first_instruction := instruction
|
||||||
|
else
|
||||||
|
_elna_generator_instruction_set_next(current_instruction, instruction)
|
||||||
|
end;
|
||||||
|
current_instruction := instruction;
|
||||||
|
|
||||||
goto compile_call_finalize
|
goto compile_call_finalize
|
||||||
end;
|
end;
|
||||||
|
instruction := _elna_generator_call(name, name_length);
|
||||||
_write_z("\tcall \0");
|
if first_instruction = 0 then
|
||||||
_write_s(name, name_length);
|
first_instruction := instruction
|
||||||
_write_c('\n')
|
else
|
||||||
|
_elna_generator_instruction_set_next(current_instruction, instruction)
|
||||||
|
end;
|
||||||
|
_elna_writer_instructions(first_instruction)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
(**
|
(**
|
||||||
@@ -1633,25 +1991,24 @@ end;
|
|||||||
proc _compile_local_designator(symbol: Word);
|
proc _compile_local_designator(symbol: Word);
|
||||||
var
|
var
|
||||||
variable_offset: Word;
|
variable_offset: Word;
|
||||||
|
instruction: Word;
|
||||||
begin
|
begin
|
||||||
_write_z("\taddi t0, sp, \0");
|
|
||||||
variable_offset := _parameter_info_get_offset(symbol);
|
variable_offset := _parameter_info_get_offset(symbol);
|
||||||
_write_i(variable_offset);
|
instruction := _elna_generator_add_immediate(ElnaGeneratorRegister.t0, ElnaGeneratorRegister.sp, variable_offset);
|
||||||
_write_c('\n')
|
return instruction
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _compile_global_designator(variable_expression: Word);
|
proc _compile_global_designator(variable_expression: Word);
|
||||||
var
|
var
|
||||||
name: Word;
|
name: Word;
|
||||||
token_length: Word;
|
token_length: Word;
|
||||||
|
instruction: Word;
|
||||||
begin
|
begin
|
||||||
_write_z("\tla t0, \0");
|
|
||||||
|
|
||||||
name := _variable_expression_get_name(variable_expression);
|
name := _variable_expression_get_name(variable_expression);
|
||||||
token_length := _variable_expression_get_length(variable_expression);
|
token_length := _variable_expression_get_length(variable_expression);
|
||||||
|
instruction := _elna_generator_load_address(ElnaGeneratorRegister.t0, name, token_length);
|
||||||
|
|
||||||
_write_s(name, token_length);
|
return instruction
|
||||||
_write_c('\n')
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _field_access_expression_size();
|
proc _field_access_expression_size();
|
||||||
@@ -1706,6 +2063,7 @@ var
|
|||||||
member_length: Word;
|
member_length: Word;
|
||||||
counter: Word;
|
counter: Word;
|
||||||
symbol: Word;
|
symbol: Word;
|
||||||
|
instruction: Word;
|
||||||
begin
|
begin
|
||||||
symbol := _field_access_expression_get_aggregate(field_access_expression);
|
symbol := _field_access_expression_get_aggregate(field_access_expression);
|
||||||
value_name := _variable_expression_get_name(symbol);
|
value_name := _variable_expression_get_name(symbol);
|
||||||
@@ -1736,9 +2094,8 @@ begin
|
|||||||
counter := counter + 1;
|
counter := counter + 1;
|
||||||
goto compile_enumeration_value_members
|
goto compile_enumeration_value_members
|
||||||
end;
|
end;
|
||||||
_write_z("\tli t0, \0");
|
instruction := _elna_generator_load_immediate(ElnaGeneratorRegister.t0, counter, 0);
|
||||||
_write_i(counter);
|
_elna_writer_instructions(instruction)
|
||||||
_write_c('\n')
|
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@@ -1769,31 +2126,32 @@ begin
|
|||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _compile_designator(parser_node: Word, symbol_table: Word);
|
proc _compile_designator(parser_node: Word, symbol_table: Word, is_address: Word);
|
||||||
var
|
var
|
||||||
name_token: Word;
|
name_token: Word;
|
||||||
lookup_result: Word;
|
lookup_result: Word;
|
||||||
token_kind: Word;
|
token_kind: Word;
|
||||||
parser_node: Word;
|
parser_node: Word;
|
||||||
is_address: Word;
|
|
||||||
node_kind: Word;
|
node_kind: Word;
|
||||||
|
instruction: Word;
|
||||||
begin
|
begin
|
||||||
is_address := 1;
|
|
||||||
node_kind := _node_get_kind(parser_node);
|
node_kind := _node_get_kind(parser_node);
|
||||||
|
|
||||||
if node_kind = NodeKind.dereference_expression then
|
if node_kind = NodeKind.dereference_expression then
|
||||||
parser_node := _dereference_expression_get_pointer(parser_node);
|
parser_node := _dereference_expression_get_pointer(parser_node);
|
||||||
_compile_simple_expression(parser_node, symbol_table);
|
_compile_simple_expression(parser_node, symbol_table, is_address);
|
||||||
_write_z("\tlw t0, (t0)\n\0")
|
instruction := _elna_generator_load_word(ElnaGeneratorRegister.t0, ElnaGeneratorRegister.t0, 0);
|
||||||
|
_elna_writer_instructions(instruction)
|
||||||
elsif node_kind = NodeKind.field_access_expression then
|
elsif node_kind = NodeKind.field_access_expression then
|
||||||
_compile_enumeration_value(parser_node);
|
_compile_enumeration_value(parser_node);
|
||||||
is_address := 0
|
is_address^ := 0
|
||||||
elsif node_kind = NodeKind.call then
|
elsif node_kind = NodeKind.call then
|
||||||
_compile_call(parser_node, symbol_table);
|
_compile_call(parser_node, symbol_table);
|
||||||
_write_z("\tmv t0, a0\n\0");
|
instruction := _elna_generator_move(ElnaGeneratorRegister.t0, ElnaGeneratorRegister.a0);
|
||||||
is_address := 0
|
_elna_writer_instructions(instruction);
|
||||||
|
is_address^ := 0
|
||||||
else
|
else
|
||||||
is_address := _compile_simple_expression(parser_node, symbol_table)
|
_compile_simple_expression(parser_node, symbol_table, is_address)
|
||||||
end;
|
end;
|
||||||
return is_address
|
return is_address
|
||||||
end;
|
end;
|
||||||
@@ -1853,18 +2211,25 @@ end;
|
|||||||
proc _compile_assignment_statement(parser_tree: Word, symbol_table: Word);
|
proc _compile_assignment_statement(parser_tree: Word, symbol_table: Word);
|
||||||
var
|
var
|
||||||
current_expression: Word;
|
current_expression: Word;
|
||||||
|
is_address: Word;
|
||||||
|
first_instruction: Word;
|
||||||
|
instruction: Word;
|
||||||
begin
|
begin
|
||||||
current_expression := _assignment_statement_get_assignee(parser_tree);
|
current_expression := _assignment_statement_get_assignee(parser_tree);
|
||||||
_compile_designator(current_expression, symbol_table);
|
_compile_designator(current_expression, symbol_table, @is_address);
|
||||||
|
|
||||||
(* Save the assignee address on the stack. *)
|
(* Save the assignee address on the stack. *)
|
||||||
_write_z("\tsw t0, 60(sp)\n\0");
|
instruction := _elna_generator_store_word(ElnaGeneratorRegister.t0, ElnaGeneratorRegister.sp, 60);
|
||||||
|
_elna_writer_instructions(instruction);
|
||||||
|
|
||||||
(* Compile the assignment. *)
|
(* Compile the assignment. *)
|
||||||
current_expression := _assignment_statement_get_assignment(parser_tree);
|
current_expression := _assignment_statement_get_assignment(parser_tree);
|
||||||
_compile_binary_expression(current_expression, symbol_table);
|
_compile_binary_expression(current_expression, symbol_table);
|
||||||
|
|
||||||
_write_z("\tlw t1, 60(sp)\n\tsw t0, (t1)\n\0")
|
first_instruction := _elna_generator_load_word(ElnaGeneratorRegister.t1, ElnaGeneratorRegister.sp, 60);
|
||||||
|
instruction := _elna_generator_store_word(ElnaGeneratorRegister.t0, ElnaGeneratorRegister.t1, 0);
|
||||||
|
_elna_generator_instruction_set_next(first_instruction, instruction);
|
||||||
|
_elna_writer_instructions(first_instruction)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _return_statement_size();
|
proc _return_statement_size();
|
||||||
@@ -1910,10 +2275,12 @@ end;
|
|||||||
proc _compile_return_statement(parser_node: Word, symbol_table: Word);
|
proc _compile_return_statement(parser_node: Word, symbol_table: Word);
|
||||||
var
|
var
|
||||||
return_expression: Word;
|
return_expression: Word;
|
||||||
|
instruction: Word;
|
||||||
begin
|
begin
|
||||||
return_expression := _return_statement_get_returned(parser_node);
|
return_expression := _return_statement_get_returned(parser_node);
|
||||||
_compile_binary_expression(return_expression, symbol_table);
|
_compile_binary_expression(return_expression, symbol_table);
|
||||||
_write_z("\tmv a0, t0\n\0")
|
instruction := _elna_generator_move(ElnaGeneratorRegister.a0, ElnaGeneratorRegister.t0);
|
||||||
|
_elna_writer_instructions(instruction)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
(**
|
(**
|
||||||
@@ -1959,6 +2326,7 @@ proc _compile_conditional_statements(parser_node: Word, after_end_label: Word, s
|
|||||||
var
|
var
|
||||||
condition_label: Word;
|
condition_label: Word;
|
||||||
current_node: Word;
|
current_node: Word;
|
||||||
|
instruction: Word;
|
||||||
begin
|
begin
|
||||||
(* Compile condition. *)
|
(* Compile condition. *)
|
||||||
current_node := _conditional_statements_get_condition(parser_node);
|
current_node := _conditional_statements_get_condition(parser_node);
|
||||||
@@ -2821,6 +3189,9 @@ var
|
|||||||
current_parameter: Word;
|
current_parameter: Word;
|
||||||
new_symbol_table: Word;
|
new_symbol_table: Word;
|
||||||
symbol_info: Word;
|
symbol_info: Word;
|
||||||
|
instruction: Word;
|
||||||
|
first_instruction: Word;
|
||||||
|
current_instruction: Word;
|
||||||
begin
|
begin
|
||||||
name_pointer := _declaration_get_name(parser_node);
|
name_pointer := _declaration_get_name(parser_node);
|
||||||
name_length := _declaration_get_length(parser_node);
|
name_length := _declaration_get_length(parser_node);
|
||||||
@@ -2843,6 +3214,7 @@ begin
|
|||||||
|
|
||||||
current_parameter := _procedure_declaration_get_parameters(parser_node);
|
current_parameter := _procedure_declaration_get_parameters(parser_node);
|
||||||
parameter_counter := 0;
|
parameter_counter := 0;
|
||||||
|
first_instruction := 0;
|
||||||
.compile_procedure_declaration_parameters;
|
.compile_procedure_declaration_parameters;
|
||||||
if current_parameter <> 0 then
|
if current_parameter <> 0 then
|
||||||
name_pointer := _declaration_get_name(current_parameter);
|
name_pointer := _declaration_get_name(current_parameter);
|
||||||
@@ -2851,12 +3223,14 @@ begin
|
|||||||
|
|
||||||
symbol_info := _parameter_info_get_offset(symbol_info);
|
symbol_info := _parameter_info_get_offset(symbol_info);
|
||||||
|
|
||||||
_write_z("\tsw a\0");
|
instruction := _elna_generator_store_word(ElnaGeneratorRegister.a0 + parameter_counter,
|
||||||
_write_i(parameter_counter);
|
ElnaGeneratorRegister.sp, symbol_info);
|
||||||
_write_z(", \0");
|
if first_instruction = 0 then
|
||||||
_write_i(symbol_info);
|
first_instruction := instruction
|
||||||
|
else
|
||||||
_write_z("(sp)\n\0");
|
_elna_generator_instruction_set_next(current_instruction, instruction)
|
||||||
|
end;
|
||||||
|
current_instruction := instruction;
|
||||||
|
|
||||||
(* _read_procedure_parameter(current_parameter, parameter_counter, new_symbol_table); *)
|
(* _read_procedure_parameter(current_parameter, parameter_counter, new_symbol_table); *)
|
||||||
parameter_counter := parameter_counter + 1;
|
parameter_counter := parameter_counter + 1;
|
||||||
@@ -2864,6 +3238,7 @@ begin
|
|||||||
current_parameter := _declaration_get_next(current_parameter);
|
current_parameter := _declaration_get_next(current_parameter);
|
||||||
goto compile_procedure_declaration_parameters
|
goto compile_procedure_declaration_parameters
|
||||||
end;
|
end;
|
||||||
|
_elna_writer_instructions(first_instruction);
|
||||||
current_parameter := _procedure_declaration_get_body(parser_node);
|
current_parameter := _procedure_declaration_get_body(parser_node);
|
||||||
_compile_statements(current_parameter, new_symbol_table);
|
_compile_statements(current_parameter, new_symbol_table);
|
||||||
|
|
||||||
@@ -4255,7 +4630,7 @@ end;
|
|||||||
proc _initialize_global_state();
|
proc _initialize_global_state();
|
||||||
begin
|
begin
|
||||||
compiler_strings_position := @compiler_strings;
|
compiler_strings_position := @compiler_strings;
|
||||||
memory_free_pointer := _mmap(495616);
|
memory_free_pointer := _mmap(1048576);
|
||||||
source_code := _mmap(495616);
|
source_code := _mmap(495616);
|
||||||
symbol_table_store := _mmap(495616)
|
symbol_table_store := _mmap(495616)
|
||||||
end;
|
end;
|
||||||
|
|||||||
Reference in New Issue
Block a user