Add symbol info for parameters and local variables
This commit is contained in:
		
							
								
								
									
										16
									
								
								Rakefile
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								Rakefile
									
									
									
									
									
								
							@@ -20,3 +20,19 @@ task default: ['build/boot/stage2b', 'build/boot/stage2b.s', 'boot/stage2.elna']
 | 
			
		||||
  diff_arguments = ['diff', '-Nur', '--text', previous_output, '-']
 | 
			
		||||
  Open3.pipeline(cat_arguments, compiler_arguments, diff_arguments)
 | 
			
		||||
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
 | 
			
		||||
 
 | 
			
		||||
@@ -62,3 +62,5 @@
 | 
			
		||||
#
 | 
			
		||||
.equ TYPE_PRIMITIVE, 0x01
 | 
			
		||||
.equ TYPE_POINTER, 0x02
 | 
			
		||||
.equ INFO_PARAMETER, 0x10
 | 
			
		||||
.equ INFO_LOCAL, 0x20
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										391
									
								
								boot/stage1.s
									
									
									
									
									
								
							
							
						
						
									
										391
									
								
								boot/stage1.s
									
									
									
									
									
								
							@@ -85,8 +85,8 @@ source_code: .zero SOURCE_BUFFER_SIZE
 | 
			
		||||
.section .text
 | 
			
		||||
 | 
			
		||||
# Ignores the import.
 | 
			
		||||
.type _compile_import, @function
 | 
			
		||||
_compile_import:
 | 
			
		||||
.type compile_import, @function
 | 
			
		||||
compile_import:
 | 
			
		||||
	# Prologue.
 | 
			
		||||
	addi sp, sp, -24
 | 
			
		||||
	sw ra, 20(sp)
 | 
			
		||||
@@ -227,8 +227,8 @@ compile_binary_expression:
 | 
			
		||||
# a1 - Identifier length.
 | 
			
		||||
#
 | 
			
		||||
# Sets a0 to 1 if the identifier starts with "loca", otherwise to 0.
 | 
			
		||||
.type _is_local_identifier, @function
 | 
			
		||||
_is_local_identifier:
 | 
			
		||||
.type is_local_identifier, @function
 | 
			
		||||
is_local_identifier:
 | 
			
		||||
	# Prologue.
 | 
			
		||||
	addi sp, sp, -16
 | 
			
		||||
	sw ra, 12(sp)
 | 
			
		||||
@@ -255,8 +255,8 @@ _is_local_identifier:
 | 
			
		||||
# a1 - Identifier length.
 | 
			
		||||
#
 | 
			
		||||
# Sets a0 to 1 if the identifier is a preserved register, otherwise to 0.
 | 
			
		||||
.type _is_register_identifier, @function
 | 
			
		||||
_is_register_identifier:
 | 
			
		||||
.type is_register_identifier, @function
 | 
			
		||||
is_register_identifier:
 | 
			
		||||
	# Prologue.
 | 
			
		||||
	addi sp, sp, -8
 | 
			
		||||
	sw ra, 4(sp)
 | 
			
		||||
@@ -279,8 +279,8 @@ _is_register_identifier:
 | 
			
		||||
# Parameters:
 | 
			
		||||
# a0 - Identifier length.
 | 
			
		||||
# a1 - Register number as character.
 | 
			
		||||
.type _compile_identifier_expression, @function
 | 
			
		||||
_compile_identifier_expression:
 | 
			
		||||
.type compile_identifier_expression, @function
 | 
			
		||||
compile_identifier_expression:
 | 
			
		||||
	# Prologue.
 | 
			
		||||
	addi sp, sp, -32
 | 
			
		||||
	sw ra, 28(sp)
 | 
			
		||||
@@ -290,24 +290,32 @@ _compile_identifier_expression:
 | 
			
		||||
	sw a0, 20(sp) # Identifier length.
 | 
			
		||||
	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
 | 
			
		||||
	lw a1, 20(sp)
 | 
			
		||||
	call _is_local_identifier
 | 
			
		||||
	call is_local_identifier
 | 
			
		||||
	bnez a0, .Lcompile_identifier_expression_local
 | 
			
		||||
 | 
			
		||||
	mv a0, s1
 | 
			
		||||
	lw a1, 20(sp)
 | 
			
		||||
	call _is_register_identifier
 | 
			
		||||
	call is_register_identifier
 | 
			
		||||
	bnez a0, .Lcompile_identifier_expression_saved
 | 
			
		||||
 | 
			
		||||
	lw t0, 12(sp)
 | 
			
		||||
	bnez t0, .Lcompile_identifier_expression_defined
 | 
			
		||||
 | 
			
		||||
	# 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 t0, 0x6120616c # la a
 | 
			
		||||
	sw t0, 4(sp)
 | 
			
		||||
	addi a0, sp, 4
 | 
			
		||||
	li a1, 7
 | 
			
		||||
	call _write_out
 | 
			
		||||
 | 
			
		||||
@@ -326,26 +334,51 @@ _compile_identifier_expression:
 | 
			
		||||
	li t0, 0x0a290061 # a\0)\n
 | 
			
		||||
	sll t2, t1, 8
 | 
			
		||||
	or t0, t0, t2
 | 
			
		||||
	sw t0, 12(sp)
 | 
			
		||||
	sw t0, 8(sp)
 | 
			
		||||
	li t0, 0x28202c00 # \0, (
 | 
			
		||||
	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)
 | 
			
		||||
	li t0, 0x6120776c # lw a
 | 
			
		||||
	sw t0, 4(sp)
 | 
			
		||||
	addi a0, sp, 4
 | 
			
		||||
	li a1, 12
 | 
			
		||||
	li a1, 7
 | 
			
		||||
	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
 | 
			
		||||
 | 
			
		||||
.Lcompile_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 t0, 0x6120766d # mv a
 | 
			
		||||
	sw t0, 4(sp)
 | 
			
		||||
	addi a0, sp, 4
 | 
			
		||||
	li a1, 7
 | 
			
		||||
	call _write_out
 | 
			
		||||
 | 
			
		||||
@@ -362,10 +395,10 @@ _compile_identifier_expression:
 | 
			
		||||
	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 t0, 0x6120776c # lw a
 | 
			
		||||
	sw t0, 4(sp)
 | 
			
		||||
	addi a0, sp, 4
 | 
			
		||||
	li a1, 7
 | 
			
		||||
	call _write_out
 | 
			
		||||
 | 
			
		||||
@@ -376,8 +409,8 @@ _compile_identifier_expression:
 | 
			
		||||
	call _write_out
 | 
			
		||||
 | 
			
		||||
	li t0, 0x29707328 # (sp)
 | 
			
		||||
	sw t0, 12(sp)
 | 
			
		||||
	addi a0, sp, 12
 | 
			
		||||
	sw t0, 8(sp)
 | 
			
		||||
	addi a0, sp, 8
 | 
			
		||||
	li a1, 4
 | 
			
		||||
	call _write_out
 | 
			
		||||
	li a0, '\n'
 | 
			
		||||
@@ -431,7 +464,7 @@ _build_expression:
 | 
			
		||||
	lw s1, 32(sp)
 | 
			
		||||
	lw a0, 28(sp)
 | 
			
		||||
	lw a1, 36(sp)
 | 
			
		||||
	call _compile_identifier_expression
 | 
			
		||||
	call compile_identifier_expression
 | 
			
		||||
 | 
			
		||||
	j .Lbuild_expression_advance
 | 
			
		||||
 | 
			
		||||
@@ -485,7 +518,7 @@ _build_expression:
 | 
			
		||||
 | 
			
		||||
	lw a0, 32(sp)
 | 
			
		||||
	lw a1, 28(sp)
 | 
			
		||||
	call _compile_call
 | 
			
		||||
	call compile_call
 | 
			
		||||
 | 
			
		||||
	j .Lbuild_expression_end
 | 
			
		||||
 | 
			
		||||
@@ -524,8 +557,8 @@ _build_expression:
 | 
			
		||||
# Parameters:
 | 
			
		||||
# a0 - Pointer to the identifier.
 | 
			
		||||
# a1 - Identifier length.
 | 
			
		||||
.type _compile_designator_expression, @function
 | 
			
		||||
_compile_designator_expression:
 | 
			
		||||
.type compile_designator_expression, @function
 | 
			
		||||
compile_designator_expression:
 | 
			
		||||
	# Prologue.
 | 
			
		||||
	addi sp, sp, -32
 | 
			
		||||
	sw ra, 28(sp)
 | 
			
		||||
@@ -537,12 +570,12 @@ _compile_designator_expression:
 | 
			
		||||
 | 
			
		||||
	lw a0, 20(sp)
 | 
			
		||||
	lw a1, 16(sp)
 | 
			
		||||
	call _is_local_identifier
 | 
			
		||||
	call is_local_identifier
 | 
			
		||||
	bnez a0, .Lcompile_designator_expression_local
 | 
			
		||||
 | 
			
		||||
	lw a0, 20(sp)
 | 
			
		||||
	lw a1, 16(sp)
 | 
			
		||||
	call _is_register_identifier
 | 
			
		||||
	call is_register_identifier
 | 
			
		||||
	bnez a0, .Lcompile_designator_expression_saved
 | 
			
		||||
 | 
			
		||||
.Lcompile_designator_expression_local:
 | 
			
		||||
@@ -603,8 +636,8 @@ _compile_designator_expression:
 | 
			
		||||
#
 | 
			
		||||
# 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:
 | 
			
		||||
.type compile_identifier, @function
 | 
			
		||||
compile_identifier:
 | 
			
		||||
	# Prologue.
 | 
			
		||||
	addi sp, sp, -32
 | 
			
		||||
	sw ra, 28(sp)
 | 
			
		||||
@@ -632,7 +665,7 @@ _compile_identifier:
 | 
			
		||||
.Lcompile_identifier_call:
 | 
			
		||||
	lw a0, 20(sp)
 | 
			
		||||
	lw a1, 16(sp)
 | 
			
		||||
	call _compile_call
 | 
			
		||||
	call compile_call
 | 
			
		||||
 | 
			
		||||
	j .Lcompile_identifier_end
 | 
			
		||||
 | 
			
		||||
@@ -640,7 +673,7 @@ _compile_identifier:
 | 
			
		||||
	call compile_binary_expression
 | 
			
		||||
	lw a0, 20(sp)
 | 
			
		||||
	lw a1, 16(sp)
 | 
			
		||||
	call _compile_designator_expression
 | 
			
		||||
	call compile_designator_expression
 | 
			
		||||
 | 
			
		||||
	j .Lcompile_identifier_end
 | 
			
		||||
 | 
			
		||||
@@ -656,8 +689,8 @@ _compile_identifier:
 | 
			
		||||
# a1 - Length of the procedure name.
 | 
			
		||||
#
 | 
			
		||||
# Returns the procedure result in a0.
 | 
			
		||||
.type _compile_call, @function
 | 
			
		||||
_compile_call:
 | 
			
		||||
.type compile_call, @function
 | 
			
		||||
compile_call:
 | 
			
		||||
	# Prologue.
 | 
			
		||||
	addi sp, sp, -32
 | 
			
		||||
	sw ra, 28(sp)
 | 
			
		||||
@@ -748,8 +781,8 @@ _compile_call:
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
# Walks through the procedure definitions.
 | 
			
		||||
.type _compile_procedure_section, @function
 | 
			
		||||
_compile_procedure_section:
 | 
			
		||||
.type compile_procedure_section, @function
 | 
			
		||||
compile_procedure_section:
 | 
			
		||||
	# Prologue.
 | 
			
		||||
	addi sp, sp, -32
 | 
			
		||||
	sw ra, 28(sp)
 | 
			
		||||
@@ -764,7 +797,7 @@ _compile_procedure_section:
 | 
			
		||||
	lw t1, 4(sp)
 | 
			
		||||
	bne t0, t1, .Lcompile_procedure_section_end
 | 
			
		||||
 | 
			
		||||
	call _compile_procedure
 | 
			
		||||
	call compile_procedure
 | 
			
		||||
 | 
			
		||||
	j .Lcompile_procedure_section_loop
 | 
			
		||||
 | 
			
		||||
@@ -775,8 +808,8 @@ _compile_procedure_section:
 | 
			
		||||
	addi sp, sp, 32
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
.type _compile_module_declaration, @function
 | 
			
		||||
_compile_module_declaration:
 | 
			
		||||
.type compile_module_declaration, @function
 | 
			
		||||
compile_module_declaration:
 | 
			
		||||
	# Prologue.
 | 
			
		||||
	addi sp, sp, -24
 | 
			
		||||
	sw ra, 20(sp)
 | 
			
		||||
@@ -799,8 +832,8 @@ _compile_module_declaration:
 | 
			
		||||
	addi sp, sp, 24
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
.type _compile_constant_section, @function
 | 
			
		||||
_compile_constant_section:
 | 
			
		||||
.type compile_constant_section, @function
 | 
			
		||||
compile_constant_section:
 | 
			
		||||
	# Prologue.
 | 
			
		||||
	addi sp, sp, -32
 | 
			
		||||
	sw ra, 28(sp)
 | 
			
		||||
@@ -830,7 +863,7 @@ _compile_constant_section:
 | 
			
		||||
	bne t0, t1, .Lcompile_constant_section_end
 | 
			
		||||
	lw s1, 20(sp)
 | 
			
		||||
 | 
			
		||||
	call _compile_constant
 | 
			
		||||
	call compile_constant
 | 
			
		||||
	j .Lcompile_constant_section_item
 | 
			
		||||
 | 
			
		||||
.Lcompile_constant_section_end:
 | 
			
		||||
@@ -840,8 +873,8 @@ _compile_constant_section:
 | 
			
		||||
	addi sp, sp, 32
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
.type _compile_constant, @function
 | 
			
		||||
_compile_constant:
 | 
			
		||||
.type compile_constant, @function
 | 
			
		||||
compile_constant:
 | 
			
		||||
	# Prologue.
 | 
			
		||||
	addi sp, sp, -32
 | 
			
		||||
	sw ra, 28(sp)
 | 
			
		||||
@@ -886,8 +919,9 @@ _compile_constant:
 | 
			
		||||
	addi sp, sp, 32
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
.type _compile_variable_section, @function
 | 
			
		||||
_compile_variable_section:
 | 
			
		||||
# Compiles global variable section.
 | 
			
		||||
.type compile_global_section, @function
 | 
			
		||||
compile_global_section:
 | 
			
		||||
	# Prologue.
 | 
			
		||||
	addi sp, sp, -32
 | 
			
		||||
	sw ra, 28(sp)
 | 
			
		||||
@@ -899,36 +933,37 @@ _compile_variable_section:
 | 
			
		||||
	call lex_next
 | 
			
		||||
	li t0, TOKEN_VAR
 | 
			
		||||
	lw t1, 4(sp)
 | 
			
		||||
	bne t0, t1, .Lcompile_variable_section_end
 | 
			
		||||
	bne t0, t1, .Lcompile_global_section_end
 | 
			
		||||
	mv s1, a0
 | 
			
		||||
 | 
			
		||||
	la a0, section_bss
 | 
			
		||||
	li a1, SECTION_BSS_SIZE
 | 
			
		||||
	call _write_out
 | 
			
		||||
 | 
			
		||||
.Lcompile_variable_section_item:
 | 
			
		||||
.Lcompile_global_section_item:
 | 
			
		||||
	mv a0, s1
 | 
			
		||||
	addi a1, sp, 12
 | 
			
		||||
	call lex_next
 | 
			
		||||
 | 
			
		||||
	lw t0, 12(sp)
 | 
			
		||||
	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.
 | 
			
		||||
 | 
			
		||||
	call _compile_variable
 | 
			
		||||
	j .Lcompile_variable_section_item
 | 
			
		||||
	call compile_global
 | 
			
		||||
	j .Lcompile_global_section_item
 | 
			
		||||
 | 
			
		||||
.Lcompile_variable_section_end:
 | 
			
		||||
.Lcompile_global_section_end:
 | 
			
		||||
	# Epilogue.
 | 
			
		||||
	lw ra, 28(sp)
 | 
			
		||||
	lw s0, 24(sp)
 | 
			
		||||
	addi sp, sp, 32
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
# Compile a global variable.
 | 
			
		||||
.type _compile_variable, @function
 | 
			
		||||
_compile_variable:
 | 
			
		||||
# Compiles a global variable.
 | 
			
		||||
.type compile_global, @function
 | 
			
		||||
compile_global:
 | 
			
		||||
	# Prologue.
 | 
			
		||||
	addi sp, sp, -48
 | 
			
		||||
	sw ra, 44(sp)
 | 
			
		||||
@@ -1010,29 +1045,10 @@ compile_type_expression:
 | 
			
		||||
	beq t0, t1, .Lcompile_type_expression_pointer
 | 
			
		||||
 | 
			
		||||
	# Named type.
 | 
			
		||||
	mv a0, zero
 | 
			
		||||
	lw a1, 16(sp)
 | 
			
		||||
	lw a2, 20(sp)
 | 
			
		||||
	lw a0, 16(sp)
 | 
			
		||||
	lw a1, 20(sp)
 | 
			
		||||
	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
 | 
			
		||||
 | 
			
		||||
.Lcompile_type_expression_pointer:
 | 
			
		||||
@@ -1051,24 +1067,87 @@ compile_type_expression:
 | 
			
		||||
	addi sp, sp, 32
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
.type _compile_parameters, @function
 | 
			
		||||
_compile_parameters:
 | 
			
		||||
# Inserts local procedure variables into the symbol table.
 | 
			
		||||
.type compile_local_section, @function
 | 
			
		||||
compile_local_section:
 | 
			
		||||
	# Prologue.
 | 
			
		||||
	addi sp, sp, -32
 | 
			
		||||
	sw ra, 28(sp)
 | 
			
		||||
	sw s0, 24(sp)
 | 
			
		||||
	addi s0, sp, 32
 | 
			
		||||
	addi sp, sp, -48
 | 
			
		||||
	sw ra, 44(sp)
 | 
			
		||||
	sw s0, 40(sp)
 | 
			
		||||
	addi s0, sp, 48
 | 
			
		||||
 | 
			
		||||
	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
 | 
			
		||||
	mv s1, a0 # Skip the opening paren.
 | 
			
		||||
 | 
			
		||||
	mv a0, s1
 | 
			
		||||
	addi a1, sp, 12
 | 
			
		||||
	addi a1, sp, 28
 | 
			
		||||
	call lex_next
 | 
			
		||||
 | 
			
		||||
	lw t0, 12(sp)
 | 
			
		||||
	lw t0, 28(sp)
 | 
			
		||||
	li t1, TOKEN_RIGHT_PAREN
 | 
			
		||||
	beq t0, t1, .Lcompile_parameters_end
 | 
			
		||||
	# When this is not the right paren, it is an identifier.
 | 
			
		||||
@@ -1076,21 +1155,37 @@ _compile_parameters:
 | 
			
		||||
 | 
			
		||||
.Lcompile_parameters_parameter:
 | 
			
		||||
	mv a0, s1
 | 
			
		||||
	addi a1, sp, 0
 | 
			
		||||
	addi a1, sp, 16
 | 
			
		||||
	call lex_next
 | 
			
		||||
	mv s1, a0 # Skip the ":" in front of the type.
 | 
			
		||||
 | 
			
		||||
	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.
 | 
			
		||||
	mv a0, s1
 | 
			
		||||
	addi a1, sp, 0
 | 
			
		||||
	addi a1, sp, 16
 | 
			
		||||
	call lex_next
 | 
			
		||||
 | 
			
		||||
	lw t0, 0(sp)
 | 
			
		||||
	lw t0, 16(sp)
 | 
			
		||||
	li t1, TOKEN_COMMA
 | 
			
		||||
	bne t0, t1, .Lcompile_parameters_end
 | 
			
		||||
	# If it is a comma, read the name of the next parameter.
 | 
			
		||||
	addi a1, sp, 12
 | 
			
		||||
	addi a1, sp, 16
 | 
			
		||||
	call lex_next
 | 
			
		||||
	mv s1, a0
 | 
			
		||||
 | 
			
		||||
@@ -1100,13 +1195,13 @@ _compile_parameters:
 | 
			
		||||
	mv s1, a0 # Skip the closing paren.
 | 
			
		||||
 | 
			
		||||
	# Epilogue.
 | 
			
		||||
	lw ra, 28(sp)
 | 
			
		||||
	lw s0, 24(sp)
 | 
			
		||||
	addi sp, sp, 32
 | 
			
		||||
	lw ra, 44(sp)
 | 
			
		||||
	lw s0, 40(sp)
 | 
			
		||||
	addi sp, sp, 48
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
.type _compile_procedure, @function
 | 
			
		||||
_compile_procedure:
 | 
			
		||||
.type compile_procedure, @function
 | 
			
		||||
compile_procedure:
 | 
			
		||||
	# Prologue.
 | 
			
		||||
	addi sp, sp, -32
 | 
			
		||||
	sw ra, 28(sp)
 | 
			
		||||
@@ -1124,17 +1219,19 @@ _compile_procedure:
 | 
			
		||||
	lw a1, 20(sp)
 | 
			
		||||
	call _write_procedure_head
 | 
			
		||||
 | 
			
		||||
	call _compile_parameters
 | 
			
		||||
	# Skip all declarations until we find the "begin" keyword, denoting the
 | 
			
		||||
	# beginning of the procedure body.
 | 
			
		||||
.Lcompile_procedure_begin:
 | 
			
		||||
	# Save the state of the symbol table before we enter the procedure scope.
 | 
			
		||||
	la t0, symbol_table
 | 
			
		||||
	lw t0, (t0)
 | 
			
		||||
	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
 | 
			
		||||
	addi a1, sp, 4
 | 
			
		||||
	addi a1, sp, 12
 | 
			
		||||
	call lex_next
 | 
			
		||||
	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.
 | 
			
		||||
	la a0, prologue
 | 
			
		||||
@@ -1147,7 +1244,7 @@ _compile_procedure:
 | 
			
		||||
	call _write_out
 | 
			
		||||
 | 
			
		||||
	# Generate the body of the procedure.
 | 
			
		||||
	call _compile_statements
 | 
			
		||||
	call compile_statements
 | 
			
		||||
	mv s1, a0 # Skip end.
 | 
			
		||||
 | 
			
		||||
	# Generate the procedure epilogue with a predefined stack size.
 | 
			
		||||
@@ -1155,6 +1252,24 @@ _compile_procedure:
 | 
			
		||||
	li a1, EPILOGUE_SIZE
 | 
			
		||||
	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.
 | 
			
		||||
	lw ra, 28(sp)
 | 
			
		||||
	lw s0, 24(sp)
 | 
			
		||||
@@ -1162,8 +1277,8 @@ _compile_procedure:
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
# Compiles a goto statement to an uncoditional jump.
 | 
			
		||||
.type _compile_goto, @function
 | 
			
		||||
_compile_goto:
 | 
			
		||||
.type compile_goto, @function
 | 
			
		||||
compile_goto:
 | 
			
		||||
	# Prologue.
 | 
			
		||||
	addi sp, sp, -32
 | 
			
		||||
	sw ra, 28(sp)
 | 
			
		||||
@@ -1199,8 +1314,8 @@ _compile_goto:
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
# Rewrites a label to assembly.
 | 
			
		||||
.type _compile_label, @function
 | 
			
		||||
_compile_label:
 | 
			
		||||
.type compile_label, @function
 | 
			
		||||
compile_label:
 | 
			
		||||
	# Prologue.
 | 
			
		||||
	addi sp, sp, -32
 | 
			
		||||
	sw ra, 28(sp)
 | 
			
		||||
@@ -1231,8 +1346,8 @@ _compile_label:
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
# Just skips the return keyword and evaluates the return expression.
 | 
			
		||||
.type _compile_return, @function
 | 
			
		||||
_compile_return:
 | 
			
		||||
.type compile_return, @function
 | 
			
		||||
compile_return:
 | 
			
		||||
	# Prologue.
 | 
			
		||||
	addi sp, sp, -32
 | 
			
		||||
	sw ra, 28(sp)
 | 
			
		||||
@@ -1252,8 +1367,8 @@ _compile_return:
 | 
			
		||||
	addi sp, sp, 32
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
.type _compile_if, @function
 | 
			
		||||
_compile_if:
 | 
			
		||||
.type compile_if, @function
 | 
			
		||||
compile_if:
 | 
			
		||||
	# Prologue.
 | 
			
		||||
	addi sp, sp, -32
 | 
			
		||||
	sw ra, 28(sp)
 | 
			
		||||
@@ -1294,7 +1409,7 @@ _compile_if:
 | 
			
		||||
	li a0, '\n'
 | 
			
		||||
	call _put_char
 | 
			
		||||
 | 
			
		||||
	call _compile_statements
 | 
			
		||||
	call compile_statements
 | 
			
		||||
	mv s1, a0 # Skip end.
 | 
			
		||||
 | 
			
		||||
	# Write the label prefix.
 | 
			
		||||
@@ -1372,8 +1487,8 @@ _write_procedure_head:
 | 
			
		||||
#
 | 
			
		||||
# Sets a0 to the end of the token finishing the list
 | 
			
		||||
# (should be the "end" token in a valid program).
 | 
			
		||||
.type _compile_statements, @function
 | 
			
		||||
_compile_statements:
 | 
			
		||||
.type compile_statements, @function
 | 
			
		||||
compile_statements:
 | 
			
		||||
	# Prologue.
 | 
			
		||||
	addi sp, sp, -32
 | 
			
		||||
	sw ra, 28(sp)
 | 
			
		||||
@@ -1390,7 +1505,7 @@ _compile_statements:
 | 
			
		||||
	beq t0, t1, .Lcompile_statements_end
 | 
			
		||||
 | 
			
		||||
.Lcompile_statements_body:
 | 
			
		||||
	call _compile_statement
 | 
			
		||||
	call compile_statement
 | 
			
		||||
 | 
			
		||||
	mv a0, s1
 | 
			
		||||
	addi a1, sp, 0
 | 
			
		||||
@@ -1411,8 +1526,8 @@ _compile_statements:
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
# Checks for the type of the current statement and compiles it.
 | 
			
		||||
.type _compile_statement, @function
 | 
			
		||||
_compile_statement:
 | 
			
		||||
.type compile_statement, @function
 | 
			
		||||
compile_statement:
 | 
			
		||||
	# Prologue.
 | 
			
		||||
	addi sp, sp, -32
 | 
			
		||||
	sw ra, 28(sp)
 | 
			
		||||
@@ -1442,23 +1557,23 @@ _compile_statement:
 | 
			
		||||
	unimp # Else.
 | 
			
		||||
 | 
			
		||||
.Lcompile_statement_if:
 | 
			
		||||
	call _compile_if
 | 
			
		||||
	call compile_if
 | 
			
		||||
	j .Lcompile_statement_end
 | 
			
		||||
 | 
			
		||||
.Lcompile_statement_label:
 | 
			
		||||
	call _compile_label
 | 
			
		||||
	call compile_label
 | 
			
		||||
	j .Lcompile_statement_end
 | 
			
		||||
 | 
			
		||||
.Lcompile_statement_return:
 | 
			
		||||
	call _compile_return
 | 
			
		||||
	call compile_return
 | 
			
		||||
	j .Lcompile_statement_end
 | 
			
		||||
 | 
			
		||||
.Lcompile_statement_goto:
 | 
			
		||||
	call _compile_goto
 | 
			
		||||
	call compile_goto
 | 
			
		||||
	j .Lcompile_statement_end
 | 
			
		||||
 | 
			
		||||
.Lcompile_statement_identifier:
 | 
			
		||||
	call _compile_identifier
 | 
			
		||||
	call compile_identifier
 | 
			
		||||
	j .Lcompile_statement_end
 | 
			
		||||
 | 
			
		||||
.Lcompile_statement_end:
 | 
			
		||||
@@ -1469,8 +1584,8 @@ _compile_statement:
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
# Prints ".section .text" and exits.
 | 
			
		||||
.type _compile_text_section, @function
 | 
			
		||||
_compile_text_section:
 | 
			
		||||
.type compile_text_section, @function
 | 
			
		||||
compile_text_section:
 | 
			
		||||
	# Prologue.
 | 
			
		||||
	addi sp, sp, -16
 | 
			
		||||
	sw ra, 12(sp)
 | 
			
		||||
@@ -1487,8 +1602,8 @@ _compile_text_section:
 | 
			
		||||
	addi sp, sp, 16
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
.type _compile_entry_point, @function
 | 
			
		||||
_compile_entry_point:
 | 
			
		||||
.type compile_entry_point, @function
 | 
			
		||||
compile_entry_point:
 | 
			
		||||
	# Prologue.
 | 
			
		||||
	addi sp, sp, -32
 | 
			
		||||
	sw ra, 28(sp)
 | 
			
		||||
@@ -1506,7 +1621,7 @@ _compile_entry_point:
 | 
			
		||||
	mv s1, a0 # Skip begin.
 | 
			
		||||
 | 
			
		||||
	# Generate the body of the procedure.
 | 
			
		||||
	call _compile_statements
 | 
			
		||||
	call compile_statements
 | 
			
		||||
	mv s1, a0 # Skip end.
 | 
			
		||||
 | 
			
		||||
	la a0, asm_exit
 | 
			
		||||
@@ -1519,21 +1634,21 @@ _compile_entry_point:
 | 
			
		||||
	addi sp, sp, 32
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
.type _compile, @function
 | 
			
		||||
_compile:
 | 
			
		||||
.type compile, @function
 | 
			
		||||
compile:
 | 
			
		||||
	# Prologue.
 | 
			
		||||
	addi sp, sp, -16
 | 
			
		||||
	sw ra, 12(sp)
 | 
			
		||||
	sw s0, 8(sp)
 | 
			
		||||
	addi s0, sp, 16
 | 
			
		||||
 | 
			
		||||
	call _compile_module_declaration
 | 
			
		||||
	call _compile_import
 | 
			
		||||
	call _compile_constant_section
 | 
			
		||||
	call _compile_variable_section
 | 
			
		||||
	call _compile_text_section
 | 
			
		||||
	call _compile_procedure_section
 | 
			
		||||
	call _compile_entry_point
 | 
			
		||||
	call compile_module_declaration
 | 
			
		||||
	call compile_import
 | 
			
		||||
	call compile_constant_section
 | 
			
		||||
	call compile_global_section
 | 
			
		||||
	call compile_text_section
 | 
			
		||||
	call compile_procedure_section
 | 
			
		||||
	call compile_entry_point
 | 
			
		||||
 | 
			
		||||
	# Epilogue.
 | 
			
		||||
	lw ra, 12(sp)
 | 
			
		||||
@@ -1554,7 +1669,7 @@ _start:
 | 
			
		||||
	mv s3, a0
 | 
			
		||||
 | 
			
		||||
	call symbol_table_build
 | 
			
		||||
	call _compile
 | 
			
		||||
	call compile
 | 
			
		||||
 | 
			
		||||
	# Call exit.
 | 
			
		||||
	li a0, 0   # Use 0 return code.
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,11 @@ end
 | 
			
		||||
 | 
			
		||||
proc _build_binary_expression()
 | 
			
		||||
var
 | 
			
		||||
	loca0, loca4, loca8, loca16, loca20: Word
 | 
			
		||||
	loca0: Word
 | 
			
		||||
	loca4: Word
 | 
			
		||||
	loca8: Word
 | 
			
		||||
	loca16: Word
 | 
			
		||||
	loca20: Word
 | 
			
		||||
	loca12: ^Byte
 | 
			
		||||
	loca24: Bool
 | 
			
		||||
begin
 | 
			
		||||
@@ -208,8 +212,12 @@ end
 | 
			
		||||
 | 
			
		||||
proc _build_expression()
 | 
			
		||||
var
 | 
			
		||||
	loca0, loca20, loca28, loca8: Word
 | 
			
		||||
	loca24, loca4: ^Byte
 | 
			
		||||
	loca0: Word
 | 
			
		||||
	loca20: Word
 | 
			
		||||
	loca28: Word
 | 
			
		||||
	loca8: Word
 | 
			
		||||
	loca24: ^Byte
 | 
			
		||||
	loca4: ^Byte
 | 
			
		||||
begin
 | 
			
		||||
	loca28 := loca84 + 0x30;
 | 
			
		||||
 | 
			
		||||
@@ -340,8 +348,11 @@ end
 | 
			
		||||
 | 
			
		||||
proc _compile_identifier()
 | 
			
		||||
var
 | 
			
		||||
	loca0, loca16, loca8: Word
 | 
			
		||||
	loca20, loca12: ^Byte
 | 
			
		||||
	loca0: Word
 | 
			
		||||
	loca16: Word
 | 
			
		||||
	loca8: Word
 | 
			
		||||
	loca20: ^Byte
 | 
			
		||||
	loca12: ^Byte
 | 
			
		||||
	loca4: Bool
 | 
			
		||||
begin
 | 
			
		||||
	loca20 := _current();
 | 
			
		||||
@@ -375,7 +386,9 @@ end
 | 
			
		||||
 | 
			
		||||
proc _compile_call(loca84: ^Byte, loca80: Word)
 | 
			
		||||
var
 | 
			
		||||
	loca0, loca4, loca12: Word
 | 
			
		||||
	loca0: Word
 | 
			
		||||
	loca4: Word
 | 
			
		||||
	loca12: Word
 | 
			
		||||
	loca8: ^Byte
 | 
			
		||||
begin
 | 
			
		||||
	loca12 := 0;
 | 
			
		||||
@@ -482,7 +495,8 @@ end
 | 
			
		||||
 | 
			
		||||
proc _read_token()
 | 
			
		||||
var
 | 
			
		||||
	loca0, loca4: Word
 | 
			
		||||
	loca0: Word
 | 
			
		||||
	loca4: Word
 | 
			
		||||
	loca8: ^Byte
 | 
			
		||||
begin
 | 
			
		||||
	loca8 := _current();
 | 
			
		||||
@@ -664,7 +678,8 @@ end
 | 
			
		||||
 | 
			
		||||
proc _compile_constant()
 | 
			
		||||
var
 | 
			
		||||
	loca0, loca4: Word
 | 
			
		||||
	loca0: Word
 | 
			
		||||
	loca4: Word
 | 
			
		||||
	loca8: ^Byte
 | 
			
		||||
begin
 | 
			
		||||
	loca4 := _read_token();
 | 
			
		||||
@@ -725,8 +740,11 @@ end
 | 
			
		||||
 | 
			
		||||
proc _compile_variable()
 | 
			
		||||
var
 | 
			
		||||
	loca28, loca16: ^Byte
 | 
			
		||||
	loca0, loca24, loca20: Word
 | 
			
		||||
	loca28: ^Byte
 | 
			
		||||
	loca16: ^Byte
 | 
			
		||||
	loca0: Word
 | 
			
		||||
	loca24: Word
 | 
			
		||||
	loca20: Word
 | 
			
		||||
begin
 | 
			
		||||
	loca24 := _read_token();
 | 
			
		||||
	loca28 := _current();
 | 
			
		||||
@@ -791,8 +809,13 @@ end
 | 
			
		||||
 | 
			
		||||
proc _compile_procedure()
 | 
			
		||||
var
 | 
			
		||||
	loca0, loca4, loca8, loca12, loca16: Word
 | 
			
		||||
	loca20, loca24: ^Byte
 | 
			
		||||
	loca0: Word
 | 
			
		||||
	loca4: Word
 | 
			
		||||
	loca8: Word
 | 
			
		||||
	loca12: Word
 | 
			
		||||
	loca16: Word
 | 
			
		||||
	loca20: ^Byte
 | 
			
		||||
	loca24: ^Byte
 | 
			
		||||
begin
 | 
			
		||||
	_advance(5);
 | 
			
		||||
	loca16 := _read_token();
 | 
			
		||||
@@ -971,7 +994,8 @@ end
 | 
			
		||||
proc _token_compare(loca84: ^Byte, loca80: Word, loca76: ^Byte)
 | 
			
		||||
var
 | 
			
		||||
	loca0: Bool
 | 
			
		||||
	loca4, loca12: Byte
 | 
			
		||||
	loca4: Byte
 | 
			
		||||
	loca12: Byte
 | 
			
		||||
	loca8: Word
 | 
			
		||||
begin
 | 
			
		||||
	.Ltoken_compare_loop;
 | 
			
		||||
@@ -1065,7 +1089,10 @@ end
 | 
			
		||||
 | 
			
		||||
proc _compile_if()
 | 
			
		||||
var
 | 
			
		||||
	loca8, loca12, loca16, loca20: Word
 | 
			
		||||
	loca8: Word
 | 
			
		||||
	loca12: Word
 | 
			
		||||
	loca16: Word
 | 
			
		||||
	loca20: Word
 | 
			
		||||
	loca4: ^Byte
 | 
			
		||||
begin
 | 
			
		||||
	_advance(2);
 | 
			
		||||
@@ -1368,7 +1395,8 @@ end
 | 
			
		||||
 | 
			
		||||
proc _compile()
 | 
			
		||||
var
 | 
			
		||||
	loca0, loca4: Word
 | 
			
		||||
	loca0: Word
 | 
			
		||||
	loca4: Word
 | 
			
		||||
	loca8: Bool
 | 
			
		||||
	loca12: Char
 | 
			
		||||
	loca16: ^Byte
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										198
									
								
								boot/symbol.s
									
									
									
									
									
								
							
							
						
						
									
										198
									
								
								boot/symbol.s
									
									
									
									
									
								
							@@ -2,7 +2,9 @@
 | 
			
		||||
# 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/.
 | 
			
		||||
 | 
			
		||||
.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"
 | 
			
		||||
 | 
			
		||||
@@ -54,14 +56,51 @@ symbol_table: .zero SYMBOL_PRIME
 | 
			
		||||
 | 
			
		||||
.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.
 | 
			
		||||
#
 | 
			
		||||
# Parameters:
 | 
			
		||||
# a0 - Local symbol table or 0.
 | 
			
		||||
# a1 - Length of the symbol to search.
 | 
			
		||||
# a2 - Pointer to the symbol name.
 | 
			
		||||
# a0 - Length of the symbol to search.
 | 
			
		||||
# a1 - 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
 | 
			
		||||
symbol_table_find:
 | 
			
		||||
	# Prologue.
 | 
			
		||||
@@ -75,8 +114,8 @@ symbol_table_find:
 | 
			
		||||
	sw s3, 12(sp) # Length of the symbol to search.
 | 
			
		||||
	sw s4, 8(sp) # Pointer to the symbol to search.
 | 
			
		||||
 | 
			
		||||
	mv s3, a1
 | 
			
		||||
	mv s4, a2
 | 
			
		||||
	mv s3, a0
 | 
			
		||||
	mv s4, a1
 | 
			
		||||
 | 
			
		||||
	la s1, symbol_table
 | 
			
		||||
	lw s2, 0(s1)
 | 
			
		||||
@@ -95,7 +134,7 @@ symbol_table_find:
 | 
			
		||||
	beqz a0, .Lsymbol_table_find_continue
 | 
			
		||||
 | 
			
		||||
	lw a0, 8(s1) # Pointer to the symbol.
 | 
			
		||||
	j .Lsymbol_table_end
 | 
			
		||||
	j .Lsymbol_table_find_end
 | 
			
		||||
 | 
			
		||||
.Lsymbol_table_find_continue:
 | 
			
		||||
	addi s1, s1, 12
 | 
			
		||||
@@ -105,7 +144,7 @@ symbol_table_find:
 | 
			
		||||
.Lsymbol_table_find_not_found:
 | 
			
		||||
	li a0, 0
 | 
			
		||||
 | 
			
		||||
.Lsymbol_table_end:
 | 
			
		||||
.Lsymbol_table_find_end:
 | 
			
		||||
	lw s1, 20(sp)
 | 
			
		||||
	lw s2, 16(sp)
 | 
			
		||||
	lw s3, 12(sp)
 | 
			
		||||
@@ -133,67 +172,108 @@ symbol_table_make_pointer:
 | 
			
		||||
	li a0, 8
 | 
			
		||||
	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.
 | 
			
		||||
#
 | 
			
		||||
# Sets a0 to the pointer to the global symbol table.
 | 
			
		||||
.type symbol_build, @function
 | 
			
		||||
symbol_table_build:
 | 
			
		||||
	# Prologue.
 | 
			
		||||
	addi sp, sp, -16
 | 
			
		||||
	sw ra, 12(sp)
 | 
			
		||||
	sw s0, 8(sp)
 | 
			
		||||
	addi s0, sp, 16
 | 
			
		||||
 | 
			
		||||
	la a0, symbol_table
 | 
			
		||||
	addi t0, a0, 4
 | 
			
		||||
 | 
			
		||||
	li t1, 3 # Length of the word "Int".
 | 
			
		||||
	sw t1, 0(t0)
 | 
			
		||||
	la t1, symbol_builtin_name_int
 | 
			
		||||
	sw t1, 4(t0)
 | 
			
		||||
	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 a0, 3 # Length of the word "Int".
 | 
			
		||||
	la a1, symbol_builtin_name_int
 | 
			
		||||
	la a2, symbol_builtin_type_int
 | 
			
		||||
	call symbol_table_insert
 | 
			
		||||
 | 
			
		||||
	li t1, 4 # Length of the word "Word".
 | 
			
		||||
	sw t1, 0(t0)
 | 
			
		||||
	la t1, symbol_builtin_name_word
 | 
			
		||||
	sw t1, 4(t0)
 | 
			
		||||
	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 a0, 4 # Length of the word "Word".
 | 
			
		||||
	la a1, symbol_builtin_name_word
 | 
			
		||||
	la a2, symbol_builtin_type_word
 | 
			
		||||
	call symbol_table_insert
 | 
			
		||||
 | 
			
		||||
	li t1, 4 # Length of the word "Byte".
 | 
			
		||||
	sw t1, 0(t0)
 | 
			
		||||
	la t1, symbol_builtin_name_byte
 | 
			
		||||
	sw t1, 4(t0)
 | 
			
		||||
	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 a0, 4 # Length of the word "Byte".
 | 
			
		||||
	la a1, symbol_builtin_name_byte
 | 
			
		||||
	la a2, symbol_builtin_type_byte
 | 
			
		||||
	call symbol_table_insert
 | 
			
		||||
 | 
			
		||||
	li t1, 4 # Length of the word "Char".
 | 
			
		||||
	sw t1, 0(t0)
 | 
			
		||||
	la t1, symbol_builtin_name_char
 | 
			
		||||
	sw t1, 4(t0)
 | 
			
		||||
	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 a0, 4 # Length of the word "Char".
 | 
			
		||||
	la a1, symbol_builtin_name_char
 | 
			
		||||
	la a2, symbol_builtin_type_char
 | 
			
		||||
	call symbol_table_insert
 | 
			
		||||
 | 
			
		||||
	li t1, 4 # Length of the word "Bool".
 | 
			
		||||
	sw t1, 0(t0)
 | 
			
		||||
	la t1, symbol_builtin_name_bool
 | 
			
		||||
	sw t1, 4(t0)
 | 
			
		||||
	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
 | 
			
		||||
	li a0, 4 # Length of the word "Bool".
 | 
			
		||||
	la a1, symbol_builtin_name_bool
 | 
			
		||||
	la a2, symbol_builtin_type_bool
 | 
			
		||||
	call symbol_table_insert
 | 
			
		||||
 | 
			
		||||
	# Epilogue.
 | 
			
		||||
	lw ra, 12(sp)
 | 
			
		||||
	lw s0, 8(sp)
 | 
			
		||||
	addi sp, sp, 16
 | 
			
		||||
	ret
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										14
									
								
								boot/test.elna
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								boot/test.elna
									
									
									
									
									
										Normal 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.
 | 
			
		||||
		Reference in New Issue
	
	Block a user