diff --git a/Rakefile b/Rakefile index 5976113..e04bff1 100644 --- a/Rakefile +++ b/Rakefile @@ -63,3 +63,35 @@ 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 + + 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 9c5ebc4..c6fcb98 100644 --- a/boot/common-boot.s +++ b/boot/common-boot.s @@ -1,4 +1,5 @@ -.global _is_alpha, _is_digit, _is_alnum, _is_upper, _is_lower, _write_out, _read_file, exit, _memcmp, _write_error +.global _is_alpha, _is_digit, _is_alnum, _is_upper, _is_lower +.global _write_out, _read_file, exit, _memcmp, _write_error, _put_char .section .rodata @@ -200,6 +201,29 @@ _read_file: ret # Terminates the program. a0 contains the return code. +.type _exit, @function exit: li a7, SYS_EXIT ecall + +# Writes a character from a0 into the standard output. +.type _put_char, @function +_put_char: + # Prologue + addi sp, sp, -16 + sw ra, 12(sp) + sw s0, 8(sp) + addi s0, sp, 16 + + sb a0, 4(sp) + li a0, STDOUT + addi a1, sp, 4 + li a2, 1 + li a7, SYS_WRITE + ecall + + # Epilogue. + lw ra, 12(sp) + lw s0, 8(sp) + add sp, sp, 16 + ret diff --git a/boot/stage1.s b/boot/stage1.s index fbfa16d..32c4e79 100644 --- a/boot/stage1.s +++ b/boot/stage1.s @@ -16,6 +16,14 @@ prologue: .ascii "addi sp, sp, -96\nsw ra, 92(sp)\nsw s0, 88(sp)\naddi s0, sp, 9 .equ PROLOGUE_SIZE, . - prologue epilogue: .ascii "lw ra, 92(sp)\nlw s0, 88(sp)\naddi sp, sp, 96\nret\n" .equ EPILOGUE_SIZE, . - epilogue +asm_exit: .ascii "li a0, 0\nli a7, 93\necall\n" +.equ ASM_EXIT_SIZE, . - asm_exit +asm_start: .ascii ".type _start, @function\n_start:\n" +.equ ASM_START_SIZE, . - asm_start +asm_and_a0_a1: .ascii "and a0, a0, a1\n" +.equ ASM_AND_A0_A1_SIZE, . - asm_and_a0_a1 +asm_or_a0_a1: .ascii "or a0, a0, a1\n" +.equ ASM_OR_A0_A1_SIZE, . - asm_or_a0_a1 .section .bss .type source_code, @object @@ -67,6 +75,14 @@ _build_binary_expression: call _token_compare beqz a0, .L_build_binary_expression_and + li t0, 0x726f # or + sw t0, 16(sp) + mv a0, s1 + lw a1, 20(sp) + addi a2, sp, 16 + call _token_compare + beqz a0, .L_build_binary_expression_or + li t0, 0x3d # = sw t0, 16(sp) mv a0, s1 @@ -75,11 +91,6 @@ _build_binary_expression: call _token_compare beqz a0, .L_build_binary_expression_equal - /* DEBUG - mv a0, s1 - li a1, 8 - call _write_error */ - j .Lbuild_binary_expression_end .L_build_binary_expression_equal: @@ -114,16 +125,18 @@ _build_binary_expression: addi s1, s1, 1 # Skip &. li a0, 1 call _build_expression - li t0, 0x0a3161 # a1\n - sw t0, 16(sp) - li t0, 0x202c3061 # a0,_ - sw t0, 12(sp) - li t0, 0x202c3061 # a0,_ - sw t0, 8(sp) - li t0, 0x20646e61 # and_ - sw t0, 4(sp) - addi a0, sp, 4 - li a1, 15 + la a0, asm_and_a0_a1 + li a1, ASM_AND_A0_A1_SIZE + call _write_out + + j .Lbuild_binary_expression_end + +.L_build_binary_expression_or: + addi s1, s1, 2 # Skip or. + li a0, 1 + call _build_expression + la a0, asm_or_a0_a1 + li a1, ASM_OR_A0_A1_SIZE call _write_out j .Lbuild_binary_expression_end @@ -141,20 +154,24 @@ _build_binary_expression: .type _build_expression, @function _build_expression: # Prologue. - addi sp, sp, -32 - sw ra, 28(sp) - sw s0, 24(sp) - addi s0, sp, 32 + addi sp, sp, -40 + sw ra, 36(sp) + sw s0, 32(sp) + addi s0, sp, 40 addi a0, a0, '0' # Make the register number to a character. - sw a0, 20(sp) # And save it. + sw a0, 28(sp) # And save it. call _skip_spaces call _read_token - sw s1, 16(sp) - sw a0, 12(sp) + sw s1, 24(sp) + sw a0, 20(sp) + + addi a0, s1, 0 + lbu a0, (a0) + li t0, '@' + beq a0, t0, .Lbuild_expression_address - # Integer literal. addi a0, s1, 0 lbu a0, (a0) call _is_digit @@ -162,7 +179,7 @@ _build_expression: addi a0, s1, 0 lbu a0, (a0) - li t0, 0x5f # _ + li t0, '_' beq a0, t0, .Lbuild_expression_call li t0, 0x61636f6c # loca @@ -174,7 +191,7 @@ _build_expression: beqz a0, .Lbuild_expression_identifier # Named identifier. - lw t1, 20(sp) + lw t1, 28(sp) li t0, 0x00202c00 # \0,_ or t0, t0, t1 sw t0, 8(sp) @@ -184,48 +201,80 @@ _build_expression: li a1, 7 call _write_out - lw a0, 16(sp) - lw a1, 12(sp) + lw a0, 24(sp) + lw a1, 20(sp) + call _write_out + + li a0, '\n' + call _put_char + + j .Lbuild_expression_advance + +.Lbuild_expression_address: + lw t1, 28(sp) + li t0, 0x20 # _ + sw t0, 16(sp) + li t0, 0x2c707320 # _sp, + sw t0, 12(sp) + li t0, 0x2c006120 # _a\0, + sw t0, 8(sp) + sb t1, 10(sp) + li t0, 0x69646461 # addi + sw t0, 4(sp) + addi a0, sp, 4 + li a1, 13 + call _write_out + + addi s1, s1, 1 # Skip @. + call _skip_spaces + call _read_token + sw s1, 24(sp) + sw a0, 20(sp) + + lw a0, 24(sp) + lw a1, 20(sp) + addi a0, a0, 4 # Skip the "loca" variable prefix. + addi a1, a1, -4 # Skip the "loca" variable prefix. call _write_out li t0, 0x0a # \n - sw t0, 8(sp) - addi a0, sp, 8 + sw t0, 16(sp) + addi a0, sp, 16 li a1, 1 call _write_out j .Lbuild_expression_advance .Lbuild_expression_identifier: - lw t1, 20(sp) + lw t1, 28(sp) li t0, 0x00202c00 # \0,_ or t0, t0, t1 - sw t0, 8(sp) + sw t0, 16(sp) li t0, 0x6120776c # lw a - sw t0, 4(sp) - addi a0, sp, 4 + sw t0, 12(sp) + addi a0, sp, 12 li a1, 7 call _write_out - lw a0, 16(sp) - lw a1, 12(sp) + lw a0, 24(sp) + lw a1, 20(sp) addi a0, a0, 4 # Skip the "loca" variable prefix. addi a1, a1, -4 # Skip the "loca" variable prefix. call _write_out li t0, 0x0a # \n - sw t0, 8(sp) + sw t0, 16(sp) li t0, 0x29707328 # (sp) - sw t0, 4(sp) - addi a0, sp, 4 + sw t0, 12(sp) + addi a0, sp, 12 li a1, 5 call _write_out j .Lbuild_expression_advance .Lbuild_expression_call: - lw a0, 16(sp) - lw a1, 12(sp) + lw a0, 24(sp) + lw a1, 20(sp) add s1, s1, a1 addi s1, s1, 1 call _compile_call @@ -233,37 +282,34 @@ _build_expression: j .Lbuild_expression_end .Lbuild_expression_literal: - lw t1, 20(sp) + lw t1, 28(sp) li t0, 0x00202c00 # \0,_ or t0, t0, t1 - sw t0, 8(sp) + sw t0, 16(sp) li t0, 0x6120696c # li a - sw t0, 4(sp) - addi a0, sp, 4 + sw t0, 12(sp) + addi a0, sp, 12 li a1, 7 call _write_out - lw a0, 16(sp) - lw a1, 12(sp) + lw a0, 24(sp) + lw a1, 20(sp) call _write_out - li t0, 0x0a # \n - sw t0, 8(sp) - addi a0, sp, 8 - li a1, 1 - call _write_out + li a0, '\n' + call _put_char j .Lbuild_expression_advance .Lbuild_expression_advance: - lw a0, 12(sp) + lw a0, 20(sp) add s1, s1, a0 .Lbuild_expression_end: # Epilogue. - lw ra, 28(sp) - lw s0, 24(sp) - addi sp, sp, 32 + lw ra, 36(sp) + lw s0, 32(sp) + addi sp, sp, 40 ret # Compiles a statement beginning with an identifier. @@ -554,6 +600,9 @@ _read_token: li t1, '=' beq t0, t1, .Ltoken_character_single + + li t1, '@' + beq t0, t1, .Ltoken_character_single # Expect an identifier or a number. .Ltoken_character_loop_do: lw t6, 4(sp) @@ -638,8 +687,50 @@ _skip_indentation: # a0 - Line length. .type _skip_comment, @function _skip_comment: - add s1, s1, a0 - addi s1, s1, 1 # Skip the new line. + # Prologue. + addi sp, sp, -16 + sw ra, 12(sp) + sw s0, 8(sp) + addi s0, sp, 16 + + /* DEBUG + mv a0, s1 + li a1, 8 + call _write_error */ + + # Check whether this is a comment. + li t0, 0x2a28 # (* + sw t0, 4(sp) + addi a0, sp, 4 + mv a1, s1 + li a2, 2 + call _memcmp + bnez a0, .Lskip_comment_end + + addi s1, s1, 2 # Skip (*. + + li t0, 0x292a # *) + sw t0, 4(sp) + +.Lskip_comment_loop: + addi a0, sp, 4 + mv a1, s1 + li a2, 2 + call _memcmp + beqz a0, .Lskip_comment_close + + addi s1, s1, 1 + + j .Lskip_comment_loop + +.Lskip_comment_close: + addi s1, s1, 2 # Skip *). + +.Lskip_comment_end: + # Epilogue. + lw ra, 12(sp) + lw s0, 8(sp) + addi sp, sp, 16 ret # Parameters: @@ -662,11 +753,8 @@ _compile_assembly: lw t0, 4(sp) add s1, s1, t0 - li t0, '\n' - sb t0, 0(sp) - addi a0, sp, 0 - li a1, 1 - call _write_out + li a0, '\n' + call _put_char addi s1, s1, 1 # Skip the new line. @@ -742,7 +830,6 @@ _compile_constant: call _write_out call _skip_spaces - call _read_token addi s1, s1, 2 # Skip the assignment sign. # : .long @@ -762,11 +849,8 @@ _compile_constant: add s1, s1, a1 call _write_out - li t0, '\n' - sw t0, 4(sp) - addi a0, sp, 4 - li a1, 1 - call _write_out + li a0, '\n' + call _put_char # Epilogue. lw ra, 12(sp) @@ -1234,7 +1318,7 @@ _compile_line: beqz a0, .Lcompile_line_empty # Skip an empty line. lbu t0, (s1) - li t1, '#' + li t1, '(' beq t0, t1, .Lcompile_line_comment li t0, 0x0a6d6172 # ram\n @@ -1396,6 +1480,11 @@ _compile_line: mv a0, zero .Lcompile_line_end: + sw a0, 12(sp) + call _skip_spaces + call _skip_comment + lw a0, 12(sp) + # Epilogue. lw ra, 28(sp) lw s0, 24(sp) @@ -1406,94 +1495,61 @@ _compile_line: .type _compile_text_section, @function _compile_text_section: # Prologue. - addi sp, sp, -24 - sw ra, 20(sp) - sw s0, 16(sp) - addi s0, sp, 24 + addi sp, sp, -8 + sw ra, 4(sp) + sw s0, 0(sp) + addi s0, sp, 8 la a0, section_text li a1, SECTION_TEXT_SIZE call _write_out # Epilogue. - lw ra, 20(sp) - lw s0, 16(sp) - addi sp, sp, 24 + lw ra, 4(sp) + lw s0, 0(sp) + addi sp, sp, 8 ret .type _compile_entry_point, @function _compile_entry_point: # Prologue. - addi sp, sp, -64 - sw ra, 60(sp) - sw s0, 56(sp) - addi s0, sp, 64 + addi sp, sp, -8 + sw ra, 4(sp) + sw s0, 0(sp) + addi s0, sp, 8 # .type _start, @function - li t0, 0x0a3a7472 # rt:\n - sw t0, 52(sp) - li t0, 0x6174735f # _sta - sw t0, 48(sp) - li t0, 0x0a6e6f69 # ion\n - sw t0, 44(sp) - li t0, 0x74636e75 # unct - sw t0, 40(sp) - li t0, 0x6640202c # , @f - sw t0, 36(sp) - li t0, 0x74726174 # tart - sw t0, 32(sp) - li t0, 0x735f2065 # e _s - sw t0, 28(sp) - li t0, 0x7079742e # .typ - sw t0, 24(sp) - addi a0, sp, 24 - li a1, 32 + la a0, asm_start + li a1, ASM_START_SIZE call _write_out addi s1, s1, 6 # Skip begin\n. # Epilogue. - lw ra, 60(sp) - lw s0, 56(sp) - addi sp, sp, 64 + lw ra, 4(sp) + lw s0, 0(sp) + addi sp, sp, 8 ret .type _compile_exit, @function _compile_exit: # Prologue. - addi sp, sp, -64 - sw ra, 60(sp) - sw s0, 56(sp) - addi s0, sp, 64 + addi sp, sp, -8 + sw ra, 4(sp) + sw s0, 0(sp) + addi s0, sp, 8 - # li a0, 0 - # li a7, SYS_EXIT - # ecall - li t0, 0x0a # \n - sw t0, 52(sp) - li t0, 0x6c6c6163 # call - sw t0, 48(sp) - li t0, 0x650a3339 # 93\ne - sw t0, 44(sp) - li t0, 0x202c3761 # a7,_ - sw t0, 40(sp) - li t0, 0x20696c0a # \nli_ - sw t0, 36(sp) - li t0, 0x30202c30 # 0, 0 - sw t0, 32(sp) - li t0, 0x6120696c # li a - sw t0, 28(sp) - addi a0, sp, 28 - li a1, 25 + la a0, asm_exit + li a1, ASM_EXIT_SIZE call _write_out addi s1, s1, 4 # Skip end. call _skip_spaces # Read the possible new line at the end of the file. # Epilogue. - lw ra, 60(sp) - lw s0, 56(sp) - addi sp, sp, 64 + lw ra, 4(sp) + lw s0, 0(sp) + addi sp, sp, 8 ret # Finds the end of the line and returns its length in a0. diff --git a/boot/stage2.elna b/boot/stage2.elna index 4e87e89..50bed53 100644 --- a/boot/stage2.elna +++ b/boot/stage2.elna @@ -1,5 +1,21 @@ +(* +s1 - Contains the current position in the source text. + +- The compiler expects valid input, otherwise it will generate invalid +assembly or hang. There is no error checking, no semantic analysis, no +type checking. + +- Imports with only a module name without package, e.g. +"import dummy", can be parsed, but are ignored. + +- No loops. Only labels and goto. + +- Only unsigned number literals are supported (in decimal or +hexadecimal format). + +- Comments are accepted only at the end of a line. +*) program -# s1 - Contains the current position in the source text. import dummy @@ -9,14 +25,14 @@ const var source_code: [40960]Byte -# Ignores the import. +(* Ignores the import. *) proc _compile_import() var loca0: Word begin _advance(6) _skip_spaces() loca0 := _read_token() - _advance(loca0) # Skip the imported module name. + _advance(loca0) (* Skip the imported module name. *) end proc _build_binary_expression() @@ -35,6 +51,14 @@ begin call _token_compare beqz a0, .L_build_binary_expression_and + li t0, 0x726f # or + sw t0, 16(sp) + mv a0, s1 + lw a1, 20(sp) + addi a2, sp, 16 + call _token_compare + beqz a0, .L_build_binary_expression_or + li t0, 0x3d # = sw t0, 16(sp) mv a0, s1 @@ -43,74 +67,82 @@ begin call _token_compare beqz a0, .L_build_binary_expression_equal - /* DEBUG - mv a0, s1 - li a1, 8 - call _write_error */ + goto .Lbuild_binary_expression_end - j .Lbuild_binary_expression_end - -.L_build_binary_expression_equal: - addi s1, s1, 1 # Skip =. + .L_build_binary_expression_equal + _advance(1) (* Skip =. *) _build_expression(1) - li t0, 0x0a3161 # a1\n - sw t0, 16(sp) - li t0, 0x202c3061 # a0,_ - sw t0, 12(sp) - li t0, 0x202c3061 # a0,_ - sw t0, 8(sp) - li t0, 0x20627573 # sub_ - sw t0, 4(sp) - addi a0, sp, 4 - li a1, 15 - call _write_out + loca0 := 0x0a3161 (* a1\n *) + _write_out(@loca0, 4) + loca0 := 0x202c3061 (* a0,_ *) + _write_out(@loca0, 4) + loca0 := 0x202c3061 (* a0,_ *) + _write_out(@loca0, 4) + loca0 := 0x20627573 (* sub_ *) + _write_out(@loca0, 4) - li t0, 0x0a306120 # _a0\n - sw t0, 16(sp) - li t0, 0x2c306120 # _a0, - sw t0, 12(sp) - li t0, 0x7a716573 # seqz - sw t0, 8(sp) - addi a0, sp, 8 - li a1, 12 - call _write_out + loca0 := 0x7a716573 (* seqz *) + _write_out(@loca0, 4) + loca0 := 0x2c306120 (* _a0, *) + _write_out(@loca0, 4) + loca0 := 0x0a306120 (* _a0\n *) + _write_out(@loca0, 4) - j .Lbuild_binary_expression_end + goto .Lbuild_binary_expression_end -.L_build_binary_expression_and: - addi s1, s1, 1 # Skip &. + .L_build_binary_expression_and + _advance(1) (* Skip &. *) _build_expression(1) - li t0, 0x0a3161 # a1\n - sw t0, 16(sp) - li t0, 0x202c3061 # a0,_ - sw t0, 12(sp) - li t0, 0x202c3061 # a0,_ - sw t0, 8(sp) - li t0, 0x20646e61 # and_ - sw t0, 4(sp) - addi a0, sp, 4 - li a1, 15 - call _write_out + loca0 := 0x20646e61 (* and_ *) + _write_out(@loca0, 4) + loca0 := 0x202c3061 (* a0,_ *) + _write_out(@loca0, 4) + loca0 := 0x202c3061 (* a0,_ *) + _write_out(@loca0, 4) + loca0 := 0x0a3161 (* a1\n *) + _write_out(@loca0, 3) - j .Lbuild_binary_expression_end + goto .Lbuild_binary_expression_end -.Lbuild_binary_expression_end: + .L_build_binary_expression_or + _advance(2) (* Skip or. *) + _build_expression(1) + loca0 := 0x6120726f (* or a *) + _write_out(@loca0, 4) + loca0 := 0x61202c30 (* 0, a *) + _write_out(@loca0, 4) + loca0 := 0x61202c30 (* 0, a *) + _write_out(@loca0, 4) + loca0 := 0x0a31 (* 1\n *) + _write_out(@loca0, 2) + + goto .Lbuild_binary_expression_end + + .Lbuild_binary_expression_end end -# Evalutes an expression and saves the result in a0. -# -# a0 - X in aX, the register number to save the result. +(* +Evalutes an expression and saves the result in a0. + +a0 - X in aX, the register number to save the result. +*) proc _build_expression() +var + loca20, loca28, loca8: Word + loca24: ^Byte begin addi a0, a0, '0' # Make the register number to a character. - sw a0, 20(sp) # And save it. + sw a0, 28(sp) # And save it. _skip_spaces() - call _read_token - sw s1, 16(sp) - sw a0, 12(sp) + loca20 := _read_token() + loca24 := _current() + + addi a0, s1, 0 + lbu a0, (a0) + li t0, '@' + beq a0, t0, .Lbuild_expression_address - # Integer literal. addi a0, s1, 0 lbu a0, (a0) call _is_digit @@ -118,7 +150,7 @@ begin addi a0, s1, 0 lbu a0, (a0) - li t0, 0x5f # _ + li t0, '_' beq a0, t0, .Lbuild_expression_call li t0, 0x61636f6c # loca @@ -129,31 +161,54 @@ begin call _memcmp beqz a0, .Lbuild_expression_identifier - # Named identifier. - lw t1, 20(sp) - li t0, 0x00202c00 # \0,_ - or t0, t0, t1 + (* Named identifier. *) + loca8 := 0x6120616c (* la a *) + _write_out(@loca8, 4) + loca8 := 0x00202c00 or loca28 + _write_out(@loca8, 3) + + _write_out(loca24, loca20) + _put_char(0x0a) + + goto .Lbuild_expression_advance + + .Lbuild_expression_address + lw t1, 28(sp) + li t0, 0x20 # _ + sw t0, 16(sp) + li t0, 0x2c707320 # _sp, + sw t0, 12(sp) + li t0, 0x2c006120 # _a\0, sw t0, 8(sp) - li t0, 0x6120616c # la a + sb t1, 10(sp) + li t0, 0x69646461 # addi sw t0, 4(sp) addi a0, sp, 4 - li a1, 7 + li a1, 13 call _write_out - lw a0, 16(sp) - lw a1, 12(sp) + _advance(1) (* Skip @. *) + _skip_spaces() + call _read_token + sw s1, 24(sp) + sw a0, 20(sp) + + lw a0, 24(sp) + lw a1, 20(sp) + addi a0, a0, 4 # Skip the "loca" variable prefix. + addi a1, a1, -4 # Skip the "loca" variable prefix. call _write_out li t0, 0x0a # \n - sw t0, 8(sp) - addi a0, sp, 8 + sw t0, 16(sp) + addi a0, sp, 16 li a1, 1 call _write_out goto .Lbuild_expression_advance .Lbuild_expression_identifier - lw t1, 20(sp) + lw t1, 28(sp) li t0, 0x00202c00 # \0,_ or t0, t0, t1 sw t0, 8(sp) @@ -163,8 +218,8 @@ begin li a1, 7 call _write_out - lw a0, 16(sp) - lw a1, 12(sp) + lw a0, 24(sp) + lw a1, 20(sp) addi a0, a0, 4 # Skip the "loca" variable prefix. addi a1, a1, -4 # Skip the "loca" variable prefix. call _write_out @@ -180,16 +235,14 @@ begin goto .Lbuild_expression_advance .Lbuild_expression_call - lw a0, 16(sp) - lw a1, 12(sp) - add s1, s1, a1 - addi s1, s1, 1 - call _compile_call + _advance(loca20) + _advance(1) + _compile_call(loca24, loca20) goto .Lbuild_expression_end .Lbuild_expression_literal - lw t1, 20(sp) + lw t1, 28(sp) li t0, 0x00202c00 # \0,_ or t0, t0, t1 sw t0, 8(sp) @@ -199,34 +252,28 @@ begin li a1, 7 call _write_out - lw a0, 16(sp) - lw a1, 12(sp) - call _write_out - - li t0, 0x0a # \n - sw t0, 8(sp) - addi a0, sp, 8 - li a1, 1 - call _write_out + _write_out(loca24, loca20) + _put_char(0x0a) # \n goto .Lbuild_expression_advance .Lbuild_expression_advance - lw a0, 12(sp) - add s1, s1, a0 + _advance(loca20) .Lbuild_expression_end end -# Compiles a statement beginning with an identifier. -# -# Left values should be variables named "loca n", where n is the offset -# of the variable on the stack, like loca8 or loca4. +(* +Compiles a statement beginning with an identifier. + +Left values should be variables named "loca n", where n is the offset +of the variable on the stack, like loca8 or loca4. +*) proc _compile_identifier() begin call _read_token - # Save the pointer to the identifier and its length on the stack. + (* Save the pointer to the identifier and its length on the stack. *) sw s1, 20(sp) sw a0, 16(sp) @@ -234,7 +281,7 @@ begin _skip_spaces() call _read_token - # Save the pointer and the length of the token following the identifier. + (* Save the pointer and the length of the token following the identifier. *) sw s1, 12(sp) sw a0, 8(sp) @@ -293,11 +340,13 @@ begin .Lcompile_identifier_end end -# Compiles a procedure call. Expects s1 to point to the first argument. -# a0 - Pointer to the procedure name. -# a1 - Length of the procedure name. -# -# Returns the procedure result in a0. +(* +Compiles a procedure call. Expects s1 to point to the first argument. +a0 - Pointer to the procedure name. +a1 - Length of the procedure name. + +Returns the procedure result in a0. +*) proc _compile_call() begin sw a0, 20(sp) @@ -324,9 +373,11 @@ begin lw t0, 12(sp) # Argument count for a procedure call. - # Only 6 arguments are supported with a0-a5. - # Save all arguments on the stack so they aren't overriden afterwards. - # The offset on the stack always has two digits in this case. + (* + Only 6 arguments are supported with a0-a5. + Save all arguments on the stack so they aren't overriden afterwards. + The offset on the stack always has two digits in this case. + *) li t1, -4 mul t1, t0, t1 addi t1, t1, 60 @@ -365,15 +416,17 @@ begin addi t0, t0, 1 sw t0, 12(sp) - _advance(1) # Skip the comma between the arguments. + _advance(1) (* Skip the comma between the arguments. *) goto .Lcompile_call_argument .Lcompile_call_complete sw zero, 12(sp) .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. + (* + 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. + *) lw t0, 12(sp) li t1, 5 bgt t0, t1, .Lcompile_call_perform @@ -436,11 +489,13 @@ begin call _write_out _skip_spaces() - _advance(1) # Skip the close paren. + _advance(1) (* Skip the close paren. *) end -# Reads a token and returns its length in a0. -# _read_token doesn't change s1, it finds the length of the token s1 is pointing to. +(* +Reads a token and returns its length in a0. +_read_token doesn't change s1, it finds the length of the token s1 is pointing to. +*) proc _read_token() begin lbu t0, (s1) # t0 = Current character. @@ -478,7 +533,10 @@ begin li t1, '=' beq t0, t1, .Ltoken_character_single - # Expect an identifier or a number. + + li t1, '@' + beq t0, t1, .Ltoken_character_single + (* Expect an identifier or a number. *) .Ltoken_character_loop_do lw t6, 4(sp) add t1, s1, t6 @@ -512,7 +570,7 @@ begin lw a0, 4(sp) end -# Skips the spaces till the next non space character. +(* Skips the spaces till the next non space character. *) proc _skip_spaces() begin .Lspace_loop_do @@ -535,7 +593,7 @@ begin .Lspace_loop_end end -# Skips tabs at the line beginning. +(* Skips tabs at the line beginning. *) proc _skip_indentation() begin .Lskip_indentation_do @@ -553,72 +611,98 @@ begin .Lskip_indentation_end end -# Parameters: -# a0 - Line length. +(* +Parameters: + a0 - Line length. +*) proc _skip_comment(loca84: Word) begin - _advance(loca84) - _advance(1) # Skip the new line. + (* DEBUG + mv a0, s1 + li a1, 8 + call _write_error *) + + (* Check whether this is a comment. *) + li t0, 0x2a28 # (* + sw t0, 4(sp) + addi a0, sp, 4 + mv a1, s1 + li a2, 2 + call _memcmp + bnez a0, .Lskip_comment_end + + _advance(2) (* Skip (*. *) + + li t0, 0x292a # *) + sw t0, 4(sp) + + .Lskip_comment_loop + addi a0, sp, 4 + mv a1, s1 + li a2, 2 + call _memcmp + beqz a0, .Lskip_comment_close + + _advance(1) + + goto .Lskip_comment_loop + + .Lskip_comment_close + _advance(2) (* Skip "*" and ")". *) + + .Lskip_comment_end end -# Parameters: -# a0 - Line length. +(* +Parameters: + a0 - Line length. +*) proc _compile_assembly(loca84: Word) var loca0: ^Byte begin - # Write the source to the standard output. + (* Write the source to the standard output. *) loca0 := _current() _write_out(loca0, loca84) _advance(loca84) - li t0, '\n' - sb t0, 0(sp) - addi a0, sp, 0 - li a1, 1 - call _write_out + _put_char(0xa) (* \n *) - _advance(1) # Skip the new line. + _advance(1) (* Skip the new line. *) end proc _compile_program() +var loca0: Word begin - # .global _start - li t0, 0x0a7472 # rt\n - sw t0, 20(sp) - li t0, 0x6174735f # _sta - sw t0, 16(sp) - li t0, 0x206c6162 # bal_ - sw t0, 12(sp) - li t0, 0x6f6c672e # .glo - sw t0, 8(sp) + (* .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) - addi a0, sp, 8 - li a1, 15 - call _write_out - - _advance(8) # program\n. + _advance(8) (* program\n. *) end proc _compile_constant_section() +var loca0: Word begin - # .section .rodata - li t0, 0x0a # \n - sw t0, 20(sp) - li t0, 0x61746164 # data - sw t0, 16(sp) - li t0, 0x6f722e20 # _.ro - sw t0, 12(sp) - li t0, 0x6e6f6974 # tion - sw t0, 8(sp) - li t0, 0x6365732e # .sec - sw t0, 4(sp) + (* .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) - addi a0, sp, 4 - li a1, 17 - call _write_out - - _advance(6) # const\n. + _advance(6) (* const\n. *) .Lcompile_constant_section_item _skip_spaces() @@ -633,59 +717,49 @@ begin end proc _compile_constant() +var + loca0, loca4: Word + loca8: ^Byte begin - call _read_token + loca4 := _read_token() + loca8 := _current() (* Save the identifier pointer before advancing it. *) - mv a1, a0 # The identifier length from _read_token should be in a1. - mv a0, s1 # Save the identifier pointer before advancing it. - add s1, s1, a1 - call _write_out + _write_out(loca8, loca4) + _advance(loca4) _skip_spaces() - call _read_token - _advance(2) # Skip the assignment sign. + _advance(2) (* Skip the assignment sign. *) - # : .long - li t0, 0x20676e6f # ong_ - sw t0, 4(sp) - li t0, 0x6c2e203a # : .l - sw t0, 0(sp) - mv a0, sp - li a1, 8 - call _write_out + (* : .long *) + loca0 := 0x6c2e203a (* : .l *) + _write_out(@loca0, 4) + loca0 := 0x20676e6f (* ong_ *) + _write_out(@loca0, 4) _skip_spaces() - call _read_token + loca4 := _read_token() + loca8 := _current() (* Save the literal pointer before advancing it. *) - mv a1, a0 # The literal length from _read_token should be in a1. - mv a0, s1 # Save the literal pointer before advancing it. - add s1, s1, a1 - call _write_out + _write_out(loca8, loca4) + _advance(loca4) - li t0, '\n' - sw t0, 4(sp) - addi a0, sp, 4 - li a1, 1 - call _write_out + _put_char(0x0a) (* \n *) end proc _compile_variable_section() +var loca0: Word begin - # .section .bss - li t0, 0x0a73 # s\n - sw t0, 12(sp) - li t0, 0x73622e20 # _.bs - sw t0, 8(sp) - li t0, 0x6e6f6974 # tion - sw t0, 4(sp) - li t0, 0x6365732e # .sec - sw t0, 0(sp) + (* .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) - addi a0, sp, 0 - li a1, 14 - call _write_out - - _advance(4) # var\n. + _advance(4) (* var\n. *) .Lcompile_variable_section_item _skip_spaces() @@ -703,32 +777,32 @@ proc _compile_variable() begin call _read_token - # Save the identifier on the stack since it should emitted multiple times. + (* Save the identifier on the stack since it should emitted multiple times. *) sw s1, 28(sp) sw a0, 24(sp) add s1, s1, a0 _skip_spaces() - _advance(1) # Skip the colon in front of the type. + _advance(1) (* Skip the colon in front of the type. *) _skip_spaces() - _advance(1) # Skip the opening bracket. + _advance(1) (* Skip the opening bracket. *) call _read_token - # Save the array size on the stack since it has to be emitted multiple times. + (* Save the array size on the stack since it has to be emitted multiple times. *) sw s1, 20(sp) sw a0, 16(sp) add s1, s1, a0 _skip_spaces() - _advance(1) # Skip the closing bracket. + _advance(1) (* Skip the closing bracket. *) _skip_spaces() call _read_token add s1, s1, a0 # Skip the type. - # .type identifier, @object + (* .type identifier, @object *) li t0, 0x2065 # e_ sw t0, 12(sp) li t0, 0x7079742e # .typ @@ -751,7 +825,7 @@ begin li a1, 10 call _write_out - # .size identifier, size + (* .size identifier, size *) li t0, 0x2065 # e_ sw t0, 12(sp) li t0, 0x7a69732e # .siz @@ -780,7 +854,7 @@ begin li a1, 1 call _write_out - # identifier: .zero size + (* identifier: .zero size *) lw a0, 28(sp) lw a1, 24(sp) call _write_out @@ -805,58 +879,47 @@ begin end proc _compile_procedure() +var + loca0, loca8, loca12, loca16: Word + loca20: ^Char begin - _advance(5) # Skip proc_ - call _read_token - sw s1, 20(sp) - sw a0, 16(sp) - add s1, s1, a0 + _advance(5) (* Skip proc_ *) + loca16 := _read_token() + loca20 := _current() + _advance(loca16) - # .type identifier, @function - li t0, 0x2065 # e_ - sw t0, 12(sp) - li t0, 0x7079742e # .typ - sw t0, 8(sp) - addi a0, sp, 8 - li a1, 6 - call _write_out + (* .type identifier, @function *) + loca0 := 0x7079742e (* .typ *) + _write_out(@loca0, 4) + loca0 := 0x2065 (* e_ *) + _write_out(@loca0, 2) - lw a0, 20(sp) - lw a1, 16(sp) - call _write_out + _write_out(loca20, loca16) - li t0, 0x0a6e6f69 # ion\n - sw t0, 12(sp) - li t0, 0x74636e75 # unct - sw t0, 8(sp) - li t0, 0x6640202c # , @f - sw t0, 4(sp) - addi a0, sp, 4 - li a1, 12 - call _write_out + loca0 := 0x6640202c (* , @f *) + _write_out(@loca0, 4) + loca0 := 0x74636e75 (* unct *) + _write_out(@loca0, 4) + loca0 := 0x0a6e6f69 (* ion\n *) + _write_out(@loca0, 4) - lw a0, 20(sp) - lw a1, 16(sp) - call _write_out + _write_out(loca20, loca16) - li t0, 0x0a3a # :\n - sw t0, 12(sp) - addi a0, sp, 12 - li a1, 2 - call _write_out + loca0 := 0x0a3a (* :\n *) + _write_out(@loca0, 2) _skip_spaces() - _advance(1) # Skip opening argument paren. + _advance(1) (* Skip opening argument paren. *) _skip_spaces() - _advance(1) # Skip closing argument paren. + _advance(1) (* Skip closing argument paren. *) - li t0, 0x6e # n - sw t0, 12(sp) - li t0, 0x69676562 # begi - sw t0, 8(sp) + loca12 := 0x6e (* n *) + loca8 := 0x69676562 (* begi *) - # Skip all declarations until we find the "begin" keyword, denoting the - # beginning of the procedure body. + (* + Skip all declarations until we find the "begin" keyword, denoting the + beginning of the procedure body. + *) .Lcompile_procedure_begin _skip_spaces() call _read_token @@ -869,67 +932,45 @@ begin bnez a0, .Lcompile_procedure_begin - # Generate the procedure prologue with a predefined stack size. - li t0, 0x69646461 # addi - sw t0, 12(sp) - addi a0, sp, 12 - li a1, 4 - call _write_out + (* Generate the procedure prologue with a predefined stack size. *) + loca0 := 0x69646461 (* addi *) + _write_out(@loca0, 4) - li t0, 0x2c707320 # _sp, - sw t0, 12(sp) + loca0 := 0x2c707320 (* _sp, *) + _write_out(@loca0, 4) + _write_out(@loca0, 4) - addi a0, sp, 12 - li a1, 4 - call _write_out + loca0 := 0x0a36392d (* -96\n *) + _write_out(@loca0, 4) - addi a0, sp, 12 - li a1, 4 - call _write_out + 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) - li t0, 0x0a36392d # -96\n - sw t0, 12(sp) - addi a0, sp, 12 - li a1, 4 - call _write_out + 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) - li t0, 0x0a29 # )\n - sw t0, 12(sp) - li t0, 0x70732832 # 2(sp - sw t0, 8(sp) - li t0, 0x39202c61 # a, 9 - sw t0, 4(sp) - li t0, 0x72207773 # sw r - sw t0, 0(sp) - addi a0, sp, 0 - li a1, 14 - call _write_out + 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) - li t0, 0x0a29 # )\n - sw t0, 12(sp) - li t0, 0x70732838 # 8(sp - sw t0, 8(sp) - li t0, 0x38202c30 # 0, 8 - sw t0, 4(sp) - li t0, 0x73207773 # sw s - sw t0, 0(sp) - addi a0, sp, 0 - li a1, 14 - call _write_out - - li t0, 0x0a363920 # _96\n - sw t0, 12(sp) - li t0, 0x2c707320 # _sp, - sw t0, 8(sp) - li t0, 0x2c307320 # _s0, - sw t0, 4(sp) - li t0, 0x69646461 # addi - sw t0, 0(sp) - addi a0, sp, 0 - li a1, 16 - call _write_out - - # Save passed arguments on the stack. + (* Save passed arguments on the stack. *) li t0, 0x0a29 # )\n sw t0, 12(sp) li t0, 0x70732834 # 4(sp @@ -982,7 +1023,7 @@ begin li a1, 14 call _write_out - # Generate the body of the procedure. + (* Generate the body of the procedure. *) .Lcompile_procedure_body _skip_indentation() call _read_line @@ -1003,68 +1044,48 @@ begin .Lcompile_procedure_end add s1, s1, 4 # Skip end\n. - # Generate the procedure epilogue with a predefined stack size. - li t0, 0x0a29 # )\n - sw t0, 12(sp) - li t0, 0x70732832 # 2(sp - sw t0, 8(sp) - li t0, 0x39202c61 # a, 9 - sw t0, 4(sp) - li t0, 0x7220776c # lw r - sw t0, 0(sp) - addi a0, sp, 0 - li a1, 14 - call _write_out + (* 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) - li t0, 0x0a29 # )\n - sw t0, 12(sp) - li t0, 0x70732838 # 8(sp - sw t0, 8(sp) - li t0, 0x38202c30 # 0, 8 - sw t0, 4(sp) - li t0, 0x7320776c # lw s - sw t0, 0(sp) - addi a0, sp, 0 - li a1, 14 - call _write_out + 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) - li t0, 0x69646461 # addi - sw t0, 12(sp) - addi a0, sp, 12 - li a1, 4 - call _write_out + loca0 := 0x69646461 (* addi *) + _write_out(@loca0, 4) - li t0, 0x2c707320 # _sp, - sw t0, 12(sp) + loca0 := 0x2c707320 (* _sp, *) + _write_out(@loca0, 4) + _write_out(@loca0, 4) - addi a0, sp, 12 - li a1, 4 - call _write_out + loca0 := 0x0a3639 (* 96\n *) + _write_out(@loca0, 4) - addi a0, sp, 12 - li a1, 4 - call _write_out - - li t0, 0x0a3639 # 96\n - sw t0, 12(sp) - addi a0, sp, 12 - li a1, 3 - call _write_out - - li t0, 0x0a746572 # ret\n - sw t0, 12(sp) - addi a0, sp, 12 - li a1, 4 - call _write_out + loca0 := 0x0a746572 (* ret\n *) + _write_out(@loca0, 4) end -# Compares two string, which of one has a length, the other one is null-terminated. -# -# a0 - The address of the token string. -# a1 - The length of the string in a0. -# a2 - The address of the null-terminated string. -# -# If the strings match sets a0 to 0, otherwise sets it to 1. +(* +Compares two string, which of one has a length, the other one is null-terminated. + + a0 - The address of the token string. + a1 - The length of the string in a0. + a2 - The address of the null-terminated string. + +If the strings match sets a0 to 0, otherwise sets it to 1. +*) proc _token_compare() begin addi t0, a0, 0 @@ -1074,8 +1095,10 @@ begin .Ltoken_compare_loop lbu t3, (t2) - # 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. + (* + 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. + *) or t4, t3, t1 beqz t4, .Ltoken_compare_equal @@ -1102,7 +1125,7 @@ end proc _compile_goto() begin - addi s1, s1, 4 # Skip the goto keyword. + _advance(4) (* Skip the goto keyword. *) li t0, 0x206a # j_ sw t0, 8(sp) @@ -1120,7 +1143,7 @@ begin lw a0, 8(sp) # Saved dot position. call _write_out - _advance(1) # Skip the new line. + _advance(1) (* Skip the new line. *) li t0, 0x0a # \n sw t0, 8(sp) @@ -1129,12 +1152,12 @@ begin call _write_out end -# a0 - Line length. +(* a0 - Line length. *) proc _compile_label() begin sw a0, 0(sp) # Save the line length. - # Write the whole line as is. + (* Write the whole line as is. *) mv a0, s1 lw a1, 0(sp) call _write_out @@ -1167,23 +1190,25 @@ begin add s1, s1, a0 # Skip the line. end -# Parameters: -# a0 - Line length. -# a1 - Whether the section header was already emitted. If not it should be -# emitted before any code is written. -# -# Returns 1 in a0 if the parsed line contained a text section element such a -# procedure or the program entry point. Otherwise sets a0 to 0. +(* +Parameters: + a0 - Line length. + a1 - Whether the section header was already emitted. If not it should be + emitted before any code is written. + +Returns 1 in a0 if the parsed line contained a text section element such a +procedure or the program entry point. Otherwise sets a0 to 0. +*) proc _compile_line() begin - # Preserve passed arguments. + (* Preserve passed arguments. *) sw a0, 20(sp) sw a1, 16(sp) beqz a0, .Lcompile_line_empty # Skip an empty line. lbu t0, (s1) - li t1, '#' + li t1, '(' beq t0, t1, .Lcompile_line_comment li t0, 0x0a6d6172 # ram\n @@ -1274,7 +1299,7 @@ begin li t1, '_' beq t0, t1, .Lcompile_line_identifier - goto .Lcompile_line_unchanged # Else. + goto .Lcompile_line_unchanged (* Else. *) .Lcompile_line_label lw a0, 20(sp) @@ -1345,80 +1370,79 @@ begin mv a0, zero .Lcompile_line_end + sw a0, 12(sp) + _skip_spaces() + _skip_comment() + lw a0, 12(sp) end -# Prints ".section .text" and exits. +(* Prints ".section .text" and exits. *) proc _compile_text_section() +var loca0: Word begin - # .section .text - li t0, 0x0a7478 # xt\n - sw t0, 12(sp) - li t0, 0x65742e20 # _.te - sw t0, 8(sp) - li t0, 0x6e6f6974 # tion - sw t0, 4(sp) - li t0, 0x6365732e # .sec - sw t0, 0(sp) - - addi a0, sp, 0 - li a1, 15 - call _write_out + (* .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 *) + _write_out(@loca0, 3) end proc _compile_entry_point() +var loca0: Word begin - # .type _start, @function - li t0, 0x0a3a7472 # rt:\n - sw t0, 52(sp) - li t0, 0x6174735f # _sta - sw t0, 48(sp) - li t0, 0x0a6e6f69 # ion\n - sw t0, 44(sp) - li t0, 0x74636e75 # unct - sw t0, 40(sp) - li t0, 0x6640202c # , @f - sw t0, 36(sp) - li t0, 0x74726174 # tart - sw t0, 32(sp) - li t0, 0x735f2065 # e _s - sw t0, 28(sp) - li t0, 0x7079742e # .typ - sw t0, 24(sp) - addi a0, sp, 24 - li a1, 32 - call _write_out + (* .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) - _advance(6) # Skip begin\n. + _advance(6) (* Skip begin\n. *) end proc _compile_exit() +var loca0: Word begin - # li a0, 0 - # li a7, SYS_EXIT - # ecall - li t0, 0x0a # \n - sw t0, 52(sp) - li t0, 0x6c6c6163 # call - sw t0, 48(sp) - li t0, 0x650a3339 # 93\ne - sw t0, 44(sp) - li t0, 0x202c3761 # a7,_ - sw t0, 40(sp) - li t0, 0x20696c0a # \nli_ - sw t0, 36(sp) - li t0, 0x30202c30 # 0, 0 - sw t0, 32(sp) - li t0, 0x6120696c # li a - sw t0, 28(sp) - addi a0, sp, 28 - li a1, 25 - call _write_out + (* + 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) - _advance(4) # Skip end. - _skip_spaces() # Read the possible new line at the end of the file. + _advance(4) (* Skip end. *) + _skip_spaces() (* Read the possible new line at the end of the file. *) end -# Finds the end of the line and returns its length in a0. +(* Finds the end of the line and returns its length in a0. *) proc _read_line() begin mv t0, s1 # Local position in the source text. @@ -1450,7 +1474,7 @@ begin call _compile_line beqz a0, .Lcompile_do - # Update whether the text section header was already emitted. + (* Update whether the text section header was already emitted. *) lw t0, 4(sp) or t0, t0, a0 sw t0, 4(sp) @@ -1459,27 +1483,27 @@ begin .Lcompile_end end -# Returns the pointer to the current position in the source text in a0. +(* Returns the pointer to the current position in the source text in a0. *) proc _current() begin mv a0, s1 end -# a0 is the number of bytes to advance in the source text. +(* a0 is the number of bytes to advance in the source text. *) proc _advance() begin add s1, s1, a0 end -# Returns the first character in the remaining source text. +(* Returns the first character in the remaining source text. *) proc _front() begin lbu a0, (s1) end -# Entry point. +(* Entry point. *) begin - # Read the source from the standard input. + (* Read the source from the standard input. *) la a0, source_code la a1, SOURCE_BUFFER_SIZE # Buffer size. lw a1, (a1)