summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2025-05-08 23:36:29 +0200
committerEugen Wissner <belka@caraus.de>2025-05-08 23:36:29 +0200
commit92f50fff5f8a9ec2db03cc57dbf00a43e64943bf (patch)
tree0bb225b4468ff9a9b7f6ad34e38e9bef5b692b11
parent3f11d63a0f86191f010bc0093ee8616c154d9a1b (diff)
downloadelna-92f50fff5f8a9ec2db03cc57dbf00a43e64943bf.tar.gz
Parse procedure parameters
-rw-r--r--boot/stage1.s101
-rw-r--r--boot/symbol.s66
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.