# 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