280 lines
5.8 KiB
ArmAsm
280 lines
5.8 KiB
ArmAsm
# This Source Code Form is subject to the terms of the Mozilla Public License,
|
|
# 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
|
|
.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"
|
|
|
|
.equ SYMBOL_PRIME, 1543
|
|
|
|
.section .rodata
|
|
|
|
.type symbol_builtin_name_int, @object
|
|
symbol_builtin_name_int: .ascii "Int"
|
|
.type symbol_builtin_name_word, @object
|
|
symbol_builtin_name_word: .ascii "Word"
|
|
.type symbol_builtin_name_byte, @object
|
|
symbol_builtin_name_byte: .ascii "Byte"
|
|
.type symbol_builtin_name_char, @object
|
|
symbol_builtin_name_char: .ascii "Char"
|
|
.type symbol_builtin_name_bool, @object
|
|
symbol_builtin_name_bool: .ascii "Bool"
|
|
|
|
# Every type info starts with a word describing what type it is.
|
|
|
|
# Primitive types have only type size.
|
|
.type symbol_builtin_type_int, @object
|
|
symbol_builtin_type_int: .word TYPE_PRIMITIVE
|
|
.word 4
|
|
.type symbol_builtin_type_word, @object
|
|
symbol_builtin_type_word: .word TYPE_PRIMITIVE
|
|
.word 4
|
|
.type symbol_builtin_type_byte, @object
|
|
symbol_builtin_type_byte: .word TYPE_PRIMITIVE
|
|
.word 1
|
|
.type symbol_builtin_type_char, @object
|
|
symbol_builtin_type_char: .word TYPE_PRIMITIVE
|
|
.word 1
|
|
.type symbol_builtin_type_bool, @object
|
|
symbol_builtin_type_bool: .word TYPE_PRIMITIVE
|
|
.word 1
|
|
|
|
.section .bss
|
|
|
|
# The first word of the symbol table is its length.
|
|
# Then a list of type infos follows:
|
|
#
|
|
# record
|
|
# name: String
|
|
# info: ^TypeInfo
|
|
# end
|
|
.type symbol_table, @object
|
|
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 - Length of the symbol to search.
|
|
# a1 - Pointer to the symbol name.
|
|
#
|
|
# 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.
|
|
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.
|
|
sw s3, 12(sp) # Length of the symbol to search.
|
|
sw s4, 8(sp) # Pointer to the symbol to search.
|
|
|
|
mv s3, a0
|
|
mv s4, a1
|
|
|
|
la s1, symbol_table
|
|
lw s2, 0(s1)
|
|
addi s1, s1, 4 # Advance to the first symbol in the table.
|
|
|
|
.Lsymbol_table_find_loop:
|
|
beqz s2, .Lsymbol_table_find_not_found
|
|
|
|
# Compare string lengths.
|
|
mv a0, s3
|
|
mv a1, s4
|
|
lw a2, 0(s1)
|
|
lw a3, 4(s1)
|
|
call _string_equal
|
|
|
|
beqz a0, .Lsymbol_table_find_continue
|
|
|
|
lw a0, 8(s1) # Pointer to the symbol.
|
|
j .Lsymbol_table_find_end
|
|
|
|
.Lsymbol_table_find_continue:
|
|
addi s1, s1, 12
|
|
addi s2, s2, -1
|
|
j .Lsymbol_table_find_loop
|
|
|
|
.Lsymbol_table_find_not_found:
|
|
li a0, 0
|
|
|
|
.Lsymbol_table_find_end:
|
|
lw s1, 20(sp)
|
|
lw s2, 16(sp)
|
|
lw s3, 12(sp)
|
|
lw s4, 8(sp)
|
|
|
|
# Epilogue.
|
|
lw ra, 28(sp)
|
|
lw s0, 24(sp)
|
|
addi sp, sp, 32
|
|
ret
|
|
|
|
# Creates a pointer type.
|
|
#
|
|
# Parameters:
|
|
# a0 - Pointer to the base type.
|
|
# a1 - Output memory.
|
|
#
|
|
# Sets a0 to the size of newly created type in bytes.
|
|
.type symbol_table_make_pointer, @function
|
|
symbol_table_make_pointer:
|
|
li t0, TYPE_POINTER
|
|
sw t0, 0(a1)
|
|
sw a0, 4(a1)
|
|
|
|
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 a0, 3 # Length of the word "Int".
|
|
la a1, symbol_builtin_name_int
|
|
la a2, symbol_builtin_type_int
|
|
call symbol_table_insert
|
|
|
|
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 a0, 4 # Length of the word "Byte".
|
|
la a1, symbol_builtin_name_byte
|
|
la a2, symbol_builtin_type_byte
|
|
call symbol_table_insert
|
|
|
|
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 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
|