summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Rakefile59
-rw-r--r--boot/stage10/cl.elna (renamed from boot/stage10.elna)0
-rw-r--r--boot/stage11/cl.elna (renamed from boot/stage11.elna)0
-rw-r--r--boot/stage12/cl.elna (renamed from boot/stage12.elna)0
-rw-r--r--boot/stage13/cl.elna (renamed from boot/stage13.elna)0
-rw-r--r--boot/stage14/cl.elna (renamed from boot/stage14.elna)0
-rw-r--r--boot/stage15/cl.elna (renamed from boot/stage15.elna)7
-rw-r--r--boot/stage16/cl.elna (renamed from boot/stage16.elna)915
-rw-r--r--boot/stage16/linker.arg0
-rw-r--r--boot/stage2/cl.elna (renamed from boot/stage2.elna)0
-rw-r--r--boot/stage3/cl.elna (renamed from boot/stage3.elna)0
-rw-r--r--boot/stage4/cl.elna (renamed from boot/stage4.elna)0
-rw-r--r--boot/stage5/cl.elna (renamed from boot/stage5.elna)0
-rw-r--r--boot/stage6/cl.elna (renamed from boot/stage6.elna)0
-rw-r--r--boot/stage7/cl.elna (renamed from boot/stage7.elna)0
-rw-r--r--boot/stage8/cl.elna (renamed from boot/stage8.elna)0
-rw-r--r--boot/stage9/cl.elna (renamed from boot/stage9.elna)0
-rw-r--r--boot/symbol.s297
18 files changed, 529 insertions, 749 deletions
diff --git a/Rakefile b/Rakefile
index ec3ae04..54c3bd3 100644
--- a/Rakefile
+++ b/Rakefile
@@ -4,19 +4,18 @@
# frozen_string_literal: true
require 'open3'
+require 'pathname'
require 'rake/clean'
-STAGES = Dir.glob('boot/stage*.elna')
- .collect { |stage| File.basename stage, '.elna' }
+STAGES = Dir.glob('boot/stage*')
+ .collect { |stage| File.basename stage }
.sort { |a, b| a.delete_prefix('stage').to_i <=> b.delete_prefix('stage').to_i }
+ .drop(1) # First assembly stage does not count.
CLEAN.include 'build/boot', 'build/valid'
-directory 'build/boot'
-directory 'build/valid'
-
-def compile(input, output)
- sh ENV.fetch('CC', 'gcc'), '-nostdlib', '-fpie', '-g', '-o', output, input
+def compile(*arguments)
+ sh(ENV.fetch('CC', 'gcc'), '-fpie', '-g', *arguments)
end
def run(exe)
@@ -26,9 +25,9 @@ end
task default: :boot
desc 'Final stage'
-task boot: "build/valid/#{STAGES.last}"
-task boot: "build/valid/#{STAGES.last}.s"
-task boot: "boot/#{STAGES.last}.elna" do |t|
+task boot: "build/valid/#{STAGES.last}/cl"
+task boot: "build/valid/#{STAGES.last}/cl.s"
+task boot: "boot/#{STAGES.last}/cl.elna" do |t|
groupped = t.prerequisites.group_by { |stage| File.extname stage }.transform_values(&:first)
exe = groupped['']
expected = groupped['.s']
@@ -81,16 +80,33 @@ task :convert do
end
end
-rule /^build\/[[:alpha:]]+\/stage[[:digit:]]+$/ => ->(match) {
- "#{match}.s"
+rule /^build\/[[:alpha:]]+\/stage[[:digit:]]+\/cl$/ => ->(match) {
+ "#{match}.o"
+} do |t|
+ arguments_path = Pathname.new('boot') + Pathname.new(t.name).dirname.basename + 'linker.arg'
+ if arguments_path.exist?
+ arguments1 = ['--dynamic-linker', '/lib32/ld-linux-riscv32-ilp32d.so.1', '/usr/lib/crt1.o', '/usr/lib/crti.o', '-lc']
+ arguments2 = ['/usr/lib/crtn.o']
+ else
+ arguments1 = arguments2 = []
+ end
+
+ sh(ENV.fetch('LD', 'ld'), '-o', t.name, *arguments1, *t.prerequisites, *arguments2)
+end
+
+rule /^build\/[[:alpha:]]+\/stage[[:digit:]]+\/cl.o$/ => ->(match) {
+ match.ext('.s')
} do |t|
- compile(*t.prerequisites, t.name)
+ compile('-c', '-o', t.name, *t.prerequisites)
end
STAGES.each do |stage|
previous = stage.delete_prefix('stage').to_i.pred
- file "build/valid/#{stage}.s" => ["build/boot/#{stage}", "boot/#{stage}.elna"] do |t|
+ directory "build/valid/#{stage}"
+ directory "build/boot/#{stage}"
+
+ file "build/valid/#{stage}/cl.s" => ["build/boot/#{stage}/cl", "boot/#{stage}/cl.elna", "build/valid/#{stage}"] do |t|
exe, source = t.prerequisites
cat_arguments = ['cat', source]
@@ -99,7 +115,7 @@ STAGES.each do |stage|
IO.copy_stream last_stdout, t.name
end
- file "build/boot/#{stage}.s" => ["build/valid/stage#{previous}", "boot/#{stage}.elna"] do |t|
+ file "build/boot/#{stage}/cl.s" => ["build/valid/stage#{previous}/cl", "boot/#{stage}/cl.elna", "build/boot/#{stage}"] do |t|
exe, source = t.prerequisites
cat_arguments = ['cat', source]
@@ -113,7 +129,14 @@ end
# Stage 1.
#
-file 'build/valid/stage1.s' => ['build/boot/stage1', 'boot/stage1.s', 'build/valid'] do |t|
+directory 'build/valid/stage1'
+directory 'build/boot/stage1'
+
+file 'build/valid/stage1/cl' => ['build/valid/stage1.s'] do |t|
+ compile('-nostdlib', '-o', t.name, *t.prerequisites)
+end
+
+file 'build/valid/stage1.s' => ['build/boot/stage1/cl', 'boot/stage1.s', 'build/valid/stage1'] do |t|
source, exe, = t.prerequisites.partition { |prerequisite| prerequisite.end_with? '.s' }
cat_arguments = ['cat', *source]
@@ -122,8 +145,8 @@ file 'build/valid/stage1.s' => ['build/boot/stage1', 'boot/stage1.s', 'build/val
IO.copy_stream last_stdout, t.name
end
-file 'build/boot/stage1' => ['build/boot', 'boot/stage1.s'] do |t|
+file 'build/boot/stage1/cl' => ['build/boot/stage1', 'boot/stage1.s'] do |t|
source = t.prerequisites.select { |prerequisite| prerequisite.end_with? '.s' }
- compile(*source, t.name)
+ compile('-nostdlib', '-o', t.name, *source)
end
diff --git a/boot/stage10.elna b/boot/stage10/cl.elna
index cc99d9e..cc99d9e 100644
--- a/boot/stage10.elna
+++ b/boot/stage10/cl.elna
diff --git a/boot/stage11.elna b/boot/stage11/cl.elna
index 74447d6..74447d6 100644
--- a/boot/stage11.elna
+++ b/boot/stage11/cl.elna
diff --git a/boot/stage12.elna b/boot/stage12/cl.elna
index 1cf4969..1cf4969 100644
--- a/boot/stage12.elna
+++ b/boot/stage12/cl.elna
diff --git a/boot/stage13.elna b/boot/stage13/cl.elna
index f4fa817..f4fa817 100644
--- a/boot/stage13.elna
+++ b/boot/stage13/cl.elna
diff --git a/boot/stage14.elna b/boot/stage14/cl.elna
index 5566518..5566518 100644
--- a/boot/stage14.elna
+++ b/boot/stage14/cl.elna
diff --git a/boot/stage15.elna b/boot/stage15/cl.elna
index 987d655..3f2dde2 100644
--- a/boot/stage15.elna
+++ b/boot/stage15/cl.elna
@@ -6,6 +6,11 @@
(* Stage 15 compiler. *)
+(* - Procedure names are not required anymore to start with an underscore. *)
+(* - Record declarations are supported. Access is done with generated procedures,
+ record_name_get_field and record_name_set_field. Record size can be queried with
+ record_name_size(). *)
+
type
ElnaLexerAction = (none, accumulate, skip, single, eof, finalize, composite, key_id, integer, delimited);
@@ -1258,7 +1263,7 @@ var
current_byte: Word;
current_part: Word;
begin
- _write_z(".globl _start\n\n\0");
+ _write_z(".globl _start, main\n\n\0");
_write_z(".section .data\n\0");
current_part := _elna_tac_module_get_data(pair);
diff --git a/boot/stage16.elna b/boot/stage16/cl.elna
index cd56cc2..f76edae 100644
--- a/boot/stage16.elna
+++ b/boot/stage16/cl.elna
@@ -4,7 +4,7 @@
* obtain one at https://mozilla.org/MPL/2.0/.
*)
-(* Stage 15 compiler. *)
+(* Stage 16 compiler. *)
type
_elna_tac_declaration = record
@@ -13,6 +13,12 @@ type
length: Word;
body: Word
end;
+ elna_rtl_declaration = record
+ next: Word;
+ name: Word;
+ length: Word;
+ body: Word
+ end;
_node = record
kind: Word
end;
@@ -88,6 +94,10 @@ type
data: Word;
code: Word
end;
+ elna_rtl_module = record
+ data: Word;
+ code: Word
+ end;
_module_declaration = record
kind: Word;
types: Word;
@@ -136,6 +146,25 @@ type
name: Word;
length: Word
end;
+ _info = record
+ kind: Word
+ end;
+ _type_info = record
+ kind: Word;
+ _type: Word
+ end;
+ _parameter_info = record
+ kind: Word;
+ offset: Word
+ end;
+ _temporary_info = record
+ kind: Word;
+ offset: Word
+ end;
+ _procedure_info = record
+ kind: Word;
+ symbol_table: Word
+ end;
(**
* Conditional statements is a list of pairs: condition and statements.
@@ -350,8 +379,37 @@ type
start,
ret
);
+ ElnaRtlOperator = (
+ load_immediate,
+ load_address,
+ add,
+ add_immediate,
+ load_word,
+ store_word,
+ jal,
+ move,
+ sub,
+ div,
+ rem,
+ mul,
+ _xor,
+ _or,
+ and,
+ seqz,
+ snez,
+ slt,
+ xor_immediate,
+ neg,
+ not,
+ jump,
+ beqz,
+ label,
+ start,
+ ret
+ );
ElnaTacOperand = (register, immediate, symbol, offset);
- ElnaTacRegister = (
+ ElnaRtlOperand = (register, immediate, symbol, offset);
+ ElnaRtlRegister = (
zero,
ra,
sp,
@@ -397,9 +455,6 @@ var
label_counter: Word;
symbol_table_store: Word;
- (* Points to a segment of free memory. *)
- memory_free_pointer: Word;
-
(**
* Calculates and returns the string token length between quotes, including the
* escaping slash characters.
@@ -476,15 +531,6 @@ proc _read_file(buffer: Word, size: Word);
end;
(**
- * MAP_ANONYMOUS is 32.
- * PROT_READ | PORT_WRITE is (1 | 2).
- * MAP_ANONYMOUS | MAP_PRIVATE is (32 | 2)
- *)
-proc _mmap(length: Word);
- return _syscall(0, length, 1 or 2, 32 or 2, -1, 0, 222)
-end;
-
-(**
* Writes to the standard output.
*
* Parameters:
@@ -537,7 +583,7 @@ begin
end;
result := @result + 11;
result := result - local_buffer;
- _memcpy(output_buffer, local_buffer + 1, result);
+ memcpy(output_buffer, local_buffer + 1, result);
return result
end;
@@ -591,34 +637,6 @@ begin
end;
(**
- * Detects if a0 is an uppercase character. Sets a0 to 1 if so, otherwise to 0.
- *)
-proc _is_upper(character: Word);
-var
- lhs: Word;
- rhs: Word;
-begin
- lhs := character >= 'A';
- rhs := character <= 'Z';
-
- return lhs & rhs
-end;
-
-(**
- * Detects if a0 is an lowercase character. Sets a0 to 1 if so, otherwise to 0.
- *)
-proc _is_lower(character: Word);
-var
- lhs: Word;
- rhs: Word;
-begin
- lhs := character >= 'a';
- rhs := character <= 'z';
-
- return lhs & rhs
-end;
-
-(**
* Detects if the passed character is a 7-bit alpha character or an underscore.
*
* Paramters:
@@ -628,109 +646,15 @@ end;
*)
proc _is_alpha(character: Word);
var
- is_upper_result: Word;
- is_lower_result: Word;
- is_alpha_result: Word;
is_underscore: Word;
begin
- is_upper_result := _is_upper(character);
- is_lower_result := _is_lower(character);
is_underscore := character = '_';
- is_alpha_result := is_lower_result or is_upper_result;
- return is_alpha_result or is_underscore
-end;
-
-(**
- * Detects whether the passed character is a digit (a value between 0 and 9).
- *
- * Parameters:
- * character - Exemined value.
- *
- * Sets a0 to 1 if it is a digit, to 0 otherwise.
- *)
-proc _is_digit(character: Word);
-var
- lhs: Word;
- rhs: Word;
-begin
- lhs := character >= '0';
- rhs := character <= '9';
-
- return lhs & rhs
+ return isalpha(character) or is_underscore
end;
proc _is_alnum(character: Word);
-var
- lhs: Word;
- rhs: Word;
-begin
- lhs := _is_alpha(character);
- rhs := _is_digit(character);
-
- return lhs or rhs
-end;
-
-(**
- * Parameters:
- * lhs - First pointer.
- * rhs - Second pointer.
- * count - The length to compare.
- *
- * Returns 0 if memory regions are equal.
- *)
-proc _memcmp(lhs: Word, rhs: Word, count: Word);
-var
- lhs_byte: Word;
- rhs_byte: Word;
- result: Word;
-begin
- result := 0;
-
- .memcmp_loop;
- if count <> 0 then
- lhs_byte := _load_byte(lhs);
- rhs_byte := _load_byte(rhs);
- result := lhs_byte - rhs_byte;
-
- lhs := lhs + 1;
- rhs := rhs + 1;
- count := count - 1;
-
- if result = 0 then
- goto memcmp_loop
- end
- end;
-
- return result
-end;
-
-(**
- * Copies memory.
- *
- * Parameters:
- * destination - Destination.
- * source - Source.
- * count - Size.
- *
- * Returns the destination.
- *)
-proc _memcpy(destination: Word, source: Word, count: Word);
-var
- current_byte: Word;
-begin
- .memcpy_loop;
- if count <> 0 then
- current_byte := _load_byte(source);
- _store_byte(current_byte, destination);
-
- destination := destination + 1;
- source := source + 1;
- count := count - 1;
- goto memcpy_loop
- end;
-
- return destination
+ return _is_alpha(character) or isdigit(character)
end;
proc _elna_tac_instruction_size();
@@ -814,10 +738,8 @@ end;
proc _elna_tac_instruction_create(kind: Word);
var
result: Word;
- instruction_size: Word;
begin
- instruction_size := _elna_tac_instruction_size();
- result := _allocate(instruction_size);
+ result := malloc(_elna_tac_instruction_size());
_elna_tac_instruction_set_kind(result, kind);
_elna_tac_instruction_set_next(result, 0);
@@ -825,13 +747,95 @@ begin
return result
end;
+proc elna_rtl_instruction_size();
+ return 44
+end;
+
+proc elna_rtl_instruction_get_kind(this: Word);
+ return this^
+end;
+
+proc elna_rtl_instruction_get_next(this: Word);
+begin
+ this := this + 4;
+ return this^
+end;
+
+proc elna_rtl_instruction_set_next(this: Word, value: Word);
+begin
+ this := this + 4;
+ this^ := value
+end;
+
+proc elna_rtl_instruction_set_kind(this: Word, value: Word);
+begin
+ this^ := value
+end;
+
+proc elna_rtl_instruction_get_operand_type(this: Word, n: Word);
+begin
+ n := n - 1;
+ n := n * 12;
+ this := this + 8;
+ this := this + n;
+
+ return this^
+end;
+
+proc elna_rtl_instruction_get_operand_value(this: Word, n: Word);
+begin
+ n := n - 1;
+ n := n * 12;
+ this := this + 8;
+ this := this + n;
+
+ this := this + 4;
+ return this^
+end;
+
+proc elna_rtl_instruction_get_operand_length(this: Word, n: Word);
+begin
+ n := n - 1;
+ n := n * 12;
+ this := this + 8;
+ this := this + n;
+
+ this := this + 8;
+ return this^
+end;
+
+proc elna_rtl_instruction_set_operand(this: Word, n: Word, operand_type: Word, operand_value: Word, operand_length: Word);
+begin
+ n := n - 1;
+ n := n * 12;
+ this := this + 8;
+ this := this + n;
+
+ this^ := operand_type;
+ this := this + 4;
+ this^ := operand_value;
+ this := this + 4;
+ this^ := operand_length
+end;
+
+proc elna_rtl_instruction(tac_instruction: Word);
+var
+ result: Word;
+ instruction_size: Word;
+begin
+ instruction_size := elna_rtl_instruction_size();
+ result := malloc(instruction_size);
+
+ memcpy(result, tac_instruction, instruction_size);
+
+ return result
+end;
+
proc _elna_tac_module_create(data: Word, code: Word);
var
result: Word;
- result_size: Word;
begin
- result_size := _elna_tac_module_size();
- result := _allocate(result_size);
+ result := malloc(_elna_tac_module_size());
_elna_tac_module_set_data(result, data);
_elna_tac_module_set_code(result, code);
@@ -1139,79 +1143,79 @@ proc _elna_writer_instruction_name(instruction_kind: Word);
var
argument_count: Word;
begin
- if instruction_kind = ElnaTacOperator.load_immediate then
+ if instruction_kind = ElnaRtlOperator.load_immediate then
argument_count := 2;
_write_s("\tli", 3)
- elsif instruction_kind = ElnaTacOperator.load_address then
+ elsif instruction_kind = ElnaRtlOperator.load_address then
argument_count := 2;
_write_s("\tla", 3)
- elsif instruction_kind = ElnaTacOperator.add then
+ elsif instruction_kind = ElnaRtlOperator.add then
argument_count := 3;
_write_s("\tadd", 4)
- elsif instruction_kind = ElnaTacOperator.add_immediate then
+ elsif instruction_kind = ElnaRtlOperator.add_immediate then
argument_count := 3;
_write_s("\taddi", 5)
- elsif instruction_kind = ElnaTacOperator.load_word then
+ elsif instruction_kind = ElnaRtlOperator.load_word then
argument_count := 2;
_write_s("\tlw", 3)
- elsif instruction_kind = ElnaTacOperator.store_word then
+ elsif instruction_kind = ElnaRtlOperator.store_word then
argument_count := 2;
_write_s("\tsw", 3)
- elsif instruction_kind = ElnaTacOperator.jal then
+ elsif instruction_kind = ElnaRtlOperator.jal then
argument_count := 1;
_write_s("\tcall", 5)
- elsif instruction_kind = ElnaTacOperator.move then
+ elsif instruction_kind = ElnaRtlOperator.move then
argument_count := 2;
_write_s("\tmv", 3)
- elsif instruction_kind = ElnaTacOperator.sub then
+ elsif instruction_kind = ElnaRtlOperator.sub then
argument_count := 3;
_write_s("\tsub", 4)
- elsif instruction_kind = ElnaTacOperator.mul then
+ elsif instruction_kind = ElnaRtlOperator.mul then
argument_count := 3;
_write_s("\tmul", 4)
- elsif instruction_kind = ElnaTacOperator.div then
+ elsif instruction_kind = ElnaRtlOperator.div then
argument_count := 3;
_write_s("\tdiv", 4)
- elsif instruction_kind = ElnaTacOperator.rem then
+ elsif instruction_kind = ElnaRtlOperator.rem then
argument_count := 3;
_write_s("\trem", 4)
- elsif instruction_kind = ElnaTacOperator._xor then
+ elsif instruction_kind = ElnaRtlOperator._xor then
argument_count := 3;
_write_s("\txor", 4)
- elsif instruction_kind = ElnaTacOperator.xor_immediate then
+ elsif instruction_kind = ElnaRtlOperator.xor_immediate then
argument_count := 3;
_write_s("\txori", 5)
- elsif instruction_kind = ElnaTacOperator._or then
+ elsif instruction_kind = ElnaRtlOperator._or then
argument_count := 3;
_write_s("\tor", 3)
- elsif instruction_kind = ElnaTacOperator.and then
+ elsif instruction_kind = ElnaRtlOperator.and then
argument_count := 3;
_write_s("\tand", 4)
- elsif instruction_kind = ElnaTacOperator.seqz then
+ elsif instruction_kind = ElnaRtlOperator.seqz then
argument_count := 2;
_write_s("\tseqz", 5)
- elsif instruction_kind = ElnaTacOperator.snez then
+ elsif instruction_kind = ElnaRtlOperator.snez then
argument_count := 2;
_write_s("\tsnez", 5)
- elsif instruction_kind = ElnaTacOperator.slt then
+ elsif instruction_kind = ElnaRtlOperator.slt then
argument_count := 3;
_write_s("\tslt", 4)
- elsif instruction_kind = ElnaTacOperator.neg then
+ elsif instruction_kind = ElnaRtlOperator.neg then
argument_count := 2;
_write_s("\tneg", 4)
- elsif instruction_kind = ElnaTacOperator.not then
+ elsif instruction_kind = ElnaRtlOperator.not then
argument_count := 2;
_write_s("\tnot", 4)
- elsif instruction_kind = ElnaTacOperator.jump then
+ elsif instruction_kind = ElnaRtlOperator.jump then
argument_count := 1;
_write_s("\tj", 2)
- elsif instruction_kind = ElnaTacOperator.beqz then
+ elsif instruction_kind = ElnaRtlOperator.beqz then
argument_count := 2;
_write_s("\tbeqz", 5)
- elsif instruction_kind = ElnaTacOperator.start then
+ elsif instruction_kind = ElnaRtlOperator.start then
argument_count := 0;
_write_z("\taddi sp, sp, -128\n\tsw ra, 124(sp)\n\tsw s0, 120(sp)\n\taddi s0, sp, 128\0")
- elsif instruction_kind = ElnaTacOperator.ret then
+ elsif instruction_kind = ElnaRtlOperator.ret then
argument_count := 0;
_write_z("\tlw ra, 124(sp)\n\tlw s0, 120(sp)\n\taddi sp, sp, 128\0")
end;
@@ -1230,25 +1234,25 @@ var
operand_length: Word;
operand_type: Word;
begin
- operand_type := _elna_tac_instruction_get_operand_type(instruction, n);
- operand_value := _elna_tac_instruction_get_operand_value(instruction, n);
- operand_length := _elna_tac_instruction_get_operand_length(instruction, n);
+ operand_type := elna_rtl_instruction_get_operand_type(instruction, n);
+ operand_value := elna_rtl_instruction_get_operand_value(instruction, n);
+ operand_length := elna_rtl_instruction_get_operand_length(instruction, n);
_write_c(' ');
- if operand_type = ElnaTacOperand.register then
+ if operand_type = ElnaRtlOperand.register then
_elna_writer_register(operand_value)
- elsif operand_type = ElnaTacOperand.offset then
+ elsif operand_type = ElnaRtlOperand.offset then
_write_i(operand_length);
_write_c('(');
_elna_writer_register(operand_value);
_write_c(')')
- elsif operand_type = ElnaTacOperand.symbol then
+ elsif operand_type = ElnaRtlOperand.symbol then
if operand_length = 0 then
_write_label(operand_value, 0)
else
_write_s(operand_value, operand_length)
end
- elsif operand_length = 0 then (* ElnaTacOperand.immediate *)
+ elsif operand_length = 0 then (* ElnaRtlOperand.immediate *)
_write_i(operand_value)
else
_write_s(operand_value, operand_length)
@@ -1263,12 +1267,12 @@ var
operand_value: Word;
operand_length: Word;
begin
- instruction_kind := _elna_tac_instruction_get_kind(instruction);
+ instruction_kind := elna_rtl_instruction_get_kind(instruction);
- if instruction_kind = ElnaTacOperator.label then
+ if instruction_kind = ElnaRtlOperator.label then
argument_count := 0;
- operand_value := _elna_tac_instruction_get_operand_value(instruction, 1);
- operand_length := _elna_tac_instruction_get_operand_length(instruction, 1);
+ 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(':')
else
@@ -1289,12 +1293,41 @@ begin
_write_c('\n')
end;
+proc elna_rtl_instructions(instruction: Word);
+var
+ current_copy: Word;
+ next_copy: Word;
+ first_copy: Word;
+begin
+ if instruction <> 0 then
+ first_copy := elna_rtl_instruction(instruction);
+ instruction := _elna_tac_instruction_get_next(instruction)
+ else
+ first_copy := 0;
+ end;
+ current_copy := first_copy;
+
+ .elna_rtl_instructions_start;
+
+ if instruction <> 0 then
+ next_copy := elna_rtl_instruction(instruction);
+
+ instruction := _elna_tac_instruction_get_next(instruction);
+ elna_rtl_instruction_set_next(current_copy, next_copy);
+ current_copy := next_copy;
+ goto elna_rtl_instructions_start
+ end;
+
+ return first_copy
+end;
+
proc _elna_writer_instructions(instruction: Word);
begin
+ .elna_writer_instructions_start;
if instruction <> 0 then
_elna_writer_instruction(instruction);
- instruction := _elna_tac_instruction_get_next(instruction);
- _elna_writer_instructions(instruction)
+ instruction := elna_rtl_instruction_get_next(instruction);
+ goto elna_writer_instructions_start
end
end;
@@ -1305,9 +1338,9 @@ var
body_statements: Word;
begin
.elna_writer_procedure_loop;
- name_pointer := _elna_tac_declaration_get_name(procedure);
- name_length := _elna_tac_declaration_get_length(procedure);
- body_statements := _elna_tac_declaration_get_body(procedure);
+ name_pointer := elna_rtl_declaration_get_name(procedure);
+ name_length := elna_rtl_declaration_get_length(procedure);
+ body_statements := elna_rtl_declaration_get_body(procedure);
(* Write .type _procedure_name, @function. *)
_write_z(".type \0");
@@ -1322,7 +1355,7 @@ begin
_elna_writer_instructions(body_statements);
_write_z("\tret\n\0");
- procedure := _elna_tac_declaration_get_next(procedure);
+ procedure := elna_rtl_declaration_get_next(procedure);
if procedure <> 0 then
goto elna_writer_procedure_loop
end
@@ -1336,9 +1369,9 @@ var
begin
.elna_writer_variable_loop;
if variable <> 0 then
- name := _elna_tac_declaration_get_name(variable);
- name_length := _elna_tac_declaration_get_length(variable);
- size := _elna_tac_declaration_get_body(variable);
+ name := elna_rtl_declaration_get_name(variable);
+ name_length := elna_rtl_declaration_get_length(variable);
+ size := elna_rtl_declaration_get_body(variable);
_write_z(".type \0");
_write_s(name, name_length);
@@ -1351,12 +1384,30 @@ begin
_write_i(size);
_write_c('\n');
- variable := _elna_tac_declaration_get_next(variable);
+ variable := elna_rtl_declaration_get_next(variable);
goto elna_writer_variable_loop
end
end;
+proc elna_rtl_module_declaration(tac_module: Word);
+var
+ result: Word;
+ current_part: Word;
+begin
+ result := malloc(elna_rtl_module_size());
+
+ current_part := _elna_tac_module_get_data(tac_module);
+ current_part := elna_rtl_globals(current_part);
+ elna_rtl_module_set_data(result, current_part);
+
+ current_part := _elna_tac_module_get_code(tac_module);
+ current_part := elna_rtl_procedures(current_part);
+ elna_rtl_module_set_code(result, current_part);
+
+ return result
+end;
+
proc _elna_writer_module(pair: Word);
var
compiler_strings_copy: Word;
@@ -1364,10 +1415,10 @@ var
current_byte: Word;
current_part: Word;
begin
- _write_z(".globl _start\n\n\0");
+ _write_z(".globl main\n\n\0");
_write_z(".section .data\n\0");
- current_part := _elna_tac_module_get_data(pair);
+ current_part := elna_rtl_module_get_data(pair);
_elna_writer_variable(current_part);
_write_z(".section .text\n\n\0");
@@ -1375,7 +1426,7 @@ begin
_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");
- current_part := _elna_tac_module_get_code(pair);
+ current_part := elna_rtl_module_get_code(pair);
_elna_writer_procedure(current_part);
_write_z(".section .rodata\n.type strings, @object\nstrings: .ascii \0");
@@ -1401,10 +1452,8 @@ var
integer_token: Word;
integer_length: Word;
result: Word;
- literal_size: Word;
begin
- literal_size := _integer_literal_node_size();
- result := _allocate(literal_size);
+ result := malloc(_integer_literal_node_size());
integer_token := _elna_lexer_global_get_start();
integer_length := _elna_lexer_global_get_end();
@@ -1427,7 +1476,7 @@ begin
integer_token := _integer_literal_node_get_value(integer_literal_node);
integer_length := _integer_literal_node_get_length(integer_literal_node);
- return _elna_tac_load_immediate(ElnaTacRegister.t0, integer_token, integer_length)
+ return _elna_tac_load_immediate(ElnaRtlRegister.t0, integer_token, integer_length)
end;
proc _elna_parser_character_literal();
@@ -1435,10 +1484,8 @@ var
character: Word;
character_length: Word;
result: Word;
- literal_size: Word;
begin
- literal_size := _character_literal_node_size();
- result := _allocate(literal_size);
+ result := malloc(_character_literal_node_size());
character := _elna_lexer_global_get_start();
character_length := _elna_lexer_global_get_end();
@@ -1460,16 +1507,7 @@ begin
character := _character_literal_node_get_value(character_literal_node);
character_length := _character_literal_node_get_length(character_literal_node);
- return _elna_tac_load_immediate(ElnaTacRegister.t0, character, character_length)
-end;
-
-proc _allocate(size: Word);
-var
- result: Word;
-begin
- result := memory_free_pointer;
- memory_free_pointer := memory_free_pointer + size;
- return result
+ return _elna_tac_load_immediate(ElnaRtlRegister.t0, character, character_length)
end;
proc _elna_parser_variable_expression();
@@ -1477,15 +1515,13 @@ var
name: Word;
name_token: Word;
result: Word;
- memory_size: Word;
begin
name := _elna_lexer_global_get_start();
name_token := _elna_lexer_global_get_end();
name_token := name_token - name;
_elna_lexer_skip_token();
- memory_size := _variable_expression_size();
- result := _allocate(memory_size);
+ result := malloc(_variable_expression_size());
_node_set_kind(result, NodeKind.variable_expression);
_variable_expression_set_name(result, name);
@@ -1518,10 +1554,8 @@ var
length: Word;
token_start: Word;
result: Word;
- memory_size: Word;
begin
- memory_size := _string_literal_node_size();
- result := _allocate(memory_size);
+ result := malloc(_string_literal_node_size());
token_start := _elna_lexer_global_get_start();
length := _string_length(token_start);
@@ -1547,10 +1581,10 @@ begin
length := _string_literal_node_get_length(string_literal_node);
offset := _add_string(token_start);
- first_instruction := _elna_tac_load_address(ElnaTacRegister.t0, "strings", 7);
- instruction := _elna_tac_load_immediate(ElnaTacRegister.t1, offset, 0);
+ first_instruction := _elna_tac_load_address(ElnaRtlRegister.t0, "strings", 7);
+ instruction := _elna_tac_load_immediate(ElnaRtlRegister.t1, offset, 0);
_elna_tac_instruction_set_next(first_instruction, instruction);
- next_instruction := _elna_tac_add(ElnaTacRegister.t0, ElnaTacRegister.t0, ElnaTacRegister.t1);
+ next_instruction := _elna_tac_add(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1);
_elna_tac_instruction_set_next(instruction, next_instruction);
return first_instruction
@@ -1580,10 +1614,8 @@ end;
proc _elna_parser_dereference_expression(simple_expression: Word);
var
result: Word;
- memory_size: Word;
begin
- memory_size := _dereference_expression_size();
- result := _allocate(memory_size);
+ result := malloc(_dereference_expression_size());
_node_set_kind(result, NodeKind.dereference_expression);
_dereference_expression_set_pointer(result, simple_expression);
@@ -1637,7 +1669,6 @@ proc _elna_parser_unary_expression();
var
token_kind: Word;
result: Word;
- memory_size: Word;
operand: Word;
operator: Word;
begin
@@ -1658,8 +1689,7 @@ begin
if operator <> 0 then
operand := result;
- memory_size := _unary_expression_size();
- result := _allocate(memory_size);
+ result := malloc(_unary_expression_size());
_node_set_kind(result, NodeKind.unary_expression);
_unary_expression_set_operand(result, operand);
@@ -1697,15 +1727,15 @@ begin
else
first_instruction := _elna_tac_designator(operand, symbol_table, @is_address);
if is_address then
- instruction := _elna_tac_load_word(ElnaTacRegister.t0, ElnaTacRegister.t0, 0);
+ instruction := _elna_tac_load_word(ElnaRtlRegister.t0, ElnaRtlRegister.t0, 0);
_elna_tac_instruction_set_next(first_instruction, instruction)
end
end;
if operator = '-' then
- instruction := _elna_tac_neg(ElnaTacRegister.t0, ElnaTacRegister.t0);
+ instruction := _elna_tac_neg(ElnaRtlRegister.t0, ElnaRtlRegister.t0);
_elna_tac_instruction_set_next(first_instruction, instruction)
elsif operator = '~' then
- instruction := _elna_tac_not(ElnaTacRegister.t0, ElnaTacRegister.t0);
+ instruction := _elna_tac_not(ElnaRtlRegister.t0, ElnaRtlRegister.t0);
_elna_tac_instruction_set_next(first_instruction, instruction)
end;
return first_instruction
@@ -1716,7 +1746,6 @@ var
lhs_node: Word;
rhs_node: Word;
token_kind: Word;
- memory_size: Word;
result: Word;
begin
lhs_node := _elna_parser_unary_expression();
@@ -1767,8 +1796,7 @@ begin
rhs_node := _elna_parser_unary_expression()
end;
if rhs_node <> 0 then
- memory_size := _binary_expression_size();
- result := _allocate(memory_size);
+ result := malloc(_binary_expression_size());
_node_set_kind(result, NodeKind.binary_expression);
_binary_expression_set_lhs(result, lhs_node);
@@ -1800,7 +1828,7 @@ begin
first_instruction := _elna_tac_unary_expression(operand_node, symbol_table);
(* Save the value of the left expression on the stack. *)
- instruction := _elna_tac_store_word(ElnaTacRegister.t0, ElnaTacRegister.sp, 64);
+ instruction := _elna_tac_store_word(ElnaRtlRegister.t0, ElnaRtlRegister.sp, 64);
_elna_tac_instruction_set_next(first_instruction, instruction);
current_instruction := instruction;
@@ -1810,67 +1838,67 @@ begin
current_instruction := instruction;
(* Load the left expression from the stack; *)
- instruction := _elna_tac_load_word(ElnaTacRegister.t1, ElnaTacRegister.sp, 64);
+ instruction := _elna_tac_load_word(ElnaRtlRegister.t1, ElnaRtlRegister.sp, 64);
_elna_tac_instruction_set_next(current_instruction, instruction);
current_instruction := instruction;
if token_kind = ElnaLexerKind.plus then
- instruction := _elna_tac_add(ElnaTacRegister.t0, ElnaTacRegister.t0, ElnaTacRegister.t1);
+ instruction := _elna_tac_add(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1);
_elna_tac_instruction_set_next(current_instruction, instruction)
elsif token_kind = ElnaLexerKind.minus then
- instruction := _elna_tac_sub(ElnaTacRegister.t0, ElnaTacRegister.t1, ElnaTacRegister.t0);
+ instruction := _elna_tac_sub(ElnaRtlRegister.t0, ElnaRtlRegister.t1, ElnaRtlRegister.t0);
_elna_tac_instruction_set_next(current_instruction, instruction)
elsif token_kind = ElnaLexerKind.multiplication then
- instruction := _elna_tac_mul(ElnaTacRegister.t0, ElnaTacRegister.t0, ElnaTacRegister.t1);
+ instruction := _elna_tac_mul(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1);
_elna_tac_instruction_set_next(current_instruction, instruction)
elsif token_kind = ElnaLexerKind.and then
- instruction := _elna_tac_and(ElnaTacRegister.t0, ElnaTacRegister.t0, ElnaTacRegister.t1);
+ instruction := _elna_tac_and(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1);
_elna_tac_instruction_set_next(current_instruction, instruction)
elsif token_kind = ElnaLexerKind._or then
- instruction := _elna_tac_or(ElnaTacRegister.t0, ElnaTacRegister.t0, ElnaTacRegister.t1);
+ instruction := _elna_tac_or(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1);
_elna_tac_instruction_set_next(current_instruction, instruction)
elsif token_kind = ElnaLexerKind._xor then
- instruction := _elna_tac_xor(ElnaTacRegister.t0, ElnaTacRegister.t0, ElnaTacRegister.t1);
+ instruction := _elna_tac_xor(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1);
_elna_tac_instruction_set_next(current_instruction, instruction)
elsif token_kind = ElnaLexerKind.equals then
- instruction := _elna_tac_xor(ElnaTacRegister.t0, ElnaTacRegister.t0, ElnaTacRegister.t1);
+ instruction := _elna_tac_xor(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1);
_elna_tac_instruction_set_next(current_instruction, instruction);
current_instruction := instruction;
- instruction := _elna_tac_seqz(ElnaTacRegister.t0, ElnaTacRegister.t0);
+ instruction := _elna_tac_seqz(ElnaRtlRegister.t0, ElnaRtlRegister.t0);
_elna_tac_instruction_set_next(current_instruction, instruction)
elsif token_kind = ElnaLexerKind.remainder then
- instruction := _elna_tac_rem(ElnaTacRegister.t0, ElnaTacRegister.t1, ElnaTacRegister.t0);
+ instruction := _elna_tac_rem(ElnaRtlRegister.t0, ElnaRtlRegister.t1, ElnaRtlRegister.t0);
_elna_tac_instruction_set_next(current_instruction, instruction)
elsif token_kind = ElnaLexerKind.division then
- instruction := _elna_tac_div(ElnaTacRegister.t0, ElnaTacRegister.t1, ElnaTacRegister.t0);
+ instruction := _elna_tac_div(ElnaRtlRegister.t0, ElnaRtlRegister.t1, ElnaRtlRegister.t0);
_elna_tac_instruction_set_next(current_instruction, instruction)
elsif token_kind = ElnaLexerKind.less_than then
- instruction := _elna_tac_slt(ElnaTacRegister.t0, ElnaTacRegister.t1, ElnaTacRegister.t0);
+ instruction := _elna_tac_slt(ElnaRtlRegister.t0, ElnaRtlRegister.t1, ElnaRtlRegister.t0);
_elna_tac_instruction_set_next(current_instruction, instruction)
elsif token_kind = ElnaLexerKind.greater_than then
- instruction := _elna_tac_slt(ElnaTacRegister.t0, ElnaTacRegister.t0, ElnaTacRegister.t1);
+ instruction := _elna_tac_slt(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1);
_elna_tac_instruction_set_next(current_instruction, instruction)
elsif token_kind = ElnaLexerKind.less_equal then
- instruction := _elna_tac_slt(ElnaTacRegister.t0, ElnaTacRegister.t0, ElnaTacRegister.t1);
+ instruction := _elna_tac_slt(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1);
_elna_tac_instruction_set_next(current_instruction, instruction);
current_instruction := instruction;
- instruction := _elna_tac_xor_immediate(ElnaTacRegister.t0, ElnaTacRegister.t0, 1);
+ instruction := _elna_tac_xor_immediate(ElnaRtlRegister.t0, ElnaRtlRegister.t0, 1);
_elna_tac_instruction_set_next(current_instruction, instruction)
elsif token_kind = ElnaLexerKind.not_equal then
- instruction := _elna_tac_xor(ElnaTacRegister.t0, ElnaTacRegister.t0, ElnaTacRegister.t1);
+ instruction := _elna_tac_xor(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1);
_elna_tac_instruction_set_next(current_instruction, instruction);
current_instruction := instruction;
- instruction := _elna_tac_snez(ElnaTacRegister.t0, ElnaTacRegister.t0);
+ instruction := _elna_tac_snez(ElnaRtlRegister.t0, ElnaRtlRegister.t0);
_elna_tac_instruction_set_next(current_instruction, instruction)
elsif token_kind = ElnaLexerKind.greater_equal then
- instruction := _elna_tac_slt(ElnaTacRegister.t0, ElnaTacRegister.t1, ElnaTacRegister.t0);
+ instruction := _elna_tac_slt(ElnaRtlRegister.t0, ElnaRtlRegister.t1, ElnaRtlRegister.t0);
_elna_tac_instruction_set_next(current_instruction, instruction);
current_instruction := instruction;
- instruction := _elna_tac_xor_immediate(ElnaTacRegister.t0, ElnaTacRegister.t0, 1);
+ instruction := _elna_tac_xor_immediate(ElnaRtlRegister.t0, ElnaRtlRegister.t0, 1);
_elna_tac_instruction_set_next(current_instruction, instruction)
end
end;
@@ -1916,10 +1944,8 @@ var
result: Word;
argument_number: Word;
token_kind: Word;
- call_size: Word;
begin
- call_size := _call_size();
- result := _allocate(call_size);
+ result := malloc(_call_size());
_node_set_kind(result, NodeKind.call);
_statement_set_next(result, 0);
@@ -1987,8 +2013,8 @@ begin
(* Save the argument on the stack. *)
stack_offset := argument_count * 4;
- instruction := _elna_tac_store_word(ElnaTacRegister.t0,
- ElnaTacRegister.sp, 116 - stack_offset);
+ instruction := _elna_tac_store_word(ElnaRtlRegister.t0,
+ ElnaRtlRegister.sp, 116 - stack_offset);
_elna_tac_instruction_set_next(current_instruction, instruction);
current_instruction := instruction;
@@ -2004,8 +2030,8 @@ begin
stack_offset := argument_count * 4;
(* Calculate the stack offset: 116 - (4 * argument_counter) *)
- instruction := _elna_tac_load_word(ElnaTacRegister.a0 + argument_count,
- ElnaTacRegister.sp, 116 - stack_offset);
+ instruction := _elna_tac_load_word(ElnaRtlRegister.a0 + argument_count,
+ ElnaRtlRegister.sp, 116 - stack_offset);
_elna_tac_instruction_set_next(current_instruction, instruction);
current_instruction := instruction;
@@ -2025,7 +2051,6 @@ var
token_kind: Word;
label_name: Word;
label_length: Word;
- statement_size: Word;
result: Word;
begin
_elna_lexer_skip_token();
@@ -2035,8 +2060,7 @@ begin
label_length := _elna_lexer_global_get_end() - label_name;
_elna_lexer_skip_token();
- statement_size := _goto_statement_size();
- result := _allocate(statement_size);
+ result := malloc(_goto_statement_size());
_node_set_kind(result, NodeKind.goto_statement);
_statement_set_next(result, 0);
@@ -2055,10 +2079,10 @@ var
begin
label_name := _goto_statement_get_label(parser_node);
label_length := _goto_statement_get_length(parser_node);
- label_with_dot := _allocate(label_length + 1);
+ label_with_dot := malloc(label_length + 1);
_store_byte('.', label_with_dot);
- _memcpy(label_with_dot + 1, label_name, label_length);
+ memcpy(label_with_dot + 1, label_name, label_length);
return _elna_tac_jump(label_with_dot, label_length + 1)
end;
@@ -2068,7 +2092,6 @@ var
token_kind: Word;
label_name: Word;
label_length: Word;
- statement_size: Word;
result: Word;
begin
_elna_lexer_skip_token();
@@ -2078,8 +2101,7 @@ begin
label_length := _elna_lexer_global_get_end() - label_name;
_elna_lexer_skip_token();
- statement_size := _label_declaration_size();
- result := _allocate(statement_size);
+ result := malloc(_label_declaration_size());
_node_set_kind(result, NodeKind.label_declaration);
_statement_set_next(result, 0);
@@ -2106,7 +2128,7 @@ var
begin
variable_offset := _parameter_info_get_offset(symbol);
- return _elna_tac_add_immediate(ElnaTacRegister.t0, ElnaTacRegister.sp, variable_offset)
+ return _elna_tac_add_immediate(ElnaRtlRegister.t0, ElnaRtlRegister.sp, variable_offset)
end;
proc _elna_tac_global_designator(variable_expression: Word);
@@ -2117,7 +2139,7 @@ begin
name := _variable_expression_get_name(variable_expression);
token_length := _variable_expression_get_length(variable_expression);
- return _elna_tac_load_address(ElnaTacRegister.t0, name, token_length)
+ return _elna_tac_load_address(ElnaRtlRegister.t0, name, token_length)
end;
proc _elna_tac_enumeration_value(field_access_expression: Word);
@@ -2140,7 +2162,7 @@ begin
symbol := _symbol_table_lookup(@symbol_table_global, value_name, name_length);
- enumeration_type := _type_info_get_type(symbol);
+ enumeration_type := _type_info_get__type(symbol);
members := _enumeration_type_get_members(enumeration_type);
members_length := _enumeration_type_get_length(enumeration_type);
@@ -2157,13 +2179,13 @@ begin
member_length := members + 4;
member_length := member_length^;
- if _string_compare(value_name, name_length, member_name, member_length) = 0 then
+ if string_compare(value_name, name_length, member_name, member_length) = 0 then
members_length := members_length - 1;
members := members + 8;
counter := counter + 1;
goto elna_tac_enumeration_value_members
end;
- instruction := _elna_tac_load_immediate(ElnaTacRegister.t0, counter, 0)
+ instruction := _elna_tac_load_immediate(ElnaRtlRegister.t0, counter, 0)
end;
return instruction
end;
@@ -2174,7 +2196,6 @@ var
name: Word;
name_token: Word;
result: Word;
- memory_size: Word;
begin
(* Skip dot. Read the enumeration value. *)
_elna_lexer_skip_token();
@@ -2183,9 +2204,9 @@ begin
name := _elna_lexer_global_get_start();
name_token := _elna_lexer_global_get_end();
name_token := name_token - name;
+
_elna_lexer_skip_token();
- memory_size := _field_access_expression_size();
- result := _allocate(memory_size);
+ result := malloc(_field_access_expression_size());
_node_set_kind(result, NodeKind.field_access_expression);
_field_access_expression_set_aggregate(result, aggregate);
@@ -2210,14 +2231,14 @@ begin
if node_kind = NodeKind.dereference_expression then
parser_node := _dereference_expression_get_pointer(parser_node);
first_instruction := _elna_tac_simple_expression(parser_node, symbol_table, is_address);
- instruction := _elna_tac_load_word(ElnaTacRegister.t0, ElnaTacRegister.t0, 0);
+ instruction := _elna_tac_load_word(ElnaRtlRegister.t0, ElnaRtlRegister.t0, 0);
_elna_tac_instruction_set_next(first_instruction, instruction)
elsif node_kind = NodeKind.field_access_expression then
first_instruction := _elna_tac_enumeration_value(parser_node);
is_address^ := 0
elsif node_kind = NodeKind.call then
first_instruction := _elna_tac_call(parser_node, symbol_table);
- instruction := _elna_tac_move(ElnaTacRegister.t0, ElnaTacRegister.a0);
+ instruction := _elna_tac_move(ElnaRtlRegister.t0, ElnaRtlRegister.a0);
_elna_tac_instruction_set_next(first_instruction, instruction);
is_address^ := 0
else
@@ -2228,13 +2249,11 @@ end;
proc _elna_parser_assign_statement(assignee: Word);
var
- statement_size: Word;
result: Word;
token_kind: Word;
assignment_node: Word;
begin
- statement_size := _assign_statement_size();
- result := _allocate(statement_size);
+ result := malloc(_assign_statement_size());
_node_set_kind(result, NodeKind.assign_statement);
_statement_set_next(result, 0);
@@ -2262,7 +2281,7 @@ begin
first_instruction := _elna_tac_designator(current_expression, symbol_table, @is_address);
(* Save the assignee address on the stack. *)
- current_instruction := _elna_tac_store_word(ElnaTacRegister.t0, ElnaTacRegister.sp, 60);
+ current_instruction := _elna_tac_store_word(ElnaRtlRegister.t0, ElnaRtlRegister.sp, 60);
_elna_tac_instruction_set_next(first_instruction, current_instruction);
(* Compile the assignment. *)
@@ -2270,10 +2289,10 @@ begin
instruction := _elna_tac_binary_expression(current_expression, symbol_table);
_elna_tac_instruction_set_next(current_instruction, instruction);
- current_instruction := _elna_tac_load_word(ElnaTacRegister.t1, ElnaTacRegister.sp, 60);
+ current_instruction := _elna_tac_load_word(ElnaRtlRegister.t1, ElnaRtlRegister.sp, 60);
_elna_tac_instruction_set_next(instruction, current_instruction);
- instruction := _elna_tac_store_word(ElnaTacRegister.t0, ElnaTacRegister.t1, 0);
+ instruction := _elna_tac_store_word(ElnaRtlRegister.t0, ElnaRtlRegister.t1, 0);
_elna_tac_instruction_set_next(current_instruction, instruction);
return first_instruction
@@ -2284,7 +2303,6 @@ var
token_kind: Word;
returned: Word;
label_length: Word;
- statement_size: Word;
result: Word;
begin
(* Skip "return" keyword and whitespace after it. *)
@@ -2292,9 +2310,7 @@ begin
_elna_lexer_read_token(@token_kind);
returned := _elna_parser_binary_expression();
-
- statement_size := _return_statement_size();
- result := _allocate(statement_size);
+ result := malloc(_return_statement_size());
_node_set_kind(result, NodeKind.return_statement);
_statement_set_next(result, 0);
@@ -2311,7 +2327,7 @@ var
begin
return_expression := _return_statement_get_returned(parser_node);
first_instruction := _elna_tac_binary_expression(return_expression, symbol_table);
- instruction := _elna_tac_move(ElnaTacRegister.a0, ElnaTacRegister.t0);
+ instruction := _elna_tac_move(ElnaRtlRegister.a0, ElnaRtlRegister.t0);
_elna_tac_instruction_set_next(first_instruction, instruction);
return first_instruction
end;
@@ -2340,13 +2356,11 @@ end;
proc _elna_parser_conditional_statements();
var
- conditional_size: Word;
token_kind: Word;
current_node: Word;
result: Word;
begin
- conditional_size := _conditional_statements_size();
- result := _allocate(conditional_size);
+ result := malloc(_conditional_statements_size());
(* Skip "if", "while" or "elsif". *)
_elna_lexer_skip_token();
@@ -2381,7 +2395,7 @@ begin
condition_label := label_counter;
label_counter := label_counter + 1;
- current_instruction := _elna_tac_beqz(ElnaTacRegister.t0, condition_label, 0);
+ current_instruction := _elna_tac_beqz(ElnaRtlRegister.t0, condition_label, 0);
_elna_tac_instruction_set_next(first_instruction, current_instruction);
current_node := _conditional_statements_get_statements(parser_node);
@@ -2404,13 +2418,11 @@ proc _elna_parser_if_statement();
var
current_node: Word;
result: Word;
- object_size: Word;
token_kind: Word;
previous_conditional: Word;
next_conditional: Word;
begin
- object_size := _if_statement_size();
- result := _allocate(object_size);
+ result := malloc(_if_statement_size());
_node_set_kind(result, NodeKind.if_statement);
_statement_set_next(result, 0);
@@ -2615,7 +2627,6 @@ var
field_length: Word;
field_type: Word;
token_kind: Word;
- type_expression_size: Word;
result: Word;
previous_entry: Word;
begin
@@ -2628,7 +2639,7 @@ begin
goto elna_parser_record_type_expression_end
end;
.elna_parser_record_type_expression_loop;
- entry := _allocate(16);
+ entry := malloc(16);
member_count := member_count + 1;
field_name := _elna_lexer_global_get_start();
@@ -2668,8 +2679,7 @@ begin
.elna_parser_record_type_expression_end;
_elna_lexer_skip_token();
- type_expression_size := _enumeration_type_expression_size();
- result := _allocate(type_expression_size);
+ result := malloc(_enumeration_type_expression_size());
_node_set_kind(result, NodeKind.record_type_expression);
_record_type_expression_set_members(result, memory_start);
@@ -2686,7 +2696,6 @@ var
memory_start: Word;
member_count: Word;
result: Word;
- type_expression_size: Word;
entry: Word;
previous_entry: Word;
begin
@@ -2699,7 +2708,7 @@ begin
goto elna_parser_enumeration_type_expression_end
end;
.elna_parser_enumeration_type_expression_loop;
- entry := _allocate(12);
+ entry := malloc(12);
member_count := member_count + 1;
enumeration_name := _elna_lexer_global_get_start();
@@ -2732,8 +2741,7 @@ begin
.elna_parser_enumeration_type_expression_end;
_elna_lexer_skip_token();
- type_expression_size := _enumeration_type_expression_size();
- result := _allocate(type_expression_size);
+ result := malloc(_enumeration_type_expression_size());
_node_set_kind(result, NodeKind.enumeration_type_expression);
_enumeration_type_expression_set_members(result, memory_start);
@@ -2759,19 +2767,16 @@ var
result: Word;
memory_start: Word;
member_count: Word;
- member_array_size: Word;
member_array_start: Word;
member_array_current: Word;
begin
- member_array_size := _enumeration_type_size();
- result := _allocate(member_array_size);
+ result := malloc(_enumeration_type_size());
memory_start := _enumeration_type_expression_get_members(parser_node);
member_count := _enumeration_type_expression_get_length(parser_node);
(* Copy the list of enumeration members into an array of strings. *)
- member_array_size := member_count * 8;
- member_array_start := _allocate(member_array_size);
+ member_array_start := malloc(member_count * 8);
member_array_current := member_array_start;
.elna_name_type_enumeration_loop;
@@ -2803,18 +2808,15 @@ var
result: Word;
memory_start: Word;
member_count: Word;
- member_array_size: Word;
member_array_start: Word;
member_array_current: Word;
begin
- member_array_size := _record_type_size();
- result := _allocate(member_array_size);
+ result := malloc(_record_type_size());
memory_start := _record_type_expression_get_members(parser_node);
member_count := _record_type_expression_get_length(parser_node);
- member_array_size := member_count * 12;
- member_array_start := _allocate(member_array_size);
+ member_array_start := malloc(member_count * 12);
member_array_current := member_array_start;
.elna_name_type_record_loop;
@@ -2847,13 +2849,11 @@ end;
proc _elna_parser_named_type_expression();
var
- type_expression_size: Word;
result: Word;
type_name: Word;
name_length: Word;
begin
- type_expression_size := _named_type_expression_size();
- result := _allocate(type_expression_size);
+ result := malloc(_named_type_expression_size());
_node_set_kind(result, NodeKind.named_type_expression);
type_name := _elna_lexer_global_get_start();
@@ -2897,7 +2897,7 @@ begin
name_length := _named_type_expression_get_length(parser_node);
result := _symbol_table_lookup(@symbol_table_global, type_name, name_length);
- result := _type_info_get_type(result)
+ result := _type_info_get__type(result)
elsif token_kind = NodeKind.enumeration_type_expression then
result := _elna_name_type_enumeration(parser_node)
elsif token_kind = NodeKind.record_type_expression then
@@ -2907,12 +2907,6 @@ begin
return result
end;
-proc _type_info_get_type(this: Word);
-begin
- this := this + 4;
- return this^
-end;
-
(**
* Parameters:
* parameter_index - Parameter index.
@@ -2920,39 +2914,25 @@ end;
proc _parameter_info_create(parameter_index: Word);
var
offset: Word;
- current_word: Word;
result: Word;
begin
- result := _allocate(8);
- current_word := result;
- current_word^ := InfoKind.parameter_info;
-
- current_word := current_word + 4;
+ result := malloc(_parameter_info_size());
+ _info_set_kind(result, InfoKind.parameter_info);
(* Calculate the stack offset: 88 - (4 * parameter_counter) *)
offset := parameter_index * 4;
- current_word^ := 88 - offset;
+ _parameter_info_set_offset(result, 88 - offset);
return result
end;
-proc _parameter_info_get_offset(this: Word);
-begin
- this := this + 4;
- return this^
-end;
-
proc _type_info_create(type_representation: Word);
var
result: Word;
- current_word: Word;
begin
- result := _allocate(8);
- current_word := result;
- current_word^ := InfoKind.type_info;
-
- current_word := current_word + 4;
- current_word^ := type_representation;
+ result := malloc(_type_info_size());
+ _info_set_kind(result, InfoKind.type_info);
+ _type_info_set__type(result, type_representation);
return result
end;
@@ -2963,17 +2943,13 @@ end;
*)
proc _temporary_info_create(temporary_index: Word);
var
- offset: Word;
- current_word: Word;
result: Word;
begin
- result := _allocate(8);
- current_word := result;
- current_word^ := InfoKind.temporary_info;
- current_word := current_word + 4;
+ result := malloc(_temporary_info_size());
+ _info_set_kind(result, InfoKind.temporary_info);
(* Calculate the stack offset: 4 * variable_counter. *)
- current_word^ := temporary_index * 4;
+ _temporary_info_set_offset(result, temporary_index * 4);
return result
end;
@@ -2984,25 +2960,15 @@ end;
*)
proc _procedure_info_create(symbol_table: Word);
var
- current_word: Word;
result: Word;
begin
- result := _allocate(8);
- current_word := result;
- current_word^ := InfoKind.procedure_info;
- current_word := current_word + 4;
-
- current_word^ := symbol_table;
+ result := malloc(_procedure_info_size());
+ _info_set_kind(result, InfoKind.procedure_info);
+ _procedure_info_set_symbol_table(result, symbol_table);
return result
end;
-proc _procedure_info_get_symbol_table(this: Word);
-begin
- this := this + 4;
- return this^
-end;
-
(**
* Parameters:
* parameter_index - Parameter index.
@@ -3059,11 +3025,9 @@ var
name_length: Word;
token_kind: Word;
result: Word;
- declaration_size: Word;
parameter_head: Word;
begin
- declaration_size := _procedure_declaration_size();
- result := _allocate(declaration_size);
+ result := malloc(_procedure_declaration_size());
_node_set_kind(result, NodeKind.procedure_declaration);
_declaration_set_next(result, 0);
@@ -3153,8 +3117,8 @@ begin
symbol_info := _parameter_info_get_offset(symbol_info);
- instruction := _elna_tac_store_word(ElnaTacRegister.a0 + parameter_counter,
- ElnaTacRegister.sp, symbol_info);
+ instruction := _elna_tac_store_word(ElnaRtlRegister.a0 + parameter_counter,
+ ElnaRtlRegister.sp, symbol_info);
if first_instruction = 0 then
first_instruction := instruction
else
@@ -3170,6 +3134,47 @@ begin
return first_instruction
end;
+proc elna_rtl_global_declaration(tac_declaration: Word);
+var
+ name: Word;
+ length: Word;
+ body: Word;
+ result: Word;
+begin
+ result := malloc(elna_rtl_declaration_size());
+ name := _elna_tac_declaration_get_name(tac_declaration);
+ length := _elna_tac_declaration_get_length(tac_declaration);
+ body := _elna_tac_declaration_get_body(tac_declaration);
+
+ elna_rtl_declaration_set_next(result, 0);
+ elna_rtl_declaration_set_name(result, name);
+ elna_rtl_declaration_set_length(result, length);
+ elna_rtl_declaration_set_body(result, body);
+
+ return result
+end;
+
+proc elna_rtl_procedure_declaration(tac_declaration: Word);
+var
+ name: Word;
+ length: Word;
+ body: Word;
+ result: Word;
+begin
+ result := malloc(elna_rtl_declaration_size());
+ name := _elna_tac_declaration_get_name(tac_declaration);
+ length := _elna_tac_declaration_get_length(tac_declaration);
+ body := _elna_tac_declaration_get_body(tac_declaration);
+ body := elna_rtl_instructions(body);
+
+ elna_rtl_declaration_set_next(result, 0);
+ elna_rtl_declaration_set_name(result, name);
+ elna_rtl_declaration_set_length(result, length);
+ elna_rtl_declaration_set_body(result, body);
+
+ return result
+end;
+
proc _elna_tac_procedure_declaration(parser_node: Word);
var
name_pointer: Word;
@@ -3183,8 +3188,7 @@ var
result: Word;
result_size: Word;
begin
- result_size := _elna_tac_declaration_size();
- result := _allocate(result_size);
+ result := malloc(_elna_tac_declaration_size());
_elna_tac_declaration_set_next(result, 0);
@@ -3248,6 +3252,62 @@ begin
return result
end;
+proc elna_rtl_globals(tac_procedure: Word);
+var
+ current_copy: Word;
+ next_copy: Word;
+ first_copy: Word;
+begin
+ if tac_procedure <> 0 then
+ first_copy := elna_rtl_global_declaration(tac_procedure);
+ tac_procedure := _elna_tac_declaration_get_next(tac_procedure)
+ else
+ first_copy := 0;
+ end;
+ current_copy := first_copy;
+
+ .elna_rtl_globals_start;
+
+ if tac_procedure <> 0 then
+ next_copy := elna_rtl_global_declaration(tac_procedure);
+
+ tac_procedure := _elna_tac_declaration_get_next(tac_procedure);
+ elna_rtl_declaration_set_next(current_copy, next_copy);
+ current_copy := next_copy;
+ goto elna_rtl_globals_start
+ end;
+
+ return first_copy
+end;
+
+proc elna_rtl_procedures(tac_procedure: Word);
+var
+ current_copy: Word;
+ next_copy: Word;
+ first_copy: Word;
+begin
+ if tac_procedure <> 0 then
+ first_copy := elna_rtl_procedure_declaration(tac_procedure);
+ tac_procedure := _elna_tac_declaration_get_next(tac_procedure)
+ else
+ first_copy := 0;
+ end;
+ current_copy := first_copy;
+
+ .elna_rtl_procedures_start;
+
+ if tac_procedure <> 0 then
+ next_copy := elna_rtl_procedure_declaration(tac_procedure);
+
+ tac_procedure := _elna_tac_declaration_get_next(tac_procedure);
+ elna_rtl_declaration_set_next(current_copy, next_copy);
+ current_copy := next_copy;
+ goto elna_rtl_procedures_start
+ end;
+
+ return first_copy
+end;
+
proc _elna_tac_procedures(parser_node: Word);
var
result: Word;
@@ -3299,7 +3359,6 @@ var
name_length: Word;
parser_node: Word;
result: Word;
- declaration_size: Word;
begin
_elna_lexer_read_token(@token_kind);
type_name := _elna_lexer_global_get_start();
@@ -3310,8 +3369,7 @@ begin
_elna_lexer_skip_token();
parser_node := _elna_parser_type_expression();
- declaration_size := _type_declaration_size();
- result := _allocate(declaration_size);
+ result := malloc(_type_declaration_size());
_node_set_kind(result, NodeKind.type_declaration);
_declaration_set_next(result, 0);
@@ -3387,7 +3445,6 @@ var
name_length: Word;
variable_type: Word;
result: Word;
- declaration_size: Word;
begin
_elna_lexer_read_token(@token_kind);
@@ -3398,10 +3455,9 @@ begin
_elna_lexer_skip_token();
_elna_lexer_read_token(@token_kind);
_elna_lexer_skip_token();
- variable_type := _elna_parser_type_expression();
- declaration_size := _variable_declaration_size();
- result := _allocate(declaration_size);
+ variable_type := _elna_parser_type_expression();
+ result := malloc(_variable_declaration_size());
_node_set_kind(result, NodeKind.variable_declaration);
_declaration_set_next(result, 0);
@@ -3418,10 +3474,8 @@ var
name_length: Word;
variable_type: Word;
result: Word;
- result_size: Word;
begin
- result_size := _elna_tac_declaration_size();
- result := _allocate(result_size);
+ result := malloc(_elna_tac_declaration_size());
_elna_tac_declaration_set_next(result, 0);
@@ -3435,7 +3489,7 @@ begin
name := _named_type_expression_get_name(variable_type);
name_length := _named_type_expression_get_length(variable_type);
- if _string_compare("Array", 5, name, name_length) then
+ if string_compare("Array", 5, name, name_length) then
(* Else we assume this is a zeroed 4096 bytes big array. *)
_elna_tac_declaration_set_body(result, 4096)
else
@@ -3446,7 +3500,6 @@ end;
proc _elna_tac_type_field(name_pointer: Word, name_length: Word, field_pointer: Word, field_offset: Word);
var
- result_size: Word;
first_result: Word;
second_result: Word;
new_name: Word;
@@ -3456,49 +3509,48 @@ var
name_target: Word;
next_instruction: Word;
begin
- result_size := _elna_tac_declaration_size();
field_length := field_pointer + 4;
field_length := field_length^;
new_length := field_length + name_length;
new_length := new_length + 5;
- first_result := _allocate(result_size);
+ first_result := malloc(_elna_tac_declaration_size());
_elna_tac_declaration_set_next(first_result, 0);
- new_name := _allocate(new_length);
+ new_name := malloc(new_length);
name_target := new_name;
- _memcpy(name_target, name_pointer, name_length);
+ memcpy(name_target, name_pointer, name_length);
name_target := name_target + name_length;
- _memcpy(name_target, "_get_", 5);
+ memcpy(name_target, "_get_", 5);
name_target := name_target + 5;
- _memcpy(name_target, field_pointer^, field_length);
+ memcpy(name_target, field_pointer^, field_length);
_elna_tac_declaration_set_name(first_result, new_name);
_elna_tac_declaration_set_length(first_result, new_length);
- instruction := _elna_tac_add_immediate(ElnaTacRegister.a0, ElnaTacRegister.a0, field_offset, 0);
- next_instruction := _elna_tac_load_word(ElnaTacRegister.a0, ElnaTacRegister.a0, 0);
+ instruction := _elna_tac_add_immediate(ElnaRtlRegister.a0, ElnaRtlRegister.a0, field_offset, 0);
+ next_instruction := _elna_tac_load_word(ElnaRtlRegister.a0, ElnaRtlRegister.a0, 0);
_elna_tac_instruction_set_next(instruction, next_instruction);
_elna_tac_declaration_set_body(first_result, instruction);
- second_result := _allocate(result_size);
+ second_result := malloc(_elna_tac_declaration_size());
_elna_tac_declaration_set_next(second_result, 0);
- new_name := _allocate(new_length);
+ new_name := malloc(new_length);
name_target := new_name;
- _memcpy(name_target, name_pointer, name_length);
+ memcpy(name_target, name_pointer, name_length);
name_target := name_target + name_length;
- _memcpy(name_target, "_set_", 5);
+ memcpy(name_target, "_set_", 5);
name_target := name_target + 5;
- _memcpy(name_target, field_pointer^, field_length);
+ memcpy(name_target, field_pointer^, field_length);
_elna_tac_declaration_set_name(second_result, new_name);
_elna_tac_declaration_set_length(second_result, new_length);
- instruction := _elna_tac_add_immediate(ElnaTacRegister.a0, ElnaTacRegister.a0, field_offset, 0);
- next_instruction := _elna_tac_store_word(ElnaTacRegister.a1, ElnaTacRegister.a0, 0);
+ instruction := _elna_tac_add_immediate(ElnaRtlRegister.a0, ElnaRtlRegister.a0, field_offset, 0);
+ next_instruction := _elna_tac_store_word(ElnaRtlRegister.a1, ElnaRtlRegister.a0, 0);
_elna_tac_instruction_set_next(instruction, next_instruction);
_elna_tac_declaration_set_body(second_result, instruction);
@@ -3509,7 +3561,6 @@ end;
proc _elna_tac_type_record(name_pointer: Word, name_length: Word, type_representation: Word, current_result: Word);
var
- result_size: Word;
first_result: Word;
result: Word;
type_size: Word;
@@ -3520,8 +3571,7 @@ var
field_offset: Word;
field_pointer: Word;
begin
- result_size := _elna_tac_declaration_size();
- first_result := _allocate(result_size);
+ first_result := malloc(_elna_tac_declaration_size());
result := 0;
(* Debug. Error stream output.
@@ -3529,15 +3579,15 @@ begin
type_size := _type_get_size(type_representation);
new_length := name_length + 5;
- new_name := _allocate(new_length);
+ new_name := malloc(new_length);
- _memcpy(new_name, name_pointer, name_length);
- _memcpy(new_name + name_length, "_size", 5);
+ memcpy(new_name, name_pointer, name_length);
+ memcpy(new_name + name_length, "_size", 5);
_elna_tac_declaration_set_name(first_result, new_name);
_elna_tac_declaration_set_length(first_result, new_length);
- instruction := _elna_tac_load_immediate(ElnaTacRegister.a0, type_size, 0);
+ instruction := _elna_tac_load_immediate(ElnaRtlRegister.a0, type_size, 0);
_elna_tac_declaration_set_body(first_result, instruction);
field_count := _record_type_get_length(type_representation);
@@ -3584,7 +3634,7 @@ begin
name_length := _declaration_get_length(parser_node);
symbol := _symbol_table_lookup(@symbol_table_global, name_pointer, name_length);
- info_type := _type_info_get_type(symbol);
+ info_type := _type_info_get__type(symbol);
type_kind := _type_get_kind(info_type);
if type_kind = TypeKind._record then
@@ -3679,11 +3729,9 @@ end;
proc _elna_parser_module_declaration();
var
parser_node: Word;
- declaration_size: Word;
result: Word;
begin
- declaration_size := _module_declaration_size();
- result := _allocate(declaration_size);
+ result := malloc(_module_declaration_size());
_node_set_kind(result, NodeKind.module_declaration);
@@ -3819,12 +3867,14 @@ proc _compile();
var
parser_node: Word;
tac: Word;
+ rtl: 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);
- _elna_writer_module(tac)
+ rtl := elna_rtl_module_declaration(tac);
+ _elna_writer_module(rtl)
end;
(**
@@ -3878,7 +3928,7 @@ begin
goto symbol_table_lookup_repeat
end;
(* If names don't match, exit and return nil. *)
- if _memcmp(symbol_name, current_name, name_length) then
+ if memcmp(symbol_name, current_name, name_length) then
goto symbol_table_lookup_repeat
end;
(* Otherwise, the symbol is found. *)
@@ -3961,7 +4011,7 @@ begin
(* Set the table length to 0. *)
symbol_table_global := 0;
- current_type := _allocate(8);
+ current_type := malloc(_type_size());
_type_set_kind(current_type, TypeKind.primitive);
_type_set_size(current_type, 4);
@@ -4474,14 +4524,14 @@ begin
return _elna_lexer_get_transition(current_state, character_class)
end;
-proc _string_compare(lhs_pointer: Word, lhs_length: Word, rhs_pointer: Word, rhs_length: Word);
+proc string_compare(lhs_pointer: Word, lhs_length: Word, rhs_pointer: Word, rhs_length: Word);
var
result: Word;
begin
result := 0;
if lhs_length = rhs_length then
- result := _memcmp(lhs_pointer, rhs_pointer, lhs_length);
+ result := memcmp(lhs_pointer, rhs_pointer, lhs_length);
result := result = 0
end;
return result
@@ -4495,37 +4545,37 @@ begin
result := ElnaLexerKind.identifier;
token_length := position_end - position_start;
- if _string_compare(position_start, token_length, "const", 5) then
+ if string_compare(position_start, token_length, "const", 5) then
result := ElnaLexerKind._const
- elsif _string_compare(position_start, token_length, "var", 3) then
+ elsif string_compare(position_start, token_length, "var", 3) then
result := ElnaLexerKind._var
- elsif _string_compare(position_start, token_length, "proc", 4) then
+ elsif string_compare(position_start, token_length, "proc", 4) then
result := ElnaLexerKind._proc
- elsif _string_compare(position_start, token_length, "type", 4) then
+ elsif string_compare(position_start, token_length, "type", 4) then
result := ElnaLexerKind._type
- elsif _string_compare(position_start, token_length, "begin", 5) then
+ elsif string_compare(position_start, token_length, "begin", 5) then
result := ElnaLexerKind._begin
- elsif _string_compare(position_start, token_length, "end", 3) then
+ elsif string_compare(position_start, token_length, "end", 3) then
result := ElnaLexerKind._end
- elsif _string_compare(position_start, token_length, "return", 6) then
+ elsif string_compare(position_start, token_length, "return", 6) then
result := ElnaLexerKind._return
- elsif _string_compare(position_start, token_length, "goto", 4) then
+ elsif string_compare(position_start, token_length, "goto", 4) then
result := ElnaLexerKind._goto
- elsif _string_compare(position_start, token_length, "if", 2) then
+ elsif string_compare(position_start, token_length, "if", 2) then
result := ElnaLexerKind._if
- elsif _string_compare(position_start, token_length, "while", 5) then
+ elsif string_compare(position_start, token_length, "while", 5) then
result := ElnaLexerKind._while
- elsif _string_compare(position_start, token_length, "then", 4) then
+ elsif string_compare(position_start, token_length, "then", 4) then
result := ElnaLexerKind._then
- elsif _string_compare(position_start, token_length, "else", 4) then
+ elsif string_compare(position_start, token_length, "else", 4) then
result := ElnaLexerKind._else
- elsif _string_compare(position_start, token_length, "elsif", 5) then
+ elsif string_compare(position_start, token_length, "elsif", 5) then
result := ElnaLexerKind._elsif
- elsif _string_compare(position_start, token_length, "record", 6) then
+ elsif string_compare(position_start, token_length, "record", 6) then
result := ElnaLexerKind._record
- elsif _string_compare(position_start, token_length, "or", 2) then
+ elsif string_compare(position_start, token_length, "or", 2) then
result := ElnaLexerKind._or
- elsif _string_compare(position_start, token_length, "xor", 2) then
+ elsif string_compare(position_start, token_length, "xor", 2) then
result := ElnaLexerKind._xor
end;
return result
@@ -4739,15 +4789,14 @@ end;
proc _initialize_global_state();
begin
compiler_strings_position := @compiler_strings;
- memory_free_pointer := _mmap(4194304);
- source_code := _mmap(495616);
- symbol_table_store := _mmap(495616)
+ source_code := malloc(495616);
+ symbol_table_store := malloc(4194304)
end;
(*
* Entry point.
*)
-proc _start();
+proc main();
var
last_read: Word;
offset: Word;
diff --git a/boot/stage16/linker.arg b/boot/stage16/linker.arg
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/boot/stage16/linker.arg
diff --git a/boot/stage2.elna b/boot/stage2/cl.elna
index 0423b3b..0423b3b 100644
--- a/boot/stage2.elna
+++ b/boot/stage2/cl.elna
diff --git a/boot/stage3.elna b/boot/stage3/cl.elna
index aec9832..aec9832 100644
--- a/boot/stage3.elna
+++ b/boot/stage3/cl.elna
diff --git a/boot/stage4.elna b/boot/stage4/cl.elna
index d873b9a..d873b9a 100644
--- a/boot/stage4.elna
+++ b/boot/stage4/cl.elna
diff --git a/boot/stage5.elna b/boot/stage5/cl.elna
index 69623db..69623db 100644
--- a/boot/stage5.elna
+++ b/boot/stage5/cl.elna
diff --git a/boot/stage6.elna b/boot/stage6/cl.elna
index 7d426f9..7d426f9 100644
--- a/boot/stage6.elna
+++ b/boot/stage6/cl.elna
diff --git a/boot/stage7.elna b/boot/stage7/cl.elna
index f83a8a5..f83a8a5 100644
--- a/boot/stage7.elna
+++ b/boot/stage7/cl.elna
diff --git a/boot/stage8.elna b/boot/stage8/cl.elna
index 75c24d7..75c24d7 100644
--- a/boot/stage8.elna
+++ b/boot/stage8/cl.elna
diff --git a/boot/stage9.elna b/boot/stage9/cl.elna
index 21d87ef..21d87ef 100644
--- a/boot/stage9.elna
+++ b/boot/stage9/cl.elna
diff --git a/boot/symbol.s b/boot/symbol.s
deleted file mode 100644
index fdf4ad2..0000000
--- a/boot/symbol.s
+++ /dev/null
@@ -1,297 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public License,
-# v. 2.0. If a copy of the MPL was not distributed with this file, You can
-# obtain one at https://mozilla.org/MPL/2.0/.
-
-.global symbol_table
-.global symbol_table_build, symbol_table_lookup, symbol_table_enter, symbol_table_dump
-.global symbol_table_make_pointer, symbol_table_make_parameter, symbol_table_make_local, symbol_table_make_procedure
-
-.include "boot/definitions.inc"
-
-.equ SYMBOL_PRIME, 1543
-
-.section .rodata
-
-.type symbol_builtin_name_int, @object
-symbol_builtin_name_int: .ascii "Int"
-.type symbol_builtin_name_word, @object
-symbol_builtin_name_word: .ascii "Word"
-.type symbol_builtin_name_byte, @object
-symbol_builtin_name_byte: .ascii "Byte"
-.type symbol_builtin_name_char, @object
-symbol_builtin_name_char: .ascii "Char"
-.type symbol_builtin_name_bool, @object
-symbol_builtin_name_bool: .ascii "Bool"
-
-# Every type info starts with a word describing what type it is.
-
-# Primitive types have only type size.
-.type symbol_builtin_type_int, @object
-symbol_builtin_type_int: .word TYPE_PRIMITIVE
- .word 4
-.type symbol_builtin_type_word, @object
-symbol_builtin_type_word: .word TYPE_PRIMITIVE
- .word 4
-.type symbol_builtin_type_byte, @object
-symbol_builtin_type_byte: .word TYPE_PRIMITIVE
- .word 1
-.type symbol_builtin_type_char, @object
-symbol_builtin_type_char: .word TYPE_PRIMITIVE
- .word 1
-.type symbol_builtin_type_bool, @object
-symbol_builtin_type_bool: .word TYPE_PRIMITIVE
- .word 1
-
-.section .bss
-
-# The first word of the symbol table is its length.
-# Then a list of type infos follows:
-#
-# record
-# name: String
-# info: ^TypeInfo
-# end
-.type symbol_table, @object
-symbol_table: .zero SYMBOL_PRIME
-
-.section .text
-
-# Prints the list of symbols in the table.
-.type symbol_table_dump, @function
-symbol_table_dump:
- # Prologue.
- addi sp, sp, -32
- sw ra, 28(sp)
- sw s0, 24(sp)
- addi s0, sp, 32
-
- sw s1, 20(sp) # Current symbol in the table.
- sw s2, 16(sp) # Symbol table length.
-
- la s1, symbol_table
- lw s2, 0(s1)
- addi s1, s1, 4 # Advance to the first symbol in the table.
-
-.Lsymbol_table_dump_loop:
- beqz s2, .Lsymbol_table_dump_end
-
- # Compare string lengths.
- lw a0, 4(s1)
- lw a1, 0(s1)
- call _write_error
-
- addi s1, s1, 12
- addi s2, s2, -1
- j .Lsymbol_table_dump_loop
-
-.Lsymbol_table_dump_end:
- lw s1, 20(sp)
- lw s2, 16(sp)
-
- # Epilogue.
- lw ra, 28(sp)
- lw s0, 24(sp)
- addi sp, sp, 32
- ret
-
-# Searches for a symbol by name.
-#
-# Parameters:
-# a0 - Length of the symbol to search.
-# a1 - Pointer to the symbol name.
-#
-# Sets a0 to the symbol info pointer or 0 if the symbol has not been found.
-.type symbol_table_lookup, @function
-symbol_table_lookup:
- # Prologue.
- addi sp, sp, -32
- sw ra, 28(sp)
- sw s0, 24(sp)
- addi s0, sp, 32
-
- sw s1, 20(sp) # Current symbol in the table.
- sw s2, 16(sp) # Symbol table length.
- sw s3, 12(sp) # Length of the symbol to search.
- sw s4, 8(sp) # Pointer to the symbol to search.
-
- mv s3, a0
- mv s4, a1
-
- la s1, symbol_table
- lw s2, 0(s1)
- addi s1, s1, 4 # Advance to the first symbol in the table.
-
-.Lsymbol_table_lookup_loop:
- beqz s2, .Lsymbol_table_lookup_not_found
-
- # Compare string lengths.
- mv a0, s3
- mv a1, s4
- lw a2, 0(s1)
- lw a3, 4(s1)
- call _string_equal
-
- beqz a0, .Lsymbol_table_lookup_continue
-
- lw a0, 8(s1) # Pointer to the symbol.
- j .Lsymbol_table_lookup_end
-
-.Lsymbol_table_lookup_continue:
- addi s1, s1, 12
- addi s2, s2, -1
- j .Lsymbol_table_lookup_loop
-
-.Lsymbol_table_lookup_not_found:
- li a0, 0
-
-.Lsymbol_table_lookup_end:
- lw s1, 20(sp)
- lw s2, 16(sp)
- lw s3, 12(sp)
- lw s4, 8(sp)
-
- # Epilogue.
- lw ra, 28(sp)
- lw s0, 24(sp)
- addi sp, sp, 32
- ret
-
-# Creates a pointer type.
-#
-# Parameters:
-# a0 - Pointer to the base type.
-# a1 - Output memory.
-#
-# Sets a0 to the size of newly created type in bytes.
-.type symbol_table_make_pointer, @function
-symbol_table_make_pointer:
- li t0, TYPE_POINTER
- sw t0, 0(a1)
- sw a0, 4(a1)
-
- li a0, 8
- ret
-
-# Creates a parameter info.
-#
-# Parameters:
-# a0 - Pointer to the parameter type.
-# a1 - Parameter offset.
-# a2 - Output memory.
-#
-# Sets a0 to the size of newly created info object in bytes.
-.type symbol_table_make_parameter, @function
-symbol_table_make_parameter:
- li t0, INFO_PARAMETER
- sw t0, 0(a2)
- sw a0, 4(a2)
- sw a1, 8(a2)
-
- li a0, 12
- ret
-
-# Creates a local variable info.
-#
-# Parameters:
-# a0 - Pointer to the variable type.
-# a1 - Variable stack offset.
-# a2 - Output memory.
-#
-# Sets a0 to the size of newly created info object in bytes.
-.type symbol_table_make_local, @function
-symbol_table_make_local:
- li t0, INFO_LOCAL
- sw t0, 0(a2)
- sw a0, 4(a2)
- sw a1, 8(a2)
-
- li a0, 12
- ret
-
-# Creates a procedure type and procedure info objects refering the type.
-#
-# Parameters:
-# a0 - Output memory.
-#
-# Sets a0 to the size of newly created info object in bytes.
-.type symbol_table_make_procedure, @function
-symbol_table_make_procedure:
- li t0, TYPE_PROCEDURE
- sw t0, 8(a0)
-
- li t0, INFO_PROCEDURE
- sw t0, 0(a0)
- sw a0, 4(a0) # Procedure type stored in the same memory segment.
-
- li a0, 12
- ret
-
-# Inserts a symbol into the table.
-#
-# Parameters:
-# a0 - Symbol name length.
-# a1 - Symbol name pointer.
-# a2 - Symbol pointer.
-.type symbol_table_enter, @function
-symbol_table_enter:
- la t0, symbol_table
-
- lw t1, 0(t0) # Current table length.
- li t2, 12 # Calculate the offset to the next entry.
- mul t2, t1, t2
- addi t2, t2, 4
- add t2, t0, t2
-
- sw a0, 0(t2)
- sw a1, 4(t2)
- sw a2, 8(t2)
-
- addi t1, t1, 1 # Save the new length.
- sw t1, 0(t0)
-
- ret
-
-# Build the initial symbols.
-#
-# Sets a0 to the pointer to the global symbol table.
-.type symbol_build, @function
-symbol_table_build:
- # Prologue.
- addi sp, sp, -16
- sw ra, 12(sp)
- sw s0, 8(sp)
- addi s0, sp, 16
-
- la a0, symbol_table
- addi t0, a0, 4
-
- li a0, 3 # Length of the word "Int".
- la a1, symbol_builtin_name_int
- la a2, symbol_builtin_type_int
- call symbol_table_enter
-
- li a0, 4 # Length of the word "Word".
- la a1, symbol_builtin_name_word
- la a2, symbol_builtin_type_word
- call symbol_table_enter
-
- li a0, 4 # Length of the word "Byte".
- la a1, symbol_builtin_name_byte
- la a2, symbol_builtin_type_byte
- call symbol_table_enter
-
- li a0, 4 # Length of the word "Char".
- la a1, symbol_builtin_name_char
- la a2, symbol_builtin_type_char
- call symbol_table_enter
-
- li a0, 4 # Length of the word "Bool".
- la a1, symbol_builtin_name_bool
- la a2, symbol_builtin_type_bool
- call symbol_table_enter
-
- # Epilogue.
- lw ra, 12(sp)
- lw s0, 8(sp)
- addi sp, sp, 16
- ret