Compile procedure calls
This commit is contained in:
parent
f343296463
commit
2e0c958aa3
@ -1,4 +1,4 @@
|
||||
.global is_alpha, is_digit, is_alnum, is_upper, is_lower, write_out, read_file, exit, memcmp, write_error
|
||||
.global _is_alpha, _is_digit, _is_alnum, _is_upper, _is_lower, _write_out, _read_file, exit, _memcmp, _write_error
|
||||
|
||||
.section .rodata
|
||||
|
||||
@ -16,8 +16,8 @@ new_line: .ascii "\n"
|
||||
# Write the current token to stderr.
|
||||
# a0 - String pointer.
|
||||
# a1 - String length.
|
||||
.type write_error, @function
|
||||
write_error:
|
||||
.type _write_error, @function
|
||||
_write_error:
|
||||
mv t0, a0
|
||||
mv t1, a1
|
||||
|
||||
@ -40,8 +40,8 @@ write_error:
|
||||
# a2 - The length to compare.
|
||||
#
|
||||
# Returns 0 in a0 if memory regions are equal.
|
||||
.type memcmp, @function
|
||||
memcmp:
|
||||
.type _memcmp, @function
|
||||
_memcmp:
|
||||
mv t0, a0
|
||||
li a0, 0
|
||||
|
||||
@ -64,7 +64,8 @@ memcmp:
|
||||
ret
|
||||
|
||||
# Detects if a0 is an uppercase character. Sets a0 to 1 if so, otherwise to 0.
|
||||
is_upper:
|
||||
.type _is_upper, @function
|
||||
_is_upper:
|
||||
li t0, 'A' - 1
|
||||
sltu t1, t0, a0 # t1 = a0 >= 'A'
|
||||
|
||||
@ -74,8 +75,8 @@ is_upper:
|
||||
ret
|
||||
|
||||
# Detects if a0 is an lowercase character. Sets a0 to 1 if so, otherwise to 0.
|
||||
.type is_lower, @function
|
||||
is_lower:
|
||||
.type _is_lower, @function
|
||||
_is_lower:
|
||||
li t0, 'a' - 1
|
||||
sltu t2, t0, a0 # t2 = a0 >= 'a'
|
||||
|
||||
@ -87,8 +88,8 @@ is_lower:
|
||||
# Detects if the passed character is a 7-bit alpha character or an underscore.
|
||||
# The character is passed in a0.
|
||||
# Sets a0 to 1 if the character is an alpha character or underscore, sets it to 0 otherwise.
|
||||
.type is_alpha, @function
|
||||
is_alpha:
|
||||
.type _is_alpha, @function
|
||||
_is_alpha:
|
||||
# Prologue.
|
||||
addi sp, sp, -16
|
||||
sw ra, 12(sp)
|
||||
@ -97,11 +98,11 @@ is_alpha:
|
||||
|
||||
sw a0, 4(sp)
|
||||
|
||||
call is_upper
|
||||
call _is_upper
|
||||
sw a0, 0(sp)
|
||||
|
||||
lw a0, 4(sp)
|
||||
call is_lower
|
||||
call _is_lower
|
||||
|
||||
lw t0, 4(sp)
|
||||
xori t1, t0, '_'
|
||||
@ -117,8 +118,8 @@ is_alpha:
|
||||
addi sp, sp, 16
|
||||
ret
|
||||
|
||||
.type is_digit, @function
|
||||
is_digit:
|
||||
.type _is_digit, @function
|
||||
_is_digit:
|
||||
li t0, '0' - 1
|
||||
sltu t1, t0, a0 # t1 = a0 >= '0'
|
||||
|
||||
@ -128,8 +129,8 @@ is_digit:
|
||||
|
||||
ret
|
||||
|
||||
.type is_alnum, @function
|
||||
is_alnum:
|
||||
.type _is_alnum, @function
|
||||
_is_alnum:
|
||||
# Prologue.
|
||||
addi sp, sp, -16
|
||||
sw ra, 12(sp)
|
||||
@ -138,11 +139,11 @@ is_alnum:
|
||||
|
||||
sw a0, 4(sp)
|
||||
|
||||
call is_alpha
|
||||
call _is_alpha
|
||||
sw a0, 0(sp)
|
||||
|
||||
lw a0, 4(sp)
|
||||
call is_digit
|
||||
call _is_digit
|
||||
|
||||
lw a1, 0(sp)
|
||||
or a0, a0, a1
|
||||
@ -153,8 +154,8 @@ is_alnum:
|
||||
addi sp, sp, 16
|
||||
ret
|
||||
|
||||
.type write, @function
|
||||
write_out:
|
||||
.type _write_out, @function
|
||||
_write_out:
|
||||
# Prologue.
|
||||
addi sp, sp, -8
|
||||
sw ra, 4(sp)
|
||||
@ -178,8 +179,8 @@ write_out:
|
||||
# a1 - Buffer size.
|
||||
#
|
||||
# Returns the result in a0.
|
||||
.type read_file, @function
|
||||
read_file:
|
||||
.type _read_file, @function
|
||||
_read_file:
|
||||
# Prologue.
|
||||
addi sp, sp, -8
|
||||
sw ra, 4(sp)
|
||||
|
449
boot/echo-boot.s
449
boot/echo-boot.s
@ -11,6 +11,325 @@ source_code: .zero 20480
|
||||
|
||||
.section .text
|
||||
|
||||
# Evalutes an expression and saves the result in a0.
|
||||
.type _build_expression, @function
|
||||
_build_expression:
|
||||
# Prologue.
|
||||
addi sp, sp, -32
|
||||
sw ra, 28(sp)
|
||||
sw s0, 24(sp)
|
||||
addi s0, sp, 32
|
||||
|
||||
call _skip_spaces
|
||||
call _read_token
|
||||
sw s1, 20(sp)
|
||||
sw a0, 16(sp)
|
||||
|
||||
# Integer literal.
|
||||
addi a0, s1, 0
|
||||
lb a0, (a0)
|
||||
call _is_digit
|
||||
bnez a0, .Lbuild_expression_number_literal
|
||||
|
||||
# Named identifier.
|
||||
li t0, 0x202c30 # 0,_
|
||||
sw t0, 12(sp)
|
||||
li t0, 0x6120616c # la a
|
||||
sw t0, 8(sp)
|
||||
addi a0, sp, 8
|
||||
li a1, 7
|
||||
call _write_out
|
||||
|
||||
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
|
||||
|
||||
j .Lbuild_expression_end
|
||||
|
||||
.Lbuild_expression_number_literal:
|
||||
li t0, 0x202c30 # 0,_
|
||||
sw t0, 12(sp)
|
||||
li t0, 0x6120696c # li a
|
||||
sw t0, 8(sp)
|
||||
addi a0, sp, 8
|
||||
li a1, 7
|
||||
call _write_out
|
||||
|
||||
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
|
||||
|
||||
j .Lbuild_expression_end
|
||||
|
||||
.Lbuild_expression_end:
|
||||
lw a0, 16(sp)
|
||||
add s1, s1, a0
|
||||
|
||||
# Epilogue.
|
||||
lw ra, 28(sp)
|
||||
lw s0, 24(sp)
|
||||
addi sp, sp, 32
|
||||
ret
|
||||
|
||||
# Compiles a statement beginning with an identifier.
|
||||
#
|
||||
# Left values should be variables named "loca n", where n is the offset
|
||||
# of the variable on the stack, like loca8 or loca4.
|
||||
.type _compile_identifier, @function
|
||||
_compile_identifier:
|
||||
# Prologue.
|
||||
addi sp, sp, -32
|
||||
sw ra, 28(sp)
|
||||
sw s0, 24(sp)
|
||||
addi s0, sp, 32
|
||||
|
||||
call _read_token
|
||||
|
||||
# Save the pointer to the identifier and its length on the stack.
|
||||
sw s1, 20(sp)
|
||||
sw a0, 16(sp)
|
||||
|
||||
add s1, s1, a0
|
||||
call _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)
|
||||
|
||||
add s1, s1, a0 # Skip that token.
|
||||
call _skip_spaces
|
||||
|
||||
li t0, 0x3d3a # :=
|
||||
sw t0, 4(sp)
|
||||
lw a0, 12(sp)
|
||||
lw a1, 8(sp)
|
||||
addi a2, sp, 4
|
||||
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
|
||||
|
||||
.Lcompile_identifier_call:
|
||||
lw a0, 20(sp)
|
||||
lw a1, 16(sp)
|
||||
call _compile_call
|
||||
|
||||
j .Lcompile_identifier_end
|
||||
|
||||
.Lcompile_identifier_assign:
|
||||
call _build_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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
j .Lcompile_identifier_end
|
||||
|
||||
.Lcompile_identifier_end:
|
||||
# Epilogue.
|
||||
lw ra, 28(sp)
|
||||
lw s0, 24(sp)
|
||||
addi sp, sp, 32
|
||||
ret
|
||||
|
||||
# Compiles a procedure call. Expects s1 to point to the first argument.
|
||||
# a0 - Pointer to the procedure name.
|
||||
# a1 - Length of the procedure name.
|
||||
#
|
||||
# Returns the procedure result in a0.
|
||||
.type _compile_call, @function
|
||||
_compile_call:
|
||||
# Prologue.
|
||||
addi sp, sp, -32
|
||||
sw ra, 28(sp)
|
||||
sw s0, 24(sp)
|
||||
addi s0, sp, 32
|
||||
|
||||
sw a0, 20(sp)
|
||||
sw a1, 16(sp)
|
||||
sw zero, 12(sp) # Argument count for a procedure call.
|
||||
|
||||
.Lcompile_call_paren:
|
||||
call _skip_spaces
|
||||
call _read_token
|
||||
lbu t0, (s1)
|
||||
li t1, 0x29 # )
|
||||
beq t0, t1, .Lcompile_call_complete
|
||||
|
||||
.Lcompile_call_argument:
|
||||
call _build_expression
|
||||
|
||||
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
|
||||
|
||||
lw t0, 12(sp) # Argument count for a procedure call.
|
||||
|
||||
# Only 8 arguments are supported with a0-a7.
|
||||
# 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
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
call _skip_spaces
|
||||
call _read_token
|
||||
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)
|
||||
|
||||
addi s1, s1, 1 # Skip the comma between the arguments.
|
||||
j .Lcompile_call_argument
|
||||
|
||||
.Lcompile_call_complete:
|
||||
sw zero, 12(sp)
|
||||
|
||||
.Lcompile_call_restore:
|
||||
# Just go through all a0-a7 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
|
||||
bgt t0, t1, .Lcompile_call_perform
|
||||
|
||||
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, 84
|
||||
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
|
||||
|
||||
lw t0, 12(sp) # Increment.
|
||||
addi t0, t0, 1
|
||||
sw t0, 12(sp)
|
||||
|
||||
j .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
|
||||
|
||||
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
|
||||
|
||||
call _skip_spaces
|
||||
addi s1, s1, 1 # Skip the close paren.
|
||||
|
||||
# Epilogue.
|
||||
lw ra, 28(sp)
|
||||
lw s0, 24(sp)
|
||||
addi sp, sp, 32
|
||||
ret
|
||||
|
||||
# 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.
|
||||
.type _read_token, @function
|
||||
@ -53,7 +372,7 @@ _read_token:
|
||||
add t1, s1, t6
|
||||
lbu a0, (t1) # a0 = Current character.
|
||||
|
||||
call is_alnum
|
||||
call _is_alnum
|
||||
|
||||
beqz a0, .Ltoken_character_end
|
||||
lw t6, 4(sp)
|
||||
@ -150,7 +469,7 @@ _compile_assembly:
|
||||
# Write the source to the standard output.
|
||||
mv a0, s1
|
||||
lw a1, 4(sp)
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
lw t0, 4(sp)
|
||||
add s1, s1, t0
|
||||
@ -159,7 +478,7 @@ _compile_assembly:
|
||||
sb t0, 0(sp)
|
||||
addi a0, sp, 0
|
||||
li a1, 1
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
addi s1, s1, 1 # Skip the new line.
|
||||
|
||||
@ -189,7 +508,7 @@ _compile_program:
|
||||
|
||||
addi a0, sp, 8
|
||||
li a1, 15
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
addi s1, s1, 8 # program\n.
|
||||
|
||||
@ -221,14 +540,14 @@ _compile_constant_section:
|
||||
|
||||
addi a0, sp, 4
|
||||
li a1, 17
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
addi s1, s1, 6 # const\n.
|
||||
|
||||
.Lcompile_constant_section_item:
|
||||
call _skip_spaces
|
||||
lbu a0, (s1)
|
||||
call is_upper
|
||||
call _is_upper
|
||||
beqz a0, .Lcompile_constant_section_end
|
||||
|
||||
call _compile_constant
|
||||
@ -254,7 +573,7 @@ _compile_constant:
|
||||
mv a1, a0 # The identifier length from _read_token should be in a1.
|
||||
mv a0, s1 # Save the identifier pointer before advancing it.
|
||||
add s1, s1, a1
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
call _skip_spaces
|
||||
call _read_token
|
||||
@ -267,7 +586,7 @@ _compile_constant:
|
||||
sw t0, 0(sp)
|
||||
mv a0, sp
|
||||
li a1, 8
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
call _skip_spaces
|
||||
call _read_token
|
||||
@ -275,13 +594,13 @@ _compile_constant:
|
||||
mv a1, a0 # The literal length from _read_token should be in a1.
|
||||
mv a0, s1 # Save the literal pointer before advancing it.
|
||||
add s1, s1, a1
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, '\n'
|
||||
sw t0, 4(sp)
|
||||
addi a0, sp, 4
|
||||
li a1, 1
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
# Epilogue.
|
||||
lw ra, 12(sp)
|
||||
@ -309,14 +628,14 @@ _compile_variable_section:
|
||||
|
||||
addi a0, sp, 0
|
||||
li a1, 14
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
addi s1, s1, 4 # var\n.
|
||||
|
||||
.Lcompile_variable_section_item:
|
||||
call _skip_spaces
|
||||
lbu a0, (s1)
|
||||
call is_lower
|
||||
call _is_lower
|
||||
beqz a0, .Lcompile_variable_section_end
|
||||
|
||||
call _compile_variable
|
||||
@ -371,11 +690,11 @@ _compile_variable:
|
||||
sw t0, 8(sp)
|
||||
addi a0, sp, 8
|
||||
li a1, 6
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
lw a0, 28(sp)
|
||||
lw a1, 24(sp)
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, 0x0a74 # t\n
|
||||
sw t0, 12(sp)
|
||||
@ -385,7 +704,7 @@ _compile_variable:
|
||||
sw t0, 4(sp)
|
||||
addi a0, sp, 4
|
||||
li a1, 10
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
# .size identifier, size
|
||||
li t0, 0x2065 # e_
|
||||
@ -394,32 +713,32 @@ _compile_variable:
|
||||
sw t0, 8(sp)
|
||||
addi a0, sp, 8
|
||||
li a1, 6
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
lw a0, 28(sp)
|
||||
lw a1, 24(sp)
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, 0x202c # ,
|
||||
sw t0, 12(sp)
|
||||
addi a0, sp, 12
|
||||
li a1, 2
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
lw a0, 20(sp)
|
||||
lw a1, 16(sp)
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, 0x0a # \n
|
||||
sw t0, 12(sp)
|
||||
addi a0, sp, 12
|
||||
li a1, 1
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
# identifier: .zero size
|
||||
lw a0, 28(sp)
|
||||
lw a1, 24(sp)
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, 0x206f7265 # ero_
|
||||
sw t0, 12(sp)
|
||||
@ -427,17 +746,17 @@ _compile_variable:
|
||||
sw t0, 8(sp)
|
||||
addi a0, sp, 8
|
||||
li a1, 8
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
lw a0, 20(sp)
|
||||
lw a1, 16(sp)
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, 0x0a # \n
|
||||
sw t0, 12(sp)
|
||||
addi a0, sp, 12
|
||||
li a1, 1
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
# Epilogue.
|
||||
lw ra, 36(sp)
|
||||
@ -466,11 +785,11 @@ _compile_procedure:
|
||||
sw t0, 8(sp)
|
||||
addi a0, sp, 8
|
||||
li a1, 6
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
lw a0, 20(sp)
|
||||
lw a1, 16(sp)
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, 0x0a6e6f69 # ion\n
|
||||
sw t0, 12(sp)
|
||||
@ -480,17 +799,17 @@ _compile_procedure:
|
||||
sw t0, 4(sp)
|
||||
addi a0, sp, 4
|
||||
li a1, 12
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
lw a0, 20(sp)
|
||||
lw a1, 16(sp)
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, 0x0a3a # :\n
|
||||
sw t0, 12(sp)
|
||||
addi a0, sp, 12
|
||||
li a1, 2
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
call _skip_spaces
|
||||
addi s1, s1, 1 # Skip opening argument paren.
|
||||
@ -521,24 +840,24 @@ _compile_procedure:
|
||||
sw t0, 12(sp)
|
||||
addi a0, sp, 12
|
||||
li a1, 4
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, 0x2c707320 # _sp,
|
||||
sw t0, 12(sp)
|
||||
|
||||
addi a0, sp, 12
|
||||
li a1, 4
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
addi a0, sp, 12
|
||||
li a1, 4
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, 0x0a36392d # -96\n
|
||||
sw t0, 12(sp)
|
||||
addi a0, sp, 12
|
||||
li a1, 4
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, 0x0a29 # )\n
|
||||
sw t0, 12(sp)
|
||||
@ -550,7 +869,7 @@ _compile_procedure:
|
||||
sw t0, 0(sp)
|
||||
addi a0, sp, 0
|
||||
li a1, 14
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, 0x0a29 # )\n
|
||||
sw t0, 12(sp)
|
||||
@ -562,7 +881,7 @@ _compile_procedure:
|
||||
sw t0, 0(sp)
|
||||
addi a0, sp, 0
|
||||
li a1, 14
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, 0x0a363920 # _96\n
|
||||
sw t0, 12(sp)
|
||||
@ -574,7 +893,7 @@ _compile_procedure:
|
||||
sw t0, 0(sp)
|
||||
addi a0, sp, 0
|
||||
li a1, 16
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
# Generate the body of the procedure.
|
||||
.Lcompile_procedure_body:
|
||||
@ -586,7 +905,7 @@ _compile_procedure:
|
||||
mv a0, s1
|
||||
addi a1, sp, 8
|
||||
li a2, 4
|
||||
call memcmp
|
||||
call _memcmp
|
||||
|
||||
beqz a0, .Lcompile_procedure_end
|
||||
|
||||
@ -608,7 +927,7 @@ _compile_procedure:
|
||||
sw t0, 0(sp)
|
||||
addi a0, sp, 0
|
||||
li a1, 14
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, 0x0a29 # )\n
|
||||
sw t0, 12(sp)
|
||||
@ -620,36 +939,36 @@ _compile_procedure:
|
||||
sw t0, 0(sp)
|
||||
addi a0, sp, 0
|
||||
li a1, 14
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, 0x69646461 # addi
|
||||
sw t0, 12(sp)
|
||||
addi a0, sp, 12
|
||||
li a1, 4
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, 0x2c707320 # _sp,
|
||||
sw t0, 12(sp)
|
||||
|
||||
addi a0, sp, 12
|
||||
li a1, 4
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
addi a0, sp, 12
|
||||
li a1, 4
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, 0x0a3639 # 96\n
|
||||
sw t0, 12(sp)
|
||||
addi a0, sp, 12
|
||||
li a1, 3
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, 0x0a746572 # ret\n
|
||||
sw t0, 12(sp)
|
||||
addi a0, sp, 12
|
||||
li a1, 4
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
# Epilogue.
|
||||
lw ra, 28(sp)
|
||||
@ -726,7 +1045,7 @@ _compile_line:
|
||||
mv a0, s1
|
||||
addi a1, sp, 12
|
||||
li a2, 8
|
||||
call memcmp
|
||||
call _memcmp
|
||||
beqz a0, .Lcompile_line_program
|
||||
|
||||
li t0, 0x0a74 # t\n
|
||||
@ -736,7 +1055,7 @@ _compile_line:
|
||||
mv a0, s1
|
||||
addi a1, sp, 12
|
||||
li a2, 6
|
||||
call memcmp
|
||||
call _memcmp
|
||||
beqz a0, .Lcompile_line_const
|
||||
|
||||
li t0, 0x0a726176 # var\n
|
||||
@ -744,7 +1063,7 @@ _compile_line:
|
||||
mv a0, s1
|
||||
addi a1, sp, 16
|
||||
li a2, 4
|
||||
call memcmp
|
||||
call _memcmp
|
||||
beqz a0, .Lcompile_line_var
|
||||
|
||||
li t0, 0x20 # _
|
||||
@ -754,7 +1073,7 @@ _compile_line:
|
||||
mv a0, s1
|
||||
addi a1, sp, 12
|
||||
li a2, 5
|
||||
call memcmp
|
||||
call _memcmp
|
||||
beqz a0, .Lcompile_line_procedure
|
||||
|
||||
li t0, 0x0a6e # n\n
|
||||
@ -764,7 +1083,7 @@ _compile_line:
|
||||
mv a0, s1
|
||||
addi a1, sp, 12
|
||||
li a2, 6
|
||||
call memcmp
|
||||
call _memcmp
|
||||
beqz a0, .Lcompile_line_begin
|
||||
|
||||
li t0, 0x2e646e65 # end.
|
||||
@ -772,11 +1091,27 @@ _compile_line:
|
||||
mv a0, s1
|
||||
addi a1, sp, 16
|
||||
li a2, 4
|
||||
call memcmp
|
||||
call _memcmp
|
||||
beqz a0, .Lcompile_line_exit
|
||||
|
||||
li t0, 0x61636f6c # loca
|
||||
sw t0, 16(sp)
|
||||
mv a0, s1
|
||||
addi a1, sp, 16
|
||||
li a2, 4
|
||||
call _memcmp
|
||||
beqz a0, .Lcompile_line_identifier
|
||||
|
||||
lbu t0, (s1)
|
||||
li t1, '_'
|
||||
beq t0, t1, .Lcompile_line_identifier
|
||||
|
||||
j .Lcompile_line_unchanged # Else.
|
||||
|
||||
.Lcompile_line_identifier:
|
||||
call _compile_identifier
|
||||
j .Lcompile_line_section
|
||||
|
||||
.Lcompile_line_exit:
|
||||
call _compile_exit
|
||||
j .Lcompile_line_section
|
||||
@ -796,12 +1131,6 @@ _compile_line:
|
||||
j .Lcompile_line_end
|
||||
|
||||
.Lcompile_line_var:
|
||||
|
||||
/* DEBUG
|
||||
mv a0, s1
|
||||
li a1, 20
|
||||
call write_error */
|
||||
|
||||
call _compile_variable_section
|
||||
j .Lcompile_line_section
|
||||
|
||||
@ -853,7 +1182,7 @@ _compile_text_section:
|
||||
|
||||
addi a0, sp, 0
|
||||
li a1, 15
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
# Epilogue.
|
||||
lw ra, 20(sp)
|
||||
@ -888,7 +1217,7 @@ _compile_entry_point:
|
||||
sw t0, 24(sp)
|
||||
addi a0, sp, 24
|
||||
li a1, 32
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
addi s1, s1, 6 # Skip begin\n.
|
||||
|
||||
@ -925,7 +1254,7 @@ _compile_exit:
|
||||
sw t0, 28(sp)
|
||||
addi a0, sp, 28
|
||||
li a1, 25
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
addi s1, s1, 4 # Skip end.
|
||||
call _skip_spaces # Read the possible new line at the end of the file.
|
||||
@ -986,7 +1315,7 @@ _start:
|
||||
la a0, source_code
|
||||
la a1, SOURCE_BUFFER_SIZE # Buffer size.
|
||||
lw a1, (a1)
|
||||
call read_file
|
||||
call _read_file
|
||||
|
||||
la s1, source_code # s1 = Source code position.
|
||||
call _compile
|
||||
|
@ -1,12 +0,0 @@
|
||||
program
|
||||
|
||||
import dummy
|
||||
|
||||
var source_code: [2048]Byte
|
||||
|
||||
begin
|
||||
read_file(source_code, 2048);
|
||||
|
||||
s1 := source_code;
|
||||
|
||||
end.
|
491
boot/stage2.elna
491
boot/stage2.elna
@ -9,6 +9,293 @@ var
|
||||
|
||||
.section .text
|
||||
|
||||
# Evalutes an expression and saves the result in a0.
|
||||
proc _build_expression()
|
||||
begin
|
||||
_skip_spaces()
|
||||
call _read_token
|
||||
sw s1, 20(sp)
|
||||
sw a0, 16(sp)
|
||||
|
||||
# Integer literal.
|
||||
addi a0, s1, 0
|
||||
lb a0, (a0)
|
||||
call _is_digit
|
||||
bnez a0, .Lbuild_expression_number_literal
|
||||
|
||||
# Named identifier.
|
||||
li t0, 0x202c30 # 0,_
|
||||
sw t0, 12(sp)
|
||||
li t0, 0x6120616c # la a
|
||||
sw t0, 8(sp)
|
||||
addi a0, sp, 8
|
||||
li a1, 7
|
||||
call _write_out
|
||||
|
||||
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
|
||||
|
||||
j .Lbuild_expression_end
|
||||
|
||||
.Lbuild_expression_number_literal:
|
||||
li t0, 0x202c30 # 0,_
|
||||
sw t0, 12(sp)
|
||||
li t0, 0x6120696c # li a
|
||||
sw t0, 8(sp)
|
||||
addi a0, sp, 8
|
||||
li a1, 7
|
||||
call _write_out
|
||||
|
||||
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
|
||||
|
||||
j .Lbuild_expression_end
|
||||
|
||||
.Lbuild_expression_end:
|
||||
lw a0, 16(sp)
|
||||
add s1, s1, a0
|
||||
end
|
||||
|
||||
# Compiles a statement beginning with an identifier.
|
||||
#
|
||||
# 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()
|
||||
begin
|
||||
call _read_token
|
||||
|
||||
# Save the pointer to the identifier and its length on the stack.
|
||||
sw s1, 20(sp)
|
||||
sw a0, 16(sp)
|
||||
|
||||
add s1, s1, a0
|
||||
_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)
|
||||
|
||||
add s1, s1, a0 # Skip that token.
|
||||
_skip_spaces()
|
||||
|
||||
li t0, 0x3d3a # :=
|
||||
sw t0, 4(sp)
|
||||
lw a0, 12(sp)
|
||||
lw a1, 8(sp)
|
||||
addi a2, sp, 4
|
||||
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
|
||||
|
||||
.Lcompile_identifier_call:
|
||||
lw a0, 20(sp)
|
||||
lw a1, 16(sp)
|
||||
call _compile_call
|
||||
|
||||
j .Lcompile_identifier_end
|
||||
|
||||
.Lcompile_identifier_assign:
|
||||
call _build_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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
j .Lcompile_identifier_end
|
||||
|
||||
.Lcompile_identifier_end:
|
||||
end
|
||||
|
||||
# Compiles a procedure call. Expects s1 to point to the first argument.
|
||||
# a0 - Pointer to the procedure name.
|
||||
# a1 - Length of the procedure name.
|
||||
#
|
||||
# Returns the procedure result in a0.
|
||||
proc _compile_call()
|
||||
begin
|
||||
sw a0, 20(sp)
|
||||
sw a1, 16(sp)
|
||||
sw zero, 12(sp) # 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
|
||||
|
||||
.Lcompile_call_argument:
|
||||
call _build_expression
|
||||
|
||||
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
|
||||
|
||||
lw t0, 12(sp) # Argument count for a procedure call.
|
||||
|
||||
# Only 8 arguments are supported with a0-a7.
|
||||
# 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
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
_skip_spaces()
|
||||
call _read_token
|
||||
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)
|
||||
|
||||
_advance(1) # Skip the comma between the arguments.
|
||||
j .Lcompile_call_argument
|
||||
|
||||
.Lcompile_call_complete:
|
||||
sw zero, 12(sp)
|
||||
|
||||
.Lcompile_call_restore:
|
||||
# Just go through all a0-a7 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
|
||||
bgt t0, t1, .Lcompile_call_perform
|
||||
|
||||
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, 84
|
||||
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
|
||||
|
||||
lw t0, 12(sp) # Increment.
|
||||
addi t0, t0, 1
|
||||
sw t0, 12(sp)
|
||||
|
||||
j .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
|
||||
|
||||
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
|
||||
|
||||
_skip_spaces()
|
||||
_advance(1) # Skip the close paren.
|
||||
end
|
||||
|
||||
# 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()
|
||||
@ -45,7 +332,7 @@ begin
|
||||
add t1, s1, t6
|
||||
lbu a0, (t1) # a0 = Current character.
|
||||
|
||||
call is_alnum
|
||||
call _is_alnum
|
||||
|
||||
beqz a0, .Ltoken_character_end
|
||||
lw t6, 4(sp)
|
||||
@ -90,7 +377,7 @@ begin
|
||||
|
||||
j .Lspace_loop_end
|
||||
.Lspace_loop_repeat:
|
||||
addi s1, s1, 1
|
||||
_advance(1)
|
||||
j .Lspace_loop_do
|
||||
|
||||
.Lspace_loop_end:
|
||||
@ -108,7 +395,7 @@ begin
|
||||
j .Lskip_indentation_end
|
||||
|
||||
.Lskip_indentation_skip:
|
||||
addi s1, s1, 1
|
||||
_advance(1)
|
||||
j .Lskip_indentation_do
|
||||
|
||||
.Lskip_indentation_end:
|
||||
@ -119,7 +406,7 @@ end
|
||||
proc _skip_comment()
|
||||
begin
|
||||
add s1, s1, a0
|
||||
addi s1, s1, 1 # Skip the new line.
|
||||
_advance(1) # Skip the new line.
|
||||
end
|
||||
|
||||
# Parameters:
|
||||
@ -131,7 +418,7 @@ begin
|
||||
# Write the source to the standard output.
|
||||
mv a0, s1
|
||||
lw a1, 4(sp)
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
lw t0, 4(sp)
|
||||
add s1, s1, t0
|
||||
@ -140,9 +427,9 @@ begin
|
||||
sb t0, 0(sp)
|
||||
addi a0, sp, 0
|
||||
li a1, 1
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
addi s1, s1, 1 # Skip the new line.
|
||||
_advance(1) # Skip the new line.
|
||||
end
|
||||
|
||||
proc _compile_program()
|
||||
@ -159,9 +446,9 @@ begin
|
||||
|
||||
addi a0, sp, 8
|
||||
li a1, 15
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
addi s1, s1, 8 # program\n.
|
||||
_advance(8) # program\n.
|
||||
end
|
||||
|
||||
proc _compile_constant_section()
|
||||
@ -180,14 +467,14 @@ begin
|
||||
|
||||
addi a0, sp, 4
|
||||
li a1, 17
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
addi s1, s1, 6 # const\n.
|
||||
_advance(6) # const\n.
|
||||
|
||||
.Lcompile_constant_section_item:
|
||||
call _skip_spaces
|
||||
_skip_spaces()
|
||||
lbu a0, (s1)
|
||||
call is_upper
|
||||
call _is_upper
|
||||
beqz a0, .Lcompile_constant_section_end
|
||||
|
||||
call _compile_constant
|
||||
@ -203,11 +490,11 @@ begin
|
||||
mv a1, a0 # The identifier length from _read_token should be in a1.
|
||||
mv a0, s1 # Save the identifier pointer before advancing it.
|
||||
add s1, s1, a1
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
call _skip_spaces
|
||||
_skip_spaces()
|
||||
call _read_token
|
||||
addi s1, s1, 2 # Skip the assignment sign.
|
||||
_advance(2) # Skip the assignment sign.
|
||||
|
||||
# : .long
|
||||
li t0, 0x20676e6f # ong_
|
||||
@ -216,21 +503,21 @@ begin
|
||||
sw t0, 0(sp)
|
||||
mv a0, sp
|
||||
li a1, 8
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
call _skip_spaces
|
||||
_skip_spaces()
|
||||
call _read_token
|
||||
|
||||
mv a1, a0 # The literal length from _read_token should be in a1.
|
||||
mv a0, s1 # Save the literal pointer before advancing it.
|
||||
add s1, s1, a1
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, '\n'
|
||||
sw t0, 4(sp)
|
||||
addi a0, sp, 4
|
||||
li a1, 1
|
||||
call write_out
|
||||
call _write_out
|
||||
end
|
||||
|
||||
proc _compile_variable_section()
|
||||
@ -247,14 +534,14 @@ begin
|
||||
|
||||
addi a0, sp, 0
|
||||
li a1, 14
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
addi s1, s1, 4 # var\n.
|
||||
_advance(4) # var\n.
|
||||
|
||||
.Lcompile_variable_section_item:
|
||||
call _skip_spaces
|
||||
_skip_spaces()
|
||||
lbu a0, (s1)
|
||||
call is_lower
|
||||
call _is_lower
|
||||
beqz a0, .Lcompile_variable_section_end
|
||||
|
||||
call _compile_variable
|
||||
@ -272,11 +559,11 @@ begin
|
||||
sw a0, 24(sp)
|
||||
add s1, s1, a0
|
||||
|
||||
call _skip_spaces
|
||||
addi s1, s1, 1 # Skip the colon in front of the type.
|
||||
_skip_spaces()
|
||||
_advance(1) # Skip the colon in front of the type.
|
||||
|
||||
call _skip_spaces
|
||||
addi s1, s1, 1 # Skip the opening bracket.
|
||||
_skip_spaces()
|
||||
_advance(1) # Skip the opening bracket.
|
||||
|
||||
call _read_token
|
||||
|
||||
@ -285,10 +572,10 @@ begin
|
||||
sw a0, 16(sp)
|
||||
add s1, s1, a0
|
||||
|
||||
call _skip_spaces
|
||||
addi s1, s1, 1 # Skip the closing bracket.
|
||||
_skip_spaces()
|
||||
_advance(1) # Skip the closing bracket.
|
||||
|
||||
call _skip_spaces
|
||||
_skip_spaces()
|
||||
call _read_token
|
||||
add s1, s1, a0 # Skip the type.
|
||||
|
||||
@ -299,11 +586,11 @@ begin
|
||||
sw t0, 8(sp)
|
||||
addi a0, sp, 8
|
||||
li a1, 6
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
lw a0, 28(sp)
|
||||
lw a1, 24(sp)
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, 0x0a74 # t\n
|
||||
sw t0, 12(sp)
|
||||
@ -313,7 +600,7 @@ begin
|
||||
sw t0, 4(sp)
|
||||
addi a0, sp, 4
|
||||
li a1, 10
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
# .size identifier, size
|
||||
li t0, 0x2065 # e_
|
||||
@ -322,32 +609,32 @@ begin
|
||||
sw t0, 8(sp)
|
||||
addi a0, sp, 8
|
||||
li a1, 6
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
lw a0, 28(sp)
|
||||
lw a1, 24(sp)
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, 0x202c # ,
|
||||
sw t0, 12(sp)
|
||||
addi a0, sp, 12
|
||||
li a1, 2
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
lw a0, 20(sp)
|
||||
lw a1, 16(sp)
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, 0x0a # \n
|
||||
sw t0, 12(sp)
|
||||
addi a0, sp, 12
|
||||
li a1, 1
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
# identifier: .zero size
|
||||
lw a0, 28(sp)
|
||||
lw a1, 24(sp)
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, 0x206f7265 # ero_
|
||||
sw t0, 12(sp)
|
||||
@ -355,22 +642,22 @@ begin
|
||||
sw t0, 8(sp)
|
||||
addi a0, sp, 8
|
||||
li a1, 8
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
lw a0, 20(sp)
|
||||
lw a1, 16(sp)
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, 0x0a # \n
|
||||
sw t0, 12(sp)
|
||||
addi a0, sp, 12
|
||||
li a1, 1
|
||||
call write_out
|
||||
call _write_out
|
||||
end
|
||||
|
||||
proc _compile_procedure()
|
||||
begin
|
||||
addi s1, s1, 5 # Skip proc_
|
||||
_advance(5) # Skip proc_
|
||||
call _read_token
|
||||
sw s1, 20(sp)
|
||||
sw a0, 16(sp)
|
||||
@ -383,11 +670,11 @@ begin
|
||||
sw t0, 8(sp)
|
||||
addi a0, sp, 8
|
||||
li a1, 6
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
lw a0, 20(sp)
|
||||
lw a1, 16(sp)
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, 0x0a6e6f69 # ion\n
|
||||
sw t0, 12(sp)
|
||||
@ -397,22 +684,22 @@ begin
|
||||
sw t0, 4(sp)
|
||||
addi a0, sp, 4
|
||||
li a1, 12
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
lw a0, 20(sp)
|
||||
lw a1, 16(sp)
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, 0x0a3a # :\n
|
||||
sw t0, 12(sp)
|
||||
addi a0, sp, 12
|
||||
li a1, 2
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
call _skip_spaces
|
||||
addi s1, s1, 1 # Skip opening argument paren.
|
||||
call _skip_spaces
|
||||
addi s1, s1, 1 # Skip closing argument paren.
|
||||
_skip_spaces()
|
||||
_advance(1) # Skip opening argument paren.
|
||||
_skip_spaces()
|
||||
_advance(1) # Skip closing argument paren.
|
||||
|
||||
li t0, 0x6e # n
|
||||
sw t0, 12(sp)
|
||||
@ -422,7 +709,7 @@ begin
|
||||
# Skip all declarations until we find the "begin" keyword, denoting the
|
||||
# beginning of the procedure body.
|
||||
.Lcompile_procedure_begin:
|
||||
call _skip_spaces
|
||||
_skip_spaces()
|
||||
call _read_token
|
||||
|
||||
mv a1, a0
|
||||
@ -438,24 +725,24 @@ begin
|
||||
sw t0, 12(sp)
|
||||
addi a0, sp, 12
|
||||
li a1, 4
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, 0x2c707320 # _sp,
|
||||
sw t0, 12(sp)
|
||||
|
||||
addi a0, sp, 12
|
||||
li a1, 4
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
addi a0, sp, 12
|
||||
li a1, 4
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, 0x0a36392d # -96\n
|
||||
sw t0, 12(sp)
|
||||
addi a0, sp, 12
|
||||
li a1, 4
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, 0x0a29 # )\n
|
||||
sw t0, 12(sp)
|
||||
@ -467,7 +754,7 @@ begin
|
||||
sw t0, 0(sp)
|
||||
addi a0, sp, 0
|
||||
li a1, 14
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, 0x0a29 # )\n
|
||||
sw t0, 12(sp)
|
||||
@ -479,7 +766,7 @@ begin
|
||||
sw t0, 0(sp)
|
||||
addi a0, sp, 0
|
||||
li a1, 14
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, 0x0a363920 # _96\n
|
||||
sw t0, 12(sp)
|
||||
@ -491,11 +778,11 @@ begin
|
||||
sw t0, 0(sp)
|
||||
addi a0, sp, 0
|
||||
li a1, 16
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
# Generate the body of the procedure.
|
||||
.Lcompile_procedure_body:
|
||||
call _skip_indentation
|
||||
_skip_indentation()
|
||||
call _read_line
|
||||
sw a0, 12(sp)
|
||||
li t0, 0x0a646e65 # end\n
|
||||
@ -503,7 +790,7 @@ begin
|
||||
mv a0, s1
|
||||
addi a1, sp, 8
|
||||
li a2, 4
|
||||
call memcmp
|
||||
call _memcmp
|
||||
|
||||
beqz a0, .Lcompile_procedure_end
|
||||
|
||||
@ -525,7 +812,7 @@ begin
|
||||
sw t0, 0(sp)
|
||||
addi a0, sp, 0
|
||||
li a1, 14
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, 0x0a29 # )\n
|
||||
sw t0, 12(sp)
|
||||
@ -537,36 +824,36 @@ begin
|
||||
sw t0, 0(sp)
|
||||
addi a0, sp, 0
|
||||
li a1, 14
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, 0x69646461 # addi
|
||||
sw t0, 12(sp)
|
||||
addi a0, sp, 12
|
||||
li a1, 4
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, 0x2c707320 # _sp,
|
||||
sw t0, 12(sp)
|
||||
|
||||
addi a0, sp, 12
|
||||
li a1, 4
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
addi a0, sp, 12
|
||||
li a1, 4
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, 0x0a3639 # 96\n
|
||||
sw t0, 12(sp)
|
||||
addi a0, sp, 12
|
||||
li a1, 3
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
li t0, 0x0a746572 # ret\n
|
||||
sw t0, 12(sp)
|
||||
addi a0, sp, 12
|
||||
li a1, 4
|
||||
call write_out
|
||||
call _write_out
|
||||
end
|
||||
|
||||
# Compares two string, which of one has a length, the other one is null-terminated.
|
||||
@ -632,7 +919,7 @@ begin
|
||||
mv a0, s1
|
||||
addi a1, sp, 12
|
||||
li a2, 8
|
||||
call memcmp
|
||||
call _memcmp
|
||||
beqz a0, .Lcompile_line_program
|
||||
|
||||
li t0, 0x0a74 # t\n
|
||||
@ -642,7 +929,7 @@ begin
|
||||
mv a0, s1
|
||||
addi a1, sp, 12
|
||||
li a2, 6
|
||||
call memcmp
|
||||
call _memcmp
|
||||
beqz a0, .Lcompile_line_const
|
||||
|
||||
li t0, 0x0a726176 # var\n
|
||||
@ -650,7 +937,7 @@ begin
|
||||
mv a0, s1
|
||||
addi a1, sp, 16
|
||||
li a2, 4
|
||||
call memcmp
|
||||
call _memcmp;
|
||||
beqz a0, .Lcompile_line_var
|
||||
|
||||
li t0, 0x20 # _
|
||||
@ -660,7 +947,7 @@ begin
|
||||
mv a0, s1
|
||||
addi a1, sp, 12
|
||||
li a2, 5
|
||||
call memcmp
|
||||
call _memcmp
|
||||
beqz a0, .Lcompile_line_procedure
|
||||
|
||||
li t0, 0x0a6e # n\n
|
||||
@ -670,7 +957,7 @@ begin
|
||||
mv a0, s1
|
||||
addi a1, sp, 12
|
||||
li a2, 6
|
||||
call memcmp
|
||||
call _memcmp
|
||||
beqz a0, .Lcompile_line_begin
|
||||
|
||||
li t0, 0x2e646e65 # end.
|
||||
@ -678,11 +965,27 @@ begin
|
||||
mv a0, s1
|
||||
addi a1, sp, 16
|
||||
li a2, 4
|
||||
call memcmp
|
||||
call _memcmp
|
||||
beqz a0, .Lcompile_line_exit
|
||||
|
||||
li t0, 0x61636f6c # loca
|
||||
sw t0, 16(sp)
|
||||
mv a0, s1
|
||||
addi a1, sp, 16
|
||||
li a2, 4
|
||||
call _memcmp
|
||||
beqz a0, .Lcompile_line_identifier
|
||||
|
||||
lbu t0, (s1)
|
||||
li t1, '_'
|
||||
beq t0, t1, .Lcompile_line_identifier
|
||||
|
||||
j .Lcompile_line_unchanged # Else.
|
||||
|
||||
.Lcompile_line_identifier:
|
||||
call _compile_identifier
|
||||
j .Lcompile_line_section
|
||||
|
||||
.Lcompile_line_exit:
|
||||
call _compile_exit
|
||||
j .Lcompile_line_section
|
||||
@ -702,12 +1005,6 @@ begin
|
||||
j .Lcompile_line_end
|
||||
|
||||
.Lcompile_line_var:
|
||||
|
||||
/* DEBUG
|
||||
mv a0, s1
|
||||
li a1, 20
|
||||
call write_error */
|
||||
|
||||
call _compile_variable_section
|
||||
j .Lcompile_line_section
|
||||
|
||||
@ -721,7 +1018,7 @@ begin
|
||||
j .Lcompile_line_section
|
||||
|
||||
.Lcompile_line_empty:
|
||||
addi s1, s1, 1
|
||||
_advance(1)
|
||||
j .Lcompile_line_section
|
||||
|
||||
.Lcompile_line_unchanged:
|
||||
@ -749,7 +1046,7 @@ begin
|
||||
|
||||
addi a0, sp, 0
|
||||
li a1, 15
|
||||
call write_out
|
||||
call _write_out
|
||||
end
|
||||
|
||||
proc _compile_entry_point()
|
||||
@ -773,9 +1070,9 @@ begin
|
||||
sw t0, 24(sp)
|
||||
addi a0, sp, 24
|
||||
li a1, 32
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
addi s1, s1, 6 # Skip begin\n.
|
||||
_advance(6) # Skip begin\n.
|
||||
end
|
||||
|
||||
proc _compile_exit()
|
||||
@ -799,10 +1096,10 @@ begin
|
||||
sw t0, 28(sp)
|
||||
addi a0, sp, 28
|
||||
li a1, 25
|
||||
call write_out
|
||||
call _write_out
|
||||
|
||||
addi s1, s1, 4 # Skip end.
|
||||
call _skip_spaces # Read the possible new line at the end of the file.
|
||||
_advance(4) # Skip end.
|
||||
_skip_spaces() # Read the possible new line at the end of the file.
|
||||
end
|
||||
|
||||
# Finds the end of the line and returns its length in a0.
|
||||
@ -829,7 +1126,7 @@ begin
|
||||
lbu t0, (s1) # t0 = Current character.
|
||||
beqz t0, .Lcompile_end # Exit the loop on the NUL character.
|
||||
|
||||
call _skip_indentation
|
||||
_skip_indentation()
|
||||
call _read_line
|
||||
call _compile_line
|
||||
|
||||
@ -837,13 +1134,25 @@ begin
|
||||
.Lcompile_end:
|
||||
end
|
||||
|
||||
# Returns the pointer to the current position in the source text in a0.
|
||||
proc _current()
|
||||
begin
|
||||
mv a0, s1
|
||||
end
|
||||
|
||||
# a0 is the number of bytes to advance in the source text.
|
||||
proc _advance()
|
||||
begin
|
||||
add s1, s1, a0
|
||||
end
|
||||
|
||||
# Entry point.
|
||||
begin
|
||||
# Read the source from the standard input.
|
||||
la a0, source_code
|
||||
la a1, SOURCE_BUFFER_SIZE # Buffer size.
|
||||
lw a1, (a1)
|
||||
call read_file
|
||||
call _read_file
|
||||
|
||||
la s1, source_code # s1 = Source code position.
|
||||
call _compile
|
||||
|
Loading…
x
Reference in New Issue
Block a user