# 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_build, symbol_table_find .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" # 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 .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 # 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. # # Sets a0 to the symbol info. .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, a1 mv s4, a2 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. lw a2, 0(s1) bne s3, a2, .Lsymbol_table_find_continue # If lengths match, compare the content. mv a0, s4 lw a1, 4(s1) call _memcmp bnez a0, .Lsymbol_table_find_continue lw a0, 8(s1) # Pointer to the symbol. j .Lsymbol_table_end .Lsymbol_table_find_continue: addi s2, s2, -1 j .Lsymbol_table_find_loop .Lsymbol_table_find_not_found: li a0, 0 .Lsymbol_table_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 # Build the initial symbols. # # Sets a0 to the pointer to the global symbol table. .type symbol_build, @function symbol_table_build: 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 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 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 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 ret