diff options
Diffstat (limited to 'boot/stage2.elna')
| -rw-r--r-- | boot/stage2.elna | 643 |
1 files changed, 487 insertions, 156 deletions
diff --git a/boot/stage2.elna b/boot/stage2.elna index e37b3e6..4e87e89 100644 --- a/boot/stage2.elna +++ b/boot/stage2.elna @@ -1,73 +1,221 @@ program # s1 - Contains the current position in the source text. +import dummy + const - SOURCE_BUFFER_SIZE := 20480 + SOURCE_BUFFER_SIZE := 40960 var - source_code: [20480]Byte + source_code: [40960]Byte + +# Ignores the import. +proc _compile_import() +var loca0: Word +begin + _advance(6) + _skip_spaces() + loca0 := _read_token() + _advance(loca0) # Skip the imported module name. +end + +proc _build_binary_expression() +begin + _build_expression(0) + + _skip_spaces() + call _read_token + sw a0, 20(sp) + + li t0, 0x26 # & + sw t0, 16(sp) + mv a0, s1 + lw a1, 20(sp) + addi a2, sp, 16 + call _token_compare + beqz a0, .L_build_binary_expression_and + + li t0, 0x3d # = + sw t0, 16(sp) + mv a0, s1 + lw a1, 20(sp) + addi a2, sp, 16 + call _token_compare + beqz a0, .L_build_binary_expression_equal -.section .text + /* DEBUG + mv a0, s1 + li a1, 8 + call _write_error */ + + j .Lbuild_binary_expression_end + +.L_build_binary_expression_equal: + addi s1, s1, 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 + + 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 + + j .Lbuild_binary_expression_end + +.L_build_binary_expression_and: + addi s1, s1, 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 + + j .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. proc _build_expression() begin + addi a0, a0, '0' # Make the register number to a character. + sw a0, 20(sp) # And save it. + _skip_spaces() call _read_token - sw s1, 20(sp) - sw a0, 16(sp) + sw s1, 16(sp) + sw a0, 12(sp) # Integer literal. addi a0, s1, 0 - lb a0, (a0) + lbu a0, (a0) call _is_digit - bnez a0, .Lbuild_expression_number_literal + bnez a0, .Lbuild_expression_literal + + addi a0, s1, 0 + lbu a0, (a0) + li t0, 0x5f # _ + beq a0, t0, .Lbuild_expression_call + + li t0, 0x61636f6c # loca + sw t0, 8(sp) + mv a0, s1 + addi a1, sp, 8 + li a2, 4 + call _memcmp + beqz a0, .Lbuild_expression_identifier # Named identifier. - li t0, 0x202c30 # 0,_ - sw t0, 12(sp) + lw t1, 20(sp) + li t0, 0x00202c00 # \0,_ + or t0, t0, t1 + sw t0, 8(sp) li t0, 0x6120616c # la a + sw t0, 4(sp) + addi a0, sp, 4 + 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 + + goto .Lbuild_expression_advance + + .Lbuild_expression_identifier + lw t1, 20(sp) + li t0, 0x00202c00 # \0,_ + or t0, t0, t1 + sw t0, 8(sp) + li t0, 0x6120776c # lw a + sw t0, 4(sp) + addi a0, sp, 4 li a1, 7 call _write_out - lw a0, 20(sp) - lw a1, 16(sp) + lw a0, 16(sp) + lw a1, 12(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, 12(sp) - addi a0, sp, 12 - li a1, 1 + sw t0, 8(sp) + li t0, 0x29707328 # (sp) + sw t0, 4(sp) + addi a0, sp, 4 + li a1, 5 call _write_out - j .Lbuild_expression_end + goto .Lbuild_expression_advance -.Lbuild_expression_number_literal: - li t0, 0x202c30 # 0,_ - sw t0, 12(sp) - li t0, 0x6120696c # li a + .Lbuild_expression_call + lw a0, 16(sp) + lw a1, 12(sp) + add s1, s1, a1 + addi s1, s1, 1 + call _compile_call + + goto .Lbuild_expression_end + + .Lbuild_expression_literal + lw t1, 20(sp) + li t0, 0x00202c00 # \0,_ + or t0, t0, t1 sw t0, 8(sp) - addi a0, sp, 8 + li t0, 0x6120696c # li a + sw t0, 4(sp) + addi a0, sp, 4 li a1, 7 call _write_out - lw a0, 20(sp) - lw a1, 16(sp) + lw a0, 16(sp) + lw a1, 12(sp) call _write_out li t0, 0x0a # \n - sw t0, 12(sp) - addi a0, sp, 12 + sw t0, 8(sp) + addi a0, sp, 8 li a1, 1 call _write_out - j .Lbuild_expression_end + goto .Lbuild_expression_advance -.Lbuild_expression_end: - lw a0, 16(sp) + .Lbuild_expression_advance + lw a0, 12(sp) add s1, s1, a0 + + .Lbuild_expression_end end # Compiles a statement beginning with an identifier. @@ -101,27 +249,22 @@ begin call _token_compare beqz a0, .Lcompile_identifier_assign - /* DEBUG - mv a0, s1 - li a1, 4 - call _write_error */ - lw t0, 12(sp) lbu t0, (t0) li t1, 0x28 # ( beq t0, t1, .Lcompile_identifier_call - j .Lcompile_identifier_end + goto .Lcompile_identifier_end -.Lcompile_identifier_call: + .Lcompile_identifier_call lw a0, 20(sp) lw a1, 16(sp) call _compile_call - j .Lcompile_identifier_end + goto .Lcompile_identifier_end -.Lcompile_identifier_assign: - call _build_expression + .Lcompile_identifier_assign + _build_binary_expression() li t0, 0x202c30 # 0,_ sw t0, 12(sp) @@ -145,9 +288,9 @@ begin li a1, 5 call _write_out - j .Lcompile_identifier_end + goto .Lcompile_identifier_end -.Lcompile_identifier_end: + .Lcompile_identifier_end end # Compiles a procedure call. Expects s1 to point to the first argument. @@ -161,15 +304,15 @@ begin sw a1, 16(sp) sw zero, 12(sp) # Argument count for a procedure call. -.Lcompile_call_paren: + .Lcompile_call_paren _skip_spaces() call _read_token lbu t0, (s1) li t1, 0x29 # ) beq t0, t1, .Lcompile_call_complete -.Lcompile_call_argument: - call _build_expression + .Lcompile_call_argument + _build_expression(0) li t0, 0x202c30 # 0,_ sw t0, 8(sp) @@ -181,12 +324,12 @@ begin lw t0, 12(sp) # Argument count for a procedure call. - # Only 8 arguments are supported with a0-a7. + # 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, 84 + addi t1, t1, 60 li t2, 10 div t3, t1, t2 rem t4, t1, t2 @@ -223,16 +366,16 @@ begin sw t0, 12(sp) _advance(1) # Skip the comma between the arguments. - j .Lcompile_call_argument + goto .Lcompile_call_argument -.Lcompile_call_complete: + .Lcompile_call_complete sw zero, 12(sp) -.Lcompile_call_restore: - # Just go through all a0-a7 registers and read them from stack. + .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. lw t0, 12(sp) - li t1, 7 + li t1, 5 bgt t0, t1, .Lcompile_call_perform li t0, 0x6120776c # lw a @@ -245,7 +388,7 @@ begin li t1, -4 mul t1, t0, t1 - addi t1, t1, 84 + addi t1, t1, 60 li t2, 10 div t3, t1, t2 rem t4, t1, t2 @@ -271,9 +414,9 @@ begin addi t0, t0, 1 sw t0, 12(sp) - j .Lcompile_call_restore + goto .Lcompile_call_restore -.Lcompile_call_perform: + .Lcompile_call_perform li t0, 0x20 sw t0, 8(sp) li t0, 0x6c6c6163 @@ -327,7 +470,16 @@ begin li t1, ']' beq t0, t1, .Ltoken_character_single -.Ltoken_character_loop_do: # Expect an identifier or a number. + 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. + .Ltoken_character_loop_do lw t6, 4(sp) add t1, s1, t6 lbu a0, (t1) # a0 = Current character. @@ -338,15 +490,15 @@ begin lw t6, 4(sp) addi t6, t6, 1 sw t6, 4(sp) - j .Ltoken_character_loop_do + goto .Ltoken_character_loop_do -.Ltoken_character_single: + .Ltoken_character_single lw t6, 4(sp) addi t6, t6, 1 sw t6, 4(sp) - j .Ltoken_character_end + goto .Ltoken_character_end -.Ltoken_character_colon: + .Ltoken_character_colon lbu t0, 1(s1) # t0 = The character after the colon. lw t6, 4(sp) addi t6, t6, 1 @@ -354,16 +506,16 @@ begin li t1, '=' beq t0, t1, .Ltoken_character_single - j .Ltoken_character_end + goto .Ltoken_character_end -.Ltoken_character_end: + .Ltoken_character_end lw a0, 4(sp) end # Skips the spaces till the next non space character. proc _skip_spaces() begin -.Lspace_loop_do: + .Lspace_loop_do lbu t0, (s1) # t0 = Current character. li t1, ' ' @@ -375,53 +527,50 @@ begin li t1, '\r' beq t0, t1, .Lspace_loop_repeat - j .Lspace_loop_end -.Lspace_loop_repeat: + goto .Lspace_loop_end + .Lspace_loop_repeat _advance(1) - j .Lspace_loop_do + goto .Lspace_loop_do -.Lspace_loop_end: + .Lspace_loop_end end # Skips tabs at the line beginning. proc _skip_indentation() begin -.Lskip_indentation_do: + .Lskip_indentation_do lbu t0, (s1) li t1, '\t' beq t0, t1, .Lskip_indentation_skip - j .Lskip_indentation_end + goto .Lskip_indentation_end -.Lskip_indentation_skip: + .Lskip_indentation_skip _advance(1) - j .Lskip_indentation_do + goto .Lskip_indentation_do -.Lskip_indentation_end: + .Lskip_indentation_end end # Parameters: # a0 - Line length. -proc _skip_comment() +proc _skip_comment(loca84: Word) begin - add s1, s1, a0 + _advance(loca84) _advance(1) # Skip the new line. end # Parameters: # a0 - Line length. -proc _compile_assembly() +proc _compile_assembly(loca84: Word) +var loca0: ^Byte begin - sw a0, 4(sp) # a0 - Line length. - # Write the source to the standard output. - mv a0, s1 - lw a1, 4(sp) - call _write_out + loca0 := _current() - lw t0, 4(sp) - add s1, s1, t0 + _write_out(loca0, loca84) + _advance(loca84) li t0, '\n' sb t0, 0(sp) @@ -471,16 +620,16 @@ begin _advance(6) # const\n. -.Lcompile_constant_section_item: + .Lcompile_constant_section_item _skip_spaces() lbu a0, (s1) call _is_upper beqz a0, .Lcompile_constant_section_end - call _compile_constant - j .Lcompile_constant_section_item + _compile_constant() + goto .Lcompile_constant_section_item -.Lcompile_constant_section_end: + .Lcompile_constant_section_end end proc _compile_constant() @@ -538,16 +687,16 @@ begin _advance(4) # var\n. -.Lcompile_variable_section_item: + .Lcompile_variable_section_item _skip_spaces() lbu a0, (s1) call _is_lower beqz a0, .Lcompile_variable_section_end - call _compile_variable - j .Lcompile_variable_section_item + _compile_variable() + goto .Lcompile_variable_section_item -.Lcompile_variable_section_end: + .Lcompile_variable_section_end end proc _compile_variable() @@ -708,7 +857,7 @@ begin # Skip all declarations until we find the "begin" keyword, denoting the # beginning of the procedure body. -.Lcompile_procedure_begin: + .Lcompile_procedure_begin _skip_spaces() call _read_token @@ -758,7 +907,7 @@ begin li t0, 0x0a29 # )\n sw t0, 12(sp) - li t0, 0x70732838 # 2(sp + li t0, 0x70732838 # 8(sp sw t0, 8(sp) li t0, 0x38202c30 # 0, 8 sw t0, 4(sp) @@ -780,8 +929,61 @@ begin li a1, 16 call _write_out + # 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 + + 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 + + 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 + + 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 + + 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 + + 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 + # Generate the body of the procedure. -.Lcompile_procedure_body: + .Lcompile_procedure_body _skip_indentation() call _read_line sw a0, 12(sp) @@ -796,9 +998,9 @@ begin lw a0, 12(sp) call _compile_line - j .Lcompile_procedure_body + goto .Lcompile_procedure_body -.Lcompile_procedure_end: + .Lcompile_procedure_end add s1, s1, 4 # Skip end\n. # Generate the procedure epilogue with a predefined stack size. @@ -816,7 +1018,7 @@ begin li t0, 0x0a29 # )\n sw t0, 12(sp) - li t0, 0x70732838 # 2(sp + li t0, 0x70732838 # 8(sp sw t0, 8(sp) li t0, 0x38202c30 # 0, 8 sw t0, 4(sp) @@ -869,7 +1071,7 @@ begin addi t1, a1, 0 addi t2, a2, 0 -.Ltoken_compare_loop: + .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 @@ -886,25 +1088,97 @@ begin addi t0, t0, 1 addi t1, t1, -1 addi t2, t2, 1 - j .Ltoken_compare_loop + goto .Ltoken_compare_loop -.Ltoken_compare_not_equal: + .Ltoken_compare_not_equal li a0, 1 - j .Ltoken_compare_end + goto .Ltoken_compare_end -.Ltoken_compare_equal: + .Ltoken_compare_equal li a0, 0 -.Ltoken_compare_end: + .Ltoken_compare_end +end + +proc _compile_goto() +begin + addi s1, s1, 4 # Skip the goto keyword. + + li t0, 0x206a # j_ + sw t0, 8(sp) + addi a0, sp, 8 + li a1, 2 + call _write_out + + _skip_spaces() + sw s1, 8(sp) # 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 + + _advance(1) # Skip the new line. + + li t0, 0x0a # \n + sw t0, 8(sp) + addi a0, sp, 8 + li a1, 1 + call _write_out +end + +# a0 - Line length. +proc _compile_label() +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 + + lw t0, 0(sp) # Line length. + mv t1, s1 # Line start. + + add t1, t1, t0 + addi t1, t1, -1 # Last character on the line. + + lbu t1, (t1) + 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 + + .Lcompile_label_colon + li t0, 0x0a # \n + sw t0, 4(sp) + addi a0, sp, 4 + li a1, 1 + call _write_out + + lw a0, 0(sp) + addi a0, a0, 1 # Skip the new line as well. + 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. proc _compile_line() begin - sw a0, 20(sp) # a0 - Line length. + # Preserve passed arguments. + sw a0, 20(sp) + sw a1, 16(sp) beqz a0, .Lcompile_line_empty # Skip an empty line. @@ -913,125 +1187,167 @@ begin beq t0, t1, .Lcompile_line_comment li t0, 0x0a6d6172 # ram\n - sw t0, 16(sp) - li t0, 0x676f7270 # prog sw t0, 12(sp) + li t0, 0x676f7270 # prog + sw t0, 8(sp) mv a0, s1 - addi a1, sp, 12 + addi a1, sp, 8 li a2, 8 call _memcmp beqz a0, .Lcompile_line_program li t0, 0x0a74 # t\n - sw t0, 16(sp) - li t0, 0x736e6f63 # cons sw t0, 12(sp) + li t0, 0x736e6f63 # cons + sw t0, 8(sp) mv a0, s1 - addi a1, sp, 12 + addi a1, sp, 8 li a2, 6 call _memcmp beqz a0, .Lcompile_line_const li t0, 0x0a726176 # var\n - sw t0, 16(sp) + sw t0, 12(sp) mv a0, s1 - addi a1, sp, 16 + addi a1, sp, 12 li a2, 4 - call _memcmp; + call _memcmp beqz a0, .Lcompile_line_var li t0, 0x20 # _ - sw t0, 16(sp) - li t0, 0x636f7270 # proc sw t0, 12(sp) + li t0, 0x636f7270 # proc + sw t0, 8(sp) mv a0, s1 - addi a1, sp, 12 + addi a1, sp, 8 li a2, 5 call _memcmp beqz a0, .Lcompile_line_procedure li t0, 0x0a6e # n\n - sw t0, 16(sp) - li t0, 0x69676562 # begi sw t0, 12(sp) + li t0, 0x69676562 # begi + sw t0, 8(sp) mv a0, s1 - addi a1, sp, 12 + addi a1, sp, 8 li a2, 6 call _memcmp beqz a0, .Lcompile_line_begin li t0, 0x2e646e65 # end. - sw t0, 16(sp) + sw t0, 12(sp) mv a0, s1 - addi a1, sp, 16 + addi a1, sp, 12 li a2, 4 call _memcmp beqz a0, .Lcompile_line_exit li t0, 0x61636f6c # loca - sw t0, 16(sp) + sw t0, 12(sp) mv a0, s1 - addi a1, sp, 16 + addi a1, sp, 12 li a2, 4 call _memcmp beqz a0, .Lcompile_line_identifier + li t0, 0x7472 # rt + sw t0, 12(sp) + li t0, 0x6f706d69 # impo + sw t0, 8(sp) + mv a0, s1 + addi a1, sp, 8 + li a2, 6 + call _memcmp + beqz a0, .Lcompile_line_import + + li t0, 0x6f746f67 # goto + sw t0, 12(sp) + mv a0, s1 + addi a1, sp, 12 + li a2, 4 + call _memcmp + beqz a0, .Lcompile_line_goto + lbu t0, (s1) + li t1, '.' + beq t0, t1, .Lcompile_line_label li t1, '_' beq t0, t1, .Lcompile_line_identifier - j .Lcompile_line_unchanged # Else. + goto .Lcompile_line_unchanged # Else. + + .Lcompile_line_label + lw a0, 20(sp) + call _compile_label + goto .Lcompile_line_section + + .Lcompile_line_goto + _compile_goto() + goto .Lcompile_line_section -.Lcompile_line_identifier: - call _compile_identifier - j .Lcompile_line_section + .Lcompile_line_import + _compile_import() + goto .Lcompile_line_section -.Lcompile_line_exit: - call _compile_exit - j .Lcompile_line_section + .Lcompile_line_identifier + _compile_identifier() + goto .Lcompile_line_section -.Lcompile_line_begin: - call _compile_entry_point + .Lcompile_line_exit + _compile_exit() + goto .Lcompile_line_section + + .Lcompile_line_begin + lw a1, 16(sp) + bnez a1, .Lcompile_line_compile_entry + _compile_text_section() + .Lcompile_line_compile_entry + _compile_entry_point() li a0, 1 - j .Lcompile_line_end + goto .Lcompile_line_end -.Lcompile_line_const: - call _compile_constant_section - j .Lcompile_line_section + .Lcompile_line_const + _compile_constant_section() + goto .Lcompile_line_section -.Lcompile_line_procedure: - call _compile_procedure + .Lcompile_line_procedure + lw a1, 16(sp) + bnez a1, .Lcompile_line_compile_procedure + _compile_text_section() + .Lcompile_line_compile_procedure + _compile_procedure() li a0, 1 - j .Lcompile_line_end + goto .Lcompile_line_end -.Lcompile_line_var: - call _compile_variable_section - j .Lcompile_line_section + .Lcompile_line_var + _compile_variable_section() + goto .Lcompile_line_section -.Lcompile_line_program: - call _compile_program - j .Lcompile_line_section + .Lcompile_line_program + _compile_program() + goto .Lcompile_line_section -.Lcompile_line_comment: + .Lcompile_line_comment lw a0, 20(sp) call _skip_comment - j .Lcompile_line_section + goto .Lcompile_line_section -.Lcompile_line_empty: + .Lcompile_line_empty _advance(1) - j .Lcompile_line_section + goto .Lcompile_line_section -.Lcompile_line_unchanged: + .Lcompile_line_unchanged lw a0, 20(sp) call _compile_assembly - j .Lcompile_line_section + goto .Lcompile_line_section -.Lcompile_line_section: + .Lcompile_line_section mv a0, zero -.Lcompile_line_end: + .Lcompile_line_end end +# Prints ".section .text" and exits. proc _compile_text_section() begin # .section .text @@ -1107,31 +1423,40 @@ proc _read_line() begin mv t0, s1 # Local position in the source text. -.Lread_line_do: + .Lread_line_do 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 - j .Lread_line_do + goto .Lread_line_do -.Lread_line_end: + .Lread_line_end sub a0, t0, s1 # Return the line length. end proc _compile() begin -.Lcompile_do: + sw zero, 4(sp) # 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 + lw a1, 4(sp) call _compile_line - j .Lcompile_do -.Lcompile_end: + beqz a0, .Lcompile_do + # Update whether the text section header was already emitted. + lw t0, 4(sp) + or t0, t0, a0 + sw t0, 4(sp) + + goto .Lcompile_do + .Lcompile_end end # Returns the pointer to the current position in the source text in a0. @@ -1146,6 +1471,12 @@ begin add s1, s1, a0 end +# Returns the first character in the remaining source text. +proc _front() +begin + lbu a0, (s1) +end + # Entry point. begin # Read the source from the standard input. @@ -1155,5 +1486,5 @@ begin call _read_file la s1, source_code # s1 = Source code position. - call _compile + _compile() end. |
