From 963d32e8d1ab322d77768b5464e7360fd6feb3cd Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Sun, 27 Apr 2025 23:18:06 +0200 Subject: [PATCH] Add return statements --- boot/stage1.s | 181 ++++++++++------ boot/stage2.elna | 550 +++++++++++++++++++++-------------------------- 2 files changed, 364 insertions(+), 367 deletions(-) diff --git a/boot/stage1.s b/boot/stage1.s index 32c4e79..5989ac9 100644 --- a/boot/stage1.s +++ b/boot/stage1.s @@ -1,7 +1,7 @@ .global _start # Program entry point. # s1 - Contains the current position in the source text. -.equ SOURCE_BUFFER_SIZE, 40960 +.equ SOURCE_BUFFER_SIZE, 81920 .section .rodata section_rodata: .ascii ".section .rodata\n" @@ -16,6 +16,7 @@ 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" @@ -24,6 +25,14 @@ 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 +asm_add_a0_a1: .ascii "add a0, a0, a1\n" +.equ ASM_ADD_A0_A1_SIZE, . - asm_add_a0_a1 +asm_sub_a0_a1: .ascii "sub a0, a0, a1\n" +.equ ASM_SUB_A0_A1_SIZE, . - asm_sub_a0_a1 +asm_seqz_a0: .ascii "seqz a0, a0\n" +.equ ASM_SEQZ_A0_SIZE, . - asm_seqz_a0 +asm_type: .ascii ".type " +.equ ASM_TYPE_SIZE, . - asm_type .section .bss .type source_code, @object @@ -67,7 +76,7 @@ _build_binary_expression: call _read_token sw a0, 20(sp) - li t0, 0x26 # & + li t0, '&' sw t0, 16(sp) mv a0, s1 lw a1, 20(sp) @@ -83,7 +92,7 @@ _build_binary_expression: call _token_compare beqz a0, .L_build_binary_expression_or - li t0, 0x3d # = + li t0, '=' sw t0, 16(sp) mv a0, s1 lw a1, 20(sp) @@ -91,32 +100,34 @@ _build_binary_expression: call _token_compare beqz a0, .L_build_binary_expression_equal + li t0, '+' + sw t0, 16(sp) + mv a0, s1 + lw a1, 20(sp) + addi a2, sp, 16 + call _token_compare + beqz a0, .L_build_binary_expression_plus + + li t0, '-' + sw t0, 16(sp) + mv a0, s1 + lw a1, 20(sp) + addi a2, sp, 16 + call _token_compare + beqz a0, .L_build_binary_expression_minus + j .Lbuild_binary_expression_end .L_build_binary_expression_equal: 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, 0x20627573 # sub_ - sw t0, 4(sp) - addi a0, sp, 4 - li a1, 15 + la a0, asm_sub_a0_a1 + li a1, ASM_SUB_A0_A1_SIZE call _write_out - 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 + la a0, asm_seqz_a0 + li a1, ASM_SEQZ_A0_SIZE call _write_out j .Lbuild_binary_expression_end @@ -141,6 +152,26 @@ _build_binary_expression: j .Lbuild_binary_expression_end +.L_build_binary_expression_plus: + addi s1, s1, 1 # Skip +. + li a0, 1 + call _build_expression + la a0, asm_add_a0_a1 + li a1, ASM_ADD_A0_A1_SIZE + call _write_out + + j .Lbuild_binary_expression_end + +.L_build_binary_expression_minus: + addi s1, s1, 1 # Skip -. + li a0, 1 + call _build_expression + la a0, asm_sub_a0_a1 + li a1, ASM_SUB_A0_A1_SIZE + call _write_out + + j .Lbuild_binary_expression_end + .Lbuild_binary_expression_end: # Epilogue. lw ra, 28(sp) @@ -237,11 +268,8 @@ _build_expression: addi a1, a1, -4 # Skip the "loca" variable prefix. call _write_out - li t0, 0x0a # \n - sw t0, 16(sp) - addi a0, sp, 16 - li a1, 1 - call _write_out + li a0, '\n' + call _put_char j .Lbuild_expression_advance @@ -262,7 +290,7 @@ _build_expression: addi a1, a1, -4 # Skip the "loca" variable prefix. call _write_out - li t0, 0x0a # \n + li t0, '\n' sw t0, 16(sp) li t0, 0x29707328 # (sp) sw t0, 12(sp) @@ -380,7 +408,7 @@ _compile_identifier: addi a1, a1, -4 # Skip the "loca" variable prefix. call _write_out - li t0, 0x0a # \n + li t0, '\n' sw t0, 12(sp) li t0, 0x29707328 # (sp) sw t0, 8(sp) @@ -416,7 +444,6 @@ _compile_call: .Lcompile_call_paren: call _skip_spaces - call _read_token lbu t0, (s1) li t1, 0x29 # ) beq t0, t1, .Lcompile_call_complete @@ -458,7 +485,7 @@ _compile_call: li a1, 1 call _write_out - li t0, 0x0a # \n + li t0, '\n' sw t0, 8(sp) li t0, 0x29707328 # (sp) sw t0, 4(sp) @@ -467,7 +494,6 @@ _compile_call: call _write_out call _skip_spaces - call _read_token lbu t0, (s1) li t1, ',' bne t0, t1, .Lcompile_call_paren @@ -507,7 +533,7 @@ _compile_call: addi t4, t4, '0' addi t0, t0, '0' - li t5, 0x0a # \n + li t5, '\n' sb t5, 11(sp) li t5, 0x29707328 # (sp) sw t5, 7(sp) @@ -540,7 +566,7 @@ _compile_call: lw a1, 16(sp) call _write_out - li t0, 0x0a # \n + li t0, '\n' sw t0, 8(sp) addi a0, sp, 8 li a1, 1 @@ -601,6 +627,12 @@ _read_token: li t1, '=' beq t0, t1, .Ltoken_character_single + li t1, '+' + beq t0, t1, .Ltoken_character_single + + li t1, '-' + beq t0, t1, .Ltoken_character_single + li t1, '@' beq t0, t1, .Ltoken_character_single # Expect an identifier or a number. @@ -693,11 +725,6 @@ _skip_comment: 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) @@ -924,12 +951,8 @@ _compile_variable: add s1, s1, a0 # Skip the type. # .type identifier, @object - li t0, 0x2065 # e_ - sw t0, 12(sp) - li t0, 0x7079742e # .typ - sw t0, 8(sp) - addi a0, sp, 8 - li a1, 6 + la a0, asm_type + li a1, ASM_TYPE_SIZE call _write_out lw a0, 28(sp) @@ -959,7 +982,7 @@ _compile_variable: lw a1, 24(sp) call _write_out - li t0, 0x202c # , + li t0, 0x202c # ,_ sw t0, 12(sp) addi a0, sp, 12 li a1, 2 @@ -969,11 +992,8 @@ _compile_variable: lw a1, 16(sp) call _write_out - li t0, 0x0a # \n - sw t0, 12(sp) - addi a0, sp, 12 - li a1, 1 - call _write_out + li a0, '\n' + call _put_char # identifier: .zero size lw a0, 28(sp) @@ -992,11 +1012,8 @@ _compile_variable: lw a1, 16(sp) call _write_out - li t0, 0x0a # \n - sw t0, 12(sp) - addi a0, sp, 12 - li a1, 1 - call _write_out + li a0, '\n' + call _put_char # Epilogue. lw ra, 36(sp) @@ -1019,12 +1036,8 @@ _compile_procedure: add s1, s1, a0 # .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 + la a0, asm_type + li a1, ASM_TYPE_SIZE call _write_out lw a0, 20(sp) @@ -1235,11 +1248,8 @@ _compile_goto: addi s1, s1, 1 # Skip the new line. - li t0, 0x0a # \n - sw t0, 8(sp) - addi a0, sp, 8 - li a1, 1 - call _write_out + li a0, '\n' + call _put_char # Epilogue. lw ra, 12(sp) @@ -1280,7 +1290,7 @@ _compile_label: call _write_out .Lcompile_label_colon: - li t0, 0x0a # \n + li t0, '\n' sw t0, 4(sp) addi a0, sp, 4 li a1, 1 @@ -1296,6 +1306,25 @@ _compile_label: addi sp, sp, 16 ret +.type _compile_return, @function +_compile_return: + # Prologue. + addi sp, sp, -16 + sw ra, 12(sp) + sw s0, 8(sp) + addi s0, sp, 16 + + addi s1, s1, 6 # Skip return. + call _skip_spaces + + call _build_binary_expression + + # Epilogue. + lw ra, 12(sp) + lw s0, 8(sp) + addi sp, sp, 16 + ret + # Parameters: # a0 - Line length. # a1 - Whether the section header was already emitted. If not it should be @@ -1403,6 +1432,16 @@ _compile_line: call _memcmp beqz a0, .Lcompile_line_goto + li t0, 0x6e72 # rn + sw t0, 12(sp) + li t0, 0x75746572 # retu + sw t0, 8(sp) + mv a0, s1 + addi a1, sp, 8 + li a2, 6 + call _memcmp + beqz a0, .Lcompile_line_return + lbu t0, (s1) li t1, '.' beq t0, t1, .Lcompile_line_label @@ -1416,6 +1455,14 @@ _compile_line: call _compile_label j .Lcompile_line_section +.Lcompile_line_return: + /* DEBUG + mv a0, s1 + li a1, 6 + call _write_error */ + call _compile_return + j .Lcompile_line_section + .Lcompile_line_goto: call _compile_goto j .Lcompile_line_section diff --git a/boot/stage2.elna b/boot/stage2.elna index 50bed53..3ee1f32 100644 --- a/boot/stage2.elna +++ b/boot/stage2.elna @@ -20,10 +20,10 @@ program import dummy const - SOURCE_BUFFER_SIZE := 40960 + SOURCE_BUFFER_SIZE := 81920 var - source_code: [40960]Byte + source_code: [81920]Byte (* Ignores the import. *) proc _compile_import() @@ -36,9 +36,13 @@ begin end proc _build_binary_expression() +var loca0, loca4, loca8: Word begin _build_expression(0) + loca4 := 0x2c306120 (* _a0, *) + loca8 := 0x0a316120 (* _a1\n *) + _skip_spaces() call _read_token sw a0, 20(sp) @@ -67,57 +71,81 @@ begin call _token_compare beqz a0, .L_build_binary_expression_equal + li t0, 0x2b # + + sw t0, 16(sp) + mv a0, s1 + lw a1, 20(sp) + addi a2, sp, 16 + call _token_compare + beqz a0, .L_build_binary_expression_plus + + li t0, 0x2d # - + sw t0, 16(sp) + mv a0, s1 + lw a1, 20(sp) + addi a2, sp, 16 + call _token_compare + beqz a0, .L_build_binary_expression_minus + goto .Lbuild_binary_expression_end .L_build_binary_expression_equal _advance(1) (* Skip =. *) _build_expression(1) - 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) + _write_out(@loca0, 3) + _write_out(@loca4, 4) + _write_out(@loca4, 4) + _write_out(@loca8, 4) loca0 := 0x7a716573 (* seqz *) _write_out(@loca0, 4) - loca0 := 0x2c306120 (* _a0, *) - _write_out(@loca0, 4) - loca0 := 0x0a306120 (* _a0\n *) - _write_out(@loca0, 4) + _write_out(@loca4, 4) + _write_out(@loca4, 4) goto .Lbuild_binary_expression_end .L_build_binary_expression_and _advance(1) (* Skip &. *) _build_expression(1) - 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 *) + loca0 := 0x646e61 (* and *) _write_out(@loca0, 3) + _write_out(@loca4, 4) + _write_out(@loca4, 4) + _write_out(@loca8, 4) goto .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 *) + loca0 := 0x726f (* or *) _write_out(@loca0, 2) + _write_out(@loca4, 4) + _write_out(@loca4, 4) + _write_out(@loca8, 4) 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) + + 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) + .Lbuild_binary_expression_end end @@ -173,25 +201,20 @@ begin 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) - sb t1, 10(sp) - li t0, 0x69646461 # addi - sw t0, 4(sp) - addi a0, sp, 4 - li a1, 13 - call _write_out + 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() - call _read_token - sw s1, 24(sp) - sw a0, 20(sp) + loca24 := _current() + loca20 := _read_token() lw a0, 24(sp) lw a1, 20(sp) @@ -199,11 +222,7 @@ begin addi a1, a1, -4 # Skip the "loca" variable prefix. call _write_out - li t0, 0x0a # \n - sw t0, 16(sp) - addi a0, sp, 16 - li a1, 1 - call _write_out + _put_char(0xa) goto .Lbuild_expression_advance @@ -270,22 +289,22 @@ 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() +var + loca0, loca16, loca8: Word + loca20, loca12: ^Byte begin - call _read_token - (* Save the pointer to the identifier and its length on the stack. *) - sw s1, 20(sp) - sw a0, 16(sp) + loca20 := _current() + loca16 := _read_token() - add s1, s1, a0 + _advance(loca16) _skip_spaces() - call _read_token (* Save the pointer and the length of the token following the identifier. *) - sw s1, 12(sp) - sw a0, 8(sp) + loca12 := _current() + loca8 := _read_token() - add s1, s1, a0 # Skip that token. + _advance(loca8) # Skip that token. _skip_spaces() li t0, 0x3d3a # := @@ -304,22 +323,17 @@ begin goto .Lcompile_identifier_end .Lcompile_identifier_call - lw a0, 20(sp) - lw a1, 16(sp) - call _compile_call + _compile_call(loca20, loca16) goto .Lcompile_identifier_end .Lcompile_identifier_assign _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 + loca0 := 0x61207773 (* sw a *) + _write_out(@loca0, 4) + loca0 := 0x202c30 (* 0,_ *) + _write_out(@loca0, 3) lw a0, 20(sp) lw a1, 16(sp) @@ -327,13 +341,9 @@ begin addi a1, a1, -4 # Skip the "loca" variable prefix. call _write_out - li t0, 0x0a # \n - sw t0, 12(sp) - li t0, 0x29707328 # (sp) - sw t0, 8(sp) - addi a0, sp, 8 - li a1, 5 - call _write_out + loca0 := 0x29707328 (* (sp) *) + _write_out(@loca0, 4) + _put_char(0x0a) (* \n *) goto .Lcompile_identifier_end @@ -347,15 +357,14 @@ a1 - Length of the procedure name. Returns the procedure result in a0. *) -proc _compile_call() +proc _compile_call(loca84: ^Byte, loca80: Word) +var + loca0, loca12: Word begin - sw a0, 20(sp) - sw a1, 16(sp) - sw zero, 12(sp) # Argument count for a procedure call. + loca12 := 0 (* Argument count for a procedure call. *) .Lcompile_call_paren _skip_spaces() - call _read_token lbu t0, (s1) li t1, 0x29 # ) beq t0, t1, .Lcompile_call_complete @@ -363,13 +372,10 @@ begin .Lcompile_call_argument _build_expression(0) - li t0, 0x202c30 # 0,_ - sw t0, 8(sp) - li t0, 0x61207773 # sw a - sw t0, 4(sp) - addi a0, sp, 4 - li a1, 7 - call _write_out + loca0 := 0x61207773 (* sw a *) + _write_out(@loca0, 4) + loca0 := 0x202c30 (* 0,_ *) + _write_out(@loca0, 3) lw t0, 12(sp) # Argument count for a procedure call. @@ -407,7 +413,6 @@ begin call _write_out _skip_spaces() - call _read_token lbu t0, (s1) li t1, ',' bne t0, t1, .Lcompile_call_paren @@ -420,7 +425,7 @@ begin goto .Lcompile_call_argument .Lcompile_call_complete - sw zero, 12(sp) + loca12 := 0 .Lcompile_call_restore (* @@ -463,30 +468,16 @@ begin li a1, 10 call _write_out - lw t0, 12(sp) # Increment. - addi t0, t0, 1 - sw t0, 12(sp) - + loca12 := loca12 + 1 goto .Lcompile_call_restore .Lcompile_call_perform - li t0, 0x20 - sw t0, 8(sp) - li t0, 0x6c6c6163 - sw t0, 4(sp) - addi a0, sp, 4 - li a1, 5 - call _write_out + loca0 := 0x6c6c6163 + _write_out(@loca0, 4) + _put_char(0x20) (* _ *) - lw a0, 20(sp) - lw a1, 16(sp) - call _write_out - - li t0, 0x0a # \n - sw t0, 8(sp) - addi a0, sp, 8 - li a1, 1 - call _write_out + _write_out(loca84, loca80) + _put_char(0x0a) (* \n *) _skip_spaces() _advance(1) (* Skip the close paren. *) @@ -497,9 +488,10 @@ 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() +var loca4: Word begin lbu t0, (s1) # t0 = Current character. - sw zero, 4(sp) + loca4 := 0 li t1, '.' beq t0, t1, .Ltoken_character_single @@ -534,6 +526,12 @@ begin li t1, '=' beq t0, t1, .Ltoken_character_single + li t1, '+' + beq t0, t1, .Ltoken_character_single + + li t1, '-' + beq t0, t1, .Ltoken_character_single + li t1, '@' beq t0, t1, .Ltoken_character_single (* Expect an identifier or a number. *) @@ -545,22 +543,16 @@ begin call _is_alnum beqz a0, .Ltoken_character_end - lw t6, 4(sp) - addi t6, t6, 1 - sw t6, 4(sp) + loca4 := loca4 + 1 goto .Ltoken_character_loop_do .Ltoken_character_single - lw t6, 4(sp) - addi t6, t6, 1 - sw t6, 4(sp) + loca4 := loca4 + 1 goto .Ltoken_character_end .Ltoken_character_colon lbu t0, 1(s1) # t0 = The character after the colon. - lw t6, 4(sp) - addi t6, t6, 1 - sw t6, 4(sp) + loca4 := loca4 + 1 li t1, '=' beq t0, t1, .Ltoken_character_single @@ -617,11 +609,6 @@ Parameters: *) proc _skip_comment(loca84: Word) begin - (* DEBUG - mv a0, s1 - li a1, 8 - call _write_error *) - (* Check whether this is a comment. *) li t0, 0x2a28 # (* sw t0, 4(sp) @@ -774,13 +761,15 @@ begin end proc _compile_variable() +var + loca28, loca16: ^Byte + loca0, loca24, loca20: Word begin - call _read_token - (* Save the identifier on the stack since it should emitted multiple times. *) - sw s1, 28(sp) - sw a0, 24(sp) - add s1, s1, a0 + loca24 := _read_token() + loca28 := _current() + + _advance(loca24) _skip_spaces() _advance(1) (* Skip the colon in front of the type. *) @@ -788,99 +777,63 @@ begin _skip_spaces() _advance(1) (* Skip the opening bracket. *) - call _read_token - (* 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 + loca16 := _read_token() + loca20 := _current() + _advance(loca16) _skip_spaces() _advance(1) (* Skip the closing bracket. *) _skip_spaces() - call _read_token - add s1, s1, a0 # Skip the type. + loca0 := _read_token() + _advance(loca0) (* Skip the type. *) (* .type identifier, @object *) - 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 + loca0 := 0x7079742e (* .typ *) + _write_out(@loca0, 4) + loca0 := 0x2065 (* e_ *) + _write_out(@loca0, 2) - lw a0, 28(sp) - lw a1, 24(sp) - call _write_out + _write_out(loca28, loca24) - li t0, 0x0a74 # t\n - sw t0, 12(sp) - li t0, 0x63656a62 # bjec - sw t0, 8(sp) - li t0, 0x6f40202c # , @o - sw t0, 4(sp) - addi a0, sp, 4 - li a1, 10 - call _write_out + 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 *) - li t0, 0x2065 # e_ - sw t0, 12(sp) - li t0, 0x7a69732e # .siz - sw t0, 8(sp) - addi a0, sp, 8 - li a1, 6 - call _write_out + loca0 := 0x7a69732e (* .siz *) + _write_out(@loca0, 4) + loca0 := 0x2065 (* e_ *) + _write_out(@loca0, 2) - lw a0, 28(sp) - lw a1, 24(sp) - call _write_out + _write_out(loca28, loca24) - li t0, 0x202c # , - sw t0, 12(sp) - addi a0, sp, 12 - li a1, 2 - call _write_out + loca0 := 0x202c (* ,_ *) + _write_out(@loca0, 2) - lw a0, 20(sp) - lw a1, 16(sp) - call _write_out - - li t0, 0x0a # \n - sw t0, 12(sp) - addi a0, sp, 12 - li a1, 1 - call _write_out + _write_out(loca20, loca16) + _put_char(0x0a) (* \n *) (* identifier: .zero size *) - lw a0, 28(sp) - lw a1, 24(sp) - call _write_out + _write_out(loca28, loca24) - li t0, 0x206f7265 # ero_ - sw t0, 12(sp) - li t0, 0x7a2e203a # : .z - sw t0, 8(sp) - addi a0, sp, 8 - li a1, 8 - call _write_out + loca0 := 0x7a2e203a (* : .z *) + _write_out(@loca0, 4) + loca0 := 0x206f7265 (* ero_ *) + _write_out(@loca0, 4) - lw a0, 20(sp) - lw a1, 16(sp) - call _write_out + _write_out(loca20, loca16) - li t0, 0x0a # \n - sw t0, 12(sp) - addi a0, sp, 12 - li a1, 1 - call _write_out + _put_char(0x0a) (* \n *) end proc _compile_procedure() var - loca0, loca8, loca12, loca16: Word + loca0, loca4, loca8, loca12, loca16: Word loca20: ^Char begin _advance(5) (* Skip proc_ *) @@ -971,57 +924,49 @@ begin _write_out(@loca0, 4) (* Save passed arguments on the stack. *) - li t0, 0x0a29 # )\n - sw t0, 12(sp) - li t0, 0x70732834 # 4(sp - sw t0, 8(sp) - li t0, 0x38202c30 # 0, 8 - sw t0, 4(sp) - li t0, 0x61207773 # sw a - sw t0, 0(sp) - addi a0, sp, 0 - li a1, 14 - call _write_out + 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) - li t0, '0' - sb t0, 8(sp) - li t0, 0x38202c31 # 1, 8 - sw t0, 4(sp) - addi a0, sp, 0 - li a1, 14 - call _write_out + _write_out(@loca0, 4) + loca4 := 0x38202c31 (* 1, 8 *) + _write_out(@loca4, 4) + loca8 := 0x70732830 (* 0(sp *) + _write_out(@loca8, 4) + _write_out(@loca12, 2) - li t0, '6' - sb t0, 8(sp) - li t0, 0x37202c32 # 2, 7 - sw t0, 4(sp) - addi a0, sp, 0 - li a1, 14 - call _write_out + _write_out(@loca0, 4) + loca4 := 0x37202c32 (* 2, 7 *) + _write_out(@loca4, 4) + loca8 := 0x70732836 (* 6(sp *) + _write_out(@loca8, 4) + _write_out(@loca12, 2) - li t0, '2' - sb t0, 8(sp) - li t0, 0x37202c33 # 3, 7 - sw t0, 4(sp) - addi a0, sp, 0 - li a1, 14 - call _write_out + _write_out(@loca0, 4) + loca4 := 0x37202c33 (* 3, 7 *) + _write_out(@loca4, 4) + loca8 := 0x70732832 (* 2(sp *) + _write_out(@loca8, 4) + _write_out(@loca12, 2) - li t0, '8' - sb t0, 8(sp) - li t0, 0x36202c34 # 4, 6 - sw t0, 4(sp) - addi a0, sp, 0 - li a1, 14 - call _write_out + _write_out(@loca0, 4) + loca4 := 0x36202c34 (* 4, 6 *) + _write_out(@loca4, 4) + loca8 := 0x70732838 (* 8(sp *) + _write_out(@loca8, 4) + _write_out(@loca12, 2) - li t0, '4' - sb t0, 8(sp) - li t0, 0x36202c35 # 5, 6 - sw t0, 4(sp) - addi a0, sp, 0 - li a1, 14 - call _write_out + _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 @@ -1042,7 +987,7 @@ begin goto .Lcompile_procedure_body .Lcompile_procedure_end - add s1, s1, 4 # Skip end\n. + _advance(4) (* Skip end\n. *) (* Generate the procedure epilogue with a predefined stack size. *) loca0 := 0x7220776c # lw r @@ -1124,45 +1069,38 @@ begin end proc _compile_goto() +var + loca0: Word + loca8: ^Byte begin _advance(4) (* Skip the goto keyword. *) - li t0, 0x206a # j_ - sw t0, 8(sp) - addi a0, sp, 8 - li a1, 2 - call _write_out + loca0 := 0x206a (* j_ *) + _write_out(@loca0, 2) _skip_spaces() - sw s1, 8(sp) # We should be on dot the label is beginning with. + loca8 := _current() (* We should be on dot the label is beginning with. *) _advance(1) - call _read_token - add s1, s1, a0 - addi a1, a0, 1 # Label length and the dot. - lw a0, 8(sp) # Saved dot position. - call _write_out + loca0 := _read_token() + _advance(loca0) + loca0 := loca0 + 1 (* Label length and the dot. *) + _write_out(loca8, loca0) _advance(1) (* Skip the new line. *) - - li t0, 0x0a # \n - sw t0, 8(sp) - addi a0, sp, 8 - li a1, 1 - call _write_out + _put_char(0x0a) (* \n *) end (* a0 - Line length. *) -proc _compile_label() +proc _compile_label(loca84: Word) +var + loca0: Word begin - sw a0, 0(sp) # Save the line length. - (* Write the whole line as is. *) - mv a0, s1 - lw a1, 0(sp) - call _write_out + loca0 := _current() + _write_out(loca0, loca84) - lw t0, 0(sp) # Line length. + lw t0, 84(sp) # Line length. mv t1, s1 # Line start. add t1, t1, t0 @@ -1172,22 +1110,19 @@ begin li t2, ':' beq t1, t2, .Lcompile_label_colon - li t0, 0x3a # : - sw t0, 4(sp) - addi a0, sp, 4 - li a1, 1 - call _write_out + _put_char(0x3a) (* : *) .Lcompile_label_colon - li t0, 0x0a # \n - sw t0, 4(sp) - addi a0, sp, 4 - li a1, 1 - call _write_out + _put_char(0x0a) (* \n *) - lw a0, 0(sp) - addi a0, a0, 1 # Skip the new line as well. - add s1, s1, a0 # Skip the line. + _advance(loca84) +end + +proc _compile_return() +begin + _advance(6) (* Skip return. *) + _skip_spaces() + _build_binary_expression() end (* @@ -1199,12 +1134,8 @@ Parameters: 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() +proc _compile_line(loca84: Word, loca80: Bool) begin - (* Preserve passed arguments. *) - sw a0, 20(sp) - sw a1, 16(sp) - beqz a0, .Lcompile_line_empty # Skip an empty line. lbu t0, (s1) @@ -1293,6 +1224,16 @@ begin call _memcmp beqz a0, .Lcompile_line_goto + li t0, 0x6e72 # rn + sw t0, 12(sp) + li t0, 0x75746572 # retu + sw t0, 8(sp) + mv a0, s1 + addi a1, sp, 8 + li a2, 6 + call _memcmp + beqz a0, .Lcompile_line_return + lbu t0, (s1) li t1, '.' beq t0, t1, .Lcompile_line_label @@ -1302,8 +1243,15 @@ begin goto .Lcompile_line_unchanged (* Else. *) .Lcompile_line_label - lw a0, 20(sp) - call _compile_label + _compile_label(loca84) + goto .Lcompile_line_section + + .Lcompile_line_return + (* DEBUG + mv a0, s1 + li a1, 8 + call _write_error *) + _compile_return() goto .Lcompile_line_section .Lcompile_line_goto @@ -1323,7 +1271,7 @@ begin goto .Lcompile_line_section .Lcompile_line_begin - lw a1, 16(sp) + lw a1, 80(sp) bnez a1, .Lcompile_line_compile_entry _compile_text_section() .Lcompile_line_compile_entry @@ -1336,7 +1284,7 @@ begin goto .Lcompile_line_section .Lcompile_line_procedure - lw a1, 16(sp) + lw a1, 80(sp) bnez a1, .Lcompile_line_compile_procedure _compile_text_section() .Lcompile_line_compile_procedure @@ -1353,8 +1301,7 @@ begin goto .Lcompile_line_section .Lcompile_line_comment - lw a0, 20(sp) - call _skip_comment + _skip_comment(loca84) goto .Lcompile_line_section .Lcompile_line_empty @@ -1362,8 +1309,7 @@ begin goto .Lcompile_line_section .Lcompile_line_unchanged - lw a0, 20(sp) - call _compile_assembly + _compile_assembly(loca84) goto .Lcompile_line_section .Lcompile_line_section @@ -1445,31 +1391,35 @@ end (* 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. + loca0 := _current() (* Local position in the source text. *) .Lread_line_do + lw t0, 0(sp) lbu t1, (t0) # t1 = Current character. beqz t1, .Lread_line_end # Exit the loop on the NUL character. li t2, '\n' beq t1, t2, .Lread_line_end # Exit the loop on the new line. - addi t0, t0, 1 + loca0 := loca0 + 1 goto .Lread_line_do .Lread_line_end - sub a0, t0, s1 # Return the line length. + loca4 := _current() + return loca0 - loca4 (* Return the line length. *) end proc _compile() +var loca0, loca4: Word begin - sw zero, 4(sp) # Whether the text section header was already emitted. + loca4 := 0 (* Whether the text section header was already emitted. *) .Lcompile_do lbu t0, (s1) # t0 = Current character. beqz t0, .Lcompile_end # Exit the loop on the NUL character. _skip_indentation() - call _read_line + loca0 := _read_line() + lw a0, 0(sp) lw a1, 4(sp) call _compile_line