diff options
| author | Eugen Wissner <belka@caraus.de> | 2025-04-29 00:55:20 +0200 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2025-04-29 00:55:20 +0200 |
| commit | 9c66cec171bafaf12713efb78ac6099ef1f23020 (patch) | |
| tree | f54e2c7713d92b2a52372dfbedfe63e6637d8ec1 /boot/stage2.elna | |
| parent | 963d32e8d1ab322d77768b5464e7360fd6feb3cd (diff) | |
| download | elna-9c66cec171bafaf12713efb78ac6099ef1f23020.tar.gz | |
Implement if statements
Diffstat (limited to 'boot/stage2.elna')
| -rw-r--r-- | boot/stage2.elna | 350 |
1 files changed, 214 insertions, 136 deletions
diff --git a/boot/stage2.elna b/boot/stage2.elna index 3ee1f32..0eb713c 100644 --- a/boot/stage2.elna +++ b/boot/stage2.elna @@ -14,6 +14,9 @@ type checking. hexadecimal format). - Comments are accepted only at the end of a line. + +- Return can be used only as the last statement of a procedure. It +doesn't actually return, but sets a0 to the appropriate value. *) program @@ -36,7 +39,7 @@ begin end proc _build_binary_expression() -var loca0, loca4, loca8: Word +var loca0, loca4, loca8, loca20: Word begin _build_expression(0) @@ -44,8 +47,7 @@ begin loca8 := 0x0a316120 (* _a1\n *) _skip_spaces() - call _read_token - sw a0, 20(sp) + loca20 := _read_token() li t0, 0x26 # & sw t0, 16(sp) @@ -87,6 +89,14 @@ begin call _token_compare beqz a0, .L_build_binary_expression_minus + li t0, 0x2a # * + sw t0, 16(sp) + mv a0, s1 + lw a1, 20(sp) + addi a2, sp, 16 + call _token_compare + beqz a0, .L_build_binary_expression_product + goto .Lbuild_binary_expression_end .L_build_binary_expression_equal @@ -146,6 +156,19 @@ begin _write_out(@loca4, 4) _write_out(@loca8, 4) + 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) + + goto .Lbuild_binary_expression_end + .Lbuild_binary_expression_end end @@ -156,28 +179,30 @@ a0 - X in aX, the register number to save the result. *) proc _build_expression() var - loca20, loca28, loca8: Word - loca24: ^Byte + loca0, loca20, loca28, loca8: Word + loca24, loca4: ^Byte begin - addi a0, a0, '0' # Make the register number to a character. - sw a0, 28(sp) # And save it. + (* Make the register number to a character and save it. *) + loca28 := loca84 + 0x30 (* 0 *) _skip_spaces() loca20 := _read_token() loca24 := _current() - addi a0, s1, 0 - lbu a0, (a0) + lbu a0, (s1) + li t0, '-' + beq a0, t0, .Lbuild_expression_negate + + lbu a0, (s1) li t0, '@' beq a0, t0, .Lbuild_expression_address - addi a0, s1, 0 - lbu a0, (a0) - call _is_digit - bnez a0, .Lbuild_expression_literal + loca0 := _front() + if _is_digit(loca0) then + goto .Lbuild_expression_literal + end - addi a0, s1, 0 - lbu a0, (a0) + lbu a0, (s1) li t0, '_' beq a0, t0, .Lbuild_expression_call @@ -200,6 +225,19 @@ begin goto .Lbuild_expression_advance + .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) + + goto .Lbuild_expression_advance + .Lbuild_expression_address loca8 := 0x69646461 (* addi *) _write_out(@loca8, 4) @@ -216,40 +254,28 @@ begin loca24 := _current() loca20 := _read_token() - 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 + (* Skip the "loca" variable prefix. *) + loca4 := loca24 + 4 + loca0 := loca20 - 4 + _write_out(loca4, loca0) _put_char(0xa) goto .Lbuild_expression_advance .Lbuild_expression_identifier - lw t1, 28(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 + loca8 := 0x6120776c (* lw a *) + _write_out(@loca8, 4) + loca8 := 0x00202c00 or loca28 # \0,_ + _write_out(@loca8, 3) - 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 + loca4 := loca24 + 4 + loca0 := loca20 - 4 + _write_out(loca4, loca0) (* Skip the "loca" variable prefix. *) - li t0, 0x0a # \n - sw t0, 8(sp) - li t0, 0x29707328 # (sp) - sw t0, 4(sp) - addi a0, sp, 4 - li a1, 5 - call _write_out + loca8 := 0x29707328 (* (sp) *) + _write_out(@loca8, 4) + _put_char(0x0a) (* \n *) goto .Lbuild_expression_advance @@ -261,18 +287,13 @@ begin goto .Lbuild_expression_end .Lbuild_expression_literal - lw t1, 28(sp) - li t0, 0x00202c00 # \0,_ - or t0, t0, t1 - sw t0, 8(sp) - li t0, 0x6120696c # li a - sw t0, 4(sp) - addi a0, sp, 4 - li a1, 7 - call _write_out + 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 + _put_char(0x0a) (* \n *) goto .Lbuild_expression_advance @@ -335,11 +356,9 @@ begin loca0 := 0x202c30 (* 0,_ *) _write_out(@loca0, 3) - 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 + loca20 := loca20 + 4 + loca16 := loca16 - 4 + _write_out(loca20, loca16) loca0 := 0x29707328 (* (sp) *) _write_out(@loca0, 4) @@ -359,7 +378,7 @@ Returns the procedure result in a0. *) proc _compile_call(loca84: ^Byte, loca80: Word) var - loca0, loca12: Word + loca0, loca4, loca12: Word begin loca12 := 0 (* Argument count for a procedure call. *) @@ -377,49 +396,24 @@ begin loca0 := 0x202c30 (* 0,_ *) _write_out(@loca0, 3) - 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. *) - li t1, -4 - mul t1, t0, t1 - addi t1, t1, 60 - li t2, 10 - div t3, t1, t2 - rem t4, t1, t2 - addi t3, t3, '0' - addi t4, t4, '0' - - sw t3, 8(sp) - sw t4, 4(sp) - - addi a0, sp, 8 - li a1, 1 - call _write_out - - addi a0, sp, 4 - li a1, 1 - call _write_out + loca0 := -4 * loca12 + loca0 := loca0 + 60 + _printi(loca0) - li t0, 0x0a # \n - sw t0, 8(sp) - li t0, 0x29707328 # (sp) - sw t0, 4(sp) - addi a0, sp, 4 - li a1, 5 - call _write_out + loca0 := 0x29707328 (* (sp) *) + _write_out(@loca0, 4) + _put_char(0x0a) (* \n *) _skip_spaces() lbu t0, (s1) li t1, ',' bne t0, t1, .Lcompile_call_paren - lw t0, 12(sp) # Argument count for a procedure call. - addi t0, t0, 1 - sw t0, 12(sp) + loca12 := loca12 + 1 (* Argument count for a procedure call. *) _advance(1) (* Skip the comma between the arguments. *) goto .Lcompile_call_argument @@ -432,47 +426,62 @@ begin 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 + 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) - li t0, 0x6120776c # lw a - sw t0, 4(sp) - addi a0, sp, 4 - li a1, 4 - call _write_out - - lw t0, 12(sp) # Argument count for a procedure call. - - li t1, -4 - mul t1, t0, t1 - addi t1, t1, 60 - li t2, 10 - div t3, t1, t2 - rem t4, t1, t2 - addi t3, t3, '0' - addi t4, t4, '0' - addi t0, t0, '0' - - li t5, 0x0a # \n - sb t5, 11(sp) - li t5, 0x29707328 # (sp) - sw t5, 7(sp) - sb t4, 6(sp) - sb t3, 5(sp) - li t5, 0x202c # ,_ - sh t5, 3(sp) - sb t0, 2(sp) - - addi a0, sp, 2 - li a1, 10 - call _write_out - - loca12 := loca12 + 1 - goto .Lcompile_call_restore - - .Lcompile_call_perform - loca0 := 0x6c6c6163 + (* 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) + + (* 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) + + (* 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) + + (* 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) + + (* 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) + + loca0 := 0x6c6c6163 (* call *) _write_out(@loca0, 4) _put_char(0x20) (* _ *) @@ -532,6 +541,9 @@ 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 (* Expect an identifier or a number. *) @@ -1125,6 +1137,61 @@ begin _build_binary_expression() end +proc _compile_if() +var + loca8, loca12, loca16, loca20: Word + loca4: ^Byte +begin + _advance(2) (* Skip the if. *) + _skip_spaces() + + _build_binary_expression() + + _skip_spaces() + _advance(4) (* Skip the then. *) + + 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) (* _ *) + + (* Write the label *) + _write_out(@loca16, 4) + mv a0, s2 + call _printi + + _put_char(0x0a) (* \n *) + + .Lcompile_if_loop + _skip_spaces() + loca12 := _read_token() + + loca4 := _current() + loca8 := _token_compare(loca4, loca12, @loca20) + + if loca8 then + loca12 := _read_line() + _compile_line(loca12, 1) + + goto .Lcompile_if_loop + end + + (* Write the label *) + _write_out(@loca16, 4) + mv a0, s2 + call _printi + + loca12 := 0x0a3a0a3a (* :\n:\n *) + _write_out(@loca12, 2) + + addi s2, s2, 1 # Increment the label counter. + _advance(4) (* Skip the end with newline. *) +end + (* Parameters: a0 - Line length. @@ -1234,6 +1301,14 @@ begin call _memcmp beqz a0, .Lcompile_line_return + li t0, 0x6669 # if + sw t0, 12(sp) + mv a0, s1 + addi a1, sp, 12 + li a2, 2 + call _memcmp + beqz a0, .Lcompile_line_if + lbu t0, (s1) li t1, '.' beq t0, t1, .Lcompile_line_label @@ -1242,6 +1317,10 @@ begin goto .Lcompile_line_unchanged (* Else. *) + .Lcompile_line_if: + _compile_if() + goto .Lcompile_line_section + .Lcompile_line_label _compile_label(loca84) goto .Lcompile_line_section @@ -1409,7 +1488,9 @@ begin end proc _compile() -var loca0, loca4: Word +var + loca0, loca4: Word + loca8: Bool begin loca4 := 0 (* Whether the text section header was already emitted. *) @@ -1419,15 +1500,11 @@ begin _skip_indentation() loca0 := _read_line() - lw a0, 0(sp) - lw a1, 4(sp) - call _compile_line + loca8 := _compile_line(loca0, loca4) 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) + loca4 := loca4 or loca8 goto .Lcompile_do .Lcompile_end @@ -1460,5 +1537,6 @@ begin call _read_file la s1, source_code # s1 = Source code position. + li s2, 1 _compile() end. |
