From 707f983fe96e4ad9bf89b07a0b4e88465c7d111f Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Sat, 10 May 2025 23:24:03 +0200 Subject: [PATCH] Add symbol info for parameters and local variables --- Rakefile | 16 ++ boot/definitions.inc | 2 + boot/stage1.s | 391 ++++++++++++++++++++++++++++--------------- boot/stage2.elna | 58 +++++-- boot/symbol.s | 198 +++++++++++++++------- boot/test.elna | 14 ++ 6 files changed, 467 insertions(+), 212 deletions(-) create mode 100644 boot/test.elna diff --git a/Rakefile b/Rakefile index 57d3784..6b38038 100644 --- a/Rakefile +++ b/Rakefile @@ -20,3 +20,19 @@ task default: ['build/boot/stage2b', 'build/boot/stage2b.s', 'boot/stage2.elna'] diff_arguments = ['diff', '-Nur', '--text', previous_output, '-'] Open3.pipeline(cat_arguments, compiler_arguments, diff_arguments) end + +file 'build/boot/test.s' => ['build/boot/stage1', 'boot/test.elna'] do |t| + source, exe = t.prerequisites.partition { |prerequisite| prerequisite.end_with? '.elna' } + + File.open t.name, 'w' do |output| + assemble_stage output, exe, source + end +end + +file 'build/boot/test' => ['build/boot/test.s', 'boot/common-boot.s'] do |t| + sh CROSS_GCC, '-nostdlib', '-o', t.name, *t.prerequisites +end + +task test: 'build/boot/test' do |t| + sh QEMU, '-L', SYSROOT, t.prerequisites.first +end diff --git a/boot/definitions.inc b/boot/definitions.inc index 574838c..731dda3 100644 --- a/boot/definitions.inc +++ b/boot/definitions.inc @@ -62,3 +62,5 @@ # .equ TYPE_PRIMITIVE, 0x01 .equ TYPE_POINTER, 0x02 +.equ INFO_PARAMETER, 0x10 +.equ INFO_LOCAL, 0x20 diff --git a/boot/stage1.s b/boot/stage1.s index e1d50cd..d957af2 100644 --- a/boot/stage1.s +++ b/boot/stage1.s @@ -85,8 +85,8 @@ source_code: .zero SOURCE_BUFFER_SIZE .section .text # Ignores the import. -.type _compile_import, @function -_compile_import: +.type compile_import, @function +compile_import: # Prologue. addi sp, sp, -24 sw ra, 20(sp) @@ -227,8 +227,8 @@ compile_binary_expression: # a1 - Identifier length. # # Sets a0 to 1 if the identifier starts with "loca", otherwise to 0. -.type _is_local_identifier, @function -_is_local_identifier: +.type is_local_identifier, @function +is_local_identifier: # Prologue. addi sp, sp, -16 sw ra, 12(sp) @@ -255,8 +255,8 @@ _is_local_identifier: # a1 - Identifier length. # # Sets a0 to 1 if the identifier is a preserved register, otherwise to 0. -.type _is_register_identifier, @function -_is_register_identifier: +.type is_register_identifier, @function +is_register_identifier: # Prologue. addi sp, sp, -8 sw ra, 4(sp) @@ -279,8 +279,8 @@ _is_register_identifier: # Parameters: # a0 - Identifier length. # a1 - Register number as character. -.type _compile_identifier_expression, @function -_compile_identifier_expression: +.type compile_identifier_expression, @function +compile_identifier_expression: # Prologue. addi sp, sp, -32 sw ra, 28(sp) @@ -290,24 +290,32 @@ _compile_identifier_expression: sw a0, 20(sp) # Identifier length. sw a1, 16(sp) # Register number as character. + lw a0, 20(sp) + mv a1, s1 + call symbol_table_find + sw a0, 12(sp) + mv a0, s1 lw a1, 20(sp) - call _is_local_identifier + call is_local_identifier bnez a0, .Lcompile_identifier_expression_local mv a0, s1 lw a1, 20(sp) - call _is_register_identifier + call is_register_identifier bnez a0, .Lcompile_identifier_expression_saved + lw t0, 12(sp) + bnez t0, .Lcompile_identifier_expression_defined + # Global identifier. lw t1, 16(sp) li t0, 0x00202c00 # \0,_ or t0, t0, t1 - sw t0, 12(sp) - li t0, 0x6120616c # la a sw t0, 8(sp) - addi a0, sp, 8 + li t0, 0x6120616c # la a + sw t0, 4(sp) + addi a0, sp, 4 li a1, 7 call _write_out @@ -326,26 +334,51 @@ _compile_identifier_expression: li t0, 0x0a290061 # a\0)\n sll t2, t1, 8 or t0, t0, t2 - sw t0, 12(sp) + sw t0, 8(sp) li t0, 0x28202c00 # \0, ( or t0, t0, t1 + sw t0, 4(sp) + li t0, 0x6120776c # lw a + sw t0, 0(sp) + addi a0, sp, 0 + li a1, 12 + call _write_out + + j .Lcompile_identifier_expression_end + +.Lcompile_identifier_expression_defined: + lw t1, 16(sp) + li t0, 0x00202c00 # \0,_ + or t0, t0, t1 sw t0, 8(sp) li t0, 0x6120776c # lw a sw t0, 4(sp) addi a0, sp, 4 - li a1, 12 + li a1, 7 call _write_out + lw a0, 12(sp) + lw a0, 8(a0) + call _printi + + li t0, 0x29707328 # (sp) + sw t0, 8(sp) + addi a0, sp, 8 + li a1, 4 + call _write_out + li a0, '\n' + call _put_char + j .Lcompile_identifier_expression_end .Lcompile_identifier_expression_saved: li t0, 0x00202c00 # \0,_ lw t1, 16(sp) or t0, t0, t1 - sw t0, 12(sp) - li t0, 0x6120766d # mv a sw t0, 8(sp) - addi a0, sp, 8 + li t0, 0x6120766d # mv a + sw t0, 4(sp) + addi a0, sp, 4 li a1, 7 call _write_out @@ -362,10 +395,10 @@ _compile_identifier_expression: lw t1, 16(sp) li t0, 0x00202c00 # \0,_ or t0, t0, t1 - sw t0, 12(sp) - li t0, 0x6120776c # lw a sw t0, 8(sp) - addi a0, sp, 8 + li t0, 0x6120776c # lw a + sw t0, 4(sp) + addi a0, sp, 4 li a1, 7 call _write_out @@ -376,8 +409,8 @@ _compile_identifier_expression: call _write_out li t0, 0x29707328 # (sp) - sw t0, 12(sp) - addi a0, sp, 12 + sw t0, 8(sp) + addi a0, sp, 8 li a1, 4 call _write_out li a0, '\n' @@ -431,7 +464,7 @@ _build_expression: lw s1, 32(sp) lw a0, 28(sp) lw a1, 36(sp) - call _compile_identifier_expression + call compile_identifier_expression j .Lbuild_expression_advance @@ -485,7 +518,7 @@ _build_expression: lw a0, 32(sp) lw a1, 28(sp) - call _compile_call + call compile_call j .Lbuild_expression_end @@ -524,8 +557,8 @@ _build_expression: # Parameters: # a0 - Pointer to the identifier. # a1 - Identifier length. -.type _compile_designator_expression, @function -_compile_designator_expression: +.type compile_designator_expression, @function +compile_designator_expression: # Prologue. addi sp, sp, -32 sw ra, 28(sp) @@ -537,12 +570,12 @@ _compile_designator_expression: lw a0, 20(sp) lw a1, 16(sp) - call _is_local_identifier + call is_local_identifier bnez a0, .Lcompile_designator_expression_local lw a0, 20(sp) lw a1, 16(sp) - call _is_register_identifier + call is_register_identifier bnez a0, .Lcompile_designator_expression_saved .Lcompile_designator_expression_local: @@ -603,8 +636,8 @@ _compile_designator_expression: # # Left values should be variables named "loca n", where n is the offset # of the variable on the stack, like loca8 or loca4. -.type _compile_identifier, @function -_compile_identifier: +.type compile_identifier, @function +compile_identifier: # Prologue. addi sp, sp, -32 sw ra, 28(sp) @@ -632,7 +665,7 @@ _compile_identifier: .Lcompile_identifier_call: lw a0, 20(sp) lw a1, 16(sp) - call _compile_call + call compile_call j .Lcompile_identifier_end @@ -640,7 +673,7 @@ _compile_identifier: call compile_binary_expression lw a0, 20(sp) lw a1, 16(sp) - call _compile_designator_expression + call compile_designator_expression j .Lcompile_identifier_end @@ -656,8 +689,8 @@ _compile_identifier: # a1 - Length of the procedure name. # # Returns the procedure result in a0. -.type _compile_call, @function -_compile_call: +.type compile_call, @function +compile_call: # Prologue. addi sp, sp, -32 sw ra, 28(sp) @@ -748,8 +781,8 @@ _compile_call: ret # Walks through the procedure definitions. -.type _compile_procedure_section, @function -_compile_procedure_section: +.type compile_procedure_section, @function +compile_procedure_section: # Prologue. addi sp, sp, -32 sw ra, 28(sp) @@ -764,7 +797,7 @@ _compile_procedure_section: lw t1, 4(sp) bne t0, t1, .Lcompile_procedure_section_end - call _compile_procedure + call compile_procedure j .Lcompile_procedure_section_loop @@ -775,8 +808,8 @@ _compile_procedure_section: addi sp, sp, 32 ret -.type _compile_module_declaration, @function -_compile_module_declaration: +.type compile_module_declaration, @function +compile_module_declaration: # Prologue. addi sp, sp, -24 sw ra, 20(sp) @@ -799,8 +832,8 @@ _compile_module_declaration: addi sp, sp, 24 ret -.type _compile_constant_section, @function -_compile_constant_section: +.type compile_constant_section, @function +compile_constant_section: # Prologue. addi sp, sp, -32 sw ra, 28(sp) @@ -830,7 +863,7 @@ _compile_constant_section: bne t0, t1, .Lcompile_constant_section_end lw s1, 20(sp) - call _compile_constant + call compile_constant j .Lcompile_constant_section_item .Lcompile_constant_section_end: @@ -840,8 +873,8 @@ _compile_constant_section: addi sp, sp, 32 ret -.type _compile_constant, @function -_compile_constant: +.type compile_constant, @function +compile_constant: # Prologue. addi sp, sp, -32 sw ra, 28(sp) @@ -886,8 +919,9 @@ _compile_constant: addi sp, sp, 32 ret -.type _compile_variable_section, @function -_compile_variable_section: +# Compiles global variable section. +.type compile_global_section, @function +compile_global_section: # Prologue. addi sp, sp, -32 sw ra, 28(sp) @@ -899,36 +933,37 @@ _compile_variable_section: call lex_next li t0, TOKEN_VAR lw t1, 4(sp) - bne t0, t1, .Lcompile_variable_section_end + bne t0, t1, .Lcompile_global_section_end mv s1, a0 la a0, section_bss li a1, SECTION_BSS_SIZE call _write_out -.Lcompile_variable_section_item: +.Lcompile_global_section_item: mv a0, s1 addi a1, sp, 12 call lex_next + lw t0, 12(sp) li t1, TOKEN_IDENTIFIER - bne t0, t1, .Lcompile_variable_section_end + bne t0, t1, .Lcompile_global_section_end lw s1, 20(sp) # Advance to the beginning of the variable name. - call _compile_variable - j .Lcompile_variable_section_item + call compile_global + j .Lcompile_global_section_item -.Lcompile_variable_section_end: +.Lcompile_global_section_end: # Epilogue. lw ra, 28(sp) lw s0, 24(sp) addi sp, sp, 32 ret -# Compile a global variable. -.type _compile_variable, @function -_compile_variable: +# Compiles a global variable. +.type compile_global, @function +compile_global: # Prologue. addi sp, sp, -48 sw ra, 44(sp) @@ -1010,29 +1045,10 @@ compile_type_expression: beq t0, t1, .Lcompile_type_expression_pointer # Named type. - mv a0, zero - lw a1, 16(sp) - lw a2, 20(sp) + lw a0, 16(sp) + lw a1, 20(sp) call symbol_table_find - /* DEBUG - sw a0, 4(sp) - - lw a0, 4(a0) - addi a0, a0, '0' - sw a0, 8(sp) - - lw a0, 20(sp) - lw a1, 16(sp) - call _write_error - - addi a0, sp, 8 - li a1, 1 - call _write_error - - lw a0, 4(sp) */ - /* DEBUG */ - j .Lcompile_type_expression_end .Lcompile_type_expression_pointer: @@ -1051,24 +1067,87 @@ compile_type_expression: addi sp, sp, 32 ret -.type _compile_parameters, @function -_compile_parameters: +# Inserts local procedure variables into the symbol table. +.type compile_local_section, @function +compile_local_section: # Prologue. - addi sp, sp, -32 - sw ra, 28(sp) - sw s0, 24(sp) - addi s0, sp, 32 + addi sp, sp, -48 + sw ra, 44(sp) + sw s0, 40(sp) + addi s0, sp, 48 mv a0, s1 - addi a1, sp, 12 + addi a1, sp, 28 + call lex_next + + lw t0, 28(sp) + li t1, TOKEN_VAR + + bne t0, t1, .Lcompile_local_section_end + mv s1, a0 + + sw zero, 12(sp) # Variable offset counter. + +.Lcompile_local_section_variable: + mv a0, s1 + addi a1, sp, 28 + call lex_next + + lw t0, 28(sp) + li t1, TOKEN_IDENTIFIER + + bne t0, t1, .Lcompile_local_section_end + addi a1, sp, 16 + call lex_next + mv s1, a0 # Skip the ":" in front of the type. + + call compile_type_expression + # a0 - Variable type. + lw a1, 12(sp) + mv a2, s3 + call symbol_table_make_local + + mv a2, s3 + add s3, s3, a0 + + lw a0, 32(sp) + lw a1, 36(sp) + call symbol_table_insert + + lw t0, 12(sp) + addi t0, t0, 4 + sw t0, 12(sp) + + j .Lcompile_local_section_variable + +.Lcompile_local_section_end: + # Epilogue. + lw ra, 44(sp) + lw s0, 40(sp) + addi sp, sp, 48 + ret + +# Inserts procedure parameters into the symbol table. +.type compile_parameters, @function +compile_parameters: + # Prologue. + addi sp, sp, -48 + sw ra, 44(sp) + sw s0, 40(sp) + addi s0, sp, 48 + + sw zero, 12(sp) # Parameter offset counter. + + mv a0, s1 + addi a1, sp, 28 call lex_next mv s1, a0 # Skip the opening paren. mv a0, s1 - addi a1, sp, 12 + addi a1, sp, 28 call lex_next - lw t0, 12(sp) + lw t0, 28(sp) li t1, TOKEN_RIGHT_PAREN beq t0, t1, .Lcompile_parameters_end # When this is not the right paren, it is an identifier. @@ -1076,21 +1155,37 @@ _compile_parameters: .Lcompile_parameters_parameter: mv a0, s1 - addi a1, sp, 0 + addi a1, sp, 16 call lex_next mv s1, a0 # Skip the ":" in front of the type. call compile_type_expression + # a0 - Parameter type. + lw a1, 12(sp) + mv a2, s3 + call symbol_table_make_parameter + + mv a2, s3 + add s3, s3, a0 + + lw a0, 32(sp) + lw a1, 36(sp) + call symbol_table_insert + + lw t0, 12(sp) + addi t0, t0, 4 + sw t0, 12(sp) + # Read the comma between the parameters or a closing paren. mv a0, s1 - addi a1, sp, 0 + addi a1, sp, 16 call lex_next - lw t0, 0(sp) + lw t0, 16(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 + addi a1, sp, 16 call lex_next mv s1, a0 @@ -1100,13 +1195,13 @@ _compile_parameters: mv s1, a0 # Skip the closing paren. # Epilogue. - lw ra, 28(sp) - lw s0, 24(sp) - addi sp, sp, 32 + lw ra, 44(sp) + lw s0, 40(sp) + addi sp, sp, 48 ret -.type _compile_procedure, @function -_compile_procedure: +.type compile_procedure, @function +compile_procedure: # Prologue. addi sp, sp, -32 sw ra, 28(sp) @@ -1124,17 +1219,19 @@ _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: + # Save the state of the symbol table before we enter the procedure scope. + la t0, symbol_table + lw t0, (t0) + sw t0, 8(sp) + + call compile_parameters + call compile_local_section + + # Skip the "begin" keyword, denoting the beginning of the procedure body. mv a0, s1 - addi a1, sp, 4 + addi a1, sp, 12 call lex_next mv s1, a0 - lw t0, 4(sp) - li t1, TOKEN_BEGIN - bne t0, t1, .Lcompile_procedure_begin # Generate the procedure prologue with a predefined stack size. la a0, prologue @@ -1147,7 +1244,7 @@ _compile_procedure: call _write_out # Generate the body of the procedure. - call _compile_statements + call compile_statements mv s1, a0 # Skip end. # Generate the procedure epilogue with a predefined stack size. @@ -1155,6 +1252,24 @@ _compile_procedure: li a1, EPILOGUE_SIZE call _write_out + /* DEBUG + lw a0, 16(sp) + lw a1, 20(sp) + call symbol_table_find + beqz a0, .x +*/ + lw a0, 20(sp) + lw a1, 16(sp) + call _write_error + + call symbol_table_dump + /* DEBUG */ + + # Restore the symbol table, removing symbols local to this procedure. + la t0, symbol_table + lw t1, 8(sp) + sw t1, (t0) + # Epilogue. lw ra, 28(sp) lw s0, 24(sp) @@ -1162,8 +1277,8 @@ _compile_procedure: ret # Compiles a goto statement to an uncoditional jump. -.type _compile_goto, @function -_compile_goto: +.type compile_goto, @function +compile_goto: # Prologue. addi sp, sp, -32 sw ra, 28(sp) @@ -1199,8 +1314,8 @@ _compile_goto: ret # Rewrites a label to assembly. -.type _compile_label, @function -_compile_label: +.type compile_label, @function +compile_label: # Prologue. addi sp, sp, -32 sw ra, 28(sp) @@ -1231,8 +1346,8 @@ _compile_label: ret # Just skips the return keyword and evaluates the return expression. -.type _compile_return, @function -_compile_return: +.type compile_return, @function +compile_return: # Prologue. addi sp, sp, -32 sw ra, 28(sp) @@ -1252,8 +1367,8 @@ _compile_return: addi sp, sp, 32 ret -.type _compile_if, @function -_compile_if: +.type compile_if, @function +compile_if: # Prologue. addi sp, sp, -32 sw ra, 28(sp) @@ -1294,7 +1409,7 @@ _compile_if: li a0, '\n' call _put_char - call _compile_statements + call compile_statements mv s1, a0 # Skip end. # Write the label prefix. @@ -1372,8 +1487,8 @@ _write_procedure_head: # # Sets a0 to the end of the token finishing the list # (should be the "end" token in a valid program). -.type _compile_statements, @function -_compile_statements: +.type compile_statements, @function +compile_statements: # Prologue. addi sp, sp, -32 sw ra, 28(sp) @@ -1390,7 +1505,7 @@ _compile_statements: beq t0, t1, .Lcompile_statements_end .Lcompile_statements_body: - call _compile_statement + call compile_statement mv a0, s1 addi a1, sp, 0 @@ -1411,8 +1526,8 @@ _compile_statements: ret # Checks for the type of the current statement and compiles it. -.type _compile_statement, @function -_compile_statement: +.type compile_statement, @function +compile_statement: # Prologue. addi sp, sp, -32 sw ra, 28(sp) @@ -1442,23 +1557,23 @@ _compile_statement: unimp # Else. .Lcompile_statement_if: - call _compile_if + call compile_if j .Lcompile_statement_end .Lcompile_statement_label: - call _compile_label + call compile_label j .Lcompile_statement_end .Lcompile_statement_return: - call _compile_return + call compile_return j .Lcompile_statement_end .Lcompile_statement_goto: - call _compile_goto + call compile_goto j .Lcompile_statement_end .Lcompile_statement_identifier: - call _compile_identifier + call compile_identifier j .Lcompile_statement_end .Lcompile_statement_end: @@ -1469,8 +1584,8 @@ _compile_statement: ret # Prints ".section .text" and exits. -.type _compile_text_section, @function -_compile_text_section: +.type compile_text_section, @function +compile_text_section: # Prologue. addi sp, sp, -16 sw ra, 12(sp) @@ -1487,8 +1602,8 @@ _compile_text_section: addi sp, sp, 16 ret -.type _compile_entry_point, @function -_compile_entry_point: +.type compile_entry_point, @function +compile_entry_point: # Prologue. addi sp, sp, -32 sw ra, 28(sp) @@ -1506,7 +1621,7 @@ _compile_entry_point: mv s1, a0 # Skip begin. # Generate the body of the procedure. - call _compile_statements + call compile_statements mv s1, a0 # Skip end. la a0, asm_exit @@ -1519,21 +1634,21 @@ _compile_entry_point: addi sp, sp, 32 ret -.type _compile, @function -_compile: +.type compile, @function +compile: # Prologue. addi sp, sp, -16 sw ra, 12(sp) sw s0, 8(sp) addi s0, sp, 16 - call _compile_module_declaration - call _compile_import - call _compile_constant_section - call _compile_variable_section - call _compile_text_section - call _compile_procedure_section - call _compile_entry_point + call compile_module_declaration + call compile_import + call compile_constant_section + call compile_global_section + call compile_text_section + call compile_procedure_section + call compile_entry_point # Epilogue. lw ra, 12(sp) @@ -1554,7 +1669,7 @@ _start: mv s3, a0 call symbol_table_build - call _compile + call compile # Call exit. li a0, 0 # Use 0 return code. diff --git a/boot/stage2.elna b/boot/stage2.elna index 695f52a..6c11543 100644 --- a/boot/stage2.elna +++ b/boot/stage2.elna @@ -19,7 +19,11 @@ end proc _build_binary_expression() var - loca0, loca4, loca8, loca16, loca20: Word + loca0: Word + loca4: Word + loca8: Word + loca16: Word + loca20: Word loca12: ^Byte loca24: Bool begin @@ -208,8 +212,12 @@ end proc _build_expression() var - loca0, loca20, loca28, loca8: Word - loca24, loca4: ^Byte + loca0: Word + loca20: Word + loca28: Word + loca8: Word + loca24: ^Byte + loca4: ^Byte begin loca28 := loca84 + 0x30; @@ -340,8 +348,11 @@ end proc _compile_identifier() var - loca0, loca16, loca8: Word - loca20, loca12: ^Byte + loca0: Word + loca16: Word + loca8: Word + loca20: ^Byte + loca12: ^Byte loca4: Bool begin loca20 := _current(); @@ -375,7 +386,9 @@ end proc _compile_call(loca84: ^Byte, loca80: Word) var - loca0, loca4, loca12: Word + loca0: Word + loca4: Word + loca12: Word loca8: ^Byte begin loca12 := 0; @@ -482,7 +495,8 @@ end proc _read_token() var - loca0, loca4: Word + loca0: Word + loca4: Word loca8: ^Byte begin loca8 := _current(); @@ -664,7 +678,8 @@ end proc _compile_constant() var - loca0, loca4: Word + loca0: Word + loca4: Word loca8: ^Byte begin loca4 := _read_token(); @@ -725,8 +740,11 @@ end proc _compile_variable() var - loca28, loca16: ^Byte - loca0, loca24, loca20: Word + loca28: ^Byte + loca16: ^Byte + loca0: Word + loca24: Word + loca20: Word begin loca24 := _read_token(); loca28 := _current(); @@ -791,8 +809,13 @@ end proc _compile_procedure() var - loca0, loca4, loca8, loca12, loca16: Word - loca20, loca24: ^Byte + loca0: Word + loca4: Word + loca8: Word + loca12: Word + loca16: Word + loca20: ^Byte + loca24: ^Byte begin _advance(5); loca16 := _read_token(); @@ -971,7 +994,8 @@ end proc _token_compare(loca84: ^Byte, loca80: Word, loca76: ^Byte) var loca0: Bool - loca4, loca12: Byte + loca4: Byte + loca12: Byte loca8: Word begin .Ltoken_compare_loop; @@ -1065,7 +1089,10 @@ end proc _compile_if() var - loca8, loca12, loca16, loca20: Word + loca8: Word + loca12: Word + loca16: Word + loca20: Word loca4: ^Byte begin _advance(2); @@ -1368,7 +1395,8 @@ end proc _compile() var - loca0, loca4: Word + loca0: Word + loca4: Word loca8: Bool loca12: Char loca16: ^Byte diff --git a/boot/symbol.s b/boot/symbol.s index 71a58e3..fe88aef 100644 --- a/boot/symbol.s +++ b/boot/symbol.s @@ -2,7 +2,9 @@ # 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, symbol_table_make_pointer +.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" @@ -54,14 +56,51 @@ 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 - Local symbol table or 0. -# a1 - Length of the symbol to search. -# a2 - Pointer to the symbol name. +# a0 - Length of the symbol to search. +# a1 - Pointer to the symbol name. # -# Sets a0 to the symbol info. +# 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. @@ -75,8 +114,8 @@ symbol_table_find: 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 + mv s3, a0 + mv s4, a1 la s1, symbol_table lw s2, 0(s1) @@ -95,7 +134,7 @@ symbol_table_find: beqz a0, .Lsymbol_table_find_continue lw a0, 8(s1) # Pointer to the symbol. - j .Lsymbol_table_end + j .Lsymbol_table_find_end .Lsymbol_table_find_continue: addi s1, s1, 12 @@ -105,7 +144,7 @@ symbol_table_find: .Lsymbol_table_find_not_found: li a0, 0 -.Lsymbol_table_end: +.Lsymbol_table_find_end: lw s1, 20(sp) lw s2, 16(sp) lw s3, 12(sp) @@ -133,67 +172,108 @@ symbol_table_make_pointer: 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 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 a0, 3 # Length of the word "Int". + la a1, symbol_builtin_name_int + la a2, symbol_builtin_type_int + call symbol_table_insert - 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 a0, 4 # Length of the word "Word". + la a1, symbol_builtin_name_word + la a2, symbol_builtin_type_word + call symbol_table_insert - 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 a0, 4 # Length of the word "Byte". + la a1, symbol_builtin_name_byte + la a2, symbol_builtin_type_byte + call symbol_table_insert - 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 + 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 t1, 4 # Length of the word "Bool". - sw t1, 0(t0) - la t1, symbol_builtin_name_bool - sw t1, 4(t0) - la t1, symbol_builtin_type_bool - sw t1, 8(t0) - lw t1, 0(a0) - addi t1, t1, 1 - sw t1, 0(a0) - addi t0, t0, 12 + 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 diff --git a/boot/test.elna b/boot/test.elna new file mode 100644 index 0000000..f4ce4c5 --- /dev/null +++ b/boot/test.elna @@ -0,0 +1,14 @@ +program + +proc _main(x: Word) +var loca0: Word +loca4: Word +begin + loca0 := 0x0a2c3061; + loca4 := x; + _write_out(@loca4, 4) +end + +begin + _main() +end.