Add symbol info for parameters and local variables

This commit is contained in:
Eugen Wissner 2025-05-10 23:24:03 +02:00
parent 890486532c
commit 707f983fe9
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
6 changed files with 467 additions and 212 deletions

View File

@ -20,3 +20,19 @@ task default: ['build/boot/stage2b', 'build/boot/stage2b.s', 'boot/stage2.elna']
diff_arguments = ['diff', '-Nur', '--text', previous_output, '-'] diff_arguments = ['diff', '-Nur', '--text', previous_output, '-']
Open3.pipeline(cat_arguments, compiler_arguments, diff_arguments) Open3.pipeline(cat_arguments, compiler_arguments, diff_arguments)
end end
file 'build/boot/test.s' => ['build/boot/stage1', 'boot/test.elna'] do |t|
source, exe = t.prerequisites.partition { |prerequisite| prerequisite.end_with? '.elna' }
File.open t.name, 'w' do |output|
assemble_stage output, exe, source
end
end
file 'build/boot/test' => ['build/boot/test.s', 'boot/common-boot.s'] do |t|
sh CROSS_GCC, '-nostdlib', '-o', t.name, *t.prerequisites
end
task test: 'build/boot/test' do |t|
sh QEMU, '-L', SYSROOT, t.prerequisites.first
end

View File

@ -62,3 +62,5 @@
# #
.equ TYPE_PRIMITIVE, 0x01 .equ TYPE_PRIMITIVE, 0x01
.equ TYPE_POINTER, 0x02 .equ TYPE_POINTER, 0x02
.equ INFO_PARAMETER, 0x10
.equ INFO_LOCAL, 0x20

View File

@ -85,8 +85,8 @@ source_code: .zero SOURCE_BUFFER_SIZE
.section .text .section .text
# Ignores the import. # Ignores the import.
.type _compile_import, @function .type compile_import, @function
_compile_import: compile_import:
# Prologue. # Prologue.
addi sp, sp, -24 addi sp, sp, -24
sw ra, 20(sp) sw ra, 20(sp)
@ -227,8 +227,8 @@ compile_binary_expression:
# a1 - Identifier length. # a1 - Identifier length.
# #
# Sets a0 to 1 if the identifier starts with "loca", otherwise to 0. # Sets a0 to 1 if the identifier starts with "loca", otherwise to 0.
.type _is_local_identifier, @function .type is_local_identifier, @function
_is_local_identifier: is_local_identifier:
# Prologue. # Prologue.
addi sp, sp, -16 addi sp, sp, -16
sw ra, 12(sp) sw ra, 12(sp)
@ -255,8 +255,8 @@ _is_local_identifier:
# a1 - Identifier length. # a1 - Identifier length.
# #
# Sets a0 to 1 if the identifier is a preserved register, otherwise to 0. # Sets a0 to 1 if the identifier is a preserved register, otherwise to 0.
.type _is_register_identifier, @function .type is_register_identifier, @function
_is_register_identifier: is_register_identifier:
# Prologue. # Prologue.
addi sp, sp, -8 addi sp, sp, -8
sw ra, 4(sp) sw ra, 4(sp)
@ -279,8 +279,8 @@ _is_register_identifier:
# Parameters: # Parameters:
# a0 - Identifier length. # a0 - Identifier length.
# a1 - Register number as character. # a1 - Register number as character.
.type _compile_identifier_expression, @function .type compile_identifier_expression, @function
_compile_identifier_expression: compile_identifier_expression:
# Prologue. # Prologue.
addi sp, sp, -32 addi sp, sp, -32
sw ra, 28(sp) sw ra, 28(sp)
@ -290,24 +290,32 @@ _compile_identifier_expression:
sw a0, 20(sp) # Identifier length. sw a0, 20(sp) # Identifier length.
sw a1, 16(sp) # Register number as character. sw a1, 16(sp) # Register number as character.
lw a0, 20(sp)
mv a1, s1
call symbol_table_find
sw a0, 12(sp)
mv a0, s1 mv a0, s1
lw a1, 20(sp) lw a1, 20(sp)
call _is_local_identifier call is_local_identifier
bnez a0, .Lcompile_identifier_expression_local bnez a0, .Lcompile_identifier_expression_local
mv a0, s1 mv a0, s1
lw a1, 20(sp) lw a1, 20(sp)
call _is_register_identifier call is_register_identifier
bnez a0, .Lcompile_identifier_expression_saved bnez a0, .Lcompile_identifier_expression_saved
lw t0, 12(sp)
bnez t0, .Lcompile_identifier_expression_defined
# Global identifier. # Global identifier.
lw t1, 16(sp) lw t1, 16(sp)
li t0, 0x00202c00 # \0,_ li t0, 0x00202c00 # \0,_
or t0, t0, t1 or t0, t0, t1
sw t0, 12(sp)
li t0, 0x6120616c # la a
sw t0, 8(sp) sw t0, 8(sp)
addi a0, sp, 8 li t0, 0x6120616c # la a
sw t0, 4(sp)
addi a0, sp, 4
li a1, 7 li a1, 7
call _write_out call _write_out
@ -326,26 +334,51 @@ _compile_identifier_expression:
li t0, 0x0a290061 # a\0)\n li t0, 0x0a290061 # a\0)\n
sll t2, t1, 8 sll t2, t1, 8
or t0, t0, t2 or t0, t0, t2
sw t0, 12(sp) sw t0, 8(sp)
li t0, 0x28202c00 # \0, ( li t0, 0x28202c00 # \0, (
or t0, t0, t1 or t0, t0, t1
sw t0, 4(sp)
li t0, 0x6120776c # lw a
sw t0, 0(sp)
addi a0, sp, 0
li a1, 12
call _write_out
j .Lcompile_identifier_expression_end
.Lcompile_identifier_expression_defined:
lw t1, 16(sp)
li t0, 0x00202c00 # \0,_
or t0, t0, t1
sw t0, 8(sp) sw t0, 8(sp)
li t0, 0x6120776c # lw a li t0, 0x6120776c # lw a
sw t0, 4(sp) sw t0, 4(sp)
addi a0, sp, 4 addi a0, sp, 4
li a1, 12 li a1, 7
call _write_out call _write_out
lw a0, 12(sp)
lw a0, 8(a0)
call _printi
li t0, 0x29707328 # (sp)
sw t0, 8(sp)
addi a0, sp, 8
li a1, 4
call _write_out
li a0, '\n'
call _put_char
j .Lcompile_identifier_expression_end j .Lcompile_identifier_expression_end
.Lcompile_identifier_expression_saved: .Lcompile_identifier_expression_saved:
li t0, 0x00202c00 # \0,_ li t0, 0x00202c00 # \0,_
lw t1, 16(sp) lw t1, 16(sp)
or t0, t0, t1 or t0, t0, t1
sw t0, 12(sp)
li t0, 0x6120766d # mv a
sw t0, 8(sp) sw t0, 8(sp)
addi a0, sp, 8 li t0, 0x6120766d # mv a
sw t0, 4(sp)
addi a0, sp, 4
li a1, 7 li a1, 7
call _write_out call _write_out
@ -362,10 +395,10 @@ _compile_identifier_expression:
lw t1, 16(sp) lw t1, 16(sp)
li t0, 0x00202c00 # \0,_ li t0, 0x00202c00 # \0,_
or t0, t0, t1 or t0, t0, t1
sw t0, 12(sp)
li t0, 0x6120776c # lw a
sw t0, 8(sp) sw t0, 8(sp)
addi a0, sp, 8 li t0, 0x6120776c # lw a
sw t0, 4(sp)
addi a0, sp, 4
li a1, 7 li a1, 7
call _write_out call _write_out
@ -376,8 +409,8 @@ _compile_identifier_expression:
call _write_out call _write_out
li t0, 0x29707328 # (sp) li t0, 0x29707328 # (sp)
sw t0, 12(sp) sw t0, 8(sp)
addi a0, sp, 12 addi a0, sp, 8
li a1, 4 li a1, 4
call _write_out call _write_out
li a0, '\n' li a0, '\n'
@ -431,7 +464,7 @@ _build_expression:
lw s1, 32(sp) lw s1, 32(sp)
lw a0, 28(sp) lw a0, 28(sp)
lw a1, 36(sp) lw a1, 36(sp)
call _compile_identifier_expression call compile_identifier_expression
j .Lbuild_expression_advance j .Lbuild_expression_advance
@ -485,7 +518,7 @@ _build_expression:
lw a0, 32(sp) lw a0, 32(sp)
lw a1, 28(sp) lw a1, 28(sp)
call _compile_call call compile_call
j .Lbuild_expression_end j .Lbuild_expression_end
@ -524,8 +557,8 @@ _build_expression:
# Parameters: # Parameters:
# a0 - Pointer to the identifier. # a0 - Pointer to the identifier.
# a1 - Identifier length. # a1 - Identifier length.
.type _compile_designator_expression, @function .type compile_designator_expression, @function
_compile_designator_expression: compile_designator_expression:
# Prologue. # Prologue.
addi sp, sp, -32 addi sp, sp, -32
sw ra, 28(sp) sw ra, 28(sp)
@ -537,12 +570,12 @@ _compile_designator_expression:
lw a0, 20(sp) lw a0, 20(sp)
lw a1, 16(sp) lw a1, 16(sp)
call _is_local_identifier call is_local_identifier
bnez a0, .Lcompile_designator_expression_local bnez a0, .Lcompile_designator_expression_local
lw a0, 20(sp) lw a0, 20(sp)
lw a1, 16(sp) lw a1, 16(sp)
call _is_register_identifier call is_register_identifier
bnez a0, .Lcompile_designator_expression_saved bnez a0, .Lcompile_designator_expression_saved
.Lcompile_designator_expression_local: .Lcompile_designator_expression_local:
@ -603,8 +636,8 @@ _compile_designator_expression:
# #
# Left values should be variables named "loca n", where n is the offset # 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.
.type _compile_identifier, @function .type compile_identifier, @function
_compile_identifier: compile_identifier:
# Prologue. # Prologue.
addi sp, sp, -32 addi sp, sp, -32
sw ra, 28(sp) sw ra, 28(sp)
@ -632,7 +665,7 @@ _compile_identifier:
.Lcompile_identifier_call: .Lcompile_identifier_call:
lw a0, 20(sp) lw a0, 20(sp)
lw a1, 16(sp) lw a1, 16(sp)
call _compile_call call compile_call
j .Lcompile_identifier_end j .Lcompile_identifier_end
@ -640,7 +673,7 @@ _compile_identifier:
call compile_binary_expression call compile_binary_expression
lw a0, 20(sp) lw a0, 20(sp)
lw a1, 16(sp) lw a1, 16(sp)
call _compile_designator_expression call compile_designator_expression
j .Lcompile_identifier_end j .Lcompile_identifier_end
@ -656,8 +689,8 @@ _compile_identifier:
# a1 - Length of the procedure name. # a1 - Length of the procedure name.
# #
# Returns the procedure result in a0. # Returns the procedure result in a0.
.type _compile_call, @function .type compile_call, @function
_compile_call: compile_call:
# Prologue. # Prologue.
addi sp, sp, -32 addi sp, sp, -32
sw ra, 28(sp) sw ra, 28(sp)
@ -748,8 +781,8 @@ _compile_call:
ret ret
# Walks through the procedure definitions. # Walks through the procedure definitions.
.type _compile_procedure_section, @function .type compile_procedure_section, @function
_compile_procedure_section: compile_procedure_section:
# Prologue. # Prologue.
addi sp, sp, -32 addi sp, sp, -32
sw ra, 28(sp) sw ra, 28(sp)
@ -764,7 +797,7 @@ _compile_procedure_section:
lw t1, 4(sp) lw t1, 4(sp)
bne t0, t1, .Lcompile_procedure_section_end bne t0, t1, .Lcompile_procedure_section_end
call _compile_procedure call compile_procedure
j .Lcompile_procedure_section_loop j .Lcompile_procedure_section_loop
@ -775,8 +808,8 @@ _compile_procedure_section:
addi sp, sp, 32 addi sp, sp, 32
ret ret
.type _compile_module_declaration, @function .type compile_module_declaration, @function
_compile_module_declaration: compile_module_declaration:
# Prologue. # Prologue.
addi sp, sp, -24 addi sp, sp, -24
sw ra, 20(sp) sw ra, 20(sp)
@ -799,8 +832,8 @@ _compile_module_declaration:
addi sp, sp, 24 addi sp, sp, 24
ret ret
.type _compile_constant_section, @function .type compile_constant_section, @function
_compile_constant_section: compile_constant_section:
# Prologue. # Prologue.
addi sp, sp, -32 addi sp, sp, -32
sw ra, 28(sp) sw ra, 28(sp)
@ -830,7 +863,7 @@ _compile_constant_section:
bne t0, t1, .Lcompile_constant_section_end bne t0, t1, .Lcompile_constant_section_end
lw s1, 20(sp) lw s1, 20(sp)
call _compile_constant call compile_constant
j .Lcompile_constant_section_item j .Lcompile_constant_section_item
.Lcompile_constant_section_end: .Lcompile_constant_section_end:
@ -840,8 +873,8 @@ _compile_constant_section:
addi sp, sp, 32 addi sp, sp, 32
ret ret
.type _compile_constant, @function .type compile_constant, @function
_compile_constant: compile_constant:
# Prologue. # Prologue.
addi sp, sp, -32 addi sp, sp, -32
sw ra, 28(sp) sw ra, 28(sp)
@ -886,8 +919,9 @@ _compile_constant:
addi sp, sp, 32 addi sp, sp, 32
ret ret
.type _compile_variable_section, @function # Compiles global variable section.
_compile_variable_section: .type compile_global_section, @function
compile_global_section:
# Prologue. # Prologue.
addi sp, sp, -32 addi sp, sp, -32
sw ra, 28(sp) sw ra, 28(sp)
@ -899,36 +933,37 @@ _compile_variable_section:
call lex_next call lex_next
li t0, TOKEN_VAR li t0, TOKEN_VAR
lw t1, 4(sp) lw t1, 4(sp)
bne t0, t1, .Lcompile_variable_section_end bne t0, t1, .Lcompile_global_section_end
mv s1, a0 mv s1, a0
la a0, section_bss la a0, section_bss
li a1, SECTION_BSS_SIZE li a1, SECTION_BSS_SIZE
call _write_out call _write_out
.Lcompile_variable_section_item: .Lcompile_global_section_item:
mv a0, s1 mv a0, s1
addi a1, sp, 12 addi a1, sp, 12
call lex_next call lex_next
lw t0, 12(sp) lw t0, 12(sp)
li t1, TOKEN_IDENTIFIER li t1, TOKEN_IDENTIFIER
bne t0, t1, .Lcompile_variable_section_end bne t0, t1, .Lcompile_global_section_end
lw s1, 20(sp) # Advance to the beginning of the variable name. lw s1, 20(sp) # Advance to the beginning of the variable name.
call _compile_variable call compile_global
j .Lcompile_variable_section_item j .Lcompile_global_section_item
.Lcompile_variable_section_end: .Lcompile_global_section_end:
# Epilogue. # Epilogue.
lw ra, 28(sp) lw ra, 28(sp)
lw s0, 24(sp) lw s0, 24(sp)
addi sp, sp, 32 addi sp, sp, 32
ret ret
# Compile a global variable. # Compiles a global variable.
.type _compile_variable, @function .type compile_global, @function
_compile_variable: compile_global:
# Prologue. # Prologue.
addi sp, sp, -48 addi sp, sp, -48
sw ra, 44(sp) sw ra, 44(sp)
@ -1010,29 +1045,10 @@ compile_type_expression:
beq t0, t1, .Lcompile_type_expression_pointer beq t0, t1, .Lcompile_type_expression_pointer
# Named type. # Named type.
mv a0, zero lw a0, 16(sp)
lw a1, 16(sp) lw a1, 20(sp)
lw a2, 20(sp)
call symbol_table_find call symbol_table_find
/* DEBUG
sw a0, 4(sp)
lw a0, 4(a0)
addi a0, a0, '0'
sw a0, 8(sp)
lw a0, 20(sp)
lw a1, 16(sp)
call _write_error
addi a0, sp, 8
li a1, 1
call _write_error
lw a0, 4(sp) */
/* DEBUG */
j .Lcompile_type_expression_end j .Lcompile_type_expression_end
.Lcompile_type_expression_pointer: .Lcompile_type_expression_pointer:
@ -1051,24 +1067,87 @@ compile_type_expression:
addi sp, sp, 32 addi sp, sp, 32
ret ret
.type _compile_parameters, @function # Inserts local procedure variables into the symbol table.
_compile_parameters: .type compile_local_section, @function
compile_local_section:
# Prologue. # Prologue.
addi sp, sp, -32 addi sp, sp, -48
sw ra, 28(sp) sw ra, 44(sp)
sw s0, 24(sp) sw s0, 40(sp)
addi s0, sp, 32 addi s0, sp, 48
mv a0, s1 mv a0, s1
addi a1, sp, 12 addi a1, sp, 28
call lex_next
lw t0, 28(sp)
li t1, TOKEN_VAR
bne t0, t1, .Lcompile_local_section_end
mv s1, a0
sw zero, 12(sp) # Variable offset counter.
.Lcompile_local_section_variable:
mv a0, s1
addi a1, sp, 28
call lex_next
lw t0, 28(sp)
li t1, TOKEN_IDENTIFIER
bne t0, t1, .Lcompile_local_section_end
addi a1, sp, 16
call lex_next
mv s1, a0 # Skip the ":" in front of the type.
call compile_type_expression
# a0 - Variable type.
lw a1, 12(sp)
mv a2, s3
call symbol_table_make_local
mv a2, s3
add s3, s3, a0
lw a0, 32(sp)
lw a1, 36(sp)
call symbol_table_insert
lw t0, 12(sp)
addi t0, t0, 4
sw t0, 12(sp)
j .Lcompile_local_section_variable
.Lcompile_local_section_end:
# Epilogue.
lw ra, 44(sp)
lw s0, 40(sp)
addi sp, sp, 48
ret
# Inserts procedure parameters into the symbol table.
.type compile_parameters, @function
compile_parameters:
# Prologue.
addi sp, sp, -48
sw ra, 44(sp)
sw s0, 40(sp)
addi s0, sp, 48
sw zero, 12(sp) # Parameter offset counter.
mv a0, s1
addi a1, sp, 28
call lex_next call lex_next
mv s1, a0 # Skip the opening paren. mv s1, a0 # Skip the opening paren.
mv a0, s1 mv a0, s1
addi a1, sp, 12 addi a1, sp, 28
call lex_next call lex_next
lw t0, 12(sp) lw t0, 28(sp)
li t1, TOKEN_RIGHT_PAREN li t1, TOKEN_RIGHT_PAREN
beq t0, t1, .Lcompile_parameters_end beq t0, t1, .Lcompile_parameters_end
# When this is not the right paren, it is an identifier. # When this is not the right paren, it is an identifier.
@ -1076,21 +1155,37 @@ _compile_parameters:
.Lcompile_parameters_parameter: .Lcompile_parameters_parameter:
mv a0, s1 mv a0, s1
addi a1, sp, 0 addi a1, sp, 16
call lex_next call lex_next
mv s1, a0 # Skip the ":" in front of the type. mv s1, a0 # Skip the ":" in front of the type.
call compile_type_expression call compile_type_expression
# a0 - Parameter type.
lw a1, 12(sp)
mv a2, s3
call symbol_table_make_parameter
mv a2, s3
add s3, s3, a0
lw a0, 32(sp)
lw a1, 36(sp)
call symbol_table_insert
lw t0, 12(sp)
addi t0, t0, 4
sw t0, 12(sp)
# Read the comma between the parameters or a closing paren. # Read the comma between the parameters or a closing paren.
mv a0, s1 mv a0, s1
addi a1, sp, 0 addi a1, sp, 16
call lex_next call lex_next
lw t0, 0(sp) lw t0, 16(sp)
li t1, TOKEN_COMMA li t1, TOKEN_COMMA
bne t0, t1, .Lcompile_parameters_end bne t0, t1, .Lcompile_parameters_end
# If it is a comma, read the name of the next parameter. # If it is a comma, read the name of the next parameter.
addi a1, sp, 12 addi a1, sp, 16
call lex_next call lex_next
mv s1, a0 mv s1, a0
@ -1100,13 +1195,13 @@ _compile_parameters:
mv s1, a0 # Skip the closing paren. mv s1, a0 # Skip the closing paren.
# Epilogue. # Epilogue.
lw ra, 28(sp) lw ra, 44(sp)
lw s0, 24(sp) lw s0, 40(sp)
addi sp, sp, 32 addi sp, sp, 48
ret ret
.type _compile_procedure, @function .type compile_procedure, @function
_compile_procedure: compile_procedure:
# Prologue. # Prologue.
addi sp, sp, -32 addi sp, sp, -32
sw ra, 28(sp) sw ra, 28(sp)
@ -1124,17 +1219,19 @@ _compile_procedure:
lw a1, 20(sp) lw a1, 20(sp)
call _write_procedure_head call _write_procedure_head
call _compile_parameters # Save the state of the symbol table before we enter the procedure scope.
# Skip all declarations until we find the "begin" keyword, denoting the la t0, symbol_table
# beginning of the procedure body. lw t0, (t0)
.Lcompile_procedure_begin: sw t0, 8(sp)
call compile_parameters
call compile_local_section
# Skip the "begin" keyword, denoting the beginning of the procedure body.
mv a0, s1 mv a0, s1
addi a1, sp, 4 addi a1, sp, 12
call lex_next call lex_next
mv s1, a0 mv s1, a0
lw t0, 4(sp)
li t1, TOKEN_BEGIN
bne t0, t1, .Lcompile_procedure_begin
# Generate the procedure prologue with a predefined stack size. # Generate the procedure prologue with a predefined stack size.
la a0, prologue la a0, prologue
@ -1147,7 +1244,7 @@ _compile_procedure:
call _write_out call _write_out
# Generate the body of the procedure. # Generate the body of the procedure.
call _compile_statements call compile_statements
mv s1, a0 # Skip end. mv s1, a0 # Skip end.
# Generate the procedure epilogue with a predefined stack size. # Generate the procedure epilogue with a predefined stack size.
@ -1155,6 +1252,24 @@ _compile_procedure:
li a1, EPILOGUE_SIZE li a1, EPILOGUE_SIZE
call _write_out call _write_out
/* DEBUG
lw a0, 16(sp)
lw a1, 20(sp)
call symbol_table_find
beqz a0, .x
*/
lw a0, 20(sp)
lw a1, 16(sp)
call _write_error
call symbol_table_dump
/* DEBUG */
# Restore the symbol table, removing symbols local to this procedure.
la t0, symbol_table
lw t1, 8(sp)
sw t1, (t0)
# Epilogue. # Epilogue.
lw ra, 28(sp) lw ra, 28(sp)
lw s0, 24(sp) lw s0, 24(sp)
@ -1162,8 +1277,8 @@ _compile_procedure:
ret ret
# Compiles a goto statement to an uncoditional jump. # Compiles a goto statement to an uncoditional jump.
.type _compile_goto, @function .type compile_goto, @function
_compile_goto: compile_goto:
# Prologue. # Prologue.
addi sp, sp, -32 addi sp, sp, -32
sw ra, 28(sp) sw ra, 28(sp)
@ -1199,8 +1314,8 @@ _compile_goto:
ret ret
# Rewrites a label to assembly. # Rewrites a label to assembly.
.type _compile_label, @function .type compile_label, @function
_compile_label: compile_label:
# Prologue. # Prologue.
addi sp, sp, -32 addi sp, sp, -32
sw ra, 28(sp) sw ra, 28(sp)
@ -1231,8 +1346,8 @@ _compile_label:
ret ret
# Just skips the return keyword and evaluates the return expression. # Just skips the return keyword and evaluates the return expression.
.type _compile_return, @function .type compile_return, @function
_compile_return: compile_return:
# Prologue. # Prologue.
addi sp, sp, -32 addi sp, sp, -32
sw ra, 28(sp) sw ra, 28(sp)
@ -1252,8 +1367,8 @@ _compile_return:
addi sp, sp, 32 addi sp, sp, 32
ret ret
.type _compile_if, @function .type compile_if, @function
_compile_if: compile_if:
# Prologue. # Prologue.
addi sp, sp, -32 addi sp, sp, -32
sw ra, 28(sp) sw ra, 28(sp)
@ -1294,7 +1409,7 @@ _compile_if:
li a0, '\n' li a0, '\n'
call _put_char call _put_char
call _compile_statements call compile_statements
mv s1, a0 # Skip end. mv s1, a0 # Skip end.
# Write the label prefix. # Write the label prefix.
@ -1372,8 +1487,8 @@ _write_procedure_head:
# #
# Sets a0 to the end of the token finishing the list # Sets a0 to the end of the token finishing the list
# (should be the "end" token in a valid program). # (should be the "end" token in a valid program).
.type _compile_statements, @function .type compile_statements, @function
_compile_statements: compile_statements:
# Prologue. # Prologue.
addi sp, sp, -32 addi sp, sp, -32
sw ra, 28(sp) sw ra, 28(sp)
@ -1390,7 +1505,7 @@ _compile_statements:
beq t0, t1, .Lcompile_statements_end beq t0, t1, .Lcompile_statements_end
.Lcompile_statements_body: .Lcompile_statements_body:
call _compile_statement call compile_statement
mv a0, s1 mv a0, s1
addi a1, sp, 0 addi a1, sp, 0
@ -1411,8 +1526,8 @@ _compile_statements:
ret ret
# Checks for the type of the current statement and compiles it. # Checks for the type of the current statement and compiles it.
.type _compile_statement, @function .type compile_statement, @function
_compile_statement: compile_statement:
# Prologue. # Prologue.
addi sp, sp, -32 addi sp, sp, -32
sw ra, 28(sp) sw ra, 28(sp)
@ -1442,23 +1557,23 @@ _compile_statement:
unimp # Else. unimp # Else.
.Lcompile_statement_if: .Lcompile_statement_if:
call _compile_if call compile_if
j .Lcompile_statement_end j .Lcompile_statement_end
.Lcompile_statement_label: .Lcompile_statement_label:
call _compile_label call compile_label
j .Lcompile_statement_end j .Lcompile_statement_end
.Lcompile_statement_return: .Lcompile_statement_return:
call _compile_return call compile_return
j .Lcompile_statement_end j .Lcompile_statement_end
.Lcompile_statement_goto: .Lcompile_statement_goto:
call _compile_goto call compile_goto
j .Lcompile_statement_end j .Lcompile_statement_end
.Lcompile_statement_identifier: .Lcompile_statement_identifier:
call _compile_identifier call compile_identifier
j .Lcompile_statement_end j .Lcompile_statement_end
.Lcompile_statement_end: .Lcompile_statement_end:
@ -1469,8 +1584,8 @@ _compile_statement:
ret ret
# Prints ".section .text" and exits. # Prints ".section .text" and exits.
.type _compile_text_section, @function .type compile_text_section, @function
_compile_text_section: compile_text_section:
# Prologue. # Prologue.
addi sp, sp, -16 addi sp, sp, -16
sw ra, 12(sp) sw ra, 12(sp)
@ -1487,8 +1602,8 @@ _compile_text_section:
addi sp, sp, 16 addi sp, sp, 16
ret ret
.type _compile_entry_point, @function .type compile_entry_point, @function
_compile_entry_point: compile_entry_point:
# Prologue. # Prologue.
addi sp, sp, -32 addi sp, sp, -32
sw ra, 28(sp) sw ra, 28(sp)
@ -1506,7 +1621,7 @@ _compile_entry_point:
mv s1, a0 # Skip begin. mv s1, a0 # Skip begin.
# Generate the body of the procedure. # Generate the body of the procedure.
call _compile_statements call compile_statements
mv s1, a0 # Skip end. mv s1, a0 # Skip end.
la a0, asm_exit la a0, asm_exit
@ -1519,21 +1634,21 @@ _compile_entry_point:
addi sp, sp, 32 addi sp, sp, 32
ret ret
.type _compile, @function .type compile, @function
_compile: compile:
# Prologue. # Prologue.
addi sp, sp, -16 addi sp, sp, -16
sw ra, 12(sp) sw ra, 12(sp)
sw s0, 8(sp) sw s0, 8(sp)
addi s0, sp, 16 addi s0, sp, 16
call _compile_module_declaration call compile_module_declaration
call _compile_import call compile_import
call _compile_constant_section call compile_constant_section
call _compile_variable_section call compile_global_section
call _compile_text_section call compile_text_section
call _compile_procedure_section call compile_procedure_section
call _compile_entry_point call compile_entry_point
# Epilogue. # Epilogue.
lw ra, 12(sp) lw ra, 12(sp)
@ -1554,7 +1669,7 @@ _start:
mv s3, a0 mv s3, a0
call symbol_table_build call symbol_table_build
call _compile call compile
# Call exit. # Call exit.
li a0, 0 # Use 0 return code. li a0, 0 # Use 0 return code.

View File

@ -19,7 +19,11 @@ end
proc _build_binary_expression() proc _build_binary_expression()
var var
loca0, loca4, loca8, loca16, loca20: Word loca0: Word
loca4: Word
loca8: Word
loca16: Word
loca20: Word
loca12: ^Byte loca12: ^Byte
loca24: Bool loca24: Bool
begin begin
@ -208,8 +212,12 @@ end
proc _build_expression() proc _build_expression()
var var
loca0, loca20, loca28, loca8: Word loca0: Word
loca24, loca4: ^Byte loca20: Word
loca28: Word
loca8: Word
loca24: ^Byte
loca4: ^Byte
begin begin
loca28 := loca84 + 0x30; loca28 := loca84 + 0x30;
@ -340,8 +348,11 @@ end
proc _compile_identifier() proc _compile_identifier()
var var
loca0, loca16, loca8: Word loca0: Word
loca20, loca12: ^Byte loca16: Word
loca8: Word
loca20: ^Byte
loca12: ^Byte
loca4: Bool loca4: Bool
begin begin
loca20 := _current(); loca20 := _current();
@ -375,7 +386,9 @@ end
proc _compile_call(loca84: ^Byte, loca80: Word) proc _compile_call(loca84: ^Byte, loca80: Word)
var var
loca0, loca4, loca12: Word loca0: Word
loca4: Word
loca12: Word
loca8: ^Byte loca8: ^Byte
begin begin
loca12 := 0; loca12 := 0;
@ -482,7 +495,8 @@ end
proc _read_token() proc _read_token()
var var
loca0, loca4: Word loca0: Word
loca4: Word
loca8: ^Byte loca8: ^Byte
begin begin
loca8 := _current(); loca8 := _current();
@ -664,7 +678,8 @@ end
proc _compile_constant() proc _compile_constant()
var var
loca0, loca4: Word loca0: Word
loca4: Word
loca8: ^Byte loca8: ^Byte
begin begin
loca4 := _read_token(); loca4 := _read_token();
@ -725,8 +740,11 @@ end
proc _compile_variable() proc _compile_variable()
var var
loca28, loca16: ^Byte loca28: ^Byte
loca0, loca24, loca20: Word loca16: ^Byte
loca0: Word
loca24: Word
loca20: Word
begin begin
loca24 := _read_token(); loca24 := _read_token();
loca28 := _current(); loca28 := _current();
@ -791,8 +809,13 @@ end
proc _compile_procedure() proc _compile_procedure()
var var
loca0, loca4, loca8, loca12, loca16: Word loca0: Word
loca20, loca24: ^Byte loca4: Word
loca8: Word
loca12: Word
loca16: Word
loca20: ^Byte
loca24: ^Byte
begin begin
_advance(5); _advance(5);
loca16 := _read_token(); loca16 := _read_token();
@ -971,7 +994,8 @@ end
proc _token_compare(loca84: ^Byte, loca80: Word, loca76: ^Byte) proc _token_compare(loca84: ^Byte, loca80: Word, loca76: ^Byte)
var var
loca0: Bool loca0: Bool
loca4, loca12: Byte loca4: Byte
loca12: Byte
loca8: Word loca8: Word
begin begin
.Ltoken_compare_loop; .Ltoken_compare_loop;
@ -1065,7 +1089,10 @@ end
proc _compile_if() proc _compile_if()
var var
loca8, loca12, loca16, loca20: Word loca8: Word
loca12: Word
loca16: Word
loca20: Word
loca4: ^Byte loca4: ^Byte
begin begin
_advance(2); _advance(2);
@ -1368,7 +1395,8 @@ end
proc _compile() proc _compile()
var var
loca0, loca4: Word loca0: Word
loca4: Word
loca8: Bool loca8: Bool
loca12: Char loca12: Char
loca16: ^Byte loca16: ^Byte

View File

@ -2,7 +2,9 @@
# v. 2.0. If a copy of the MPL was not distributed with this file, You can # v. 2.0. If a copy of the MPL was not distributed with this file, You can
# obtain one at https://mozilla.org/MPL/2.0/. # obtain one at https://mozilla.org/MPL/2.0/.
.global symbol_table_build, symbol_table_find, symbol_table_make_pointer .global symbol_table
.global symbol_table_build, symbol_table_find, symbol_table_insert, symbol_table_dump
.global symbol_table_make_pointer, symbol_table_make_parameter, symbol_table_make_local
.include "boot/definitions.inc" .include "boot/definitions.inc"
@ -54,14 +56,51 @@ symbol_table: .zero SYMBOL_PRIME
.section .text .section .text
# Prints the list of symbols in the table.
.type symbol_table_dump, @function
symbol_table_dump:
# Prologue.
addi sp, sp, -32
sw ra, 28(sp)
sw s0, 24(sp)
addi s0, sp, 32
sw s1, 20(sp) # Current symbol in the table.
sw s2, 16(sp) # Symbol table length.
la s1, symbol_table
lw s2, 0(s1)
addi s1, s1, 4 # Advance to the first symbol in the table.
.Lsymbol_table_dump_loop:
beqz s2, .Lsymbol_table_dump_end
# Compare string lengths.
lw a0, 4(s1)
lw a1, 0(s1)
call _write_error
addi s1, s1, 12
addi s2, s2, -1
j .Lsymbol_table_dump_loop
.Lsymbol_table_dump_end:
lw s1, 20(sp)
lw s2, 16(sp)
# Epilogue.
lw ra, 28(sp)
lw s0, 24(sp)
addi sp, sp, 32
ret
# Searches for a symbol by name. # Searches for a symbol by name.
# #
# Parameters: # Parameters:
# a0 - Local symbol table or 0. # a0 - Length of the symbol to search.
# a1 - Length of the symbol to search. # a1 - Pointer to the symbol name.
# a2 - Pointer to the symbol name.
# #
# Sets a0 to the symbol info. # Sets a0 to the symbol info pointer or 0 if the symbol has not been found.
.type symbol_table_find, @function .type symbol_table_find, @function
symbol_table_find: symbol_table_find:
# Prologue. # Prologue.
@ -75,8 +114,8 @@ symbol_table_find:
sw s3, 12(sp) # Length of the symbol to search. sw s3, 12(sp) # Length of the symbol to search.
sw s4, 8(sp) # Pointer to the symbol to search. sw s4, 8(sp) # Pointer to the symbol to search.
mv s3, a1 mv s3, a0
mv s4, a2 mv s4, a1
la s1, symbol_table la s1, symbol_table
lw s2, 0(s1) lw s2, 0(s1)
@ -95,7 +134,7 @@ symbol_table_find:
beqz a0, .Lsymbol_table_find_continue beqz a0, .Lsymbol_table_find_continue
lw a0, 8(s1) # Pointer to the symbol. lw a0, 8(s1) # Pointer to the symbol.
j .Lsymbol_table_end j .Lsymbol_table_find_end
.Lsymbol_table_find_continue: .Lsymbol_table_find_continue:
addi s1, s1, 12 addi s1, s1, 12
@ -105,7 +144,7 @@ symbol_table_find:
.Lsymbol_table_find_not_found: .Lsymbol_table_find_not_found:
li a0, 0 li a0, 0
.Lsymbol_table_end: .Lsymbol_table_find_end:
lw s1, 20(sp) lw s1, 20(sp)
lw s2, 16(sp) lw s2, 16(sp)
lw s3, 12(sp) lw s3, 12(sp)
@ -133,67 +172,108 @@ symbol_table_make_pointer:
li a0, 8 li a0, 8
ret ret
# Creates a parameter info.
#
# Parameters:
# a0 - Pointer to the parameter type.
# a1 - Parameter offset.
# a2 - Output memory.
#
# Sets a0 to the size of newly created info object in bytes.
.type symbol_table_make_parameter, @function
symbol_table_make_parameter:
li t0, INFO_PARAMETER
sw t0, 0(a2)
sw a0, 4(a2)
sw a1, 8(a2)
li a0, 12
ret
# Creates a local variable info.
#
# Parameters:
# a0 - Pointer to the variable type.
# a1 - Variable stack offset.
# a2 - Output memory.
#
# Sets a0 to the size of newly created info object in bytes.
.type symbol_table_make_local, @function
symbol_table_make_local:
li t0, INFO_LOCAL
sw t0, 0(a2)
sw a0, 4(a2)
sw a1, 8(a2)
li a0, 12
ret
# Inserts a symbol into the table.
#
# Parameters:
# a0 - Symbol name length.
# a1 - Symbol name pointer.
# a2 - Symbol pointer.
.type symbol_table_insert, @function
symbol_table_insert:
la t0, symbol_table
lw t1, 0(t0) # Current table length.
li t2, 12 # Calculate the offset to the next entry.
mul t2, t1, t2
addi t2, t2, 4
add t2, t0, t2
sw a0, 0(t2)
sw a1, 4(t2)
sw a2, 8(t2)
addi t1, t1, 1 # Save the new length.
sw t1, 0(t0)
ret
# Build the initial symbols. # Build the initial symbols.
# #
# Sets a0 to the pointer to the global symbol table. # Sets a0 to the pointer to the global symbol table.
.type symbol_build, @function .type symbol_build, @function
symbol_table_build: symbol_table_build:
# Prologue.
addi sp, sp, -16
sw ra, 12(sp)
sw s0, 8(sp)
addi s0, sp, 16
la a0, symbol_table la a0, symbol_table
addi t0, a0, 4 addi t0, a0, 4
li t1, 3 # Length of the word "Int". li a0, 3 # Length of the word "Int".
sw t1, 0(t0) la a1, symbol_builtin_name_int
la t1, symbol_builtin_name_int la a2, symbol_builtin_type_int
sw t1, 4(t0) call symbol_table_insert
la t1, symbol_builtin_type_int
sw t1, 8(t0)
lw t1, 0(a0)
addi t1, t1, 1
sw t1, 0(a0)
addi t0, t0, 12
li t1, 4 # Length of the word "Word". li a0, 4 # Length of the word "Word".
sw t1, 0(t0) la a1, symbol_builtin_name_word
la t1, symbol_builtin_name_word la a2, symbol_builtin_type_word
sw t1, 4(t0) call symbol_table_insert
la t1, symbol_builtin_type_word
sw t1, 8(t0)
lw t1, 0(a0)
addi t1, t1, 1
sw t1, 0(a0)
addi t0, t0, 12
li t1, 4 # Length of the word "Byte". li a0, 4 # Length of the word "Byte".
sw t1, 0(t0) la a1, symbol_builtin_name_byte
la t1, symbol_builtin_name_byte la a2, symbol_builtin_type_byte
sw t1, 4(t0) call symbol_table_insert
la t1, symbol_builtin_type_byte
sw t1, 8(t0)
lw t1, 0(a0)
addi t1, t1, 1
sw t1, 0(a0)
addi t0, t0, 12
li t1, 4 # Length of the word "Char". li a0, 4 # Length of the word "Char".
sw t1, 0(t0) la a1, symbol_builtin_name_char
la t1, symbol_builtin_name_char la a2, symbol_builtin_type_char
sw t1, 4(t0) call symbol_table_insert
la t1, symbol_builtin_type_char
sw t1, 8(t0)
lw t1, 0(a0)
addi t1, t1, 1
sw t1, 0(a0)
addi t0, t0, 12
li t1, 4 # Length of the word "Bool". li a0, 4 # Length of the word "Bool".
sw t1, 0(t0) la a1, symbol_builtin_name_bool
la t1, symbol_builtin_name_bool la a2, symbol_builtin_type_bool
sw t1, 4(t0) call symbol_table_insert
la t1, symbol_builtin_type_bool
sw t1, 8(t0)
lw t1, 0(a0)
addi t1, t1, 1
sw t1, 0(a0)
addi t0, t0, 12
# Epilogue.
lw ra, 12(sp)
lw s0, 8(sp)
addi sp, sp, 16
ret ret

14
boot/test.elna Normal file
View File

@ -0,0 +1,14 @@
program
proc _main(x: Word)
var loca0: Word
loca4: Word
begin
loca0 := 0x0a2c3061;
loca4 := x;
_write_out(@loca4, 4)
end
begin
_main()
end.