Add return statements

This commit is contained in:
Eugen Wissner 2025-04-27 23:18:06 +02:00
parent a60e623af5
commit 963d32e8d1
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
2 changed files with 364 additions and 367 deletions

View File

@ -1,7 +1,7 @@
.global _start # Program entry point. .global _start # Program entry point.
# s1 - Contains the current position in the source text. # s1 - Contains the current position in the source text.
.equ SOURCE_BUFFER_SIZE, 40960 .equ SOURCE_BUFFER_SIZE, 81920
.section .rodata .section .rodata
section_rodata: .ascii ".section .rodata\n" 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 .equ PROLOGUE_SIZE, . - prologue
epilogue: .ascii "lw ra, 92(sp)\nlw s0, 88(sp)\naddi sp, sp, 96\nret\n" epilogue: .ascii "lw ra, 92(sp)\nlw s0, 88(sp)\naddi sp, sp, 96\nret\n"
.equ EPILOGUE_SIZE, . - epilogue .equ EPILOGUE_SIZE, . - epilogue
asm_exit: .ascii "li a0, 0\nli a7, 93\necall\n" asm_exit: .ascii "li a0, 0\nli a7, 93\necall\n"
.equ ASM_EXIT_SIZE, . - asm_exit .equ ASM_EXIT_SIZE, . - asm_exit
asm_start: .ascii ".type _start, @function\n_start:\n" 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 .equ ASM_AND_A0_A1_SIZE, . - asm_and_a0_a1
asm_or_a0_a1: .ascii "or a0, a0, a1\n" asm_or_a0_a1: .ascii "or a0, a0, a1\n"
.equ ASM_OR_A0_A1_SIZE, . - asm_or_a0_a1 .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 .section .bss
.type source_code, @object .type source_code, @object
@ -67,7 +76,7 @@ _build_binary_expression:
call _read_token call _read_token
sw a0, 20(sp) sw a0, 20(sp)
li t0, 0x26 # & li t0, '&'
sw t0, 16(sp) sw t0, 16(sp)
mv a0, s1 mv a0, s1
lw a1, 20(sp) lw a1, 20(sp)
@ -83,7 +92,7 @@ _build_binary_expression:
call _token_compare call _token_compare
beqz a0, .L_build_binary_expression_or beqz a0, .L_build_binary_expression_or
li t0, 0x3d # = li t0, '='
sw t0, 16(sp) sw t0, 16(sp)
mv a0, s1 mv a0, s1
lw a1, 20(sp) lw a1, 20(sp)
@ -91,32 +100,34 @@ _build_binary_expression:
call _token_compare call _token_compare
beqz a0, .L_build_binary_expression_equal 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 j .Lbuild_binary_expression_end
.L_build_binary_expression_equal: .L_build_binary_expression_equal:
addi s1, s1, 1 # Skip =. addi s1, s1, 1 # Skip =.
li a0, 1 li a0, 1
call _build_expression call _build_expression
li t0, 0x0a3161 # a1\n la a0, asm_sub_a0_a1
sw t0, 16(sp) li a1, ASM_SUB_A0_A1_SIZE
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 call _write_out
li t0, 0x0a306120 # _a0\n la a0, asm_seqz_a0
sw t0, 16(sp) li a1, ASM_SEQZ_A0_SIZE
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 call _write_out
j .Lbuild_binary_expression_end j .Lbuild_binary_expression_end
@ -141,6 +152,26 @@ _build_binary_expression:
j .Lbuild_binary_expression_end 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: .Lbuild_binary_expression_end:
# Epilogue. # Epilogue.
lw ra, 28(sp) lw ra, 28(sp)
@ -237,11 +268,8 @@ _build_expression:
addi a1, a1, -4 # Skip the "loca" variable prefix. addi a1, a1, -4 # Skip the "loca" variable prefix.
call _write_out call _write_out
li t0, 0x0a # \n li a0, '\n'
sw t0, 16(sp) call _put_char
addi a0, sp, 16
li a1, 1
call _write_out
j .Lbuild_expression_advance j .Lbuild_expression_advance
@ -262,7 +290,7 @@ _build_expression:
addi a1, a1, -4 # Skip the "loca" variable prefix. addi a1, a1, -4 # Skip the "loca" variable prefix.
call _write_out call _write_out
li t0, 0x0a # \n li t0, '\n'
sw t0, 16(sp) sw t0, 16(sp)
li t0, 0x29707328 # (sp) li t0, 0x29707328 # (sp)
sw t0, 12(sp) sw t0, 12(sp)
@ -380,7 +408,7 @@ _compile_identifier:
addi a1, a1, -4 # Skip the "loca" variable prefix. addi a1, a1, -4 # Skip the "loca" variable prefix.
call _write_out call _write_out
li t0, 0x0a # \n li t0, '\n'
sw t0, 12(sp) sw t0, 12(sp)
li t0, 0x29707328 # (sp) li t0, 0x29707328 # (sp)
sw t0, 8(sp) sw t0, 8(sp)
@ -416,7 +444,6 @@ _compile_call:
.Lcompile_call_paren: .Lcompile_call_paren:
call _skip_spaces call _skip_spaces
call _read_token
lbu t0, (s1) lbu t0, (s1)
li t1, 0x29 # ) li t1, 0x29 # )
beq t0, t1, .Lcompile_call_complete beq t0, t1, .Lcompile_call_complete
@ -458,7 +485,7 @@ _compile_call:
li a1, 1 li a1, 1
call _write_out call _write_out
li t0, 0x0a # \n li t0, '\n'
sw t0, 8(sp) sw t0, 8(sp)
li t0, 0x29707328 # (sp) li t0, 0x29707328 # (sp)
sw t0, 4(sp) sw t0, 4(sp)
@ -467,7 +494,6 @@ _compile_call:
call _write_out call _write_out
call _skip_spaces call _skip_spaces
call _read_token
lbu t0, (s1) lbu t0, (s1)
li t1, ',' li t1, ','
bne t0, t1, .Lcompile_call_paren bne t0, t1, .Lcompile_call_paren
@ -507,7 +533,7 @@ _compile_call:
addi t4, t4, '0' addi t4, t4, '0'
addi t0, t0, '0' addi t0, t0, '0'
li t5, 0x0a # \n li t5, '\n'
sb t5, 11(sp) sb t5, 11(sp)
li t5, 0x29707328 # (sp) li t5, 0x29707328 # (sp)
sw t5, 7(sp) sw t5, 7(sp)
@ -540,7 +566,7 @@ _compile_call:
lw a1, 16(sp) lw a1, 16(sp)
call _write_out call _write_out
li t0, 0x0a # \n li t0, '\n'
sw t0, 8(sp) sw t0, 8(sp)
addi a0, sp, 8 addi a0, sp, 8
li a1, 1 li a1, 1
@ -601,6 +627,12 @@ _read_token:
li t1, '=' li t1, '='
beq t0, t1, .Ltoken_character_single beq t0, t1, .Ltoken_character_single
li t1, '+'
beq t0, t1, .Ltoken_character_single
li t1, '-'
beq t0, t1, .Ltoken_character_single
li t1, '@' li t1, '@'
beq t0, t1, .Ltoken_character_single beq t0, t1, .Ltoken_character_single
# Expect an identifier or a number. # Expect an identifier or a number.
@ -693,11 +725,6 @@ _skip_comment:
sw s0, 8(sp) sw s0, 8(sp)
addi s0, sp, 16 addi s0, sp, 16
/* DEBUG
mv a0, s1
li a1, 8
call _write_error */
# Check whether this is a comment. # Check whether this is a comment.
li t0, 0x2a28 # (* li t0, 0x2a28 # (*
sw t0, 4(sp) sw t0, 4(sp)
@ -924,12 +951,8 @@ _compile_variable:
add s1, s1, a0 # Skip the type. add s1, s1, a0 # Skip the type.
# .type identifier, @object # .type identifier, @object
li t0, 0x2065 # e_ la a0, asm_type
sw t0, 12(sp) li a1, ASM_TYPE_SIZE
li t0, 0x7079742e # .typ
sw t0, 8(sp)
addi a0, sp, 8
li a1, 6
call _write_out call _write_out
lw a0, 28(sp) lw a0, 28(sp)
@ -959,7 +982,7 @@ _compile_variable:
lw a1, 24(sp) lw a1, 24(sp)
call _write_out call _write_out
li t0, 0x202c # , li t0, 0x202c # ,_
sw t0, 12(sp) sw t0, 12(sp)
addi a0, sp, 12 addi a0, sp, 12
li a1, 2 li a1, 2
@ -969,11 +992,8 @@ _compile_variable:
lw a1, 16(sp) lw a1, 16(sp)
call _write_out call _write_out
li t0, 0x0a # \n li a0, '\n'
sw t0, 12(sp) call _put_char
addi a0, sp, 12
li a1, 1
call _write_out
# identifier: .zero size # identifier: .zero size
lw a0, 28(sp) lw a0, 28(sp)
@ -992,11 +1012,8 @@ _compile_variable:
lw a1, 16(sp) lw a1, 16(sp)
call _write_out call _write_out
li t0, 0x0a # \n li a0, '\n'
sw t0, 12(sp) call _put_char
addi a0, sp, 12
li a1, 1
call _write_out
# Epilogue. # Epilogue.
lw ra, 36(sp) lw ra, 36(sp)
@ -1019,12 +1036,8 @@ _compile_procedure:
add s1, s1, a0 add s1, s1, a0
# .type identifier, @function # .type identifier, @function
li t0, 0x2065 # e_ la a0, asm_type
sw t0, 12(sp) li a1, ASM_TYPE_SIZE
li t0, 0x7079742e # .typ
sw t0, 8(sp)
addi a0, sp, 8
li a1, 6
call _write_out call _write_out
lw a0, 20(sp) lw a0, 20(sp)
@ -1235,11 +1248,8 @@ _compile_goto:
addi s1, s1, 1 # Skip the new line. addi s1, s1, 1 # Skip the new line.
li t0, 0x0a # \n li a0, '\n'
sw t0, 8(sp) call _put_char
addi a0, sp, 8
li a1, 1
call _write_out
# Epilogue. # Epilogue.
lw ra, 12(sp) lw ra, 12(sp)
@ -1280,7 +1290,7 @@ _compile_label:
call _write_out call _write_out
.Lcompile_label_colon: .Lcompile_label_colon:
li t0, 0x0a # \n li t0, '\n'
sw t0, 4(sp) sw t0, 4(sp)
addi a0, sp, 4 addi a0, sp, 4
li a1, 1 li a1, 1
@ -1296,6 +1306,25 @@ _compile_label:
addi sp, sp, 16 addi sp, sp, 16
ret 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: # Parameters:
# a0 - Line length. # a0 - Line length.
# a1 - Whether the section header was already emitted. If not it should be # a1 - Whether the section header was already emitted. If not it should be
@ -1403,6 +1432,16 @@ _compile_line:
call _memcmp call _memcmp
beqz a0, .Lcompile_line_goto 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) lbu t0, (s1)
li t1, '.' li t1, '.'
beq t0, t1, .Lcompile_line_label beq t0, t1, .Lcompile_line_label
@ -1416,6 +1455,14 @@ _compile_line:
call _compile_label call _compile_label
j .Lcompile_line_section 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: .Lcompile_line_goto:
call _compile_goto call _compile_goto
j .Lcompile_line_section j .Lcompile_line_section

View File

@ -20,10 +20,10 @@ program
import dummy import dummy
const const
SOURCE_BUFFER_SIZE := 40960 SOURCE_BUFFER_SIZE := 81920
var var
source_code: [40960]Byte source_code: [81920]Byte
(* Ignores the import. *) (* Ignores the import. *)
proc _compile_import() proc _compile_import()
@ -36,9 +36,13 @@ begin
end end
proc _build_binary_expression() proc _build_binary_expression()
var loca0, loca4, loca8: Word
begin begin
_build_expression(0) _build_expression(0)
loca4 := 0x2c306120 (* _a0, *)
loca8 := 0x0a316120 (* _a1\n *)
_skip_spaces() _skip_spaces()
call _read_token call _read_token
sw a0, 20(sp) sw a0, 20(sp)
@ -67,57 +71,81 @@ begin
call _token_compare call _token_compare
beqz a0, .L_build_binary_expression_equal 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 goto .Lbuild_binary_expression_end
.L_build_binary_expression_equal .L_build_binary_expression_equal
_advance(1) (* Skip =. *) _advance(1) (* Skip =. *)
_build_expression(1) _build_expression(1)
loca0 := 0x0a3161 (* a1\n *) _write_out(@loca0, 3)
_write_out(@loca0, 4) _write_out(@loca4, 4)
loca0 := 0x202c3061 (* a0,_ *) _write_out(@loca4, 4)
_write_out(@loca0, 4) _write_out(@loca8, 4)
loca0 := 0x202c3061 (* a0,_ *)
_write_out(@loca0, 4)
loca0 := 0x20627573 (* sub_ *)
_write_out(@loca0, 4)
loca0 := 0x7a716573 (* seqz *) loca0 := 0x7a716573 (* seqz *)
_write_out(@loca0, 4) _write_out(@loca0, 4)
loca0 := 0x2c306120 (* _a0, *) _write_out(@loca4, 4)
_write_out(@loca0, 4) _write_out(@loca4, 4)
loca0 := 0x0a306120 (* _a0\n *)
_write_out(@loca0, 4)
goto .Lbuild_binary_expression_end goto .Lbuild_binary_expression_end
.L_build_binary_expression_and .L_build_binary_expression_and
_advance(1) (* Skip &. *) _advance(1) (* Skip &. *)
_build_expression(1) _build_expression(1)
loca0 := 0x20646e61 (* and_ *) loca0 := 0x646e61 (* 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) _write_out(@loca0, 3)
_write_out(@loca4, 4)
_write_out(@loca4, 4)
_write_out(@loca8, 4)
goto .Lbuild_binary_expression_end goto .Lbuild_binary_expression_end
.L_build_binary_expression_or .L_build_binary_expression_or
_advance(2) (* Skip or. *) _advance(2) (* Skip or. *)
_build_expression(1) _build_expression(1)
loca0 := 0x6120726f (* or a *) loca0 := 0x726f (* or *)
_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) _write_out(@loca0, 2)
_write_out(@loca4, 4)
_write_out(@loca4, 4)
_write_out(@loca8, 4)
goto .Lbuild_binary_expression_end goto .Lbuild_binary_expression_end
.L_build_binary_expression_plus
_advance(1) (* Skip +. *)
_build_expression(1)
loca0 := 0x646461 (* add *)
_write_out(@loca0, 3)
_write_out(@loca4, 4)
_write_out(@loca4, 4)
_write_out(@loca8, 4)
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 .Lbuild_binary_expression_end
end end
@ -173,25 +201,20 @@ begin
goto .Lbuild_expression_advance goto .Lbuild_expression_advance
.Lbuild_expression_address .Lbuild_expression_address
lw t1, 28(sp) loca8 := 0x69646461 (* addi *)
li t0, 0x20 # _ _write_out(@loca8, 4)
sw t0, 16(sp) loca8 := 0x6120 (* _a *)
li t0, 0x2c707320 # _sp, _write_out(@loca8, 2)
sw t0, 12(sp) _put_char(loca28)
li t0, 0x2c006120 # _a\0, loca8 := 0x7073202c (* , sp *)
sw t0, 8(sp) _write_out(@loca8, 4)
sb t1, 10(sp) loca8 := 0x202c (* ,_ *)
li t0, 0x69646461 # addi _write_out(@loca8, 2)
sw t0, 4(sp)
addi a0, sp, 4
li a1, 13
call _write_out
_advance(1) (* Skip @. *) _advance(1) (* Skip @. *)
_skip_spaces() _skip_spaces()
call _read_token loca24 := _current()
sw s1, 24(sp) loca20 := _read_token()
sw a0, 20(sp)
lw a0, 24(sp) lw a0, 24(sp)
lw a1, 20(sp) lw a1, 20(sp)
@ -199,11 +222,7 @@ begin
addi a1, a1, -4 # Skip the "loca" variable prefix. addi a1, a1, -4 # Skip the "loca" variable prefix.
call _write_out call _write_out
li t0, 0x0a # \n _put_char(0xa)
sw t0, 16(sp)
addi a0, sp, 16
li a1, 1
call _write_out
goto .Lbuild_expression_advance 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. of the variable on the stack, like loca8 or loca4.
*) *)
proc _compile_identifier() proc _compile_identifier()
var
loca0, loca16, loca8: Word
loca20, loca12: ^Byte
begin 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) loca20 := _current()
sw a0, 16(sp) loca16 := _read_token()
add s1, s1, a0 _advance(loca16)
_skip_spaces() _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) loca12 := _current()
sw a0, 8(sp) loca8 := _read_token()
add s1, s1, a0 # Skip that token. _advance(loca8) # Skip that token.
_skip_spaces() _skip_spaces()
li t0, 0x3d3a # := li t0, 0x3d3a # :=
@ -304,22 +323,17 @@ begin
goto .Lcompile_identifier_end goto .Lcompile_identifier_end
.Lcompile_identifier_call .Lcompile_identifier_call
lw a0, 20(sp) _compile_call(loca20, loca16)
lw a1, 16(sp)
call _compile_call
goto .Lcompile_identifier_end goto .Lcompile_identifier_end
.Lcompile_identifier_assign .Lcompile_identifier_assign
_build_binary_expression() _build_binary_expression()
li t0, 0x202c30 # 0,_ loca0 := 0x61207773 (* sw a *)
sw t0, 12(sp) _write_out(@loca0, 4)
li t0, 0x61207773 # sw a loca0 := 0x202c30 (* 0,_ *)
sw t0, 8(sp) _write_out(@loca0, 3)
addi a0, sp, 8
li a1, 7
call _write_out
lw a0, 20(sp) lw a0, 20(sp)
lw a1, 16(sp) lw a1, 16(sp)
@ -327,13 +341,9 @@ begin
addi a1, a1, -4 # Skip the "loca" variable prefix. addi a1, a1, -4 # Skip the "loca" variable prefix.
call _write_out call _write_out
li t0, 0x0a # \n loca0 := 0x29707328 (* (sp) *)
sw t0, 12(sp) _write_out(@loca0, 4)
li t0, 0x29707328 # (sp) _put_char(0x0a) (* \n *)
sw t0, 8(sp)
addi a0, sp, 8
li a1, 5
call _write_out
goto .Lcompile_identifier_end goto .Lcompile_identifier_end
@ -347,15 +357,14 @@ a1 - Length of the procedure name.
Returns the procedure result in a0. Returns the procedure result in a0.
*) *)
proc _compile_call() proc _compile_call(loca84: ^Byte, loca80: Word)
var
loca0, loca12: Word
begin begin
sw a0, 20(sp) loca12 := 0 (* Argument count for a procedure call. *)
sw a1, 16(sp)
sw zero, 12(sp) # Argument count for a procedure call.
.Lcompile_call_paren .Lcompile_call_paren
_skip_spaces() _skip_spaces()
call _read_token
lbu t0, (s1) lbu t0, (s1)
li t1, 0x29 # ) li t1, 0x29 # )
beq t0, t1, .Lcompile_call_complete beq t0, t1, .Lcompile_call_complete
@ -363,13 +372,10 @@ begin
.Lcompile_call_argument .Lcompile_call_argument
_build_expression(0) _build_expression(0)
li t0, 0x202c30 # 0,_ loca0 := 0x61207773 (* sw a *)
sw t0, 8(sp) _write_out(@loca0, 4)
li t0, 0x61207773 # sw a loca0 := 0x202c30 (* 0,_ *)
sw t0, 4(sp) _write_out(@loca0, 3)
addi a0, sp, 4
li a1, 7
call _write_out
lw t0, 12(sp) # Argument count for a procedure call. lw t0, 12(sp) # Argument count for a procedure call.
@ -407,7 +413,6 @@ begin
call _write_out call _write_out
_skip_spaces() _skip_spaces()
call _read_token
lbu t0, (s1) lbu t0, (s1)
li t1, ',' li t1, ','
bne t0, t1, .Lcompile_call_paren bne t0, t1, .Lcompile_call_paren
@ -420,7 +425,7 @@ begin
goto .Lcompile_call_argument goto .Lcompile_call_argument
.Lcompile_call_complete .Lcompile_call_complete
sw zero, 12(sp) loca12 := 0
.Lcompile_call_restore .Lcompile_call_restore
(* (*
@ -463,30 +468,16 @@ begin
li a1, 10 li a1, 10
call _write_out call _write_out
lw t0, 12(sp) # Increment. loca12 := loca12 + 1
addi t0, t0, 1
sw t0, 12(sp)
goto .Lcompile_call_restore goto .Lcompile_call_restore
.Lcompile_call_perform .Lcompile_call_perform
li t0, 0x20 loca0 := 0x6c6c6163
sw t0, 8(sp) _write_out(@loca0, 4)
li t0, 0x6c6c6163 _put_char(0x20) (* _ *)
sw t0, 4(sp)
addi a0, sp, 4
li a1, 5
call _write_out
lw a0, 20(sp) _write_out(loca84, loca80)
lw a1, 16(sp) _put_char(0x0a) (* \n *)
call _write_out
li t0, 0x0a # \n
sw t0, 8(sp)
addi a0, sp, 8
li a1, 1
call _write_out
_skip_spaces() _skip_spaces()
_advance(1) (* Skip the close paren. *) _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. _read_token doesn't change s1, it finds the length of the token s1 is pointing to.
*) *)
proc _read_token() proc _read_token()
var loca4: Word
begin begin
lbu t0, (s1) # t0 = Current character. lbu t0, (s1) # t0 = Current character.
sw zero, 4(sp) loca4 := 0
li t1, '.' li t1, '.'
beq t0, t1, .Ltoken_character_single beq t0, t1, .Ltoken_character_single
@ -534,6 +526,12 @@ begin
li t1, '=' li t1, '='
beq t0, t1, .Ltoken_character_single beq t0, t1, .Ltoken_character_single
li t1, '+'
beq t0, t1, .Ltoken_character_single
li t1, '-'
beq t0, t1, .Ltoken_character_single
li t1, '@' li t1, '@'
beq t0, t1, .Ltoken_character_single beq t0, t1, .Ltoken_character_single
(* Expect an identifier or a number. *) (* Expect an identifier or a number. *)
@ -545,22 +543,16 @@ begin
call _is_alnum call _is_alnum
beqz a0, .Ltoken_character_end beqz a0, .Ltoken_character_end
lw t6, 4(sp) loca4 := loca4 + 1
addi t6, t6, 1
sw t6, 4(sp)
goto .Ltoken_character_loop_do goto .Ltoken_character_loop_do
.Ltoken_character_single .Ltoken_character_single
lw t6, 4(sp) loca4 := loca4 + 1
addi t6, t6, 1
sw t6, 4(sp)
goto .Ltoken_character_end goto .Ltoken_character_end
.Ltoken_character_colon .Ltoken_character_colon
lbu t0, 1(s1) # t0 = The character after the colon. lbu t0, 1(s1) # t0 = The character after the colon.
lw t6, 4(sp) loca4 := loca4 + 1
addi t6, t6, 1
sw t6, 4(sp)
li t1, '=' li t1, '='
beq t0, t1, .Ltoken_character_single beq t0, t1, .Ltoken_character_single
@ -617,11 +609,6 @@ Parameters:
*) *)
proc _skip_comment(loca84: Word) proc _skip_comment(loca84: Word)
begin begin
(* DEBUG
mv a0, s1
li a1, 8
call _write_error *)
(* Check whether this is a comment. *) (* Check whether this is a comment. *)
li t0, 0x2a28 # (* li t0, 0x2a28 # (*
sw t0, 4(sp) sw t0, 4(sp)
@ -774,13 +761,15 @@ begin
end end
proc _compile_variable() proc _compile_variable()
var
loca28, loca16: ^Byte
loca0, loca24, loca20: Word
begin 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) loca24 := _read_token()
sw a0, 24(sp) loca28 := _current()
add s1, s1, a0
_advance(loca24)
_skip_spaces() _skip_spaces()
_advance(1) (* Skip the colon in front of the type. *) _advance(1) (* Skip the colon in front of the type. *)
@ -788,99 +777,63 @@ begin
_skip_spaces() _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) loca16 := _read_token()
sw a0, 16(sp) loca20 := _current()
add s1, s1, a0 _advance(loca16)
_skip_spaces() _skip_spaces()
_advance(1) (* Skip the closing bracket. *) _advance(1) (* Skip the closing bracket. *)
_skip_spaces() _skip_spaces()
call _read_token loca0 := _read_token()
add s1, s1, a0 # Skip the type. _advance(loca0) (* Skip the type. *)
(* .type identifier, @object *) (* .type identifier, @object *)
li t0, 0x2065 # e_ loca0 := 0x7079742e (* .typ *)
sw t0, 12(sp) _write_out(@loca0, 4)
li t0, 0x7079742e # .typ loca0 := 0x2065 (* e_ *)
sw t0, 8(sp) _write_out(@loca0, 2)
addi a0, sp, 8
li a1, 6
call _write_out
lw a0, 28(sp) _write_out(loca28, loca24)
lw a1, 24(sp)
call _write_out
li t0, 0x0a74 # t\n loca0 := 0x6f40202c (* , @o *)
sw t0, 12(sp) _write_out(@loca0, 4)
li t0, 0x63656a62 # bjec loca0 := 0x63656a62 (* bjec *)
sw t0, 8(sp) _write_out(@loca0, 4)
li t0, 0x6f40202c # , @o loca0 := 0x0a74 (* t\n *)
sw t0, 4(sp) _write_out(@loca0, 2)
addi a0, sp, 4
li a1, 10
call _write_out
(* .size identifier, size *) (* .size identifier, size *)
li t0, 0x2065 # e_ loca0 := 0x7a69732e (* .siz *)
sw t0, 12(sp) _write_out(@loca0, 4)
li t0, 0x7a69732e # .siz loca0 := 0x2065 (* e_ *)
sw t0, 8(sp) _write_out(@loca0, 2)
addi a0, sp, 8
li a1, 6
call _write_out
lw a0, 28(sp) _write_out(loca28, loca24)
lw a1, 24(sp)
call _write_out
li t0, 0x202c # , loca0 := 0x202c (* ,_ *)
sw t0, 12(sp) _write_out(@loca0, 2)
addi a0, sp, 12
li a1, 2
call _write_out
lw a0, 20(sp) _write_out(loca20, loca16)
lw a1, 16(sp) _put_char(0x0a) (* \n *)
call _write_out
li t0, 0x0a # \n
sw t0, 12(sp)
addi a0, sp, 12
li a1, 1
call _write_out
(* identifier: .zero size *) (* identifier: .zero size *)
lw a0, 28(sp) _write_out(loca28, loca24)
lw a1, 24(sp)
call _write_out
li t0, 0x206f7265 # ero_ loca0 := 0x7a2e203a (* : .z *)
sw t0, 12(sp) _write_out(@loca0, 4)
li t0, 0x7a2e203a # : .z loca0 := 0x206f7265 (* ero_ *)
sw t0, 8(sp) _write_out(@loca0, 4)
addi a0, sp, 8
li a1, 8
call _write_out
lw a0, 20(sp) _write_out(loca20, loca16)
lw a1, 16(sp)
call _write_out
li t0, 0x0a # \n _put_char(0x0a) (* \n *)
sw t0, 12(sp)
addi a0, sp, 12
li a1, 1
call _write_out
end end
proc _compile_procedure() proc _compile_procedure()
var var
loca0, loca8, loca12, loca16: Word loca0, loca4, loca8, loca12, loca16: Word
loca20: ^Char loca20: ^Char
begin begin
_advance(5) (* Skip proc_ *) _advance(5) (* Skip proc_ *)
@ -971,57 +924,49 @@ begin
_write_out(@loca0, 4) _write_out(@loca0, 4)
(* Save passed arguments on the stack. *) (* Save passed arguments on the stack. *)
li t0, 0x0a29 # )\n loca0 := 0x61207773 (* sw a *)
sw t0, 12(sp) _write_out(@loca0, 4)
li t0, 0x70732834 # 4(sp loca4 := 0x38202c30 (* 0, 8 *)
sw t0, 8(sp) _write_out(@loca4, 4)
li t0, 0x38202c30 # 0, 8 loca8 := 0x70732834 (* 4(sp *)
sw t0, 4(sp) _write_out(@loca8, 4)
li t0, 0x61207773 # sw a loca12 := 0x0a29 (* )\n *)
sw t0, 0(sp) _write_out(@loca12, 2)
addi a0, sp, 0
li a1, 14
call _write_out
li t0, '0' _write_out(@loca0, 4)
sb t0, 8(sp) loca4 := 0x38202c31 (* 1, 8 *)
li t0, 0x38202c31 # 1, 8 _write_out(@loca4, 4)
sw t0, 4(sp) loca8 := 0x70732830 (* 0(sp *)
addi a0, sp, 0 _write_out(@loca8, 4)
li a1, 14 _write_out(@loca12, 2)
call _write_out
li t0, '6' _write_out(@loca0, 4)
sb t0, 8(sp) loca4 := 0x37202c32 (* 2, 7 *)
li t0, 0x37202c32 # 2, 7 _write_out(@loca4, 4)
sw t0, 4(sp) loca8 := 0x70732836 (* 6(sp *)
addi a0, sp, 0 _write_out(@loca8, 4)
li a1, 14 _write_out(@loca12, 2)
call _write_out
li t0, '2' _write_out(@loca0, 4)
sb t0, 8(sp) loca4 := 0x37202c33 (* 3, 7 *)
li t0, 0x37202c33 # 3, 7 _write_out(@loca4, 4)
sw t0, 4(sp) loca8 := 0x70732832 (* 2(sp *)
addi a0, sp, 0 _write_out(@loca8, 4)
li a1, 14 _write_out(@loca12, 2)
call _write_out
li t0, '8' _write_out(@loca0, 4)
sb t0, 8(sp) loca4 := 0x36202c34 (* 4, 6 *)
li t0, 0x36202c34 # 4, 6 _write_out(@loca4, 4)
sw t0, 4(sp) loca8 := 0x70732838 (* 8(sp *)
addi a0, sp, 0 _write_out(@loca8, 4)
li a1, 14 _write_out(@loca12, 2)
call _write_out
li t0, '4' _write_out(@loca0, 4)
sb t0, 8(sp) loca4 := 0x36202c35 (* 5, 6 *)
li t0, 0x36202c35 # 5, 6 _write_out(@loca4, 4)
sw t0, 4(sp) loca8 := 0x70732838 (* 4(sp *)
addi a0, sp, 0 _write_out(@loca8, 4)
li a1, 14 _write_out(@loca12, 2)
call _write_out
(* Generate the body of the procedure. *) (* Generate the body of the procedure. *)
.Lcompile_procedure_body .Lcompile_procedure_body
@ -1042,7 +987,7 @@ begin
goto .Lcompile_procedure_body goto .Lcompile_procedure_body
.Lcompile_procedure_end .Lcompile_procedure_end
add s1, s1, 4 # Skip end\n. _advance(4) (* Skip end\n. *)
(* Generate the procedure epilogue with a predefined stack size. *) (* Generate the procedure epilogue with a predefined stack size. *)
loca0 := 0x7220776c # lw r loca0 := 0x7220776c # lw r
@ -1124,45 +1069,38 @@ begin
end end
proc _compile_goto() proc _compile_goto()
var
loca0: Word
loca8: ^Byte
begin begin
_advance(4) (* Skip the goto keyword. *) _advance(4) (* Skip the goto keyword. *)
li t0, 0x206a # j_ loca0 := 0x206a (* j_ *)
sw t0, 8(sp) _write_out(@loca0, 2)
addi a0, sp, 8
li a1, 2
call _write_out
_skip_spaces() _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) _advance(1)
call _read_token loca0 := _read_token()
add s1, s1, a0 _advance(loca0)
addi a1, a0, 1 # Label length and the dot. loca0 := loca0 + 1 (* Label length and the dot. *)
lw a0, 8(sp) # Saved dot position. _write_out(loca8, loca0)
call _write_out
_advance(1) (* Skip the new line. *) _advance(1) (* Skip the new line. *)
_put_char(0x0a) (* \n *)
li t0, 0x0a # \n
sw t0, 8(sp)
addi a0, sp, 8
li a1, 1
call _write_out
end end
(* a0 - Line length. *) (* a0 - Line length. *)
proc _compile_label() proc _compile_label(loca84: Word)
var
loca0: Word
begin begin
sw a0, 0(sp) # Save the line length.
(* Write the whole line as is. *) (* Write the whole line as is. *)
mv a0, s1 loca0 := _current()
lw a1, 0(sp) _write_out(loca0, loca84)
call _write_out
lw t0, 0(sp) # Line length. lw t0, 84(sp) # Line length.
mv t1, s1 # Line start. mv t1, s1 # Line start.
add t1, t1, t0 add t1, t1, t0
@ -1172,22 +1110,19 @@ begin
li t2, ':' li t2, ':'
beq t1, t2, .Lcompile_label_colon beq t1, t2, .Lcompile_label_colon
li t0, 0x3a # : _put_char(0x3a) (* : *)
sw t0, 4(sp)
addi a0, sp, 4
li a1, 1
call _write_out
.Lcompile_label_colon .Lcompile_label_colon
li t0, 0x0a # \n _put_char(0x0a) (* \n *)
sw t0, 4(sp)
addi a0, sp, 4
li a1, 1
call _write_out
lw a0, 0(sp) _advance(loca84)
addi a0, a0, 1 # Skip the new line as well. end
add s1, s1, a0 # Skip the line.
proc _compile_return()
begin
_advance(6) (* Skip return. *)
_skip_spaces()
_build_binary_expression()
end end
(* (*
@ -1199,12 +1134,8 @@ Parameters:
Returns 1 in a0 if the parsed line contained a text section element such a 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. procedure or the program entry point. Otherwise sets a0 to 0.
*) *)
proc _compile_line() proc _compile_line(loca84: Word, loca80: Bool)
begin begin
(* Preserve passed arguments. *)
sw a0, 20(sp)
sw a1, 16(sp)
beqz a0, .Lcompile_line_empty # Skip an empty line. beqz a0, .Lcompile_line_empty # Skip an empty line.
lbu t0, (s1) lbu t0, (s1)
@ -1293,6 +1224,16 @@ begin
call _memcmp call _memcmp
beqz a0, .Lcompile_line_goto 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) lbu t0, (s1)
li t1, '.' li t1, '.'
beq t0, t1, .Lcompile_line_label beq t0, t1, .Lcompile_line_label
@ -1302,8 +1243,15 @@ begin
goto .Lcompile_line_unchanged (* Else. *) goto .Lcompile_line_unchanged (* Else. *)
.Lcompile_line_label .Lcompile_line_label
lw a0, 20(sp) _compile_label(loca84)
call _compile_label goto .Lcompile_line_section
.Lcompile_line_return
(* DEBUG
mv a0, s1
li a1, 8
call _write_error *)
_compile_return()
goto .Lcompile_line_section goto .Lcompile_line_section
.Lcompile_line_goto .Lcompile_line_goto
@ -1323,7 +1271,7 @@ begin
goto .Lcompile_line_section goto .Lcompile_line_section
.Lcompile_line_begin .Lcompile_line_begin
lw a1, 16(sp) lw a1, 80(sp)
bnez a1, .Lcompile_line_compile_entry bnez a1, .Lcompile_line_compile_entry
_compile_text_section() _compile_text_section()
.Lcompile_line_compile_entry .Lcompile_line_compile_entry
@ -1336,7 +1284,7 @@ begin
goto .Lcompile_line_section goto .Lcompile_line_section
.Lcompile_line_procedure .Lcompile_line_procedure
lw a1, 16(sp) lw a1, 80(sp)
bnez a1, .Lcompile_line_compile_procedure bnez a1, .Lcompile_line_compile_procedure
_compile_text_section() _compile_text_section()
.Lcompile_line_compile_procedure .Lcompile_line_compile_procedure
@ -1353,8 +1301,7 @@ begin
goto .Lcompile_line_section goto .Lcompile_line_section
.Lcompile_line_comment .Lcompile_line_comment
lw a0, 20(sp) _skip_comment(loca84)
call _skip_comment
goto .Lcompile_line_section goto .Lcompile_line_section
.Lcompile_line_empty .Lcompile_line_empty
@ -1362,8 +1309,7 @@ begin
goto .Lcompile_line_section goto .Lcompile_line_section
.Lcompile_line_unchanged .Lcompile_line_unchanged
lw a0, 20(sp) _compile_assembly(loca84)
call _compile_assembly
goto .Lcompile_line_section goto .Lcompile_line_section
.Lcompile_line_section .Lcompile_line_section
@ -1445,31 +1391,35 @@ 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() proc _read_line()
begin begin
mv t0, s1 # Local position in the source text. loca0 := _current() (* Local position in the source text. *)
.Lread_line_do .Lread_line_do
lw t0, 0(sp)
lbu t1, (t0) # t1 = Current character. lbu t1, (t0) # t1 = Current character.
beqz t1, .Lread_line_end # Exit the loop on the NUL character. beqz t1, .Lread_line_end # Exit the loop on the NUL character.
li t2, '\n' li t2, '\n'
beq t1, t2, .Lread_line_end # Exit the loop on the new line. beq t1, t2, .Lread_line_end # Exit the loop on the new line.
addi t0, t0, 1 loca0 := loca0 + 1
goto .Lread_line_do goto .Lread_line_do
.Lread_line_end .Lread_line_end
sub a0, t0, s1 # Return the line length. loca4 := _current()
return loca0 - loca4 (* Return the line length. *)
end end
proc _compile() proc _compile()
var loca0, loca4: Word
begin 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 .Lcompile_do
lbu t0, (s1) # t0 = Current character. lbu t0, (s1) # t0 = Current character.
beqz t0, .Lcompile_end # Exit the loop on the NUL character. beqz t0, .Lcompile_end # Exit the loop on the NUL character.
_skip_indentation() _skip_indentation()
call _read_line loca0 := _read_line()
lw a0, 0(sp)
lw a1, 4(sp) lw a1, 4(sp)
call _compile_line call _compile_line