summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2025-12-09 17:16:31 +0100
committerEugen Wissner <belka@caraus.de>2025-12-09 18:49:11 +0100
commit305032b53476267083457b706ce25bf81afcf0c5 (patch)
treecfba61a54e0db9f17f9829cb27cda4fea5e30aec
parentcc8f8153379c1ca071418d32e7e98129c9f6d5bb (diff)
downloadelna-305032b53476267083457b706ce25bf81afcf0c5.tar.gz
Assign stack offset to local variables in a later pass
-rw-r--r--boot/stage17/cl.elna840
1 files changed, 468 insertions, 372 deletions
diff --git a/boot/stage17/cl.elna b/boot/stage17/cl.elna
index e10be76..6483c85 100644
--- a/boot/stage17/cl.elna
+++ b/boot/stage17/cl.elna
@@ -8,6 +8,7 @@ program;
(* Stage 17 compiler. *)
(* - true and false boolean literals. *)
+(* - the number of local variables is not limited. *)
type
(**
@@ -231,28 +232,36 @@ type
base: Word;
length: Word
end;
- _info = record
+ ElnaSymbolInfo = record
kind: Word
end;
- _type_info = record
+ ElnaSymbolTypeInfo = record
kind: Word;
_type: Word
end;
- _parameter_info = record
+ ElnaSymbolParameterInfo = record
kind: Word;
offset: Word;
variable_type: Word
end;
- _temporary_info = record
+ ElnaSymbolTemporaryInfo = record
kind: Word;
offset: Word;
variable_type: Word
end;
- _procedure_info = record
+ ElnaSymbolProcedureInfo = record
kind: Word;
symbol_table: Word
end;
+ ElnaErrorList = record
+ first: Word;
+ last: Word
+ end;
+ ElnaError = record
+ next: Word
+ end;
+
ElnaLexerAction = (none, accumulate, skip, single, eof, finalize, composite, key_id, integer, delimited);
(**
@@ -399,7 +408,7 @@ type
array_type_expression,
null
);
- InfoKind = (type_info, parameter_info, temporary_info, procedure_info);
+ ElnaSymbolInfoKind = (type_info, parameter_info, temporary_info, procedure_info);
ElnaTypeKind = (primitive, enumeration, _record, pointer, array);
ElnaTacOperator = (
get_address,
@@ -458,8 +467,8 @@ type
allocate_stack,
ret
);
- ElnaTacOperand = (temporary, immediate, symbol, stack);
- ElnaRtlOperand = (register, immediate, symbol, offset);
+ ElnaTacOperand = (temporary, immediate, symbol, stack, pseudo);
+ ElnaRtlOperand = (register, immediate, symbol, offset, pseudo);
ElnaRtlRegister = (
zero,
ra,
@@ -499,6 +508,7 @@ var
symbol_table_global: Array;
compiler_strings: Array;
classification: Array;
+ variable_map: Array;
source_code: Word;
compiler_strings_position: Word;
@@ -518,22 +528,22 @@ var
*)
proc _string_length(string: Word);
var
- counter: Word;
- current_byte: Word;
+ counter1: Word;
+ current_byte1: Word;
begin
(* Reset the counter. *)
- counter := 0;
+ counter1 := 0;
.string_length_loop;
string := string + 1;
- current_byte := _load_byte(string);
- if current_byte <> '"' then
- counter := counter + 1;
+ current_byte1 := _load_byte(string);
+ if current_byte1 <> '"' then
+ counter1 := counter1 + 1;
goto string_length_loop
end;
- return counter
+ return counter1
end;
(**
@@ -546,40 +556,27 @@ end;
*)
proc _add_string(string: Word);
var
- contents: Word;
- result: Word;
- current_byte: Word;
+ contents1: Word;
+ result1: Word;
+ current_byte1: Word;
begin
- contents := string + 1;
- result := compiler_strings_length;
+ contents1 := string + 1;
+ result1 := compiler_strings_length;
.add_string_loop;
- current_byte := _load_byte(contents);
- if current_byte <> '"' then
- _store_byte(current_byte, compiler_strings_position);
+ current_byte1 := _load_byte(contents1);
+ if current_byte1 <> '"' then
+ _store_byte(current_byte1, compiler_strings_position);
compiler_strings_position := compiler_strings_position + 1;
- contents := contents + 1;
+ contents1 := contents1 + 1;
- if current_byte <> '\\' then
+ if current_byte1 <> '\\' then
compiler_strings_length := compiler_strings_length + 1
end;
goto add_string_loop
end;
- return result
-end;
-
-(**
- * Reads standard input into a buffer.
- *
- * Parameters:
- * buffer - Buffer pointer.
- * size - Buffer size.
- *
- * Returns the amount of bytes written in a0.
- *)
-proc _read_file(buffer: Word, size: Word);
- return _syscall(0, buffer, size, 0, 0, 0, 63)
+ return result1
end;
(**
@@ -591,53 +588,7 @@ end;
*)
proc _write_s(buffer: Word, size: Word);
begin
- _syscall(1, buffer, size, 0, 0, 0, 64)
-end;
-
-(**
- * Writes a number to a string buffer.
- *
- * Parameters:
- * number - Whole number.
- * output_buffer - Buffer pointer.
- *
- * Sets a0 to the length of the written number.
- *)
-proc _print_i(number: Word, output_buffer: Word);
-var
- local_buffer: Word;
- is_negative: Word;
- current_character: Word;
- result: Word;
-begin
- local_buffer := @result + 11;
-
- if number >= 0 then
- is_negative := 0
- else
- number = -number;
- is_negative := 1
- end;
-
- .print_i_digit10;
- current_character := number % 10;
- _store_byte(current_character + '0', local_buffer);
-
- number := number / 10;
- local_buffer := local_buffer - 1;
-
- if number <> 0 then
- goto print_i_digit10
- end;
- if is_negative = 1 then
- _store_byte('-', local_buffer);
- local_buffer := local_buffer - 1
- end;
- result := @result + 11;
- result := result - local_buffer;
- memcpy(output_buffer, local_buffer + 1, result);
-
- return result
+ write(1, buffer, size)
end;
(**
@@ -647,12 +598,9 @@ end;
* number - Whole number.
*)
proc _write_i(number: Word);
-var
- local_buffer: Word;
- length: Word;
begin
- length := _print_i(number, @local_buffer);
- _write_s(@local_buffer, length)
+ printf("%i\0", number);
+ fflush(nil)
end;
(**
@@ -663,7 +611,7 @@ end;
*)
proc _write_c(character: Word);
begin
- _write_s(@character, 1)
+ write(1, @character, 1)
end;
(**
@@ -673,19 +621,9 @@ end;
* string - String.
*)
proc _write_z(string: Word);
-var
- next_byte: Word;
begin
- (* Check for 0 character. *)
- next_byte := _load_byte(string);
-
- if next_byte <> 0 then
- (* Print a character. *)
- _write_c(next_byte);
-
- (* Advance the input string by one byte. *)
- _write_z(string + 1)
- end
+ printf("%s\0", string);
+ fflush(nil)
end;
(**
@@ -698,11 +636,11 @@ end;
*)
proc _is_alpha(character: Word);
var
- is_underscore: Word;
+ is_underscore1: Word;
begin
- is_underscore := character = '_';
+ is_underscore1 := character = '_';
- return isalpha(character) or is_underscore
+ return isalpha(character) or is_underscore1
end;
proc _is_alnum(character: Word);
@@ -727,13 +665,13 @@ end;
proc elna_instruction_list_concatenate(this: Word, value: Word);
var
- start: Word;
+ start1: Word;
begin
if this = 0 then
- start := value;
+ start1 := value;
goto elna_instruction_list_concatenate_end
else
- start := this
+ start1 := this
end;
.elna_instruction_list_concatenate_loop;
if value <> 0 then
@@ -744,7 +682,7 @@ begin
end;
this^ := value;
.elna_instruction_list_concatenate_end;
- return start
+ return start1
end;
proc _elna_tac_instruction_get_operand_type(this: Word, n: Word);
@@ -795,26 +733,26 @@ end;
proc _elna_tac_instruction_create(kind: Word);
var
- result: Word;
+ result1: Word;
begin
- result := malloc(_elna_tac_instruction_size());
+ result1 := malloc(_elna_tac_instruction_size());
- _elna_tac_instruction_set_kind(result, kind);
- elna_instruction_list_concatenate(result, 0);
+ _elna_tac_instruction_set_kind(result1, kind);
+ elna_instruction_list_concatenate(result1, 0);
- return result
+ return result1
end;
proc elna_rtl_instruction_create(kind: Word);
var
- result: ^ElnaInstructionList;
+ result1: ^ElnaInstructionList;
begin
- result := malloc(elna_rtl_instruction_size());
+ result1 := malloc(elna_rtl_instruction_size());
- elna_rtl_instruction_set_kind(result, kind);
- result^.next := nil;
+ elna_rtl_instruction_set_kind(result1, kind);
+ result1^.next := nil;
- return result
+ return result1
end;
proc elna_rtl_instruction_size();
@@ -881,41 +819,45 @@ end;
proc elna_rtl_load_operand_value(tac_instruction: Word, operand_number: Word, into: Word);
var
- result: ^ElnaInstructionList;
- operand_value: Word;
- operand_length: Word;
- operand_type: Word;
+ result1: ^ElnaInstructionList;
+ operand_value1: Word;
+ operand_length1: Word;
+ operand_type1: Word;
next_instruction: Word;
begin
- operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, operand_number);
- operand_length := _elna_tac_instruction_get_operand_length(tac_instruction, operand_number);
- operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, operand_number);
-
- if operand_type = ElnaTacOperand.immediate then
- result := elna_rtl_instruction_create(ElnaRtlOperator.li);
- elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0);
- elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.immediate, operand_value, operand_length)
- elsif operand_type = ElnaTacOperand.stack then
- result := elna_rtl_instruction_create(ElnaRtlOperator.lw);
- elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0);
- elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, operand_value)
- elsif operand_type = ElnaTacOperand.symbol then
- result := elna_rtl_instruction_create(ElnaRtlOperator.la);
- elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0);
- elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.symbol, operand_value, operand_length);
+ operand_value1 := _elna_tac_instruction_get_operand_value(tac_instruction, operand_number);
+ operand_length1 := _elna_tac_instruction_get_operand_length(tac_instruction, operand_number);
+ operand_type1 := _elna_tac_instruction_get_operand_type(tac_instruction, operand_number);
+
+ if operand_type1 = ElnaTacOperand.immediate then
+ result1 := elna_rtl_instruction_create(ElnaRtlOperator.li);
+ elna_rtl_instruction_set_operand(result1, 1, ElnaRtlOperand.register, into, 0);
+ elna_rtl_instruction_set_operand(result1, 2, ElnaRtlOperand.immediate, operand_value1, operand_length1)
+ elsif operand_type1 = ElnaTacOperand.stack then
+ result1 := elna_rtl_instruction_create(ElnaRtlOperator.lw);
+ elna_rtl_instruction_set_operand(result1, 1, ElnaRtlOperand.register, into, 0);
+ elna_rtl_instruction_set_operand(result1, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, operand_value1)
+ elsif operand_type1 = ElnaTacOperand.symbol then
+ result1 := elna_rtl_instruction_create(ElnaRtlOperator.la);
+ elna_rtl_instruction_set_operand(result1, 1, ElnaRtlOperand.register, into, 0);
+ elna_rtl_instruction_set_operand(result1, 2, ElnaRtlOperand.symbol, operand_value1, operand_length1);
next_instruction := elna_rtl_instruction_create(ElnaRtlOperator.lw);
elna_rtl_instruction_set_operand(next_instruction, 1, ElnaRtlOperand.register, into, 0);
elna_rtl_instruction_set_operand(next_instruction, 2, ElnaRtlOperand.offset, into, 0);
- result^.next := next_instruction
- elsif operand_type = ElnaTacOperand.temporary then
- result := elna_rtl_instruction_create(ElnaRtlOperator.move);
- elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0);
- elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.register, operand_value, 0)
+ result1^.next := next_instruction
+ elsif operand_type1 = ElnaTacOperand.temporary then
+ result1 := elna_rtl_instruction_create(ElnaRtlOperator.move);
+ elna_rtl_instruction_set_operand(result1, 1, ElnaRtlOperand.register, into, 0);
+ elna_rtl_instruction_set_operand(result1, 2, ElnaRtlOperand.register, operand_value1, 0)
+ elsif operand_type1 = ElnaTacOperand.pseudo then
+ result1 := elna_rtl_instruction_create(ElnaRtlOperator.move);
+ elna_rtl_instruction_set_operand(result1, 1, ElnaRtlOperand.register, into, 0);
+ elna_rtl_instruction_set_operand(result1, 2, ElnaRtlOperand.pseudo, operand_value1, operand_length1)
end;
- return result
+ return result1
end;
proc elna_rtl_load_operand_address(tac_instruction: Word, operand_number: Word, into: Word);
@@ -937,6 +879,10 @@ begin
result := elna_rtl_instruction_create(ElnaRtlOperator.la);
elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0);
elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.symbol, operand_value, operand_length)
+ elsif operand_type = ElnaTacOperand.pseudo then
+ result := elna_rtl_instruction_create(ElnaRtlOperator.la);
+ elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0);
+ elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.pseudo, operand_value, operand_length)
end;
return result
@@ -1053,23 +999,23 @@ end;
proc elna_rtl_instruction(tac_instruction: Word, next_instruction: ^^ElnaInstructionList);
var
result: ^ElnaInstructionList;
- instruction_size: Word;
instruction_kind: Word;
operand_type: Word;
operand_value: Word;
+ operand_length: Word;
operands: ^ElnaInstructionList;
intermediate_instruction: ^ElnaInstructionList;
begin
- instruction_size := elna_rtl_instruction_size();
- result := malloc(instruction_size);
+ result := malloc(elna_rtl_instruction_size());
instruction_kind := _elna_tac_instruction_get_kind(tac_instruction);
next_instruction^ := nil;
if instruction_kind = ElnaTacOperator.get_address then
operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, 2);
+ operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2);
+ operand_length := _elna_tac_instruction_get_operand_length(tac_instruction, 2);
if operand_type = ElnaTacOperand.stack then
- operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2);
result := elna_rtl_instruction_create(ElnaRtlOperator.add);
elna_rtl_copy_operand(tac_instruction, 1, result);
@@ -1085,6 +1031,11 @@ begin
elna_rtl_copy_operand(tac_instruction, 1, result);
elna_rtl_copy_operand(tac_instruction, 2, result)
+ elsif operand_type = ElnaTacOperand.pseudo then
+ result := elna_rtl_instruction_create(ElnaRtlOperator.la);
+
+ elna_rtl_copy_operand(tac_instruction, 1, result);
+ elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.pseudo, operand_value, operand_length)
end
elsif instruction_kind = ElnaTacOperator.add then
result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.add)
@@ -1108,6 +1059,13 @@ begin
elna_rtl_copy_operand(tac_instruction, 1, result);
operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2);
elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.offset, operand_value, 0)
+ elsif operand_type = ElnaTacOperand.pseudo then
+ operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2);
+ operand_length := _elna_tac_instruction_get_operand_length(tac_instruction, 2);
+
+ result := elna_rtl_instruction_create(ElnaRtlOperator.lw);
+ elna_rtl_copy_operand(tac_instruction, 1, result);
+ elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.pseudo, operand_value, operand_length)
end
elsif instruction_kind = ElnaTacOperator.store then
operands := elna_rtl_load_operand_value(tac_instruction, 1, ElnaRtlRegister.t0);
@@ -1118,12 +1076,14 @@ begin
elna_rtl_instruction_set_operand(next_instruction^, 1, ElnaRtlOperand.register, ElnaRtlRegister.t0, 0);
operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, 2);
+ operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2);
+ operand_length := _elna_tac_instruction_get_operand_length(tac_instruction, 2);
if operand_type = ElnaTacOperand.stack then
- operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2);
elna_rtl_instruction_set_operand(next_instruction^, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, operand_value)
elsif operand_type = ElnaTacOperand.temporary then
- operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2);
elna_rtl_instruction_set_operand(next_instruction^, 2, ElnaRtlOperand.offset, operand_value, 0)
+ elsif operand_type = ElnaTacOperand.pseudo then
+ elna_rtl_instruction_set_operand(next_instruction^, 2, ElnaRtlOperand.pseudo, operand_value, operand_length)
end;
if operands = 0 then
result^.next := next_instruction^
@@ -1224,6 +1184,7 @@ begin
elsif instruction_kind = ElnaTacOperator.copy then
operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, 1);
operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 1);
+ operand_length := _elna_tac_instruction_get_operand_length(tac_instruction, 1);
if operand_type = ElnaTacOperand.temporary then
result := elna_rtl_load_operand_value(tac_instruction, 2, operand_value);
@@ -1242,6 +1203,20 @@ begin
else
operands^.next := next_instruction^
end
+ elsif operand_type = ElnaTacOperand.pseudo then
+ operands := elna_rtl_load_operand_value(tac_instruction, 2, ElnaRtlRegister.t4);
+ result := operands;
+ operands := result^.next;
+
+ next_instruction^ := elna_rtl_instruction_create(ElnaRtlOperator.move);
+ _elna_tac_instruction_set_operand(next_instruction^, 1, ElnaRtlOperand.pseudo, operand_value, operand_length);
+ _elna_tac_instruction_set_operand(next_instruction^, 2, ElnaRtlOperand.register, ElnaRtlRegister.t4, 0);
+
+ if operands = nil then
+ result^.next := next_instruction^
+ else
+ operands^.next := next_instruction^
+ end
end
end;
if next_instruction^ = nil then
@@ -1264,13 +1239,13 @@ end;
proc _elna_tac_label(counter: Word, length: Word);
var
- result: Word;
+ result1: Word;
begin
- result := _elna_tac_instruction_create(ElnaTacOperator.label);
+ result1 := _elna_tac_instruction_create(ElnaTacOperator.label);
- _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.symbol, counter, length);
+ _elna_tac_instruction_set_operand(result1, 1, ElnaTacOperand.symbol, counter, length);
- return result
+ return result1
end;
proc _elna_writer_instruction_name(instruction_kind: Word);
@@ -1349,8 +1324,6 @@ begin
elsif instruction_kind = ElnaRtlOperator.bnez then
argument_count := 2;
_write_s("\tbnez", 5)
- else (* ElnaRtlOperator.allocate_stack or ElnaRtlOperator.ret *)
- argument_count := 0
end;
return argument_count
end;
@@ -1392,22 +1365,110 @@ begin
end
end;
-proc _elna_writer_instruction(instruction: Word);
+proc elna_alloc_variable(operand_value: Word, operand_length: Word);
+var
+ pseudo_symbol1: Word;
+begin
+ pseudo_symbol1 := _symbol_table_lookup(@variable_map, operand_value, operand_length);
+ if pseudo_symbol1 = nil then
+ _symbol_table_enter(@variable_map, operand_value, operand_length, temporary_variable_counter);
+ pseudo_symbol1 := temporary_variable_counter;
+ temporary_variable_counter := temporary_variable_counter + 4
+ end;
+ return pseudo_symbol1
+end;
+
+proc elna_alloc_instruction(instruction: Word);
var
instruction_kind: Word;
+ operand_type: Word;
+ operand_value: Word;
+ operand_length: Word;
+ pseudo_symbol1: Word;
+begin
+ instruction_kind := elna_rtl_instruction_get_kind(instruction);
+
+ if instruction_kind = ElnaRtlOperator.move then
+ operand_type := elna_rtl_instruction_get_operand_type(instruction, 1);
+ operand_value := elna_rtl_instruction_get_operand_value(instruction, 1);
+ operand_length := elna_rtl_instruction_get_operand_length(instruction, 1);
+
+ if operand_type = ElnaRtlOperand.pseudo then
+ pseudo_symbol1 := elna_alloc_variable(operand_value, operand_length);
+ elna_rtl_instruction_set_kind(instruction, ElnaRtlOperator.sw);
+
+ operand_type := elna_rtl_instruction_get_operand_type(instruction, 2);
+ operand_value := elna_rtl_instruction_get_operand_value(instruction, 2);
+ operand_length := elna_rtl_instruction_get_operand_length(instruction, 2);
+
+ elna_rtl_instruction_set_operand(instruction, 1, operand_type, operand_value, operand_length);
+ elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, pseudo_symbol1);
+
+ goto elna_alloc_instruction_end
+ end;
+
+ operand_type := elna_rtl_instruction_get_operand_type(instruction, 2);
+ operand_value := elna_rtl_instruction_get_operand_value(instruction, 2);
+ operand_length := elna_rtl_instruction_get_operand_length(instruction, 2);
+
+ if operand_type = ElnaRtlOperand.pseudo then
+ pseudo_symbol1 := elna_alloc_variable(operand_value, operand_length);
+ elna_rtl_instruction_set_kind(instruction, ElnaRtlOperator.lw);
+ elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, pseudo_symbol1);
+
+ goto elna_alloc_instruction_end
+ end
+ elsif instruction_kind = ElnaRtlOperator.la then
+ operand_type := elna_rtl_instruction_get_operand_type(instruction, 2);
+ operand_value := elna_rtl_instruction_get_operand_value(instruction, 2);
+ operand_length := elna_rtl_instruction_get_operand_length(instruction, 2);
+
+ if operand_type = ElnaRtlOperand.pseudo then
+ (* Debug. Error stream output.
+ printf("# %i %.*s\n\0", operand_length, operand_length, operand_value);
+ fflush(nil); *)
+
+ pseudo_symbol1 := elna_alloc_variable(operand_value, operand_length);
+ elna_rtl_instruction_set_kind(instruction, ElnaRtlOperator.addi);
+
+ elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlOperand.register, ElnaRtlRegister.sp, 0);
+ elna_rtl_instruction_set_operand(instruction, 3, ElnaRtlOperand.immediate, pseudo_symbol1, 0);
+
+ goto elna_alloc_instruction_end
+ end
+ end;
+ .elna_alloc_instruction_end;
+end;
+
+proc _elna_writer_instruction(instruction: Word);
+var
argument_count: Word;
+ instruction_kind: Word;
current_argument: Word;
operand_value: Word;
operand_length: Word;
begin
instruction_kind := elna_rtl_instruction_get_kind(instruction);
+ argument_count := 0;
if instruction_kind = ElnaRtlOperator.label then
- argument_count := 0;
operand_value := elna_rtl_instruction_get_operand_value(instruction, 1);
operand_length := elna_rtl_instruction_get_operand_length(instruction, 1);
_write_label(operand_value, operand_length);
_write_c(':')
+ elsif instruction_kind = ElnaRtlOperator.allocate_stack then
+ operand_value := elna_rtl_instruction_get_operand_value(instruction, 1);
+
+ (* Write the prologue. *)
+ printf("\taddi sp, sp, -%i\n\tsw ra, %i(sp)\n\tsw s0, %i(sp)\n\taddi s0, sp, %i\n\0",
+ operand_value + 8, operand_value + 4, operand_value, operand_value + 8);
+ fflush(nil)
+ elsif instruction_kind = ElnaRtlOperator.ret then
+ operand_value := elna_rtl_instruction_get_operand_value(instruction, 1);
+
+ (* Write the epilogue. *)
+ printf("\tlw ra, %i(sp)\n\tlw s0, %i(sp)\n\taddi sp, sp, %i\n\0", operand_value + 4, operand_value, operand_value + 8);
+ fflush(nil)
else
argument_count := _elna_writer_instruction_name(instruction_kind)
end;
@@ -1428,10 +1489,10 @@ end;
proc elna_rtl_instructions(instruction: ^ElnaInstructionList);
var
+ last_copy1: ^ElnaInstructionList;
current_copy: ^ElnaInstructionList;
next_copy: ^ElnaInstructionList;
first_copy: ^ElnaInstructionList;
- last_copy: ^ElnaInstructionList;
begin
if instruction <> nil then
first_copy := elna_rtl_instruction(instruction, @current_copy);
@@ -1443,27 +1504,65 @@ begin
.elna_rtl_instructions_start;
if instruction <> nil then
- next_copy := elna_rtl_instruction(instruction, @last_copy);
+ next_copy := elna_rtl_instruction(instruction, @last_copy1);
instruction := instruction^.next;
current_copy^.next := next_copy;
- current_copy := last_copy;
+ current_copy := last_copy1;
goto elna_rtl_instructions_start
end;
return first_copy
end;
+proc elna_alloc_instructions(instruction: ^ElnaInstructionList);
+begin
+ .elna_alloc_instructions_start;
+
+ if instruction <> nil then
+ elna_alloc_instruction(instruction);
+ instruction := instruction^.next;
+ goto elna_alloc_instructions_start
+ end
+end;
+
proc _elna_writer_instructions(instruction: ^ElnaInstructionList);
begin
.elna_writer_instructions_start;
- if instruction <> 0 then
+ if instruction <> nil then
_elna_writer_instruction(instruction);
instruction := instruction^.next;
goto elna_writer_instructions_start
end
end;
+proc elna_alloc_procedure(rtl_declaration: ^ElnaInstructionDeclaration);
+var
+ stack_instruction: ^ElnaInstructionList;
+begin
+ .elna_alloc_procedure_loop;
+ temporary_variable_counter := 60;
+ variable_map := 0;
+
+ elna_alloc_instructions(rtl_declaration^.body);
+ if rtl_declaration^.stack then
+ stack_instruction := elna_rtl_instruction_create(ElnaRtlOperator.allocate_stack);
+ stack_instruction^.next := rtl_declaration^.body;
+ elna_rtl_instruction_set_operand(stack_instruction, 1, ElnaRtlOperand.immediate, temporary_variable_counter, 0);
+
+ rtl_declaration^.body := stack_instruction;
+ stack_instruction := elna_rtl_instruction_create(ElnaRtlOperator.ret);
+ elna_rtl_instruction_set_operand(stack_instruction, 1, ElnaRtlOperand.immediate, temporary_variable_counter, 0);
+
+ elna_instruction_list_concatenate(rtl_declaration^.body, stack_instruction)
+ end;
+
+ rtl_declaration := rtl_declaration^.next;
+ if rtl_declaration <> nil then
+ goto elna_alloc_procedure_loop
+ end
+end;
+
proc _elna_writer_procedure(procedure: ^ElnaInstructionDeclaration);
begin
.elna_writer_procedure_loop;
@@ -1478,19 +1577,11 @@ begin
_write_s(procedure^.name, procedure^.length);
_write_z(":\n\0");
- (* Write the prologue. *)
- if procedure^.stack then
- _write_z("\taddi sp, sp, -144\n\tsw ra, 140(sp)\n\tsw s0, 136(sp)\n\taddi s0, sp, 144\n\0")
- end;
_elna_writer_instructions(procedure^.body);
- (* Write the epilogue. *)
- if procedure^.stack then
- _write_z("\tlw ra, 140(sp)\n\tlw s0, 136(sp)\n\taddi sp, sp, 144\n\0")
- end;
_write_z("\tret\n\0");
procedure := procedure^.next;
- if procedure <> 0 then
+ if procedure <> nil then
goto elna_writer_procedure_loop
end
end;
@@ -1527,6 +1618,11 @@ begin
return elna_instruction_module_create(data_part, code_part)
end;
+proc elna_alloc_module(pair: ^ElnaInstructionModule);
+begin
+ elna_alloc_procedure(pair^.code)
+end;
+
proc _elna_writer_module(pair: ^ElnaInstructionModule);
var
compiler_strings_copy: Word;
@@ -1539,7 +1635,6 @@ begin
_elna_writer_variable(pair^.data);
_write_z(".section .text\n\n\0");
- _write_z(".type _syscall, @function\n_syscall:\n\tmv a7, a6\n\tecall\n\tret\n\n\0");
_write_z(".type _load_byte, @function\n_load_byte:\n\tlb a0, (a0)\nret\n\n\0");
_write_z(".type _store_byte, @function\n_store_byte:\n\tsb a0, (a1)\nret\n\n\0");
@@ -1694,13 +1789,20 @@ end;
proc _elna_tac_variable_expression(variable_expression: ^ElnaTreeVariableExpression, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word);
var
- lookup_result: ^_parameter_info;
+ lookup_result: ^ElnaSymbolParameterInfo;
begin
lookup_result := _symbol_table_lookup(symbol_table, variable_expression^.name, variable_expression^.length);
+
if lookup_result <> nil then
- operand_type^ := ElnaTacOperand.stack;
- operand_value^ := lookup_result^.offset;
- operand_length^ := 0
+ if lookup_result^.kind = ElnaSymbolInfoKind.temporary_info then
+ operand_type^ := ElnaTacOperand.pseudo;
+ operand_value^ := variable_expression^.name;
+ operand_length^ := variable_expression^.length
+ else
+ operand_type^ := ElnaTacOperand.stack;
+ operand_value^ := lookup_result^.offset;
+ operand_length^ := 0
+ end
else
operand_type^ := ElnaTacOperand.symbol;
operand_value^ := variable_expression^.name;
@@ -1796,20 +1898,20 @@ end;
proc elna_parser_designator();
var
simple_expression: Word;
- token_kind: Word;
+ token_kind1: Word;
begin
simple_expression := elna_parser_simple_expression();
.elna_parser_designator_loop;
- _elna_lexer_read_token(@token_kind);
+ _elna_lexer_read_token(@token_kind1);
- if token_kind = ElnaLexerKind.hat then
+ if token_kind1 = ElnaLexerKind.hat then
simple_expression := elna_parser_dereference_expression(simple_expression);
goto elna_parser_designator_loop
- elsif token_kind = ElnaLexerKind.dot then
+ elsif token_kind1 = ElnaLexerKind.dot then
simple_expression := elna_parser_field_access_expression(simple_expression);
goto elna_parser_designator_loop
- elsif token_kind = ElnaLexerKind.left_paren then
+ elsif token_kind1 = ElnaLexerKind.left_paren then
simple_expression := elna_parser_call(simple_expression);
goto elna_parser_designator_loop
end;
@@ -2015,8 +2117,6 @@ end;
proc _elna_tac_binary_expression(parser_node: ^ElnaTreeBinaryExpression, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word);
var
- token_kind: Word;
- operand_node: Word;
first_instruction: Word;
instruction: Word;
current_instruction: Word;
@@ -2027,17 +2127,14 @@ begin
if parser_node^.kind <> ElnaTreeKind.binary_expression then
first_instruction := _elna_tac_unary_expression(parser_node, symbol_table, operand_type, operand_value, operand_length)
else
- token_kind := parser_node^.operator;
-
- operand_node := parser_node^.lhs;
lhs_type := 0;
lhs_value := 0;
lhs_length := 0;
- first_instruction := _elna_tac_unary_expression(operand_node, symbol_table, @lhs_type, @lhs_value, @lhs_length);
+ first_instruction := _elna_tac_unary_expression(parser_node^.lhs, symbol_table, @lhs_type, @lhs_value, @lhs_length);
(* Save the value of the left expression on the stack. *)
instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
- _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.stack, 72, 0);
+ _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.pseudo, "$lhs", 4);
_elna_tac_instruction_set_operand(instruction, 2, lhs_type, lhs_value, lhs_length);
if first_instruction = 0 then
@@ -2047,53 +2144,52 @@ begin
end;
current_instruction := instruction;
- operand_node := parser_node^.rhs;
lhs_type := 0;
lhs_value := 0;
lhs_length := 0;
- instruction := _elna_tac_unary_expression(operand_node, symbol_table, @lhs_type, @lhs_value, @lhs_length);
+ instruction := _elna_tac_unary_expression(parser_node^.rhs, symbol_table, @lhs_type, @lhs_value, @lhs_length);
current_instruction := elna_instruction_list_concatenate(current_instruction, instruction);
(* Load the left expression from the stack; *)
instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 7, 0);
- _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, 72, 0);
+ _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.pseudo, "$lhs", 4);
elna_instruction_list_concatenate(current_instruction, instruction);
current_instruction := instruction;
- if token_kind = ElnaLexerKind.plus then
+ if parser_node^.operator = ElnaLexerKind.plus then
instruction := _elna_tac_instruction_create(ElnaTacOperator.add)
- elsif token_kind = ElnaLexerKind.minus then
+ elsif parser_node^.operator = ElnaLexerKind.minus then
instruction := _elna_tac_instruction_create(ElnaTacOperator.subtract)
- elsif token_kind = ElnaLexerKind.multiplication then
+ elsif parser_node^.operator = ElnaLexerKind.multiplication then
instruction := _elna_tac_instruction_create(ElnaTacOperator.multiply)
- elsif token_kind = ElnaLexerKind.and then
+ elsif parser_node^.operator = ElnaLexerKind.and then
instruction := _elna_tac_instruction_create(ElnaTacOperator.and)
- elsif token_kind = ElnaLexerKind._or then
+ elsif parser_node^.operator = ElnaLexerKind._or then
instruction := _elna_tac_instruction_create(ElnaTacOperator._or)
- elsif token_kind = ElnaLexerKind._xor then
+ elsif parser_node^.operator = ElnaLexerKind._xor then
instruction := _elna_tac_instruction_create(ElnaTacOperator._xor)
- elsif token_kind = ElnaLexerKind.equals then
+ elsif parser_node^.operator = ElnaLexerKind.equals then
instruction := _elna_tac_instruction_create(ElnaTacOperator.equal)
- elsif token_kind = ElnaLexerKind.remainder then
+ elsif parser_node^.operator = ElnaLexerKind.remainder then
instruction := _elna_tac_instruction_create(ElnaTacOperator.remainder)
- elsif token_kind = ElnaLexerKind.division then
+ elsif parser_node^.operator = ElnaLexerKind.division then
instruction := _elna_tac_instruction_create(ElnaTacOperator.divide)
- elsif token_kind = ElnaLexerKind.less_than then
+ elsif parser_node^.operator = ElnaLexerKind.less_than then
instruction := _elna_tac_instruction_create(ElnaTacOperator.less_than)
- elsif token_kind = ElnaLexerKind.greater_than then
+ elsif parser_node^.operator = ElnaLexerKind.greater_than then
instruction := _elna_tac_instruction_create(ElnaTacOperator.greater_than)
- elsif token_kind = ElnaLexerKind.less_equal then
+ elsif parser_node^.operator = ElnaLexerKind.less_equal then
instruction := _elna_tac_instruction_create(ElnaTacOperator.less_or_equal)
- elsif token_kind = ElnaLexerKind.greater_equal then
+ elsif parser_node^.operator = ElnaLexerKind.greater_equal then
instruction := _elna_tac_instruction_create(ElnaTacOperator.greater_or_equal)
- elsif token_kind = ElnaLexerKind.not_equal then
+ elsif parser_node^.operator = ElnaLexerKind.not_equal then
instruction := _elna_tac_instruction_create(ElnaTacOperator.not_equal)
end;
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 6, 0);
- _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, 72, 0);
+ _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.pseudo, "$lhs", 4);
_elna_tac_instruction_set_operand(instruction, 3, lhs_type, lhs_value, lhs_length);
elna_instruction_list_concatenate(current_instruction, instruction);
@@ -2181,9 +2277,9 @@ end;
proc _elna_tac_call(parsed_call: Word, symbol_table: Word);
var
+ argument_count1: Word;
name_length: Word;
name: Word;
- argument_count: Word;
stack_offset: Word;
parsed_expression: ^ElnaTreeVariableExpression;
instruction: Word;
@@ -2196,12 +2292,12 @@ begin
parsed_expression := _call_get_name(parsed_call);
name := parsed_expression^.name;
name_length := parsed_expression^.length;
- argument_count := 0;
+ argument_count1 := 0;
first_instruction := 0;
.elna_tac_call_loop;
- parsed_expression := _call_get_argument(parsed_call, argument_count + 1);
+ parsed_expression := _call_get_argument(parsed_call, argument_count1 + 1);
if parsed_expression = 0 then
goto elna_tac_call_finalize
else
@@ -2219,11 +2315,11 @@ begin
end;
(* Save the argument on the stack. *)
- stack_offset := argument_count * 4;
+ stack_offset := argument_count1 * 4;
instruction := _elna_tac_instruction_create(ElnaTacOperator.store);
_elna_tac_instruction_set_operand(instruction, 1, operand_type, operand_value, operand_length);
- _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, 132 - stack_offset, 0);
+ _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, 56 - stack_offset, 0);
if first_instruction = 0 then
first_instruction := instruction
else
@@ -2231,21 +2327,21 @@ begin
end;
current_instruction := instruction;
- argument_count := argument_count + 1;
+ argument_count1 := argument_count1 + 1;
goto elna_tac_call_loop
end;
.elna_tac_call_finalize;
(* Load the argument from the stack. *)
- if argument_count <> 0 then
+ if argument_count1 <> 0 then
(* Decrement the argument counter. *)
- argument_count := argument_count - 1;
- stack_offset := argument_count * 4;
+ argument_count1 := argument_count1 - 1;
+ stack_offset := argument_count1 * 4;
- (* Calculate the stack offset: 132 - (4 * argument_counter) *)
+ (* Calculate the stack offset: 56 - (4 * argument_counter) *)
instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
- _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 11 + argument_count, 0);
- _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, 132 - stack_offset, 0);
+ _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 11 + argument_count1, 0);
+ _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, 56 - stack_offset, 0);
elna_instruction_list_concatenate(current_instruction, instruction);
current_instruction := instruction;
@@ -2263,43 +2359,38 @@ end;
proc elna_parser_goto_statement();
var
- token_kind: Word;
- label_name: Word;
- label_length: Word;
- result: ^ElnaTreeGotoStatement;
+ token_kind1: Word;
+ result1: ^ElnaTreeGotoStatement;
begin
_elna_lexer_skip_token();
- _elna_lexer_read_token(@token_kind);
-
- label_name := _elna_lexer_global_get_start();
- label_length := _elna_lexer_global_get_end() - label_name;
- _elna_lexer_skip_token();
+ _elna_lexer_read_token(@token_kind1);
- result := malloc(ElnaTreeGotoStatement_size());
+ result1 := malloc(ElnaTreeGotoStatement_size());
+ result1^.kind := ElnaTreeKind.goto_statement;
+ result1^.next := nil;
+ result1^.label := _elna_lexer_global_get_start();
+ result1^.length := _elna_lexer_global_get_end() - result1^.label;
- result^.kind := ElnaTreeKind.goto_statement;
- result^.next := nil;
- result^.label := label_name;
- result^.length := label_length;
+ _elna_lexer_skip_token();
- return result
+ return result1
end;
proc _elna_tac_goto_statement(parser_node: ^ElnaTreeGotoStatement);
var
- label_length: Word;
- label_with_dot: Word;
- instruction: Word;
+ label_length1: Word;
+ label_with_dot1: Word;
+ instruction1: Word;
begin
- label_length := parser_node^.length + 1;
- label_with_dot := malloc(label_length);
+ label_length1 := parser_node^.length + 1;
+ label_with_dot1 := malloc(label_length1);
- _store_byte('.', label_with_dot);
- memcpy(label_with_dot + 1, parser_node^.label, parser_node^.length);
+ _store_byte('.', label_with_dot1);
+ memcpy(label_with_dot1 + 1, parser_node^.label, parser_node^.length);
- instruction := _elna_tac_instruction_create(ElnaTacOperator.jump);
- _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.symbol, label_with_dot, label_length);
- return instruction
+ instruction1 := _elna_tac_instruction_create(ElnaTacOperator.jump);
+ _elna_tac_instruction_set_operand(instruction1, 1, ElnaTacOperand.symbol, label_with_dot1, label_length1);
+ return instruction1
end;
proc elna_parser_label_declaration();
@@ -2336,7 +2427,7 @@ var
members: Word;
members_length: Word;
token_type: Word;
- symbol_info: ^_type_info;
+ symbol_info: ^ElnaSymbolTypeInfo;
member_name: Word;
member_length: Word;
counter: Word;
@@ -2375,25 +2466,21 @@ end;
proc elna_parser_field_access_expression(aggregate: Word);
var
token_kind: Word;
- name_pointer: Word;
- name_length: Word;
result: ^ElnaTreeFieldAccessExpression;
begin
(* Skip dot. Read the enumeration value. *)
_elna_lexer_skip_token();
_elna_lexer_read_token(@token_kind);
- name_pointer := _elna_lexer_global_get_start();
- name_length := _elna_lexer_global_get_end() - name_pointer;
-
- _elna_lexer_skip_token();
result := malloc(ElnaTreeFieldAccessExpression_size());
result^.kind := ElnaTreeKind.field_access_expression;
- result^.aggregate := aggregate;
- result^.field := name_pointer;
- result^.length := name_length;
result^.type_decoration := nil;
+ result^.aggregate := aggregate;
+ result^.field := _elna_lexer_global_get_start();
+ result^.length := _elna_lexer_global_get_end() - result^.field;
+
+ _elna_lexer_skip_token();
return result
end;
@@ -2516,41 +2603,53 @@ begin
operand_length := 0;
first_instruction := _elna_tac_designator(parser_tree^.assignee, symbol_table, @is_address, @operand_type, @operand_value, @operand_length);
- current_instruction := _elna_tac_instruction_create(ElnaTacOperator.get_address);
- _elna_tac_instruction_set_operand(current_instruction, 1, ElnaTacOperand.temporary, 6, 0);
- _elna_tac_instruction_set_operand(current_instruction, 2, operand_type, operand_value, operand_length);
- first_instruction := elna_instruction_list_concatenate(first_instruction, current_instruction);
-
- (* Save the assignee address on the stack. *)
- current_instruction := _elna_tac_instruction_create(ElnaTacOperator.store);
- _elna_tac_instruction_set_operand(current_instruction, 1, ElnaTacOperand.temporary, 6, 0);
- _elna_tac_instruction_set_operand(current_instruction, 2, ElnaTacOperand.stack, 76, 0);
- elna_instruction_list_concatenate(first_instruction, current_instruction);
+ if operand_type = ElnaTacOperand.pseudo then
+ current_instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
+ _elna_tac_instruction_set_operand(current_instruction, 1, operand_type, operand_value, operand_length);
- (* Compile the assignment. *)
- operand_type := 0;
- operand_value := 0;
- operand_length := 0;
- instruction := _elna_tac_binary_expression(parser_tree^.assignment, symbol_table, @operand_type, @operand_value, @operand_length);
+ operand_type := 0;
+ operand_value := 0;
+ operand_length := 0;
+ instruction := _elna_tac_binary_expression(parser_tree^.assignment, symbol_table, @operand_type, @operand_value, @operand_length);
+ _elna_tac_instruction_set_operand(current_instruction, 2, operand_type, operand_value, operand_length);
- if instruction <> 0 then
- elna_instruction_list_concatenate(current_instruction, instruction);
- current_instruction := instruction
- end;
+ first_instruction := elna_instruction_list_concatenate(instruction, current_instruction)
+ else
+ current_instruction := _elna_tac_instruction_create(ElnaTacOperator.get_address);
+ _elna_tac_instruction_set_operand(current_instruction, 1, ElnaTacOperand.temporary, 6, 0);
+ _elna_tac_instruction_set_operand(current_instruction, 2, operand_type, operand_value, operand_length);
+ first_instruction := elna_instruction_list_concatenate(first_instruction, current_instruction);
+
+ (* Save the assignee address on the stack. *)
+ current_instruction := _elna_tac_instruction_create(ElnaTacOperator.store);
+ _elna_tac_instruction_set_operand(current_instruction, 1, ElnaTacOperand.temporary, 6, 0);
+ _elna_tac_instruction_set_operand(current_instruction, 2, ElnaTacOperand.stack, 0, 0);
+ elna_instruction_list_concatenate(first_instruction, current_instruction);
+
+ (* Compile the assignment. *)
+ operand_type := 0;
+ operand_value := 0;
+ operand_length := 0;
+ instruction := _elna_tac_binary_expression(parser_tree^.assignment, symbol_table, @operand_type, @operand_value, @operand_length);
- instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
- _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 7, 0);
- _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, 76, 0);
+ if instruction <> 0 then
+ elna_instruction_list_concatenate(current_instruction, instruction);
+ current_instruction := instruction
+ end;
- elna_instruction_list_concatenate(current_instruction, instruction);
- current_instruction := instruction;
+ instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
+ _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 7, 0);
+ _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, 0, 0);
- instruction := _elna_tac_instruction_create(ElnaTacOperator.store);
- _elna_tac_instruction_set_operand(instruction, 1, operand_type, operand_value, operand_length);
- _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.temporary, 7, 0);
+ elna_instruction_list_concatenate(current_instruction, instruction);
+ current_instruction := instruction;
- elna_instruction_list_concatenate(current_instruction, instruction);
+ instruction := _elna_tac_instruction_create(ElnaTacOperator.store);
+ _elna_tac_instruction_set_operand(instruction, 1, operand_type, operand_value, operand_length);
+ _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.temporary, 7, 0);
+ elna_instruction_list_concatenate(current_instruction, instruction);
+ end;
return first_instruction
end;
@@ -3214,7 +3313,7 @@ end;
proc elna_name_type_expression(parser_node: ^ElnaTreeNode);
var
named_type_expression: ^ElnaTreeNamedTypeExpression;
- type_symbol: ^_type_info;
+ type_symbol: ^ElnaSymbolTypeInfo;
result: Word;
begin
if parser_node^.kind = ElnaTreeKind.named_type_expression then
@@ -3243,14 +3342,14 @@ end;
proc _parameter_info_create(parameter_index: Word, parameter_type: Word);
var
offset: Word;
- result: ^_parameter_info;
+ result: ^ElnaSymbolParameterInfo;
begin
- result := malloc(_parameter_info_size());
- result^.kind := InfoKind.parameter_info;
+ result := malloc(ElnaSymbolParameterInfo_size());
+ result^.kind := ElnaSymbolInfoKind.parameter_info;
- (* Calculate the stack offset: 104 - (4 * parameter_counter) *)
+ (* Calculate the stack offset: 28 - (4 * parameter_counter) *)
offset := parameter_index * 4;
- result^.offset := 104 - offset;
+ result^.offset := 28 - offset;
result^.variable_type := parameter_type;
return result
@@ -3258,10 +3357,10 @@ end;
proc _type_info_create(type_representation: Word);
var
- result: ^_type_info;
+ result: ^ElnaSymbolTypeInfo;
begin
- result := malloc(_type_info_size());
- result^.kind := InfoKind.type_info;
+ result := malloc(ElnaSymbolTypeInfo_size());
+ result^.kind := ElnaSymbolInfoKind.type_info;
result^._type := type_representation;
return result
@@ -3274,10 +3373,10 @@ end;
*)
proc _temporary_info_create(temporary_index: Word, temporary_type: Word);
var
- result: ^_temporary_info;
+ result: ^ElnaSymbolTemporaryInfo;
begin
- result := malloc(_temporary_info_size());
- result^.kind := InfoKind.temporary_info;
+ result := malloc(ElnaSymbolTemporaryInfo_size());
+ result^.kind := ElnaSymbolInfoKind.temporary_info;
(* Calculate the stack offset: 4 * variable_counter. *)
result^.offset := temporary_index * 4;
@@ -3292,10 +3391,10 @@ end;
*)
proc _procedure_info_create(symbol_table: Word);
var
- result: ^_procedure_info;
+ result: ^ElnaSymbolProcedureInfo;
begin
- result := malloc(_procedure_info_size());
- result^.kind := InfoKind.procedure_info;
+ result := malloc(ElnaSymbolProcedureInfo_size());
+ result^.kind := ElnaSymbolInfoKind.procedure_info;
result^.symbol_table := symbol_table;
return result
@@ -3308,11 +3407,11 @@ end;
proc elna_name_procedure_parameter(parser_node: ^ElnaTreeVariableDeclaration, parameter_index: Word, symbol_table: Word);
var
info: Word;
- variable_type: Word;
+ variable_type1: Word;
begin
- variable_type := elna_name_type_expression(parser_node^._type);
+ variable_type1 := elna_name_type_expression(parser_node^._type);
- info := _parameter_info_create(parameter_index, variable_type);
+ info := _parameter_info_create(parameter_index, variable_type1);
_symbol_table_enter(symbol_table, parser_node^.name, parser_node^.length, info)
end;
@@ -3323,11 +3422,11 @@ end;
proc elna_name_procedure_temporary(parser_node: ^ElnaTreeVariableDeclaration, variable_index: Word, symbol_table: Word);
var
info: Word;
- variable_type: Word;
+ variable_type1: Word;
begin
- variable_type := elna_name_type_expression(parser_node^._type);
+ variable_type1 := elna_name_type_expression(parser_node^._type);
- info := _temporary_info_create(variable_index, variable_type);
+ info := _temporary_info_create(variable_index, variable_type1);
_symbol_table_enter(symbol_table, parser_node^.name, parser_node^.length, info)
end;
@@ -3430,7 +3529,7 @@ var
instruction: Word;
first_instruction: Word;
current_instruction: Word;
- symbol_info: ^_parameter_info;
+ symbol_info: ^ElnaSymbolParameterInfo;
begin
first_instruction := 0;
parameter_counter := 0;
@@ -3473,25 +3572,15 @@ end;
proc elna_rtl_procedure_declaration(tac_declaration: ^ElnaInstructionDeclaration);
var
- body: Word;
result: ^ElnaInstructionDeclaration;
- return_instruction: ^ElnaInstructionList;
begin
result := malloc(ElnaInstructionDeclaration_size());
- body := tac_declaration^.body;
- body := elna_rtl_instructions(body);
-
- return_instruction := elna_rtl_instruction_create(ElnaRtlOperator.allocate_stack);
- return_instruction^.next := body;
- body := return_instruction;
- return_instruction := elna_rtl_instruction_create(ElnaRtlOperator.ret);
- elna_instruction_list_concatenate(body, return_instruction);
result^.next := nil;
result^.name := tac_declaration^.name;
result^.length := tac_declaration^.length;
result^.stack := tac_declaration^.stack;
- result^.body := body;
+ result^.body := elna_rtl_instructions(tac_declaration^.body);
return result
end;
@@ -3500,7 +3589,7 @@ proc _elna_tac_procedure_declaration(parser_node: ElnaTreeProcedureDeclaration);
var
current_parameter: Word;
new_symbol_table: Word;
- symbol_info: ^_procedure_info;
+ symbol_info: ^ElnaSymbolProcedureInfo;
instruction: Word;
first_instruction: Word;
result: ^ElnaInstructionDeclaration;
@@ -3621,14 +3710,14 @@ var
current_procedure: ^ElnaInstructionList;
first_procedure: Word;
begin
- first_procedure := 0;
+ first_procedure := nil;
.elna_tac_procedures_loop;
if parser_node = 0 then
goto elna_tac_procedures_end
end;
result := _elna_tac_procedure_declaration(parser_node);
- if first_procedure = 0 then
+ if first_procedure = nil then
first_procedure := result
else
current_procedure^.next := result
@@ -3749,7 +3838,7 @@ var
token_kind: Word;
name: Word;
name_length: Word;
- variable_type: Word;
+ variable_type1: Word;
result: ^ElnaTreeVariableDeclaration;
begin
_elna_lexer_read_token(@token_kind);
@@ -3762,14 +3851,14 @@ begin
_elna_lexer_read_token(@token_kind);
_elna_lexer_skip_token();
- variable_type := elna_parser_type_expression();
+ variable_type1 := elna_parser_type_expression();
result := malloc(ElnaTreeVariableDeclaration_size());
result^.kind := ElnaTreeKind.variable_declaration;
result^.next := nil;
result^.name := name;
result^.length := name_length;
- result^._type := variable_type;
+ result^._type := variable_type1;
return result
end;
@@ -3838,7 +3927,7 @@ proc _elna_tac_type_part(parser_node: ^ElnaTreeDeclaration);
var
result: Word;
first_result: Word;
- symbol: ^_type_info;
+ symbol: ^ElnaSymbolTypeInfo;
info_type: ^ElnaType;
type_kind: Word;
current_result: ^ElnaInstructionList;
@@ -3944,11 +4033,12 @@ begin
return first_variable
end;
-proc elna_parser_module_declaration();
+proc elna_parser_module_declaration(error_list: ^ElnaErrorList);
var
parser_node: Word;
result: ^ElnaTreeModuleDeclaration;
token_kind: Word;
+ parser_error: ^ElnaError;
begin
result := malloc(ElnaTreeModuleDeclaration_size());
result^.kind := ElnaTreeKind.module_declaration;
@@ -3956,14 +4046,22 @@ begin
(* Skip "program;". *)
_skip_empty_lines();
_elna_lexer_read_token(@token_kind);
- _elna_lexer_skip_token();
- _elna_lexer_read_token(@token_kind);
- _elna_lexer_skip_token();
- result^.types := elna_parser_type_part();
- result^.globals := elna_parser_var_part();
- result^.procedures := elna_parser_procedures();
+ if token_kind <> ElnaLexerKind._program then
+ parser_error := malloc(ElnaError_size());
+ parser_error^.next := nil;
+
+ error_list^.first := parser_error;
+ error_list^.last := parser_error
+ else
+ _elna_lexer_skip_token();
+ _elna_lexer_read_token(@token_kind);
+ _elna_lexer_skip_token();
+ result^.types := elna_parser_type_part();
+ result^.globals := elna_parser_var_part();
+ result^.procedures := elna_parser_procedures()
+ end;
return result
end;
@@ -4108,7 +4206,7 @@ end;
proc elna_type_character_literal(parser_node: ^ElnaTreeCharacterLiteral);
var
- symbol_info: ^_type_info;
+ symbol_info: ^ElnaSymbolTypeInfo;
begin
symbol_info := _symbol_table_lookup(@symbol_table_global, "Word", 4);
parser_node^.type_decoration := symbol_info^._type
@@ -4116,7 +4214,7 @@ end;
proc elna_type_integer_literal(parser_node: ^ElnaTreeIntegerLiteral);
var
- symbol_info: ^_type_info;
+ symbol_info: ^ElnaSymbolTypeInfo;
begin
symbol_info := _symbol_table_lookup(@symbol_table_global, "Word", 4);
parser_node^.type_decoration := symbol_info^._type
@@ -4124,7 +4222,7 @@ end;
proc elna_type_string_literal(parser_node: ^ElnaTreeStringLiteral);
var
- symbol_info: ^_type_info;
+ symbol_info: ^ElnaSymbolTypeInfo;
begin
symbol_info := _symbol_table_lookup(@symbol_table_global, "Word", 4);
parser_node^.type_decoration := symbol_info^._type
@@ -4132,7 +4230,7 @@ end;
proc elna_type_boolean_literal(parser_node: ^ElnaTreeBooleanLiteral);
var
- symbol_info: ^_type_info;
+ symbol_info: ^ElnaSymbolTypeInfo;
begin
symbol_info := _symbol_table_lookup(@symbol_table_global, "Bool", 4);
parser_node^.type_decoration := symbol_info^._type
@@ -4140,7 +4238,7 @@ end;
proc elna_type_nil_literal(parser_node: ^ElnaTreeNilLiteral);
var
- symbol_info: ^_type_info;
+ symbol_info: ^ElnaSymbolTypeInfo;
begin
symbol_info := _symbol_table_lookup(@symbol_table_global, "Pointer", 7);
parser_node^.type_decoration := symbol_info^._type
@@ -4148,9 +4246,9 @@ end;
proc elna_type_variable_expression(parser_node: ^ElnaTreeVariableExpression, symbol_table: Word);
var
- variable_info: ^_info;
- parameter_info: ^_parameter_info;
- temporary_info: ^_temporary_info;
+ variable_info: ^ElnaSymbolInfo;
+ parameter_info: ^ElnaSymbolParameterInfo;
+ temporary_info: ^ElnaSymbolTemporaryInfo;
begin
variable_info := _symbol_table_lookup(symbol_table, parser_node^.name, parser_node^.length);
@@ -4158,10 +4256,10 @@ begin
variable_info := _symbol_table_lookup(@symbol_table_global, parser_node^.name, parser_node^.length)
end;
- if variable_info^.kind = InfoKind.parameter_info then
+ if variable_info^.kind = ElnaSymbolInfoKind.parameter_info then
parameter_info := variable_info;
parser_node^.type_decoration := parameter_info^.variable_type
- elsif variable_info^.kind = InfoKind.temporary_info then
+ elsif variable_info^.kind = ElnaSymbolInfoKind.temporary_info then
temporary_info := variable_info;
parser_node^.type_decoration := temporary_info^.variable_type
end
@@ -4207,8 +4305,8 @@ proc elna_type_field_access_expression(parser_node: ^ElnaTreeFieldAccessExpressi
var
variable_expression: ^ElnaTreeVariableExpression;
base_type: Word;
- type_kind: ^_type_info;
- symbol_info: ^_info;
+ type_kind: ^ElnaSymbolTypeInfo;
+ symbol_info: ^ElnaSymbolInfo;
aggregate_type: ^ElnaTypeRecord;
field_count: Word;
current_field: ^ElnaTypeField;
@@ -4222,7 +4320,7 @@ begin
if symbol_info <> nil then
type_kind := symbol_info;
- if symbol_info^.kind = InfoKind.type_info then
+ if symbol_info^.kind = ElnaSymbolInfoKind.type_info then
base_type := type_kind^._type
end
end
@@ -4238,11 +4336,6 @@ begin
.elna_type_field_access_expression_field;
if string_compare(parser_node^.field, parser_node^.length, current_field^.name, current_field^.length) = 0 then
- (* Debug. Error stream output.
- _syscall(2, name_pointer, name_length, 0, 0, 0, 64);
- printf("# if %.*s\n\0", name_length, name_pointer);
- fflush(0) *)
-
field_count := field_count - 1;
current_field := current_field + ElnaTypeField_size();
goto elna_type_field_access_expression_field
@@ -4298,7 +4391,7 @@ end;
proc elna_type_procedure_declaration(parser_node: ^ElnaTreeProcedureDeclaration);
var
- procedure_info: ^_procedure_info;
+ procedure_info: ^ElnaSymbolProcedureInfo;
symbol_table: Word;
begin
procedure_info := _symbol_table_lookup(@symbol_table_global, parser_node^.name, parser_node^.length);
@@ -4365,24 +4458,26 @@ var
parser_node: Word;
tac: Word;
rtl: Word;
+ error_list: ^ElnaErrorList;
+ compiled: Word;
begin
- parser_node := elna_parser_module_declaration();
- elna_name_module_declaration(parser_node);
- elna_type_module_declaration(parser_node);
- tac := _elna_tac_module_declaration(parser_node);
- rtl := elna_rtl_module_declaration(tac);
- _elna_writer_module(rtl)
-end;
+ error_list := malloc(ElnaErrorList_size());
+ error_list^.first := nil;
+ error_list^.last := nil;
-(**
- * Terminates the program. a0 contains the return code.
- *
- * Parameters:
- * a0 - Status code.
- *)
-proc _exit(status: Word);
-begin
- _syscall(status, 0, 0, 0, 0, 0, 93)
+ parser_node := elna_parser_module_declaration(error_list);
+ compiled := error_list^.first = nil;
+
+ if compiled then
+ elna_name_module_declaration(parser_node);
+ elna_type_module_declaration(parser_node);
+ tac := _elna_tac_module_declaration(parser_node);
+ rtl := elna_rtl_module_declaration(tac);
+ elna_alloc_module(rtl);
+ _elna_writer_module(rtl);
+ end;
+
+ return compiled
end;
(**
@@ -4502,7 +4597,7 @@ end;
proc _symbol_table_build();
var
- current_info: ^_type_info;
+ current_info: ^ElnaSymbolTypeInfo;
current_type: ^ElnaType;
begin
(* Set the table length to 0. *)
@@ -5312,7 +5407,6 @@ begin
compiler_strings_position := @compiler_strings;
source_code := malloc(495616);
symbol_table_store := malloc(4194304);
- temporary_variable_counter := 0
end;
(*
@@ -5332,12 +5426,14 @@ begin
.start_read;
(* Second argument is buffer size. Modifying update the source_code definition. *)
- last_read := _read_file(offset, 409600);
+ last_read := read(0, offset, 409600);
if last_read > 0 then
offset := offset + last_read;
goto start_read
end;
- _compile();
-
- _exit(0)
+ if _compile() then
+ exit(0)
+ else
+ exit(4)
+ end;
end;