From 92f50fff5f8a9ec2db03cc57dbf00a43e64943bf Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Thu, 8 May 2025 23:36:29 +0200 Subject: [PATCH] Parse procedure parameters --- boot/stage1.s | 101 ++++++++++++++++++++++++++++++++++++++++++-------- boot/symbol.s | 66 ++++++++++++++++++++++++++++++++- 2 files changed, 150 insertions(+), 17 deletions(-) diff --git a/boot/stage1.s b/boot/stage1.s index b39f5bc..efbd521 100644 --- a/boot/stage1.s +++ b/boot/stage1.s @@ -989,6 +989,90 @@ _compile_variable: addi sp, sp, 48 ret +.type _compile_type_expression, @function +_compile_type_expression: + # Prologue. + addi sp, sp, -32 + sw ra, 28(sp) + sw s0, 24(sp) + addi s0, sp, 32 + +.Lcompile_type_expression_type: + mv a0, s1 + addi a1, sp, 12 + call _tokenize_next + mv s1, a0 + lw t0, 12(sp) + + # Skip the pointer designator and handle the rest of the type. + li t1, TOKEN_HAT + beq t0, t1, .Lcompile_type_expression_type + + /* DEBUG */ + lw a0, 20(sp) + lw a1, 16(sp) + call _write_error + + # Epilogue. + lw ra, 28(sp) + lw s0, 24(sp) + addi sp, sp, 32 + ret + +.type _compile_parameters, @function +_compile_parameters: + # Prologue. + addi sp, sp, -32 + sw ra, 28(sp) + sw s0, 24(sp) + addi s0, sp, 32 + + mv a0, s1 + addi a1, sp, 12 + call _tokenize_next + mv s1, a0 # Skip the opening paren. + + mv a0, s1 + addi a1, sp, 12 + call _tokenize_next + + lw t0, 12(sp) + li t1, TOKEN_RIGHT_PAREN + beq t0, t1, .Lcompile_parameters_end + # When this is not the right paren, it is an identifier. + mv s1, a0 + +.Lcompile_parameters_parameter: + mv a0, s1 + addi a1, sp, 0 + call _tokenize_next + mv s1, a0 # Skip the ":" in front of the type. + + call _compile_type_expression + # Read the comma between the parameters or a closing paren. + mv a0, s1 + addi a1, sp, 0 + call _tokenize_next + + lw t0, 0(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 + call _tokenize_next + mv s1, a0 + + j .Lcompile_parameters_parameter + +.Lcompile_parameters_end: + mv s1, a0 # Skip the closing paren. + + # Epilogue. + lw ra, 28(sp) + lw s0, 24(sp) + addi sp, sp, 32 + ret + .type _compile_procedure, @function _compile_procedure: # Prologue. @@ -1008,6 +1092,7 @@ _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: @@ -1033,22 +1118,6 @@ _compile_procedure: call _compile_statements mv s1, a0 # Skip end. - /* DEBUG - sw a0, 8(sp) - lw a1, 12(sp) - li a2, TOKEN_END - sub a1, a1, a2 - seqz a1, a1 - seqz a0, a0 - addi a0, a0, '0' - addi a1, a1, '0' - sb a0, 4(sp) - sb a1, 5(sp) - addi a0, sp, 4 - li a1, 2 - call _write_error - lw a0, 8(sp) */ - # Generate the procedure epilogue with a predefined stack size. la a0, epilogue li a1, EPILOGUE_SIZE diff --git a/boot/symbol.s b/boot/symbol.s index 66409aa..a927b0e 100644 --- a/boot/symbol.s +++ b/boot/symbol.s @@ -2,7 +2,7 @@ # 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 +.global symbol_table_build, symbol_table_find .include "boot/definitions.inc" @@ -49,6 +49,70 @@ 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.