diff --git a/Rakefile b/Rakefile index ef74301..4398ef8 100644 --- a/Rakefile +++ b/Rakefile @@ -66,36 +66,3 @@ end file 'build/stage2b' => ['build/stage2b.s', 'boot/common-boot.s'] do |t| sh CROSS_GCC, '-nostdlib', '-o', t.name, *t.prerequisites end - -desc 'Print remaining lines to rewrite' -task :statistics do - def is_false_positive(word) - word.start_with?('(*') || - word.start_with?('*)') || - ('A'..'Z').include?(word[0]) || - /^[[:alpha:]][[:digit:]]$/.match(word) || - ['end', 'if'].include?(word) - end - - lines = File.read('boot/stage2.elna') - .split("\n") - .select { |line| line.start_with? "\t" } - .map { |line| line.delete_prefix("\t").split(' ') } - .reject { |words| is_false_positive(words.first) } - .group_by do |words| - if words.first.length < 5 - case words.first - when 'goto' - 'Statements' - else - words.first - end - else - 'Statements' - end - end - - lines.each do |key, value| - puts "#{key}: #{value.count}" - end -end diff --git a/boot/common-boot.s b/boot/common-boot.s index e5796f1..0cf31f1 100644 --- a/boot/common-boot.s +++ b/boot/common-boot.s @@ -1,6 +1,6 @@ .global _is_alpha, _is_digit, _is_alnum, _is_upper, _is_lower .global _write_out, _read_file, _write_error, _put_char, _printi -.global _get, _memcmp +.global _get, _memcmp, _memchr, _memmem, _memcpy .global _divide_by_zero_error, _exit .section .rodata @@ -16,7 +16,8 @@ new_line: .ascii "\n" .section .text -# Write the current token to stderr. +# Write the current token to stderr. Ends the output with a newline. +# # a0 - String pointer. # a1 - String length. .type _write_error, @function @@ -306,3 +307,120 @@ _put_char: _get: lw a0, (a0) ret + +# Searches for the occurences of a character in the given memory block. +# +# Parameters: +# a0 - Memory block. +# a1 - Needle. +# a2 - Memory size. +# +# Sets a0 to the pointer to the found character or to null if the character +# doesn't occur in the memory block. +.type _memchr, @function +_memchr: +.Lmemchr_loop: + beqz a2, .Lmemchr_nil # Exit if the length is 0. + + lbu t0, (a0) # Load the character from the memory block. + beq t0, a1, .Lmemchr_end # Exit if the character was found. + + # Otherwise, continue with the next character. + addi a0, a0, 1 + addi a2, a2, -1 + + j .Lmemchr_loop + +.Lmemchr_nil: + li a0, 0 + +.Lmemchr_end: + ret + +# Locates a substring. +# +# Parameters: +# a0 - Haystack. +# a1 - Haystack size. +# a2 - Needle. +# a3 - Needle size. +# +# Sets a0 to the pointer to the beginning of the substring in memory or to 0 +# if the substring doesn't occur in the block. +.type _memmem, @function +_memmem: + # Prologue. + addi sp, sp, -24 + sw ra, 20(sp) + sw s0, 16(sp) + addi s0, sp, 24 + + # Save preserved registers. They are used to keep arguments. + sw s1, 12(sp) + sw s2, 8(sp) + sw s3, 4(sp) + sw s4, 0(sp) + + mv s1, a0 + mv s2, a1 + mv s3, a2 + mv s4, a3 + +.Lmemmem_loop: + blt s2, s3, .Lmemmem_nil # Exit if the needle length is greater than memory. + + mv a0, s1 + mv a1, s3 + mv a2, s4 + call _memcmp + + mv t0, a0 # memcmp result. + mv a0, s1 # Memory pointer for the case the substring was found. + beqz t0, .Lmemmem_end + + addi s1, s1, 1 + add s2, s2, -1 + + j .Lmemmem_loop + +.Lmemmem_nil: + li a0, 0 + +.Lmemmem_end: + + # Restore the preserved registers. + lw s1, 12(sp) + lw s2, 8(sp) + lw s3, 4(sp) + lw s4, 0(sp) + + # Epilogue. + lw ra, 20(sp) + lw s0, 16(sp) + add sp, sp, 24 + ret + +# Copies memory. +# +# Parameters: +# a0 - Destination. +# a1 - Source. +# a2 - Size. +# +# Preserves a0. +.type _memcpy, @function +_memcpy: + mv t0, a0 + +.Lmemcpy_loop: + beqz a2, .Lmemcpy_end + + lbu t1, (a1) + sb t1, (a0) + + addi a0, a0, 1 + addi a1, a1, 1 + +.Lmemcpy_end: + mv a0, t0 + ret diff --git a/boot/stage1.s b/boot/stage1.s index 7137edc..e591e21 100644 --- a/boot/stage1.s +++ b/boot/stage1.s @@ -207,11 +207,66 @@ _build_binary_expression: addi sp, sp, 32 ret +# Checks whether the given identifier starts with "loca". +# Parameters: +# a0 - Pointer to the identifier. +# a1 - Identifier length. +# +# Sets a0 to 1 if the identifier starts with "loca", otherwise to 0. +.type _is_local_identifier, @function +_is_local_identifier: + # Prologue. + addi sp, sp, -16 + sw ra, 12(sp) + sw s0, 8(sp) + addi s0, sp, 16 + + li t0, 0x61636f6c # loca + sw t0, 4(sp) + # a0 is already set. + addi a1, sp, 4 + li a2, 4 + call _memcmp + seqz a0, a0 + + # Epilogue. + lw ra, 12(sp) + lw s0, 8(sp) + addi sp, sp, 16 + ret + +# Checks whether the given identifier is a saved register name, like s1 or s2. +# Parameters: +# a0 - Pointer to the identifier. +# a1 - Identifier length. +# +# Sets a0 to 1 if the identifier is a preserved register, otherwise to 0. +.type _is_register_identifier, @function +_is_register_identifier: + # Prologue. + addi sp, sp, -8 + sw ra, 4(sp) + sw s0, 0(sp) + addi s0, sp, 8 + + lbu a0, (a0) + addi a1, a1, -2 + seqz a1, a1 + addi t0, a0, -'s' + seqz t0, t0 + and a0, a1, t0 + + # Epilogue. + lw ra, 4(sp) + lw s0, 0(sp) + addi sp, sp, 8 + ret + # Parameters: # a0 - Identifier length. # a1 - Register number as character. -.type _build_identifier_expression, @function -_build_identifier_expression: +.type _compile_identifier_expression, @function +_compile_identifier_expression: # Prologue. addi sp, sp, -32 sw ra, 28(sp) @@ -221,22 +276,15 @@ _build_identifier_expression: sw a0, 20(sp) # Identifier length. sw a1, 16(sp) # Register number as character. - li t0, 0x61636f6c # loca - sw t0, 12(sp) mv a0, s1 - addi a1, sp, 12 - li a2, 4 - call _memcmp - beqz a0, .Lbuild_identifier_expression_local + lw a1, 20(sp) + call _is_local_identifier + bnez a0, .Lcompile_identifier_expression_local - lbu a0, (s1) - lw t0, 20(sp) - addi t0, t0, -2 - seqz t0, t0 - addi t1, a0, -'s' - seqz t1, t1 - and t0, t0, t1 - bnez t0, .Lbuild_identifier_expression_saved + mv a0, s1 + lw a1, 20(sp) + call _is_register_identifier + bnez a0, .Lcompile_identifier_expression_saved # Global identifier. lw t1, 16(sp) @@ -258,7 +306,7 @@ _build_identifier_expression: lbu a0, (s1) call _is_upper - beqz a0, .Lbuild_identifier_expression_end + beqz a0, .Lcompile_identifier_expression_end lw t1, 16(sp) li t0, 0x0a290061 # a\0)\n @@ -274,9 +322,9 @@ _build_identifier_expression: li a1, 12 call _write_out - j .Lbuild_identifier_expression_end + j .Lcompile_identifier_expression_end -.Lbuild_identifier_expression_saved: +.Lcompile_identifier_expression_saved: li t0, 0x00202c00 # \0,_ lw t1, 16(sp) or t0, t0, t1 @@ -294,9 +342,9 @@ _build_identifier_expression: li a0, '\n' call _put_char - j .Lbuild_identifier_expression_end + j .Lcompile_identifier_expression_end -.Lbuild_identifier_expression_local: +.Lcompile_identifier_expression_local: lw t1, 16(sp) li t0, 0x00202c00 # \0,_ or t0, t0, t1 @@ -321,9 +369,9 @@ _build_identifier_expression: li a0, '\n' call _put_char - j .Lbuild_identifier_expression_end + j .Lcompile_identifier_expression_end -.Lbuild_identifier_expression_end: +.Lcompile_identifier_expression_end: # Epilogue. lw ra, 28(sp) @@ -368,7 +416,7 @@ _build_expression: lw a0, 20(sp) lw a1, 28(sp) - call _build_identifier_expression + call _compile_identifier_expression j .Lbuild_expression_advance @@ -455,6 +503,86 @@ _build_expression: addi sp, sp, 40 ret +# Compiles an lvalue. +# +# Parameters: +# a0 - Pointer to the identifier. +# a1 - Identifier length. +.type _compile_designator_expression, @function +_compile_designator_expression: + # Prologue. + addi sp, sp, -32 + sw ra, 28(sp) + sw s0, 24(sp) + addi s0, sp, 32 + + sw a0, 20(sp) # Identifier pointer. + sw a1, 16(sp) # Identifier length. + + lw a0, 20(sp) + lw a1, 16(sp) + call _is_local_identifier + bnez a0, .Lcompile_designator_expression_local + + lw a0, 20(sp) + lw a1, 16(sp) + call _is_register_identifier + bnez a0, .Lcompile_designator_expression_saved + +.Lcompile_designator_expression_local: + li t0, 0x202c30 # 0,_ + sw t0, 12(sp) + li t0, 0x61207773 # sw a + sw t0, 8(sp) + addi a0, sp, 8 + li a1, 7 + call _write_out + + lw a0, 20(sp) + lw a1, 16(sp) + addi a0, a0, 4 # Skip the "loca" variable prefix. + addi a1, a1, -4 # Skip the "loca" variable prefix. + call _write_out + + li t0, '\n' + sw t0, 12(sp) + li t0, 0x29707328 # (sp) + sw t0, 8(sp) + addi a0, sp, 8 + li a1, 5 + call _write_out + + j .Lcompile_designator_expression_end + +.Lcompile_designator_expression_saved: + li t0, 0x20766d # mv_ + sw t0, 12(sp) + addi a0, sp, 12 + li a1, 3 + call _write_out + + lw a0, 20(sp) + lw a1, 16(sp) + call _write_out + + li t0, 0x0a # \n + sw t0, 12(sp) + li t0, 0x3061202c # , a0 + sw t0, 8(sp) + addi a0, sp, 8 + li a1, 5 + call _write_out + + j .Lcompile_designator_expression_end + +.Lcompile_designator_expression_end: + + # Epilogue. + lw ra, 28(sp) + lw s0, 24(sp) + addi sp, sp, 32 + ret + # Compiles a statement beginning with an identifier. # # Left values should be variables named "loca n", where n is the offset @@ -508,28 +636,9 @@ _compile_identifier: .Lcompile_identifier_assign: call _build_binary_expression - - li t0, 0x202c30 # 0,_ - sw t0, 12(sp) - li t0, 0x61207773 # sw a - sw t0, 8(sp) - addi a0, sp, 8 - li a1, 7 - call _write_out - lw a0, 20(sp) lw a1, 16(sp) - addi a0, a0, 4 # Skip the "loca" variable prefix. - addi a1, a1, -4 # Skip the "loca" variable prefix. - call _write_out - - li t0, '\n' - sw t0, 12(sp) - li t0, 0x29707328 # (sp) - sw t0, 8(sp) - addi a0, sp, 8 - li a1, 5 - call _write_out + call _compile_designator_expression j .Lcompile_identifier_end @@ -1310,11 +1419,7 @@ _compile_label: addi s0, sp, 16 sw a0, 0(sp) # Save the line length. - - # Write the whole line as is. - mv a0, s1 - lw a1, 0(sp) - call _write_out + mv a1, a0 # Argument for _write_out later. lw t0, 0(sp) # Line length. mv t1, s1 # Line start. @@ -1323,8 +1428,15 @@ _compile_label: addi t1, t1, -1 # Last character on the line. lbu t1, (t1) - li t2, ':' - beq t1, t2, .Lcompile_label_colon + li t2, ';' + bne t1, t2, .Lcompile_label_colon + + addi a1, a1, -1 + +.Lcompile_label_colon: + # Write the whole line as is. + mv a0, s1 + call _write_out li t0, 0x3a # : sw t0, 4(sp) @@ -1332,7 +1444,6 @@ _compile_label: li a1, 1 call _write_out -.Lcompile_label_colon: li t0, '\n' sw t0, 4(sp) addi a0, sp, 4 @@ -1411,12 +1522,6 @@ _compile_if: call _put_char .Lcompile_if_loop: - /* DEBUG - mv a0, s1 - li a1, 6 - call _write_error - call _divide_by_zero_error */ - call _skip_spaces call _read_token @@ -1532,13 +1637,15 @@ _compile_line: call _memcmp beqz a0, .Lcompile_line_exit - li t0, 0x61636f6c # loca - sw t0, 12(sp) mv a0, s1 - addi a1, sp, 12 - li a2, 4 - call _memcmp - beqz a0, .Lcompile_line_identifier + lw a1, 20(sp) + call _is_local_identifier + bnez a0, .Lcompile_line_identifier + + mv a0, s1 + li a1, 2 + call _is_register_identifier + bnez a0, .Lcompile_line_identifier li t0, 0x6f706d69 # impo sw t0, 12(sp) @@ -1806,9 +1913,6 @@ _main: .type _start, @function _start: call _tokenizer_initialize - li a1, 50 - call _write_error - call _main call _compile diff --git a/boot/stage2.elna b/boot/stage2.elna index 3cb2deb..366096e 100644 --- a/boot/stage2.elna +++ b/boot/stage2.elna @@ -1,5 +1,6 @@ (* s1 - Contains the current position in the source text. +s2 - Label counter. - The compiler expects valid input, otherwise it will generate invalid assembly or hang. There is no error checking, no semantic analysis, no @@ -17,6 +18,8 @@ hexadecimal format). - Return can be used only as the last statement of a procedure. It doesn't actually return, but sets a0 to the appropriate value. + +- The lvalue of an assignment can only be an identifier. *) program @@ -32,9 +35,9 @@ var proc _compile_import() var loca0: Word begin - _advance(6) - _skip_spaces() - loca0 := _read_token() + _advance(6); + _skip_spaces(); + loca0 := _read_token(); _advance(loca0) (* Skip the imported module name. *) end @@ -44,188 +47,193 @@ var loca12: ^Byte loca24: Bool begin - _build_expression(0) + _build_expression(0); - loca4 := 0x2c306120 (* _a0, *) - loca8 := 0x0a316120 (* _a1\n *) + loca4 := 0x2c306120 (* _a0, *); + loca8 := 0x0a316120 (* _a1\n *); - _skip_spaces() - loca20 := _read_token() - loca12 := _current() + _skip_spaces(); + loca20 := _read_token(); + loca12 := _current(); - loca16 := 0x26 (* & *) - loca24 := _token_compare(loca12, loca20, @loca16) + loca16 := 0x26 (* & *); + loca24 := _token_compare(loca12, loca20, @loca16); if loca24 = 0 then goto .L_build_binary_expression_and - end + end; - loca16 := 0x726f (* or *) - loca24 := _token_compare(loca12, loca20, @loca16) + loca16 := 0x726f (* or *); + loca24 := _token_compare(loca12, loca20, @loca16); if loca24 = 0 then goto .L_build_binary_expression_or - end + end; - loca16 := 0x3d (* = *) - loca24 := _token_compare(loca12, loca20, @loca16) + loca16 := 0x3d (* = *); + loca24 := _token_compare(loca12, loca20, @loca16); if loca24 = 0 then goto .L_build_binary_expression_equal - end + end; - loca16 := 0x2b (* + *) - loca24 := _token_compare(loca12, loca20, @loca16) + loca16 := 0x2b (* + *); + loca24 := _token_compare(loca12, loca20, @loca16); if loca24 = 0 then goto .L_build_binary_expression_plus - end + end; - loca16 := 0x2d (* - *) - loca24 := _token_compare(loca12, loca20, @loca16) + loca16 := 0x2d (* - *); + loca24 := _token_compare(loca12, loca20, @loca16); if loca24 = 0 then goto .L_build_binary_expression_minus end - loca16 := 0x2a (* * *) - loca24 := _token_compare(loca12, loca20, @loca16) + loca16 := 0x2a (* * *); + loca24 := _token_compare(loca12, loca20, @loca16); if loca24 = 0 then goto .L_build_binary_expression_product - end + end; - goto .Lbuild_binary_expression_end + goto .Lbuild_binary_expression_end; - .L_build_binary_expression_equal - _advance(1) (* Skip =. *) - _build_expression(1) + .L_build_binary_expression_equal; + _advance(1) (* Skip =. *); + _build_expression(1); - loca0 := 0x627573(* sub *) - _write_out(@loca0, 3) - _write_out(@loca4, 4) - _write_out(@loca4, 4) - _write_out(@loca8, 4) + loca0 := 0x627573(* sub *); + _write_out(@loca0, 3); + _write_out(@loca4, 4); + _write_out(@loca4, 4); + _write_out(@loca8, 4); - loca0 := 0x7a716573 (* seqz *) - _write_out(@loca0, 4) - _write_out(@loca4, 4) - _write_out(@loca4, 3) - _put_char(0x0a) (* \n *) + loca0 := 0x7a716573 (* seqz *); + _write_out(@loca0, 4); + _write_out(@loca4, 4); + _write_out(@loca4, 3); + _put_char(0x0a) (* \n *); - goto .Lbuild_binary_expression_end + goto .Lbuild_binary_expression_end; - .L_build_binary_expression_and - _advance(1) (* Skip &. *) - _build_expression(1) - loca0 := 0x646e61 (* and *) - _write_out(@loca0, 3) - _write_out(@loca4, 4) - _write_out(@loca4, 4) - _write_out(@loca8, 4) + .L_build_binary_expression_and; + _advance(1) (* Skip &. *); + _build_expression(1); + loca0 := 0x646e61 (* and *); + _write_out(@loca0, 3); + _write_out(@loca4, 4); + _write_out(@loca4, 4); + _write_out(@loca8, 4); - goto .Lbuild_binary_expression_end + goto .Lbuild_binary_expression_end; - .L_build_binary_expression_or - _advance(2) (* Skip or. *) - _build_expression(1) - loca0 := 0x726f (* or *) - _write_out(@loca0, 2) - _write_out(@loca4, 4) - _write_out(@loca4, 4) - _write_out(@loca8, 4) + .L_build_binary_expression_or; + _advance(2) (* Skip or. *); + _build_expression(1); + loca0 := 0x726f (* or *); + _write_out(@loca0, 2); + _write_out(@loca4, 4); + _write_out(@loca4, 4); + _write_out(@loca8, 4); - goto .Lbuild_binary_expression_end + goto .Lbuild_binary_expression_end; - .L_build_binary_expression_plus - _advance(1) (* Skip +. *) - _build_expression(1) - loca0 := 0x646461 (* add *) - _write_out(@loca0, 3) - _write_out(@loca4, 4) - _write_out(@loca4, 4) - _write_out(@loca8, 4) + .L_build_binary_expression_plus; + _advance(1) (* Skip +. *); + _build_expression(1); + loca0 := 0x646461 (* add *); + _write_out(@loca0, 3); + _write_out(@loca4, 4); + _write_out(@loca4, 4); + _write_out(@loca8, 4); - goto .Lbuild_binary_expression_end + goto .Lbuild_binary_expression_end; - .L_build_binary_expression_minus - _advance(1) (* Skip -. *) - _build_expression(1) - loca0 := 0x627573 (* sub *) - _write_out(@loca0, 3) - _write_out(@loca4, 4) - _write_out(@loca4, 4) - _write_out(@loca8, 4) + .L_build_binary_expression_minus; + _advance(1) (* Skip -. *); + _build_expression(1); + loca0 := 0x627573 (* sub *); + _write_out(@loca0, 3); + _write_out(@loca4, 4); + _write_out(@loca4, 4); + _write_out(@loca8, 4); - goto .Lbuild_binary_expression_end + goto .Lbuild_binary_expression_end; - .L_build_binary_expression_product - _advance(1) (* Skip *. *) - _build_expression(1) - loca0 := 0x6c756d (* mul *) - _write_out(@loca0, 3) - _write_out(@loca4, 4) - _write_out(@loca4, 4) - _write_out(@loca8, 4) + .L_build_binary_expression_product; + _advance(1) (* Skip *. *); + _build_expression(1); + loca0 := 0x6c756d (* mul *); + _write_out(@loca0, 3); + _write_out(@loca4, 4); + _write_out(@loca4, 4); + _write_out(@loca8, 4); - goto .Lbuild_binary_expression_end + goto .Lbuild_binary_expression_end; .Lbuild_binary_expression_end end -proc _build_identifier_expression(loca84: Word, loca80: Byte) +(* +Parameters: +a0 - Identifier length. +a1 - Register number as character. +*) +proc _compile_identifier_expression(loca84: Word, loca80: Byte) begin - loca24 := _current() - loca0 := 0x61636f6c (* loca *) - loca0 := _memcmp(@loca0, loca24, 4) + loca24 := _current(); + loca0 := 0x61636f6c (* loca *); + loca0 := _memcmp(@loca0, loca24, 4); if loca0 = 0 then - loca8 := 0x6120776c (* lw a *) - _write_out(@loca8, 4) - loca8 := 0x00202c00 or loca80 (* \0,_ *) - _write_out(@loca8, 3) + loca8 := 0x6120776c (* lw a *); + _write_out(@loca8, 4); + loca8 := 0x00202c00 or loca80 (* \0,_ *); + _write_out(@loca8, 3); - loca4 := loca24 + 4 - loca0 := loca84 - 4 - _write_out(loca4, loca0) (* Skip the "loca" variable prefix. *) + loca4 := loca24 + 4; + loca0 := loca84 - 4; + _write_out(loca4, loca0) (* Skip the "loca" variable prefix. *); - loca8 := 0x29707328 (* (sp) *) - _write_out(@loca8, 4) - _put_char(0x0a) (* \n *) + loca8 := 0x29707328 (* (sp) *); + _write_out(@loca8, 4); + _put_char(0x0a) (* \n *); - goto .Lbuild_identifier_expression_end - end - loca0 := _front(loca24) - loca8 := loca84 = 2 - loca12 := loca0 = 0x73 + goto .Lcompile_identifier_expression_end + end; + loca0 := _front(loca24); + loca8 := loca84 = 2; + loca12 := loca0 = 0x73; if loca8 & loca12 then - loca8 := 0x6120766d (* mv a *) - _write_out(@loca8, 4) - loca8 := 0x00202c00 or loca80 (* \0,_ *) - _write_out(@loca8, 3) - _write_out(loca24, loca84) - _put_char(0x0a) (* \n *) + loca8 := 0x6120766d (* mv a *); + _write_out(@loca8, 4); + loca8 := 0x00202c00 or loca80 (* \0,_ *); + _write_out(@loca8, 3); + _write_out(loca24, loca84); + _put_char(0x0a) (* \n *); - goto .Lbuild_identifier_expression_end + goto .Lcompile_identifier_expression_end end - (* Global identifier. *) - loca8 := 0x6120616c (* la a *) - _write_out(@loca8, 4) - loca8 := 0x00202c00 or loca80 - _write_out(@loca8, 3) + (* Global identifier. *); + loca8 := 0x6120616c (* la a *); + _write_out(@loca8, 4); + loca8 := 0x00202c00 or loca80; + _write_out(@loca8, 3); - _write_out(loca24, loca84) - _put_char(0x0a) + _write_out(loca24, loca84); + _put_char(0x0a); if _is_upper(loca0) then - loca8 := 0x6120776c (* lw a *) - _write_out(@loca8, 4) - loca8 := 0x28202c00 or loca28 (* \0, ( *) - _write_out(@loca8, 4) - _put_char(0x61) (* a *) - _put_char(loca28) - _put_char(0x29) (* ) *) - _put_char(0x0a) (* \n *) + loca8 := 0x6120776c (* lw a *); + _write_out(@loca8, 4); + loca8 := 0x28202c00 or loca28 (* \0, ( *); + _write_out(@loca8, 4); + _put_char(0x61) (* a *); + _put_char(loca28); + _put_char(0x29) (* ) *); + _put_char(0x0a) (* \n *); - goto .Lbuild_identifier_expression_end - end + goto .Lcompile_identifier_expression_end + end; - .Lbuild_identifier_expression_end + .Lcompile_identifier_expression_end end (* @@ -239,97 +247,144 @@ var loca24, loca4: ^Byte begin (* Make the register number to a character and save it. *) - loca28 := loca84 + 0x30 (* 0 *) + loca28 := loca84 + 0x30 (* 0 *); - _skip_spaces() - loca20 := _read_token() - loca24 := _current() - loca0 := _front(loca24) + _skip_spaces(); + loca20 := _read_token(); + loca24 := _current(); + loca0 := _front(loca24); (* - *) if loca0 = 0x2d then goto .Lbuild_expression_negate - end + end; (* @ *) if loca0 = 0x40 then goto .Lbuild_expression_address - end + end; if _is_digit(loca0) then goto .Lbuild_expression_literal - end + end; (* _ *) if loca0 = 0x5f then goto .Lbuild_expression_call - end + end; - _build_identifier_expression(loca20, loca28); - goto .Lbuild_expression_advance + _compile_identifier_expression(loca20, loca28); + goto .Lbuild_expression_advance; - .Lbuild_expression_negate - _advance(1) (* Skip the -. *) - _build_expression(0) + .Lbuild_expression_negate; + _advance(1) (* Skip the -. *); + _build_expression(0); - loca8 := 0x2067656e (* neg_ *) - _write_out(@loca8, 4) - loca8 := 0x202c3061 (* a0,_ *) - _write_out(@loca8, 4) - loca8 := 0x0a3061 (* a0,_ *) - _write_out(@loca8, 3) + loca8 := 0x2067656e (* neg_ *); + _write_out(@loca8, 4); + loca8 := 0x202c3061 (* a0,_ *); + _write_out(@loca8, 4); + loca8 := 0x0a3061 (* a0,_ *); + _write_out(@loca8, 3); - goto .Lbuild_expression_advance + goto .Lbuild_expression_advance; - .Lbuild_expression_address - loca8 := 0x69646461 (* addi *) - _write_out(@loca8, 4) - loca8 := 0x6120 (* _a *) - _write_out(@loca8, 2) - _put_char(loca28) - loca8 := 0x7073202c (* , sp *) - _write_out(@loca8, 4) - loca8 := 0x202c (* ,_ *) - _write_out(@loca8, 2) + .Lbuild_expression_address; + loca8 := 0x69646461 (* addi *); + _write_out(@loca8, 4); + loca8 := 0x6120 (* _a *); + _write_out(@loca8, 2); + _put_char(loca28); + loca8 := 0x7073202c (* , sp *); + _write_out(@loca8, 4); + loca8 := 0x202c (* ,_ *); + _write_out(@loca8, 2); - _advance(1) (* Skip @. *) - _skip_spaces() - loca24 := _current() - loca20 := _read_token() + _advance(1) (* Skip @. *); + _skip_spaces(); + loca24 := _current(); + loca20 := _read_token(); (* Skip the "loca" variable prefix. *) - loca4 := loca24 + 4 - loca0 := loca20 - 4 - _write_out(loca4, loca0) + loca4 := loca24 + 4; + loca0 := loca20 - 4; + _write_out(loca4, loca0); - _put_char(0xa) + _put_char(0xa); - goto .Lbuild_expression_advance + goto .Lbuild_expression_advance; - .Lbuild_expression_call - _advance(loca20) - _advance(1) - _compile_call(loca24, loca20) + .Lbuild_expression_call; + _advance(loca20); + _advance(1); + _compile_call(loca24, loca20); - goto .Lbuild_expression_end + goto .Lbuild_expression_end; - .Lbuild_expression_literal - loca8 := 0x6120696c (* li a *) - _write_out(@loca8, 4) - loca8 := 0x00202c00 or loca28 (* \0,_ *) - _write_out(@loca8, 3) + .Lbuild_expression_literal; + loca8 := 0x6120696c (* li a *); + _write_out(@loca8, 4); + loca8 := 0x00202c00 or loca28 (* \0,_ *); + _write_out(@loca8, 3); - _write_out(loca24, loca20) - _put_char(0x0a) (* \n *) + _write_out(loca24, loca20); + _put_char(0x0a) (* \n *); - goto .Lbuild_expression_advance + goto .Lbuild_expression_advance; - .Lbuild_expression_advance - _advance(loca20) + .Lbuild_expression_advance; + _advance(loca20); .Lbuild_expression_end end +(* +Compiles an lvalue. + +Parameters: +a0 - Pointer to the identifier. +a1 - Identifier length. +*) +proc _compile_designator_expression(loca84: ^Byte, loca80: Word) +var + loca0: Word +begin + loca0 := 0x61636f6c (* loca *); + loca4 := _memcmp(@loca0, loca84, 4); + + if loca4 = 0 then + loca0 := 0x61207773 (* sw a *); + _write_out(@loca0, 4); + loca0 := 0x202c30 (* 0,_ *); + _write_out(@loca0, 3); + + loca84 := loca84 + 4; + loca80 := loca80 - 4; + _write_out(loca84, loca80); + + loca0 := 0x29707328 (* (sp) *); + _write_out(@loca0, 4); + _put_char(0x0a) (* \n *); + + goto .Lcompile_designator_expression_end + end; + loca8 := _front(loca84); + loca12 := loca8 = 0x73 (* s *); + loca16 := loca80 = 2; + if loca12 & loca16 then + loca0 := 0x20766d (* mv_ *); + _write_out(@loca0, 3); + _write_out(loca84, loca80); + loca0 := 0x3061202c (* , a0 *); + _write_out(@loca0, 4); + _put_char(0x0a) (* \n *); + + goto .Lcompile_designator_expression_end + end; + + .Lcompile_designator_expression_end +end + (* Compiles a statement beginning with an identifier. @@ -343,53 +398,32 @@ var loca4: Bool begin (* Save the pointer to the identifier and its length on the stack. *) - loca20 := _current() - loca16 := _read_token() + loca20 := _current(); + loca16 := _read_token(); - _advance(loca16) - _skip_spaces() + _advance(loca16); + _skip_spaces(); (* Save the pointer and the length of the token following the identifier. *) - loca12 := _current() - loca8 := _read_token() + loca12 := _current(); + loca8 := _read_token(); - _advance(loca8) (* Skip that token. *) - _skip_spaces() + _advance(loca8) (* Skip that token. *); + _skip_spaces(); - loca0 := 0x3d3a (* := *) - loca4 := _token_compare(loca12, loca8, @loca0) + loca0 := 0x3d3a (* := *); + loca4 := _token_compare(loca12, loca8, @loca0); if loca4 = 0 then - goto .Lcompile_identifier_assign - end + _build_binary_expression(); + _compile_designator_expression(loca20, loca16); + goto .Lcompile_identifier_end + end; if _front(loca12) = 0x28 then - goto .Lcompile_identifier_call - end + _compile_call(loca20, loca16); - goto .Lcompile_identifier_end - - .Lcompile_identifier_call - _compile_call(loca20, loca16) - - goto .Lcompile_identifier_end - - .Lcompile_identifier_assign - _build_binary_expression() - - loca0 := 0x61207773 (* sw a *) - _write_out(@loca0, 4) - loca0 := 0x202c30 (* 0,_ *) - _write_out(@loca0, 3) - - loca20 := loca20 + 4 - loca16 := loca16 - 4 - _write_out(loca20, loca16) - - loca0 := 0x29707328 (* (sp) *) - _write_out(@loca0, 4) - _put_char(0x0a) (* \n *) - - goto .Lcompile_identifier_end + goto .Lcompile_identifier_end + end; .Lcompile_identifier_end end @@ -406,118 +440,118 @@ var loca0, loca4, loca12: Word loca8: ^Byte begin - loca12 := 0 (* Argument count for a procedure call. *) + loca12 := 0 (* Argument count for a procedure call. *); - .Lcompile_call_paren - _skip_spaces() - loca8 := _current() + .Lcompile_call_paren; + _skip_spaces(); + loca8 := _current(); if _front(loca8) = 0x29 then goto .Lcompile_call_complete - end + end; - .Lcompile_call_argument - _build_expression(0) + .Lcompile_call_argument; + _build_expression(0); - loca0 := 0x61207773 (* sw a *) - _write_out(@loca0, 4) - loca0 := 0x202c30 (* 0,_ *) - _write_out(@loca0, 3) + loca0 := 0x61207773 (* sw a *); + _write_out(@loca0, 4); + loca0 := 0x202c30 (* 0,_ *); + _write_out(@loca0, 3); (* Only 6 arguments are supported with a0-a5. Save all arguments on the stack so they aren't overriden afterwards. *) - loca0 := -4 * loca12 - loca0 := loca0 + 60 - _printi(loca0) + loca0 := -4 * loca12; + loca0 := loca0 + 60; + _printi(loca0); - loca0 := 0x29707328 (* (sp) *) - _write_out(@loca0, 4) - _put_char(0x0a) (* \n *) + loca0 := 0x29707328 (* (sp) *); + _write_out(@loca0, 4); + _put_char(0x0a) (* \n *); - _skip_spaces() - loca8 := _current() - loca0 := _front(loca8) = 0x2c + _skip_spaces(); + loca8 := _current(); + loca0 := _front(loca8) = 0x2c; if loca0 = 0 then goto .Lcompile_call_paren end - loca12 := loca12 + 1 (* Argument count for a procedure call. *) + loca12 := loca12 + 1 (* Argument count for a procedure call. *); - _advance(1) (* Skip the comma between the arguments. *) - goto .Lcompile_call_argument + _advance(1) (* Skip the comma between the arguments. *); + goto .Lcompile_call_argument; - .Lcompile_call_complete - loca12 := 0 + .Lcompile_call_complete; + loca12 := 0; - .Lcompile_call_restore + .Lcompile_call_restore; (* Just go through all a0-a5 registers and read them from stack. If this stack value contains garbage, the procedure just shouldn't use it. *) - loca0 := 0x6120776c (* lw a *) + loca0 := 0x6120776c (* lw a *); (* lw a0, 60(sp) *) - _write_out(@loca0, 4) - loca4 := 0x36202c30 (* 0, 6 *) - _write_out(@loca4, 4) - loca4 := 0x70732830 (* 0(sp *) - _write_out(@loca4, 4) - loca4 := 0x0a29 (* )\n *) - _write_out(@loca4, 2) + _write_out(@loca0, 4); + loca4 := 0x36202c30 (* 0, 6 *); + _write_out(@loca4, 4); + loca4 := 0x70732830 (* 0(sp *); + _write_out(@loca4, 4); + loca4 := 0x0a29 (* )\n *); + _write_out(@loca4, 2); (* lw a1, 56(sp) *) - _write_out(@loca0, 4) - loca4 := 0x35202c31 (* 1, 5 *) - _write_out(@loca4, 4) - loca4 := 0x70732836 (* 6(sp *) - _write_out(@loca4, 4) - loca4 := 0x0a29 (* )\n *) - _write_out(@loca4, 2) + _write_out(@loca0, 4); + loca4 := 0x35202c31 (* 1, 5 *); + _write_out(@loca4, 4); + loca4 := 0x70732836 (* 6(sp *); + _write_out(@loca4, 4); + loca4 := 0x0a29 (* )\n *); + _write_out(@loca4, 2); (* lw a2, 52(sp) *) - _write_out(@loca0, 4) - loca4 := 0x35202c32 (* 2, 5 *) - _write_out(@loca4, 4) - loca4 := 0x70732832 (* 2(sp *) - _write_out(@loca4, 4) - loca4 := 0x0a29 (* )\n *) - _write_out(@loca4, 2) + _write_out(@loca0, 4); + loca4 := 0x35202c32 (* 2, 5 *); + _write_out(@loca4, 4); + loca4 := 0x70732832 (* 2(sp *); + _write_out(@loca4, 4); + loca4 := 0x0a29 (* )\n *); + _write_out(@loca4, 2); (* lw a3, 48(sp) *) - _write_out(@loca0, 4) - loca4 := 0x34202c33 (* 3, 4 *) - _write_out(@loca4, 4) - loca4 := 0x70732838 (* 8(sp *) - _write_out(@loca4, 4) - loca4 := 0x0a29 (* )\n *) - _write_out(@loca4, 2) + _write_out(@loca0, 4); + loca4 := 0x34202c33 (* 3, 4 *); + _write_out(@loca4, 4); + loca4 := 0x70732838 (* 8(sp *); + _write_out(@loca4, 4); + loca4 := 0x0a29 (* )\n *); + _write_out(@loca4, 2); (* lw a4, 44(sp) *) - _write_out(@loca0, 4) - loca4 := 0x34202c34 (* 4, 4 *) - _write_out(@loca4, 4) - loca4 := 0x70732834 (* 4(sp *) - _write_out(@loca4, 4) - loca4 := 0x0a29 (* )\n *) - _write_out(@loca4, 2) + _write_out(@loca0, 4); + loca4 := 0x34202c34 (* 4, 4 *); + _write_out(@loca4, 4); + loca4 := 0x70732834 (* 4(sp *); + _write_out(@loca4, 4); + loca4 := 0x0a29 (* )\n *); + _write_out(@loca4, 2); (* lw a5, 40(sp) *) - _write_out(@loca0, 4) - loca4 := 0x34202c35 (* 5, 4 *) - _write_out(@loca4, 4) - loca4 := 0x70732830 (* 0(sp *) - _write_out(@loca4, 4) - loca4 := 0x0a29 (* )\n *) - _write_out(@loca4, 2) + _write_out(@loca0, 4); + loca4 := 0x34202c35 (* 5, 4 *); + _write_out(@loca4, 4); + loca4 := 0x70732830 (* 0(sp *); + _write_out(@loca4, 4); + loca4 := 0x0a29 (* )\n *); + _write_out(@loca4, 2); - loca0 := 0x6c6c6163 (* call *) - _write_out(@loca0, 4) - _put_char(0x20) (* _ *) + loca0 := 0x6c6c6163 (* call *); + _write_out(@loca0, 4); + _put_char(0x20) (* _ *); - _write_out(loca84, loca80) - _put_char(0x0a) (* \n *) + _write_out(loca84, loca80); + _put_char(0x0a) (* \n *); - _skip_spaces() + _skip_spaces(); _advance(1) (* Skip the close paren. *) end @@ -530,112 +564,109 @@ var loca0, loca4: Word loca8: ^Byte begin - loca8 := _current() - loca0 := _front(loca8) (* t0 = Current character. *) - loca4 := 0 + loca8 := _current(); + loca0 := _front(loca8) (* t0 = Current character. *); + loca4 := 0; (* . *) if loca0 = 0x2e then goto .Ltoken_character_single - end + end; (* , *) if loca0 = 0x2c then goto .Ltoken_character_single - end + end; (* : *) if loca0 = 0x3a then goto .Ltoken_character_colon - end + end; (* ; *) if loca0 = 0x3b then goto .Ltoken_character_single - end + end; (* ( *) if loca0 = 0x28 then goto .Ltoken_character_single - end + end; (* ) *) if loca0 = 0x29 then goto .Ltoken_character_single - end + end; (* [ *) if loca0 = 0x5b then goto .Ltoken_character_single - end + end; (* ] *) if loca0 = 0x5d then goto .Ltoken_character_single - end + end; (* ^ *) if loca0 = 0x5e then goto .Ltoken_character_single - end + end; (* & *) if loca0 = 0x26 then goto .Ltoken_character_single - end + end; (* = *) if loca0 = 0x3d then goto .Ltoken_character_single - end + end; (* + *) if loca0 = 0x2b then goto .Ltoken_character_single - end + end; (* - *) if loca0 = 0x2d then goto .Ltoken_character_single - end + end; (* * *) if loca0 = 0x2a then goto .Ltoken_character_single - end + end; (* @ *) if loca0 = 0x40 then goto .Ltoken_character_single - end + end; (* Expect an identifier or a number. *) - .Ltoken_character_loop_do - loca0 := loca8 + loca4 - loca0 := _front(loca0) + .Ltoken_character_loop_do; + loca0 := loca8 + loca4; + loca0 := _front(loca0); - if _is_alnum(loca0) = 0 then - goto .Ltoken_character_end - end - loca4 := loca4 + 1 - goto .Ltoken_character_loop_do + if _is_alnum(loca0) then + loca4 := loca4 + 1; + goto .Ltoken_character_loop_do; - .Ltoken_character_single - loca4 := loca4 + 1 - goto .Ltoken_character_end + .Ltoken_character_single; + loca4 := loca4 + 1; + goto .Ltoken_character_end; - .Ltoken_character_colon - loca0 := loca8 + 1 - loca0 := _front(loca0) (* t0 = The character after the colon. *) - loca4 := loca4 + 1 + .Ltoken_character_colon; + loca0 := loca8 + 1; + loca0 := _front(loca0) (* t0 = The character after the colon. *); + loca4 := loca4 + 1; - (* = *) - if loca0 = 0x3d then - goto .Ltoken_character_single - end - goto .Ltoken_character_end - - .Ltoken_character_end + (* = *) + if loca0 = 0x3d then + goto .Ltoken_character_single + end + end; + .Ltoken_character_end; return loca4 end @@ -645,31 +676,31 @@ var loca0: Byte loca4: ^Byte begin - .Lspace_loop_do - loca4 := _current() - loca0 := _front(loca4) (* t0 = Current character. *) + .Lspace_loop_do; + loca4 := _current(); + loca0 := _front(loca4) (* t0 = Current character. *); (* _ *) if loca0 = 0x20 then goto .Lspace_loop_repeat - end + end; (* \t *) if loca0 = 0x09 then goto .Lspace_loop_repeat - end + end; (* \n *) if loca0 = 0x0a then goto .Lspace_loop_repeat - end + end; (* \r *) if loca0 = 0x0d then goto .Lspace_loop_repeat - end + end; - goto .Lspace_loop_end - .Lspace_loop_repeat - _advance(1) - goto .Lspace_loop_do + goto .Lspace_loop_end; + .Lspace_loop_repeat; + _advance(1); + goto .Lspace_loop_do; .Lspace_loop_end end @@ -684,34 +715,34 @@ var loca4: Word loca8: Int begin - loca0 := _current() + loca0 := _current(); (* Check whether this is a comment. *) - loca4 := 0x2a28 (* ( and * *) - loca8 := _memcmp(loca0, @loca4, 2) + loca4 := 0x2a28 (* ( and * *); + loca8 := _memcmp(loca0, @loca4, 2); if loca8 = 0 then goto .Lskip_comment_continue - end - goto .Lskip_comment_end + end; + goto .Lskip_comment_end; - .Lskip_comment_continue - _advance(2) (* Skip (*. *) + .Lskip_comment_continue; + _advance(2) (* Skip (*. *); - loca4 := 0x292a (* ( and * *) + loca4 := 0x292a (* ( and * *); - .Lskip_comment_loop - loca0 := _current() - loca8 := _memcmp(loca0, @loca4, 2) + .Lskip_comment_loop; + loca0 := _current(); + loca8 := _memcmp(loca0, @loca4, 2); if loca8 = 0 then goto .Lskip_comment_close - end + end; - _advance(1) + _advance(1); - goto .Lskip_comment_loop + goto .Lskip_comment_loop; - .Lskip_comment_close - _advance(2) (* Skip "*" and ")". *) + .Lskip_comment_close; + _advance(2) (* Skip "*" and ")". *); .Lskip_comment_end end @@ -724,12 +755,12 @@ proc _compile_assembly(loca84: Word) var loca0: ^Byte begin (* Write the source to the standard output. *) - loca0 := _current() + loca0 := _current(); - _write_out(loca0, loca84) - _advance(loca84) + _write_out(loca0, loca84); + _advance(loca84); - _put_char(0xa) (* \n *) + _put_char(0xa) (* \n *); _advance(1) (* Skip the new line. *) end @@ -738,14 +769,14 @@ proc _compile_program() var loca0: Word begin (* .global _start *) - loca0 := 0x6f6c672e (* .glo *) - _write_out(@loca0, 4) - loca0 := 0x206c6162 (* bal_ *) - _write_out(@loca0, 4) - loca0 := 0x6174735f (* _sta *) - _write_out(@loca0, 4) - loca0 := 0x0a7472 (* rt\n *) - _write_out(@loca0, 3) + loca0 := 0x6f6c672e (* .glo *); + _write_out(@loca0, 4); + loca0 := 0x206c6162 (* bal_ *); + _write_out(@loca0, 4); + loca0 := 0x6174735f (* _sta *); + _write_out(@loca0, 4); + loca0 := 0x0a7472 (* rt\n *); + _write_out(@loca0, 3); _advance(8) (* program\n. *) end @@ -756,29 +787,27 @@ var loca4: ^Byte begin (* .section .rodata *) - loca0 := 0x6365732e (* .sec *) - _write_out(@loca0, 4) - loca0 := 0x6e6f6974 (* tion *) - _write_out(@loca0, 4) - loca0 := 0x6f722e20 (* _.ro *) - _write_out(@loca0, 4) - loca0 := 0x61746164 (* data *) - _write_out(@loca0, 4) - loca0 := 0x0a (* \n *) - _write_out(@loca0, 1) + loca0 := 0x6365732e (* .sec *); + _write_out(@loca0, 4); + loca0 := 0x6e6f6974 (* tion *); + _write_out(@loca0, 4); + loca0 := 0x6f722e20 (* _.ro *); + _write_out(@loca0, 4); + loca0 := 0x61746164 (* data *); + _write_out(@loca0, 4); + loca0 := 0x0a (* \n *); + _write_out(@loca0, 1); - _advance(6) (* const\n. *) + _advance(6) (* const\n. *); - .Lcompile_constant_section_item - _skip_spaces() - loca4 := _current() - loca0 := _front(loca4) - if _is_upper(loca0) = 0 then - goto .Lcompile_constant_section_end - end - - _compile_constant() - goto .Lcompile_constant_section_item + .Lcompile_constant_section_item; + _skip_spaces(); + loca4 := _current(); + loca0 := _front(loca4); + if _is_upper(loca0) then + _compile_constant(); + goto .Lcompile_constant_section_item + end; .Lcompile_constant_section_end end @@ -788,27 +817,27 @@ var loca0, loca4: Word loca8: ^Byte begin - loca4 := _read_token() - loca8 := _current() (* Save the identifier pointer before advancing it. *) + loca4 := _read_token(); + loca8 := _current() (* Save the identifier pointer before advancing it. *); - _write_out(loca8, loca4) - _advance(loca4) + _write_out(loca8, loca4); + _advance(loca4); - _skip_spaces() - _advance(2) (* Skip the assignment sign. *) + _skip_spaces(); + _advance(2) (* Skip the assignment sign. *); (* : .long *) - loca0 := 0x6c2e203a (* : .l *) - _write_out(@loca0, 4) - loca0 := 0x20676e6f (* ong_ *) - _write_out(@loca0, 4) + loca0 := 0x6c2e203a (* : .l *); + _write_out(@loca0, 4); + loca0 := 0x20676e6f (* ong_ *); + _write_out(@loca0, 4); - _skip_spaces() - loca4 := _read_token() - loca8 := _current() (* Save the literal pointer before advancing it. *) + _skip_spaces(); + loca4 := _read_token(); + loca8 := _current() (* Save the literal pointer before advancing it. *); - _write_out(loca8, loca4) - _advance(loca4) + _write_out(loca8, loca4); + _advance(loca4); _put_char(0x0a) (* \n *) end @@ -819,27 +848,27 @@ var loca4: ^Byte begin (* .section .bss *) - loca0 := 0x6365732e (* .sec *) - _write_out(@loca0, 4) - loca0 := 0x6e6f6974 (* tion *) - _write_out(@loca0, 4) - loca0 := 0x73622e20 (* _.bs *) - _write_out(@loca0, 4) - loca0 := 0x0a73 (* s\n *) - _write_out(@loca0, 2) + loca0 := 0x6365732e (* .sec *); + _write_out(@loca0, 4); + loca0 := 0x6e6f6974 (* tion *); + _write_out(@loca0, 4); + loca0 := 0x73622e20 (* _.bs *); + _write_out(@loca0, 4); + loca0 := 0x0a73 (* s\n *); + _write_out(@loca0, 2); - _advance(4) (* var\n. *) + _advance(4) (* var\n. *); - .Lcompile_variable_section_item - _skip_spaces() - loca4 := _current() - loca0 := _front(loca4) + .Lcompile_variable_section_item; + _skip_spaces(); + loca4 := _current(); + loca0 := _front(loca4); if _is_lower(loca0) = 0 then goto .Lcompile_variable_section_end - end - _compile_variable() - goto .Lcompile_variable_section_item + end; + _compile_variable(); + goto .Lcompile_variable_section_item; .Lcompile_variable_section_end end @@ -850,67 +879,67 @@ var loca0, loca24, loca20: Word begin (* Save the identifier on the stack since it should emitted multiple times. *) - loca24 := _read_token() - loca28 := _current() + loca24 := _read_token(); + loca28 := _current(); - _advance(loca24) + _advance(loca24); - _skip_spaces() - _advance(1) (* Skip the colon in front of the type. *) + _skip_spaces(); + _advance(1) (* Skip the colon in front of the type. *); - _skip_spaces() - _advance(1) (* Skip the opening bracket. *) + _skip_spaces(); + _advance(1) (* Skip the opening bracket. *); (* Save the array size on the stack since it has to be emitted multiple times. *) - loca16 := _read_token() - loca20 := _current() - _advance(loca16) + loca16 := _read_token(); + loca20 := _current(); + _advance(loca16); - _skip_spaces() - _advance(1) (* Skip the closing bracket. *) + _skip_spaces(); + _advance(1) (* Skip the closing bracket. *); - _skip_spaces() - loca0 := _read_token() - _advance(loca0) (* Skip the type. *) + _skip_spaces(); + loca0 := _read_token(); + _advance(loca0) (* Skip the type. *); (* .type identifier, @object *) - loca0 := 0x7079742e (* .typ *) - _write_out(@loca0, 4) - loca0 := 0x2065 (* e_ *) - _write_out(@loca0, 2) + loca0 := 0x7079742e (* .typ *); + _write_out(@loca0, 4); + loca0 := 0x2065 (* e_ *); + _write_out(@loca0, 2); - _write_out(loca28, loca24) + _write_out(loca28, loca24); - loca0 := 0x6f40202c (* , @o *) - _write_out(@loca0, 4) - loca0 := 0x63656a62 (* bjec *) - _write_out(@loca0, 4) - loca0 := 0x0a74 (* t\n *) - _write_out(@loca0, 2) + loca0 := 0x6f40202c (* , @o *); + _write_out(@loca0, 4); + loca0 := 0x63656a62 (* bjec *); + _write_out(@loca0, 4); + loca0 := 0x0a74 (* t\n *); + _write_out(@loca0, 2); - (* .size identifier, size *) - loca0 := 0x7a69732e (* .siz *) - _write_out(@loca0, 4) - loca0 := 0x2065 (* e_ *) - _write_out(@loca0, 2) + (* .size identifier, size *); + loca0 := 0x7a69732e (* .siz *); + _write_out(@loca0, 4); + loca0 := 0x2065 (* e_ *); + _write_out(@loca0, 2); - _write_out(loca28, loca24) + _write_out(loca28, loca24); - loca0 := 0x202c (* ,_ *) - _write_out(@loca0, 2) + loca0 := 0x202c (* ,_ *); + _write_out(@loca0, 2); - _write_out(loca20, loca16) - _put_char(0x0a) (* \n *) + _write_out(loca20, loca16); + _put_char(0x0a) (* \n *); (* identifier: .zero size *) - _write_out(loca28, loca24) + _write_out(loca28, loca24); - loca0 := 0x7a2e203a (* : .z *) - _write_out(@loca0, 4) - loca0 := 0x206f7265 (* ero_ *) - _write_out(@loca0, 4) + loca0 := 0x7a2e203a (* : .z *); + _write_out(@loca0, 4); + loca0 := 0x206f7265 (* ero_ *); + _write_out(@loca0, 4); - _write_out(loca20, loca16) + _write_out(loca20, loca16); _put_char(0x0a) (* \n *) end @@ -920,186 +949,186 @@ var loca0, loca4, loca8, loca12, loca16: Word loca20, loca24: ^Byte begin - _advance(5) (* Skip proc_ *) - loca16 := _read_token() - loca20 := _current() - _advance(loca16) + _advance(5) (* Skip proc_ *); + loca16 := _read_token(); + loca20 := _current(); + _advance(loca16); - (* .type identifier, @function *) - loca0 := 0x7079742e (* .typ *) - _write_out(@loca0, 4) - loca0 := 0x2065 (* e_ *) - _write_out(@loca0, 2) + (* .type identifier, @function *); + loca0 := 0x7079742e (* .typ *); + _write_out(@loca0, 4); + loca0 := 0x2065 (* e_ *); + _write_out(@loca0, 2); - _write_out(loca20, loca16) + _write_out(loca20, loca16); - loca0 := 0x6640202c (* , @f *) - _write_out(@loca0, 4) - loca0 := 0x74636e75 (* unct *) - _write_out(@loca0, 4) - loca0 := 0x0a6e6f69 (* ion\n *) - _write_out(@loca0, 4) + loca0 := 0x6640202c (* , @f *); + _write_out(@loca0, 4); + loca0 := 0x74636e75 (* unct *); + _write_out(@loca0, 4); + loca0 := 0x0a6e6f69 (* ion\n *); + _write_out(@loca0, 4); - _write_out(loca20, loca16) + _write_out(loca20, loca16); - loca0 := 0x0a3a (* :\n *) - _write_out(@loca0, 2) + loca0 := 0x0a3a (* :\n *); + _write_out(@loca0, 2); - _skip_spaces() - _advance(1) (* Skip opening argument paren. *) - _skip_spaces() - _advance(1) (* Skip closing argument paren. *) + _skip_spaces(); + _advance(1) (* Skip opening argument paren. *); + _skip_spaces(); + _advance(1) (* Skip closing argument paren. *); - loca12 := 0x6e (* n *) - loca8 := 0x69676562 (* begi *) + loca12 := 0x6e (* n *); + loca8 := 0x69676562 (* begi *); (* Skip all declarations until we find the "begin" keyword, denoting the beginning of the procedure body. *) - .Lcompile_procedure_begin - _skip_spaces() - loca0 := _read_token() + .Lcompile_procedure_begin; + _skip_spaces(); + loca0 := _read_token(); - loca24 := _current() - _advance(loca0) - loca0 := _token_compare(loca24, loca0, @loca8) + loca24 := _current(); + _advance(loca0); + loca0 := _token_compare(loca24, loca0, @loca8); if loca0 = 1 then goto .Lcompile_procedure_begin - end + end; (* Generate the procedure prologue with a predefined stack size. *) - loca0 := 0x69646461 (* addi *) - _write_out(@loca0, 4) + loca0 := 0x69646461 (* addi *); + _write_out(@loca0, 4); - loca0 := 0x2c707320 (* _sp, *) - _write_out(@loca0, 4) - _write_out(@loca0, 4) + loca0 := 0x2c707320 (* _sp, *); + _write_out(@loca0, 4); + _write_out(@loca0, 4); - loca0 := 0x0a36392d (* -96\n *) - _write_out(@loca0, 4) + loca0 := 0x0a36392d (* -96\n *); + _write_out(@loca0, 4); - loca0 := 0x72207773 (* sw r *) - _write_out(@loca0, 4) - loca0 := 0x39202c61 (* a, 9 *) - _write_out(@loca0, 4) - loca0 := 0x70732832 (* 2(sp *) - _write_out(@loca0, 4) - loca0 := 0x0a29 (* )\n *) - _write_out(@loca0, 2) + loca0 := 0x72207773 (* sw r *); + _write_out(@loca0, 4); + loca0 := 0x39202c61 (* a, 9 *); + _write_out(@loca0, 4); + loca0 := 0x70732832 (* 2(sp *); + _write_out(@loca0, 4); + loca0 := 0x0a29 (* )\n *); + _write_out(@loca0, 2); - loca0 := 0x73207773 (* sw s *) - _write_out(@loca0, 4) - loca0 := 0x38202c30 (* 0, 8 *) - _write_out(@loca0, 4) - loca0 := 0x70732838 (* 8(sp *) - _write_out(@loca0, 4) - loca0 := 0x0a29 (* )\n *) - _write_out(@loca0, 2) + loca0 := 0x73207773 (* sw s *); + _write_out(@loca0, 4); + loca0 := 0x38202c30 (* 0, 8 *); + _write_out(@loca0, 4); + loca0 := 0x70732838 (* 8(sp *); + _write_out(@loca0, 4); + loca0 := 0x0a29 (* )\n *); + _write_out(@loca0, 2); - loca0 := 0x69646461 (* addi *) - _write_out(@loca0, 4) - loca0 := 0x2c307320 (* _s0, *) - _write_out(@loca0, 4) - loca0 := 0x2c707320 (* _sp, *) - _write_out(@loca0, 4) - loca0 := 0x0a363920 (* _96\n *) - _write_out(@loca0, 4) + loca0 := 0x69646461 (* addi *); + _write_out(@loca0, 4); + loca0 := 0x2c307320 (* _s0, *); + _write_out(@loca0, 4); + loca0 := 0x2c707320 (* _sp, *); + _write_out(@loca0, 4); + loca0 := 0x0a363920 (* _96\n *); + _write_out(@loca0, 4); (* Save passed arguments on the stack. *) - loca0 := 0x61207773 (* sw a *) - _write_out(@loca0, 4) - loca4 := 0x38202c30 (* 0, 8 *) - _write_out(@loca4, 4) - loca8 := 0x70732834 (* 4(sp *) - _write_out(@loca8, 4) - loca12 := 0x0a29 (* )\n *) - _write_out(@loca12, 2) + loca0 := 0x61207773 (* sw a *); + _write_out(@loca0, 4); + loca4 := 0x38202c30 (* 0, 8 *); + _write_out(@loca4, 4); + loca8 := 0x70732834 (* 4(sp *); + _write_out(@loca8, 4); + loca12 := 0x0a29 (* )\n *); + _write_out(@loca12, 2); - _write_out(@loca0, 4) - loca4 := 0x38202c31 (* 1, 8 *) - _write_out(@loca4, 4) - loca8 := 0x70732830 (* 0(sp *) - _write_out(@loca8, 4) - _write_out(@loca12, 2) + _write_out(@loca0, 4); + loca4 := 0x38202c31 (* 1, 8 *); + _write_out(@loca4, 4); + loca8 := 0x70732830 (* 0(sp *); + _write_out(@loca8, 4); + _write_out(@loca12, 2); - _write_out(@loca0, 4) - loca4 := 0x37202c32 (* 2, 7 *) - _write_out(@loca4, 4) - loca8 := 0x70732836 (* 6(sp *) - _write_out(@loca8, 4) - _write_out(@loca12, 2) + _write_out(@loca0, 4); + loca4 := 0x37202c32 (* 2, 7 *); + _write_out(@loca4, 4); + loca8 := 0x70732836 (* 6(sp *); + _write_out(@loca8, 4); + _write_out(@loca12, 2); - _write_out(@loca0, 4) - loca4 := 0x37202c33 (* 3, 7 *) - _write_out(@loca4, 4) - loca8 := 0x70732832 (* 2(sp *) - _write_out(@loca8, 4) - _write_out(@loca12, 2) + _write_out(@loca0, 4); + loca4 := 0x37202c33 (* 3, 7 *); + _write_out(@loca4, 4); + loca8 := 0x70732832 (* 2(sp *); + _write_out(@loca8, 4); + _write_out(@loca12, 2); - _write_out(@loca0, 4) - loca4 := 0x36202c34 (* 4, 6 *) - _write_out(@loca4, 4) - loca8 := 0x70732838 (* 8(sp *) - _write_out(@loca8, 4) - _write_out(@loca12, 2) + _write_out(@loca0, 4); + loca4 := 0x36202c34 (* 4, 6 *); + _write_out(@loca4, 4); + loca8 := 0x70732838 (* 8(sp *); + _write_out(@loca8, 4); + _write_out(@loca12, 2); - _write_out(@loca0, 4) - loca4 := 0x36202c35 (* 5, 6 *) - _write_out(@loca4, 4) - loca8 := 0x70732838 (* 4(sp *) - _write_out(@loca8, 4) - _write_out(@loca12, 2) + _write_out(@loca0, 4); + loca4 := 0x36202c35 (* 5, 6 *); + _write_out(@loca4, 4); + loca8 := 0x70732838 (* 4(sp *); + _write_out(@loca8, 4); + _write_out(@loca12, 2); (* Generate the body of the procedure. *) - .Lcompile_procedure_body - _skip_spaces() - loca12 := _read_line() - loca8 := 0x0a646e65 (* end\n *) - loca24 := _current() - loca8 := _memcmp(loca24, @loca8, 4) + .Lcompile_procedure_body; + _skip_spaces(); + loca12 := _read_line(); + loca8 := 0x0a646e65 (* end\n *); + loca24 := _current(); + loca8 := _memcmp(loca24, @loca8, 4); if loca8 = 0 then goto .Lcompile_procedure_end - end + end; - _compile_line(loca12) - goto .Lcompile_procedure_body + _compile_line(loca12); + goto .Lcompile_procedure_body; - .Lcompile_procedure_end - _advance(4) (* Skip end\n. *) + .Lcompile_procedure_end; + _advance(4) (* Skip end\n. *); (* Generate the procedure epilogue with a predefined stack size. *) - loca0 := 0x7220776c (* lw r *) - _write_out(@loca0, 4) - loca0 := 0x39202c61 (* a, 9 *) - _write_out(@loca0, 4) - loca0 := 0x70732832 (* 2(sp *) - _write_out(@loca0, 4) - loca0 := 0x0a29 (* )\n *) - _write_out(@loca0, 2) + loca0 := 0x7220776c (* lw r *); + _write_out(@loca0, 4); + loca0 := 0x39202c61 (* a, 9 *); + _write_out(@loca0, 4); + loca0 := 0x70732832 (* 2(sp *); + _write_out(@loca0, 4); + loca0 := 0x0a29 (* )\n *); + _write_out(@loca0, 2); - loca0 := 0x7320776c (* lw s *) - _write_out(@loca0, 4) - loca0 := 0x38202c30 (* 0, 8 *) - _write_out(@loca0, 4) - loca0 := 0x70732838 (* 8(sp *) - _write_out(@loca0, 4) - loca0 := 0x0a29 (* )\n *) - _write_out(@loca0, 2) + loca0 := 0x7320776c (* lw s *); + _write_out(@loca0, 4); + loca0 := 0x38202c30 (* 0, 8 *); + _write_out(@loca0, 4); + loca0 := 0x70732838 (* 8(sp *); + _write_out(@loca0, 4); + loca0 := 0x0a29 (* )\n *); + _write_out(@loca0, 2); - loca0 := 0x69646461 (* addi *) - _write_out(@loca0, 4) + loca0 := 0x69646461 (* addi *); + _write_out(@loca0, 4); - loca0 := 0x2c707320 (* _sp, *) - _write_out(@loca0, 4) - _write_out(@loca0, 4) + loca0 := 0x2c707320 (* _sp, *); + _write_out(@loca0, 4); + _write_out(@loca0, 4); - loca0 := 0x0a3639 (* 96\n *) - _write_out(@loca0, 4) + loca0 := 0x0a3639 (* 96\n *); + _write_out(@loca0, 4); - loca0 := 0x0a746572 (* ret\n *) + loca0 := 0x0a746572 (* ret\n *); _write_out(@loca0, 4) end @@ -1118,44 +1147,44 @@ var loca4, loca12: Byte loca8: Word begin - .Ltoken_compare_loop - loca4 := _front(loca76) + .Ltoken_compare_loop; + loca4 := _front(loca76); (* Will only be 0 if the current character in the null terminated string is \0 and the remaining length of the another string is 0. *) - loca8 := loca4 or loca80 + loca8 := loca4 or loca80; if loca8 = 0 then goto .Ltoken_compare_equal - end + end; if loca80 = 0 then goto .Ltoken_compare_not_equal - end + end; if loca4 = 0 then goto .Ltoken_compare_not_equal - end - loca12 := _front(loca84) + end; + loca12 := _front(loca84); if loca4 = loca12 then goto .Ltoken_compare_continue - end - goto .Ltoken_compare_not_equal + end; + goto .Ltoken_compare_not_equal; - .Ltoken_compare_continue + .Ltoken_compare_continue; - loca84 := loca84 + 1 - loca80 := loca80 - 1 - loca76 := loca76 + 1 - goto .Ltoken_compare_loop + loca84 := loca84 + 1; + loca80 := loca80 - 1; + loca76 := loca76 + 1; + goto .Ltoken_compare_loop; - .Ltoken_compare_not_equal - loca0 := 1 - goto .Ltoken_compare_end + .Ltoken_compare_not_equal; + loca0 := 1; + goto .Ltoken_compare_end; - .Ltoken_compare_equal - loca0 := 0 + .Ltoken_compare_equal; + loca0 := 0; - .Ltoken_compare_end + .Ltoken_compare_end; return loca0 end @@ -1164,21 +1193,21 @@ var loca0: Word loca8: ^Byte begin - _advance(4) (* Skip the goto keyword. *) + _advance(4) (* Skip the goto keyword. *); - loca0 := 0x206a (* j_ *) - _write_out(@loca0, 2) + loca0 := 0x206a (* j_ *); + _write_out(@loca0, 2); - _skip_spaces() - loca8 := _current() (* We should be on dot the label is beginning with. *) - _advance(1) + _skip_spaces(); + loca8 := _current() (* We should be on dot the label is beginning with. *); + _advance(1); - loca0 := _read_token() - _advance(loca0) - loca0 := loca0 + 1 (* Label length and the dot. *) - _write_out(loca8, loca0) + loca0 := _read_token(); + _advance(loca0); + loca0 := loca0 + 1 (* Label length and the dot. *); + _write_out(loca8, loca0); - _advance(1) (* Skip the new line. *) + _advance(1) (* Skip the new line. *); _put_char(0x0a) (* \n *) end @@ -1188,30 +1217,29 @@ var loca0: Word begin (* Write the whole line as is. *) - loca0 := _current() - _write_out(loca0, loca84) + loca0 := _current(); - loca0 := loca0 + loca84 - loca0 := loca0 - 1 (* Last character on the line. *) + loca0 := loca0 + loca84; + loca0 := loca0 - 1 (* Last character on the line. *); + loca4 := loca84; - loca0 := _front(loca0) - if loca0 = 0x3a then - goto .Lcompile_label_colon - end + loca0 := _front(loca0); + if loca0 = 0x3b then + loca4 := loca4 - 1 + end; + _write_out(s1, loca4); - _put_char(0x3a) (* : *) - - .Lcompile_label_colon - _put_char(0x0a) (* \n *) + _put_char(0x3a) (* : *); + _put_char(0x0a) (* \n *); _advance(loca84) end proc _compile_return() begin - _advance(6) (* Skip return. *) - _skip_spaces() - _build_binary_expression() + _advance(6) (* Skip return. *); + _skip_spaces(); + _build_binary_expression(); end proc _compile_if() @@ -1219,52 +1247,52 @@ var loca8, loca12, loca16, loca20: Word loca4: ^Byte begin - _advance(2) (* Skip the if. *) - _skip_spaces() + _advance(2) (* Skip the if. *); + _skip_spaces(); - _build_binary_expression() + _build_binary_expression(); - _skip_spaces() - _advance(4) (* Skip the then. *) + _skip_spaces(); + _advance(4) (* Skip the then. *); - loca20 := 0x00646e65 (* if end marker and newline. *) - loca16 := 0x66694c2e (* Label prefix ".Lif". *) + loca20 := 0x00646e65 (* if end marker and newline. *); + loca16 := 0x66694c2e (* Label prefix ".Lif". *); - loca12 := 0x7a716562 (* beqz *) - _write_out(@loca12, 4) - loca12 := 0x2c306120 (* _a0, *) - _write_out(@loca12, 4) - _put_char(0x20) (* _ *) + loca12 := 0x7a716562 (* beqz *); + _write_out(@loca12, 4); + loca12 := 0x2c306120 (* _a0, *); + _write_out(@loca12, 4); + _put_char(0x20) (* _ *); - (* Write the label *) - _write_out(@loca16, 4) - _printi(s2) + (* Write the label *); + _write_out(@loca16, 4); + _printi(s2); - _put_char(0x0a) (* \n *) + _put_char(0x0a) (* \n *); - .Lcompile_if_loop - _skip_spaces() - loca12 := _read_token() + .Lcompile_if_loop; + _skip_spaces(); + loca12 := _read_token(); - loca4 := _current() - loca8 := _token_compare(loca4, loca12, @loca20) + loca4 := _current(); + loca8 := _token_compare(loca4, loca12, @loca20); if loca8 then - loca12 := _read_line() - _compile_line(loca12, 1) + loca12 := _read_line(); + _compile_line(loca12, 1); goto .Lcompile_if_loop - end + end; (* Write the label *) - _write_out(@loca16, 4) - _printi(s2) + _write_out(@loca16, 4); + _printi(s2); - loca12 := 0x0a3a0a3a (* :\n:\n *) - _write_out(@loca12, 2) + loca12 := 0x0a3a0a3a (* :\n:\n *); + _write_out(@loca12, 2); - (* Increment the label counter. *) - addi s2, s2, 1 + (* Increment the label counter. *); + s2 := s2 + 1; _advance(4) (* Skip the end with newline. *) end @@ -1287,171 +1315,175 @@ var begin if loca84 = 0 then goto .Lcompile_line_empty (* Skip an empty line. *) - end + end; - loca16 := _current() - loca0 := _front(loca16) + loca16 := _current(); + loca0 := _front(loca16); (* ( *) if loca0 = 0x28 then goto .Lcompile_line_comment - end - loca16 := _current() + end; + loca16 := _current(); - loca12 := 0x676f7270 (* prog *) - loca4 := _memcmp(loca16, @loca12, 4) + loca12 := 0x676f7270 (* prog *); + loca4 := _memcmp(loca16, @loca12, 4); if loca4 = 0 then goto .Lcompile_line_program - end + end; - loca12 := 0x736e6f63 (* cons *) - loca4 := _memcmp(loca16, @loca12, 4) + loca12 := 0x736e6f63 (* cons *); + loca4 := _memcmp(loca16, @loca12, 4); if loca4 = 0 then goto .Lcompile_line_const - end + end; - loca12 := 0x0a726176 (* var\n *) - loca4 := _memcmp(loca16, @loca12, 4) + loca12 := 0x0a726176 (* var\n *); + loca4 := _memcmp(loca16, @loca12, 4); if loca4 = 0 then goto .Lcompile_line_var - end + end; - loca12 := 0x636f7270 (* proc *) - loca4 := _memcmp(loca16, @loca12, 4) + loca12 := 0x636f7270 (* proc *); + loca4 := _memcmp(loca16, @loca12, 4); if loca4 = 0 then goto .Lcompile_line_procedure - end + end; - loca12 := 0x69676562 (* begi *) - loca4 := _memcmp(loca16, @loca12, 4) + loca12 := 0x69676562 (* begi *); + loca4 := _memcmp(loca16, @loca12, 4); if loca4 = 0 then goto .Lcompile_line_begin - end + end; - loca12 := 0x2e646e65 (* end. *) - loca4 := _memcmp(loca16, @loca12, 4) + loca12 := 0x2e646e65 (* end. *); + loca4 := _memcmp(loca16, @loca12, 4); if loca4 = 0 then goto .Lcompile_line_exit - end + end; - loca12 := 0x61636f6c (* loca *) - loca4 := _memcmp(loca16, @loca12, 4) + loca12 := 0x61636f6c (* loca *); + loca4 := _memcmp(loca16, @loca12, 4); if loca4 = 0 then goto .Lcompile_line_identifier - end + end; + loca4 := _front(loca16); + if loca4 = 0x73 then + goto .Lcompile_line_identifier + end; - loca12 := 0x6f706d69 (* impo *) - loca4 := _memcmp(loca16, @loca12, 4) + loca12 := 0x6f706d69 (* impo *); + loca4 := _memcmp(loca16, @loca12, 4); if loca4 = 0 then goto .Lcompile_line_import - end + end; - loca12 := 0x6f746f67 (* goto *) - loca4 := _memcmp(loca16, @loca12, 4) + loca12 := 0x6f746f67 (* goto *); + loca4 := _memcmp(loca16, @loca12, 4); if loca4 = 0 then goto .Lcompile_line_goto - end + end; - loca12 := 0x75746572 (* retu *) - loca4 := _memcmp(loca16, @loca12, 4) + loca12 := 0x75746572 (* retu *); + loca4 := _memcmp(loca16, @loca12, 4); if loca4 = 0 then goto .Lcompile_line_return - end + end; - loca12 := 0x6669 (* if *) - loca4 := _memcmp(loca16, @loca12, 2) + loca12 := 0x6669 (* if *); + loca4 := _memcmp(loca16, @loca12, 2); if loca4 = 0 then goto .Lcompile_line_if - end + end; (* . *) if loca0 = 0x2e then goto .Lcompile_line_label - end + end; (* _ *) if loca0 = 0x5f then goto .Lcompile_line_identifier - end - goto .Lcompile_line_unchanged (* Else. *) + end; + goto .Lcompile_line_unchanged (* Else. *); - .Lcompile_line_if: - _compile_if() - goto .Lcompile_line_section + .Lcompile_line_if; + _compile_if(); + goto .Lcompile_line_section; - .Lcompile_line_label - _compile_label(loca84) - goto .Lcompile_line_section + .Lcompile_line_label; + _compile_label(loca84); + goto .Lcompile_line_section; - .Lcompile_line_return - _compile_return() - goto .Lcompile_line_section + .Lcompile_line_return; + _compile_return(); + goto .Lcompile_line_section; - .Lcompile_line_goto - _compile_goto() - goto .Lcompile_line_section + .Lcompile_line_goto; + _compile_goto(); + goto .Lcompile_line_section; - .Lcompile_line_import - _compile_import() - goto .Lcompile_line_section + .Lcompile_line_import; + _compile_import(); + goto .Lcompile_line_section; - .Lcompile_line_identifier - _compile_identifier() - goto .Lcompile_line_section + .Lcompile_line_identifier; + _compile_identifier(); + goto .Lcompile_line_section; - .Lcompile_line_exit - _compile_exit() - goto .Lcompile_line_section + .Lcompile_line_exit; + _compile_exit(); + goto .Lcompile_line_section; - .Lcompile_line_begin + .Lcompile_line_begin; if loca80 = 1 then goto .Lcompile_line_compile_entry - end - _compile_text_section() - .Lcompile_line_compile_entry - _compile_entry_point() - loca8 := 1 - goto .Lcompile_line_end + end; + _compile_text_section(); + .Lcompile_line_compile_entry; + _compile_entry_point(); + loca8 := 1; + goto .Lcompile_line_end; - .Lcompile_line_const - _compile_constant_section() - goto .Lcompile_line_section + .Lcompile_line_const; + _compile_constant_section(); + goto .Lcompile_line_section; - .Lcompile_line_procedure + .Lcompile_line_procedure; if loca80 = 1 then goto .Lcompile_line_compile_procedure - end - _compile_text_section() - .Lcompile_line_compile_procedure - _compile_procedure() - loca8 := 1 - goto .Lcompile_line_end + end; + _compile_text_section(); + .Lcompile_line_compile_procedure; + _compile_procedure(); + loca8 := 1; + goto .Lcompile_line_end; - .Lcompile_line_var - _compile_variable_section() - goto .Lcompile_line_section + .Lcompile_line_var; + _compile_variable_section(); + goto .Lcompile_line_section; - .Lcompile_line_program - _compile_program() - goto .Lcompile_line_section + .Lcompile_line_program; + _compile_program(); + goto .Lcompile_line_section; - .Lcompile_line_comment - _skip_comment(loca84) - goto .Lcompile_line_section + .Lcompile_line_comment; + _skip_comment(loca84); + goto .Lcompile_line_section; - .Lcompile_line_empty - _advance(1) - goto .Lcompile_line_section + .Lcompile_line_empty; + _advance(1); + goto .Lcompile_line_section; - .Lcompile_line_unchanged - _compile_assembly(loca84) - goto .Lcompile_line_section + .Lcompile_line_unchanged; + _compile_assembly(loca84); + goto .Lcompile_line_section; - .Lcompile_line_section - loca8 := 0 + .Lcompile_line_section; + loca8 := 0; - .Lcompile_line_end - _skip_spaces() - _skip_comment() + .Lcompile_line_end; + _skip_spaces(); + _skip_comment(); return loca8 end @@ -1461,13 +1493,13 @@ proc _compile_text_section() var loca0: Word begin (* .section .text *) - loca0 := 0x6365732e (* .sec *) - _write_out(@loca0, 4) - loca0 := 0x6e6f6974 (* tion *) - _write_out(@loca0, 4) - loca0 := 0x65742e20 (* _.te *) - _write_out(@loca0, 4) - loca0 := 0x0a7478 (* xt\n *) + loca0 := 0x6365732e (* .sec *); + _write_out(@loca0, 4); + loca0 := 0x6e6f6974 (* tion *); + _write_out(@loca0, 4); + loca0 := 0x65742e20 (* _.te *); + _write_out(@loca0, 4); + loca0 := 0x0a7478 (* xt\n *); _write_out(@loca0, 3) end @@ -1475,22 +1507,22 @@ proc _compile_entry_point() var loca0: Word begin (* .type _start, @function *) - loca0 := 0x7079742e (* .typ *) - _write_out(@loca0, 4) - loca0 := 0x735f2065 (* e _s *) - _write_out(@loca0, 4) - loca0 := 0x74726174 (* tart *) - _write_out(@loca0, 4) - loca0 := 0x6640202c (* , @f *) - _write_out(@loca0, 4) - loca0 := 0x74636e75 (* unct *) - _write_out(@loca0, 4) - loca0 := 0x0a6e6f69 (* ion\n *) - _write_out(@loca0, 4) - loca0 := 0x6174735f (* _sta *) - _write_out(@loca0, 4) - loca0 := 0x0a3a7472 (* rt:\n *) - _write_out(@loca0, 4) + loca0 := 0x7079742e (* .typ *); + _write_out(@loca0, 4); + loca0 := 0x735f2065 (* e _s *); + _write_out(@loca0, 4); + loca0 := 0x74726174 (* tart *); + _write_out(@loca0, 4); + loca0 := 0x6640202c (* , @f *); + _write_out(@loca0, 4); + loca0 := 0x74636e75 (* unct *); + _write_out(@loca0, 4); + loca0 := 0x0a6e6f69 (* ion\n *); + _write_out(@loca0, 4); + loca0 := 0x6174735f (* _sta *); + _write_out(@loca0, 4); + loca0 := 0x0a3a7472 (* rt:\n *); + _write_out(@loca0, 4); _advance(6) (* Skip begin\n. *) end @@ -1501,22 +1533,22 @@ begin (* li a0, 0 *) (* li a7, SYS_EXIT *) (* ecall *) - loca0 := 0x6120696c (* li a *) - _write_out(@loca0, 4) - loca0 := 0x30202c30 (* 0, 0 *) - _write_out(@loca0, 4) - loca0 := 0x20696c0a (* \nli_ *) - _write_out(@loca0, 4) - loca0 := 0x202c3761 (* a7,_ *) - _write_out(@loca0, 4) - loca0 := 0x650a3339 (* 93\ne *) - _write_out(@loca0, 4) - loca0 := 0x6c6c6163 (* call *) - _write_out(@loca0, 4) - loca0 := 0x0a (* \n *) - _write_out(@loca0, 1) + loca0 := 0x6120696c (* li a *); + _write_out(@loca0, 4); + loca0 := 0x30202c30 (* 0, 0 *); + _write_out(@loca0, 4); + loca0 := 0x20696c0a (* \nli_ *); + _write_out(@loca0, 4); + loca0 := 0x202c3761 (* a7,_ *); + _write_out(@loca0, 4); + loca0 := 0x650a3339 (* 93\ne *); + _write_out(@loca0, 4); + loca0 := 0x6c6c6163 (* call *); + _write_out(@loca0, 4); + loca0 := 0x0a (* \n *); + _write_out(@loca0, 1); - _advance(4) (* Skip end. *) + _advance(4) (* Skip end. *); _skip_spaces() (* Read the possible new line at the end of the file. *) end @@ -1526,21 +1558,21 @@ var loca0: ^Byte loca4: Byte begin - loca0 := _current() (* Local position in the source text. *) + loca0 := _current() (* Local position in the source text. *); - .Lread_line_do - loca4 := _front(loca0) (* t1 = Current character. *) + .Lread_line_do; + loca4 := _front(loca0) (* t1 = Current character. *); if loca4 = 0 then goto .Lread_line_end (* Exit the loop on the NUL character. *) - end + end; if loca4 = 0x0a then goto .Lread_line_end (* Exit the loop on the new line. *) - end - loca0 := loca0 + 1 - goto .Lread_line_do + end; + loca0 := loca0 + 1; + goto .Lread_line_do; - .Lread_line_end - loca4 := _current() + .Lread_line_end; + loca4 := _current(); return loca0 - loca4 (* Return the line length. *) end @@ -1551,27 +1583,27 @@ var loca12: Char loca16: ^Byte begin - loca4 := 0 (* Whether the text section header was already emitted. *) + loca4 := 0 (* Whether the text section header was already emitted. *); - .Lcompile_do - loca16 := _current() - loca12 := _front(loca16) (* t0 = Current character. *) + .Lcompile_do; + loca16 := _current(); + loca12 := _front(loca16) (* t0 = Current character. *); if loca12 = 0 then goto .Lcompile_end (* Exit the loop on the NUL character. *) - end + end; - _skip_spaces() - loca0 := _read_line() - loca8 := _compile_line(loca0, loca4) + _skip_spaces(); + loca0 := _read_line(); + loca8 := _compile_line(loca0, loca4); if loca8 = 0 then goto .Lcompile_do - end + end; (* Update whether the text section header was already emitted. *) - loca4 := loca4 or loca8 + loca4 := loca4 or loca8; - goto .Lcompile_do + goto .Lcompile_do; .Lcompile_end end @@ -1584,7 +1616,7 @@ end (* a0 is the number of bytes to advance in the source text. *) proc _advance(loca84: Word) begin - add s1, s1, a0 + s1 := s1 + loca84 end (* @@ -1600,13 +1632,13 @@ end proc _main() begin (* Read the source from the standard input. *) - _read_file(source_code, SOURCE_BUFFER_SIZE) + _read_file(source_code, SOURCE_BUFFER_SIZE); - addi s2, zero, 1 + s2 := 1 end (* Entry point. *) begin - _main() + _main(); _compile() end. diff --git a/boot/tokenizer.s b/boot/tokenizer.s index 2057c2e..b1ac11f 100644 --- a/boot/tokenizer.s +++ b/boot/tokenizer.s @@ -1,165 +1,195 @@ .global _tokenizer_initialize .section .rodata +# +# Classes: +# +# 0x00: Invalid +# 0x01: Digit +# 0x02: Character +# 0x03: Space +.type classes, @object +.size classes, 128 +classes: + .byte 0x00 # 00 NUL + .byte 0x00 # 01 SOH + .byte 0x00 # 02 STX + .byte 0x00 # 03 ETX + .byte 0x00 # 04 EOT + .byte 0x00 # 05 ENQ + .byte 0x00 # 06 ACK + .byte 0x00 # 07 BEL + .byte 0x00 # 08 BS + .byte 0x00 # 09 HT + .byte 0x00 # 0A LF + .byte 0x00 # 0B VT + .byte 0x00 # 0C FF + .byte 0x00 # 0D CR + .byte 0x00 # 0E SO + .byte 0x00 # 0F SI + .byte 0x00 # 10 DLE + .byte 0x00 # 11 DC1 + .byte 0x00 # 12 DC2 + .byte 0x00 # 13 DC3 + .byte 0x00 # 14 DC4 + .byte 0x00 # 15 NAK + .byte 0x00 # 16 SYN + .byte 0x00 # 17 ETB + .byte 0x00 # 18 CAN + .byte 0x00 # 19 EM + .byte 0x00 # 1A SUB + .byte 0x00 # 1B ESC + .byte 0x00 # 1C FS + .byte 0x00 # 1D GS + .byte 0x00 # 1E RS + .byte 0x00 # 1F US + .byte 0x03 # 20 Space + .byte 0x00 # 21 ! + .byte 0x00 # 22 " + .byte 0x00 # 23 # + .byte 0x00 # 24 $ + .byte 0x00 # 25 % + .byte 0x00 # 26 & + .byte 0x00 # 27 ' + .byte 0x00 # 28 ( + .byte 0x00 # 29 ) + .byte 0x00 # 2A * + .byte 0x00 # 2B + + .byte 0x00 # 2C , + .byte 0x00 # 2D - + .byte 0x00 # 2E . + .byte 0x00 # 2F / + .byte 0x01 # 30 0 + .byte 0x01 # 31 1 + .byte 0x01 # 32 2 + .byte 0x01 # 33 3 + .byte 0x01 # 34 4 + .byte 0x01 # 35 5 + .byte 0x01 # 36 6 + .byte 0x01 # 37 7 + .byte 0x01 # 38 8 + .byte 0x01 # 39 9 + .byte 0x00 # 3A : + .byte 0x00 # 3B ; + .byte 0x00 # 3C < + .byte 0x00 # 3D = + .byte 0x00 # 3E > + .byte 0x00 # 3F ? + .byte 0x00 # 40 @ + .byte 0x02 # 41 A + .byte 0x02 # 42 B + .byte 0x02 # 43 C + .byte 0x02 # 44 D + .byte 0x02 # 45 E + .byte 0x02 # 46 F + .byte 0x02 # 47 G + .byte 0x02 # 48 H + .byte 0x02 # 49 I + .byte 0x02 # 4A J + .byte 0x02 # 4B K + .byte 0x02 # 4C L + .byte 0x02 # 4D M + .byte 0x02 # 4E N + .byte 0x02 # 4F O + .byte 0x02 # 50 P + .byte 0x02 # 51 Q + .byte 0x02 # 52 R + .byte 0x02 # 53 S + .byte 0x02 # 54 T + .byte 0x02 # 55 U + .byte 0x02 # 56 V + .byte 0x02 # 57 W + .byte 0x02 # 58 X + .byte 0x02 # 59 Y + .byte 0x02 # 5A Z + .byte 0x00 # 5B [ + .byte 0x00 # 5C \ + .byte 0x00 # 5D ] + .byte 0x00 # 5E ^ + .byte 0x00 # 5F _ + .byte 0x00 # 60 ` + .byte 0x02 # 61 a + .byte 0x02 # 62 b + .byte 0x02 # 63 c + .byte 0x02 # 64 d + .byte 0x02 # 65 e + .byte 0x02 # 66 f + .byte 0x02 # 67 g + .byte 0x02 # 68 h + .byte 0x02 # 69 i + .byte 0x02 # 6A j + .byte 0x02 # 6B k + .byte 0x02 # 6C l + .byte 0x02 # 6D m + .byte 0x02 # 6E n + .byte 0x02 # 6F o + .byte 0x02 # 70 p + .byte 0x02 # 71 q + .byte 0x02 # 72 r + .byte 0x02 # 73 s + .byte 0x02 # 74 t + .byte 0x02 # 75 u + .byte 0x02 # 76 v + .byte 0x02 # 77 w + .byte 0x02 # 78 x + .byte 0x02 # 79 y + .byte 0x02 # 7A z + .byte 0x00 # 7B { + .byte 0x00 # 7C | + .byte 0x00 # 7D } + .byte 0x00 # 7E ~ + .byte 0x00 # 7F DEL -raw_classes: - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "space\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "digit\n" - .ascii "digit\n" - .ascii "digit\n" - .ascii "digit\n" - .ascii "digit\n" - .ascii "digit\n" - .ascii "digit\n" - .ascii "digit\n" - .ascii "digit\n" - .ascii "digit\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "upper\n" - .ascii "upper\n" - .ascii "upper\n" - .ascii "upper\n" - .ascii "upper\n" - .ascii "upper\n" - .ascii "upper\n" - .ascii "upper\n" - .ascii "upper\n" - .ascii "upper\n" - .ascii "upper\n" - .ascii "upper\n" - .ascii "upper\n" - .ascii "upper\n" - .ascii "upper\n" - .ascii "upper\n" - .ascii "upper\n" - .ascii "upper\n" - .ascii "upper\n" - .ascii "upper\n" - .ascii "upper\n" - .ascii "upper\n" - .ascii "upper\n" - .ascii "upper\n" - .ascii "upper\n" - .ascii "upper\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "lower\n" - .ascii "lower\n" - .ascii "lower\n" - .ascii "lower\n" - .ascii "lower\n" - .ascii "lower\n" - .ascii "lower\n" - .ascii "lower\n" - .ascii "lower\n" - .ascii "lower\n" - .ascii "lower\n" - .ascii "lower\n" - .ascii "lower\n" - .ascii "lower\n" - .ascii "lower\n" - .ascii "lower\n" - .ascii "lower\n" - .ascii "lower\n" - .ascii "lower\n" - .ascii "lower\n" - .ascii "lower\n" - .ascii "lower\n" - .ascii "lower\n" - .ascii "lower\n" - .ascii "lower\n" - .ascii "lower\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" - .ascii "invalid\n" +.section .data .section .bss .type class_names, @object .size class_names, 1024 class_names: .zero 1024 -.section .data -.type classes, @object -.size classes, 512 # 128 characters * 4 byte. -classes: - .section .text # Initializes the classification table. # # Paramaters: # a0 - Raw input for the classification table. -.type _tokenizer_classes, @function -_tokenizer_classes: +.type _initialize_classes, @function +_initialize_classes: # Prologue. - addi sp, sp, -8 - sw ra, 4(sp) - sw s0, 0(sp) - addi s0, sp, 8 + addi sp, sp, -24 + sw ra, 20(sp) + sw s0, 16(sp) + addi s0, sp, 24 + + sw s1, 12(sp) # Preserve the s1 register used for the character counter. + li s1, 128 # 128 ASCII characters. + +.Linitialize_classes_loop: + addi s1, s1, -1 + + la t0, classes + add t0, t0, s1 + lbu t0, (t0) + li t1, 0x01 + + bne t0, t1, .Linitialize_classes_step + + /* DEBUG */ + li a0, 0x69676964 + sw a0, 8(sp) # Preserve the memory address. + addi a0, sp, 8 + li a1, 4 + call _write_error + +.Linitialize_classes_step: + bnez s1, .Linitialize_classes_loop + + lw s1, 12(sp) # Restore the saved register. # Epilogue. - lw ra, 4(sp) - lw s0, 0(sp) - addi sp, sp, 8 + lw ra, 20(sp) + lw s0, 16(sp) + addi sp, sp, 24 ret # Initializes the lookup tables. @@ -171,8 +201,7 @@ _tokenizer_initialize: sw s0, 0(sp) addi s0, sp, 8 - la a0, raw_classes - call _tokenizer_classes + call _initialize_classes # Epilogue. lw ra, 4(sp)