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; | ||||||
| 	_write_c(','); | 	if current_argument <= argument_count then | ||||||
| 	_elna_writer_operand(instruction, 2); | 		_elna_writer_operand(instruction, current_argument); | ||||||
|  | 		current_argument := current_argument + 1 | ||||||
|  | 	end; | ||||||
|  | 	if current_argument <= argument_count then | ||||||
|  | 		_write_c(','); | ||||||
|  | 		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