Support preserved registers as identifiers

… in expressions
This commit is contained in:
2025-04-29 23:08:46 +02:00
parent 9c66cec171
commit 23b7a1ab30
6 changed files with 851 additions and 503 deletions

View File

@@ -207,6 +207,130 @@ _build_binary_expression:
addi sp, sp, 32
ret
# Parameters:
# a0 - Identifier length.
# a1 - Register number as character.
.type _build_identifier_expression, @function
_build_identifier_expression:
# Prologue.
addi sp, sp, -32
sw ra, 28(sp)
sw s0, 24(sp)
addi s0, sp, 32
sw a0, 20(sp) # Identifier length.
sw a1, 16(sp) # Register number as character.
li t0, 0x61636f6c # loca
sw t0, 12(sp)
mv a0, s1
addi a1, sp, 12
li a2, 4
call _memcmp
beqz a0, .Lbuild_identifier_expression_local
lbu a0, (s1)
lw t0, 20(sp)
addi t0, t0, -2
seqz t0, t0
addi t1, a0, -'s'
seqz t1, t1
and t0, t0, t1
bnez t0, .Lbuild_identifier_expression_saved
# Global identifier.
lw t1, 16(sp)
li t0, 0x00202c00 # \0,_
or t0, t0, t1
sw t0, 12(sp)
li t0, 0x6120616c # la a
sw t0, 8(sp)
addi a0, sp, 8
li a1, 7
call _write_out
mv a0, s1
lw a1, 20(sp)
call _write_out
li a0, '\n'
call _put_char
lbu a0, (s1)
call _is_upper
beqz a0, .Lbuild_identifier_expression_end
lw t1, 16(sp)
li t0, 0x0a290061 # a\0)\n
sll t2, t1, 8
or t0, t0, t2
sw t0, 12(sp)
li t0, 0x28202c00 # \0, (
or t0, t0, t1
sw t0, 8(sp)
li t0, 0x6120776c # lw a
sw t0, 4(sp)
addi a0, sp, 4
li a1, 12
call _write_out
j .Lbuild_identifier_expression_end
.Lbuild_identifier_expression_saved:
li t0, 0x00202c00 # \0,_
lw t1, 16(sp)
or t0, t0, t1
sw t0, 12(sp)
li t0, 0x6120766d # mv a
sw t0, 8(sp)
addi a0, sp, 8
li a1, 7
call _write_out
mv a0, s1
lw a1, 20(sp)
call _write_out
li a0, '\n'
call _put_char
j .Lbuild_identifier_expression_end
.Lbuild_identifier_expression_local:
lw t1, 16(sp)
li t0, 0x00202c00 # \0,_
or t0, t0, t1
sw t0, 12(sp)
li t0, 0x6120776c # lw a
sw t0, 8(sp)
addi a0, sp, 8
li a1, 7
call _write_out
mv a0, s1
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, 0x29707328 # (sp)
sw t0, 12(sp)
addi a0, sp, 12
li a1, 4
call _write_out
li a0, '\n'
call _put_char
j .Lbuild_identifier_expression_end
.Lbuild_identifier_expression_end:
# Epilogue.
lw ra, 28(sp)
lw s0, 24(sp)
addi sp, sp, 32
ret
# Evalutes an expression and saves the result in a0.
#
# a0 - X in aX, the register number to save the result.
@@ -242,31 +366,9 @@ _build_expression:
li t0, '_'
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.
lw t1, 28(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, 24(sp)
lw a1, 20(sp)
call _write_out
li a0, '\n'
call _put_char
lw a0, 20(sp)
lw a1, 28(sp)
call _build_identifier_expression
j .Lbuild_expression_advance
@@ -313,33 +415,6 @@ _build_expression:
j .Lbuild_expression_advance
.Lbuild_expression_identifier:
lw t1, 28(sp)
li t0, 0x00202c00 # \0,_
or t0, t0, t1
sw t0, 16(sp)
li t0, 0x6120776c # lw a
sw t0, 12(sp)
addi a0, sp, 12
li a1, 7
call _write_out
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, '\n'
sw t0, 16(sp)
li t0, 0x29707328 # (sp)
sw t0, 12(sp)
addi a0, sp, 12
li a1, 5
call _write_out
j .Lbuild_expression_advance
.Lbuild_expression_call:
lw a0, 24(sp)
lw a1, 20(sp)
@@ -683,24 +758,6 @@ _skip_spaces:
.Lspace_loop_end:
ret
# Skips tabs at the line beginning.
.type _skip_indentation, @function
_skip_indentation:
.Lskip_indentation_do:
lbu t0, (s1)
li t1, '\t'
beq t0, t1, .Lskip_indentation_skip
j .Lskip_indentation_end
.Lskip_indentation_skip:
addi s1, s1, 1
j .Lskip_indentation_do
.Lskip_indentation_end:
ret
# Parameters:
# a0 - Line length.
.type _skip_comment, @function
@@ -1134,7 +1191,7 @@ _compile_procedure:
# Generate the body of the procedure.
.Lcompile_procedure_body:
call _skip_indentation
call _skip_spaces
call _read_line
sw a0, 12(sp)
li t0, 0x0a646e65 # end\n
@@ -1427,23 +1484,19 @@ _compile_line:
li t1, '('
beq t0, t1, .Lcompile_line_comment
li t0, 0x0a6d6172 # ram\n
sw t0, 12(sp)
li t0, 0x676f7270 # prog
sw t0, 8(sp)
sw t0, 12(sp)
mv a0, s1
addi a1, sp, 8
li a2, 8
addi a1, sp, 12
li a2, 4
call _memcmp
beqz a0, .Lcompile_line_program
li t0, 0x0a74 # t\n
sw t0, 12(sp)
li t0, 0x736e6f63 # cons
sw t0, 8(sp)
sw t0, 12(sp)
mv a0, s1
addi a1, sp, 8
li a2, 6
addi a1, sp, 12
li a2, 4
call _memcmp
beqz a0, .Lcompile_line_const
@@ -1455,23 +1508,19 @@ _compile_line:
call _memcmp
beqz a0, .Lcompile_line_var
li t0, 0x20 # _
sw t0, 12(sp)
li t0, 0x636f7270 # proc
sw t0, 8(sp)
sw t0, 12(sp)
mv a0, s1
addi a1, sp, 8
li a2, 5
addi a1, sp, 12
li a2, 4
call _memcmp
beqz a0, .Lcompile_line_procedure
li t0, 0x0a6e # n\n
sw t0, 12(sp)
li t0, 0x69676562 # begi
sw t0, 8(sp)
sw t0, 12(sp)
mv a0, s1
addi a1, sp, 8
li a2, 6
addi a1, sp, 12
li a2, 4
call _memcmp
beqz a0, .Lcompile_line_begin
@@ -1491,13 +1540,11 @@ _compile_line:
call _memcmp
beqz a0, .Lcompile_line_identifier
li t0, 0x7472 # rt
sw t0, 12(sp)
li t0, 0x6f706d69 # impo
sw t0, 8(sp)
sw t0, 12(sp)
mv a0, s1
addi a1, sp, 8
li a2, 6
addi a1, sp, 12
li a2, 4
call _memcmp
beqz a0, .Lcompile_line_import
@@ -1509,13 +1556,11 @@ _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)
sw t0, 12(sp)
mv a0, s1
addi a1, sp, 8
li a2, 6
addi a1, sp, 12
li a2, 4
call _memcmp
beqz a0, .Lcompile_line_return
@@ -1716,7 +1761,7 @@ _compile:
lbu t0, (s1) # t0 = Current character.
beqz t0, .Lcompile_end # Exit the loop on the NUL character.
call _skip_indentation
call _skip_spaces
call _read_line
lw a1, 4(sp)
call _compile_line
@@ -1736,16 +1781,35 @@ _compile:
addi sp, sp, 16
ret
# Entry point.
.type _start, @function
_start:
.type _main, @function
_main:
# Prologue.
addi sp, sp, -8
sw ra, 4(sp)
sw s0, 0(sp)
addi s0, sp, 8
# Read the source from the standard input.
la a0, source_code
li a1, SOURCE_BUFFER_SIZE # Buffer size.
call _read_file
li s2, 1
la s1, source_code # s1 = Source code position.
# Epilogue.
lw ra, 4(sp)
lw s0, 0(sp)
addi sp, sp, 8
ret
# Entry point.
.type _start, @function
_start:
call _tokenizer_initialize
li a1, 50
call _write_error
call _main
call _compile
# Call exit.