diff options
| -rw-r--r-- | asm/ast_compiler_bootstrap.atk16 | 4 | ||||
| -rw-r--r-- | asm/ext_std.py | 20 | ||||
| -rw-r--r-- | asm/test_py_src.atk16 | 286 | ||||
| -rw-r--r-- | asm/test_py_src.atk16_optimized | 146 | ||||
| -rw-r--r-- | asm/test_py_src.py | 41 | ||||
| -rw-r--r-- | digital/atk16_mem.dig | 2 | ||||
| -rw-r--r-- | src/asm_ops.py | 5 | ||||
| -rw-r--r-- | src/asm_pass1.py | 9 | ||||
| -rw-r--r-- | src/asm_pass2.py | 3 | ||||
| -rw-r--r-- | src/asm_pass3.py | 2 | ||||
| -rw-r--r-- | src/asm_pass4.py | 9 | ||||
| -rw-r--r-- | src/ast_compiler.py | 108 | ||||
| -rw-r--r-- | src/bytecode_compiler.py | 6 |
13 files changed, 318 insertions, 323 deletions
diff --git a/asm/ast_compiler_bootstrap.atk16 b/asm/ast_compiler_bootstrap.atk16 index 7297c90..7036291 100644 --- a/asm/ast_compiler_bootstrap.atk16 +++ b/asm/ast_compiler_bootstrap.atk16 @@ -1,10 +1,8 @@ ;; BEGIN BOOTSTRAP -@opt stack_pointer RG -@opt csr_scratch RH - @use ext_std:* +@let sp RH @let vector_table 0x10 @let vt_ISR0 0x10 ; ISR0 @let vt_ISR1 0x11 ; ISR1 diff --git a/asm/ext_std.py b/asm/ext_std.py index f4751a3..247e605 100644 --- a/asm/ext_std.py +++ b/asm/ext_std.py @@ -78,24 +78,24 @@ def expand_sinc(imm: str) -> ExpandResult: def expand_sdec(imm: str) -> ExpandResult: return expand_subi("SP", imm, "SP") -def expand_csr(addr_reg: str): +def expand_csr(addr_reg: str, stratch_reg: str): return [ - ["lpc", "CSR_SCRATCH"], - *expand_addi("CSR_SCRATCH", "4", "CSR_SCRATCH"), - *expand_spu("CSR_SCRATCH"), + ["lpc", stratch_reg], + *expand_addi(stratch_reg, "4", stratch_reg), + *expand_spu(stratch_reg), ["jpr", addr_reg] ] -def expand_csi(addr_imm: str): +def expand_csi(addr_imm: str, stratch_reg: str): return [ - ["lpc", "CSR_SCRATCH"], - *expand_addi("CSR_SCRATCH", "4", "CSR_SCRATCH"), - *expand_spu("CSR_SCRATCH"), + ["lpc", stratch_reg], + *expand_addi(stratch_reg, "4", stratch_reg), + *expand_spu(stratch_reg), ["jpi", addr_imm] ] -def expand_rsr(): - return expand_spo("CSR_SCRATCH") + [["jpr", "CSR_SCRATCH"]] +def expand_rsr(stratch_reg: str): + return expand_spo(stratch_reg) + [["jpr", stratch_reg]] def stack_stash(*rs: str): diff --git a/asm/test_py_src.atk16 b/asm/test_py_src.atk16 index 02752ec..2d8e311 100644 --- a/asm/test_py_src.atk16 +++ b/asm/test_py_src.atk16 @@ -1,10 +1,8 @@ ;; BEGIN BOOTSTRAP -@opt stack_pointer RG -@opt csr_scratch RH - @use ext_std:* +@let sp RH @let vector_table 0x10 @let vt_ISR0 0x10 ; ISR0 @let vt_ISR1 0x11 ; ISR1 @@ -80,56 +78,41 @@ @label text_mem_addr_p 25 @label int_1 - 104 -@label int_2 - 105 + 65 +@label int_5 + 26 -; <ast.FunctionDef object at 0x1032fef50> -@label func -; stack frame names: ['return_address_0', 'arg1', 'arg2', 'a'] - addi SP 1 SP -; <ast.Assign object at 0x1032fee30> -; assigning a to stack segment + offset 7 -; <ast.Name object at 0x1032fedd0> (arg1) - ldi vt_stack_addr RC - ldr RC RC - ldi 5 RD - add RC RD RC - ldr RC RC - spu RC +; <ast.FunctionDef object at 0x1048ce500> +@label nth_letter +; stack frame with offsets +; return_address_0 3 +; n 4 +; <ast.Return object at 0x1048ce440> +; <ast.Add object at 0x1045f6ad0> +; BinOp lhs <ast.BinOp object at 0x1048ce410> +; <ast.Name object at 0x1048ce3e0> (n) ldi vt_stack_addr RA ldr RA RA - ldi 7 RB + ldi 4 RB add RA RB RA + ldr RA RA + spu RA +; BinOp rhs <ast.BinOp object at 0x1048ce410> +; <ast.Constant object at 0x1048ce3b0> + ldi int_1 RA + ldr RA RA + spu RA spo RB - str RB RA -; <ast.Return object at 0x1032feda0> + spo RA + add RA RB RA + spu RA ldi vt_stack_addr RA ldr RA RA - ldi 4 RB + ldi 3 RB add RA RB RA -; <ast.Add object at 0x10301ab60> -; BinOp lhs <ast.BinOp object at 0x1032fed70> -; <ast.Name object at 0x1032fed40> (a) - ldi vt_stack_addr RC - ldr RC RC - ldi 7 RD - add RC RD RC - ldr RC RC - spu RC -; BinOp rhs <ast.BinOp object at 0x1032fed70> -; <ast.Name object at 0x1032fed10> (a) - ldi vt_stack_addr RC - ldr RC RC - ldi 7 RD - add RC RD RC - ldr RC RC - spu RC - spo RD - spo RC - add RC RD RC - spu RC +; stack address of return address is stored in reg RA spo RB +; return value is stored in reg RB mov RA SP ldr RA RA spu RB @@ -137,109 +120,124 @@ jpr RA @label main -; stack frame names: ['i', 'graphics_mode_addr', 'text_mem_addr', 'b'] - addi SP 4 SP -; <ast.Assign object at 0x103067b80> -; assigning graphics_mode_addr to stack segment + offset 1 -; <ast.Call object at 0x1030677f0> -; Builtin call load [<ast.Name object at 0x103067fa0>] -; <ast.Name object at 0x103067fa0> (GRAPHICS_MODE_ADDR_P) +; stack frame with offsets +; graphics_mode_addr 0 +; text_mem_addr 1 +; i 2 + addi SP 3 SP +; <ast.Assign object at 0x1048ce860> +; assigning graphics_mode_addr at stack segment + 0 +; evaluating value to be assigned +; <ast.Call object at 0x1048ce800> +; Builtin call load [<ast.Name object at 0x1048ce770>] +; <ast.Name object at 0x1048ce770> (GRAPHICS_MODE_ADDR_P) ldi graphics_mode_addr_p RC ldr RC RC spu RC spo RC ldr RC RC spu RC +; assigning value to stack segment + 0 ldi vt_stack_addr RA ldr RA RA - ldi 1 RB + ldi 0 RB add RA RB RA spo RB str RB RA -; <ast.Assign object at 0x103067790> -; assigning text_mem_addr to stack segment + offset 2 -; <ast.Call object at 0x103067220> -; Builtin call load [<ast.Name object at 0x103067f40>] -; <ast.Name object at 0x103067f40> (TEXT_MEM_ADDR_P) +; <ast.Assign object at 0x1048ce740> +; assigning text_mem_addr at stack segment + 1 +; evaluating value to be assigned +; <ast.Call object at 0x1048ce6e0> +; Builtin call load [<ast.Name object at 0x1048ce650>] +; <ast.Name object at 0x1048ce650> (TEXT_MEM_ADDR_P) ldi text_mem_addr_p RC ldr RC RC spu RC spo RC ldr RC RC spu RC +; assigning value to stack segment + 1 ldi vt_stack_addr RA ldr RA RA - ldi 2 RB + ldi 1 RB add RA RB RA spo RB str RB RA -; <ast.Call object at 0x1030673d0> -; Builtin call store [<ast.Name object at 0x1032fefb0>, <ast.Name object at 0x1032fef80>] -; <ast.Name object at 0x1032fefb0> (graphics_mode_addr) +; <ast.Call object at 0x1048ce5f0> +; Builtin call store [<ast.Name object at 0x1048ce560>, <ast.Name object at 0x1048ce530>] +; <ast.Name object at 0x1048ce560> (graphics_mode_addr) ldi vt_stack_addr RA ldr RA RA - ldi 1 RB + ldi 0 RB add RA RB RA ldr RA RA spu RA -; <ast.Name object at 0x1032fef80> (TEXT_MODE) +; <ast.Name object at 0x1048ce530> (TEXT_MODE) ldi text_mode RA ldr RA RA spu RA spo RB spo RA str RB RA -; <ast.Assign object at 0x1032fecb0> -; assigning b to stack segment + offset 3 -; <ast.Call object at 0x1032fec50> -; Call function func +; <ast.Assign object at 0x1048ce350> +; assigning i at stack segment + 2 +; evaluating value to be assigned +; <ast.Constant object at 0x1048ce2f0> ldi 0 RC spu RC -; <ast.Constant object at 0x1032febf0> - ldi 1 RC - spu RC -; <ast.Constant object at 0x1032febc0> - ldi 3 RC - spu RC -; set up return address and jump to subroutine - subi SP 3 RC - lpc RD - addi RD 3 RD - str RD RC - jpi func +; assigning value to stack segment + 2 ldi vt_stack_addr RA ldr RA RA - ldi 3 RB + ldi 2 RB add RA RB RA spo RB str RB RA -; <ast.Assign object at 0x1032feb90> -; assigning i to stack segment + offset 0 -; <ast.Constant object at 0x1032feb30> - ldi 0 RC - spu RC - ldi vt_stack_addr RA - ldr RA RA - ldi 0 RB - add RA RB RA +; <ast.Call object at 0x1048ce290> +; Builtin call asm [<ast.Constant object at 0x1048ce200>] + ldi 0b111111111 RG +; <ast.While object at 0x1048ce1d0> +@label while_test_2 +; <ast.Name object at 0x1048ce170> (i) + ldi vt_stack_addr RB + ldr RB RB + ldi 2 RC + add RB RC RB + ldr RB RB + spu RB +; <ast.Constant object at 0x1048ce140> + ldi int_5 RB + ldr RB RB + spu RB + spo RC spo RB - str RB RA -; <ast.Call object at 0x1032fead0> -; Builtin call store [<ast.BinOp object at 0x1032fea40>, <ast.Call object at 0x1032fe9b0>] -; <ast.Add object at 0x10301ab60> -; BinOp lhs <ast.BinOp object at 0x1032fea40> -; <ast.Name object at 0x1032fea10> (text_mem_addr) + sub RB RC RB + bri carry Compare_true_6 + ldi 0 RB + spu RB + jpi Compare_end_7 +@label compare_true_6 + ldi 1 RB + spu RB +@label compare_end_7 + spo RA + addi RA 0 RA + bri zero While_else_3 +; <ast.Call object at 0x1048ce0e0> +; Builtin call store [<ast.BinOp object at 0x1048ce050>, <ast.Call object at 0x1048cdd80>] +; <ast.Add object at 0x1045f6ad0> +; BinOp lhs <ast.BinOp object at 0x1048ce050> +; <ast.Name object at 0x1048ce020> (text_mem_addr) ldi vt_stack_addr RA ldr RA RA - ldi 2 RB + ldi 1 RB add RA RB RA ldr RA RA spu RA -; BinOp rhs <ast.BinOp object at 0x1032fea40> -; <ast.Name object at 0x1032fe9e0> (i) +; BinOp rhs <ast.BinOp object at 0x1048ce050> +; <ast.Name object at 0x1048cdff0> (i) ldi vt_stack_addr RA ldr RA RA - ldi 0 RB + ldi 2 RB add RA RB RA ldr RA RA spu RA @@ -247,82 +245,66 @@ spo RA add RA RB RA spu RA -; <ast.Call object at 0x1032fe9b0> -; Builtin call ord [<ast.Constant object at 0x1032fe920>] -; <ast.Constant object at 0x1032fe920> - ldi int_1 RA +; <ast.Call object at 0x1048cdd80> +; Call function nth_letter + ldi 0 RA + spu RA +; <ast.Name object at 0x1048cdd20> (i) + ldi vt_stack_addr RA + ldr RA RA + ldi 2 RB + add RA RB RA ldr RA RA spu RA +; set up return address and jump to subroutine + subi SP 2 RA + lpc RB + addi RB 3 RB + str RB RA + jpi nth_letter spo RB spo RA str RB RA -; <ast.Assign object at 0x1032fe8f0> -; assigning i to stack segment + offset 0 -; <ast.Add object at 0x10301ab60> -; BinOp lhs <ast.BinOp object at 0x1032fe890> -; <ast.Name object at 0x1032fe860> (i) +; <ast.Assign object at 0x1048ccc70> +; assigning i at stack segment + 2 +; evaluating value to be assigned +; <ast.Add object at 0x1045f6ad0> +; BinOp lhs <ast.BinOp object at 0x1048cda50> +; <ast.Name object at 0x1048cd750> (i) ldi vt_stack_addr RC ldr RC RC - ldi 0 RD + ldi 2 RD add RC RD RC ldr RC RC spu RC -; BinOp rhs <ast.BinOp object at 0x1032fe890> -; <ast.Constant object at 0x1032fe830> +; BinOp rhs <ast.BinOp object at 0x1048cda50> +; <ast.Constant object at 0x1048cd720> ldi 1 RC spu RC spo RD spo RC add RC RD RC spu RC - ldi vt_stack_addr RA - ldr RA RA - ldi 0 RB - add RA RB RA - spo RB - str RB RA -; <ast.Call object at 0x1032fe7d0> -; Builtin call store [<ast.BinOp object at 0x1032fe740>, <ast.Call object at 0x1032fe6b0>] -; <ast.Add object at 0x10301ab60> -; BinOp lhs <ast.BinOp object at 0x1032fe740> -; <ast.Name object at 0x1032fe710> (text_mem_addr) +; assigning value to stack segment + 2 ldi vt_stack_addr RA ldr RA RA ldi 2 RB add RA RB RA - ldr RA RA - spu RA -; BinOp rhs <ast.BinOp object at 0x1032fe740> -; <ast.Name object at 0x1032fe6e0> (i) - ldi vt_stack_addr RA - ldr RA RA - ldi 0 RB - add RA RB RA - ldr RA RA - spu RA - spo RB - spo RA - add RA RB RA - spu RA -; <ast.Call object at 0x1032fe6b0> -; Builtin call ord [<ast.Constant object at 0x1032fe620>] -; <ast.Constant object at 0x1032fe620> - ldi int_2 RA - ldr RA RA - spu RA spo RB - spo RA str RB RA -; <ast.While object at 0x1032fe5f0> -@label while_test_3 -; <ast.Constant object at 0x1032fe5c0> + jpi While_test_2 +@label while_else_3 +@label while_end_4 +; <ast.While object at 0x1048cd0f0> +@label while_test_8 +; <ast.Constant object at 0x1048cd060> ldi 1 RB spu RB spo RA addi RA 0 RA - bri zero While_else_4 -; <ast.Pass object at 0x1032fe590> - jpi While_test_3 -@label while_else_4 -@label while_end_5 - subi SP 4 SP + bri zero While_else_9 +; <ast.Pass object at 0x1048ccfa0> + jpi While_test_8 +@label while_else_9 +@label while_end_10 + subi SP 3 SP diff --git a/asm/test_py_src.atk16_optimized b/asm/test_py_src.atk16_optimized index 601dfad..f526853 100644 --- a/asm/test_py_src.atk16_optimized +++ b/asm/test_py_src.atk16_optimized @@ -1,6 +1,5 @@ -@opt stack_pointer RG -@opt csr_scratch RH @use ext_std:* +@let sp RH @let vector_table 0x10 @let vt_ISR0 0x10 @let vt_ISR1 0x11 @@ -65,53 +64,37 @@ @label text_mem_addr_p 25 @label int_1 - 104 -@label int_2 - 105 -@label func - addi SP 1 SP - ldi vt_stack_addr RC - ldr RC RC - ldi 5 RD - add RC RD RC - ldr RC RC - spu RC + 65 +@label int_5 + 26 +@label nth_letter ldi vt_stack_addr RA ldr RA RA - ldi 7 RB + ldi 4 RB add RA RB RA - spo RB - str RB RA + ldr RA RA + ldi int_1 RB + ldr RB RB + add RA RB RA + spu RA ldi vt_stack_addr RA ldr RA RA - ldi 4 RB + ldi 3 RB add RA RB RA - ldi vt_stack_addr RC - ldr RC RC - ldi 7 RD - add RC RD RC - ldr RC RC - spu RC - ldi vt_stack_addr RC - ldr RC RC - ldi 7 RD - add RC RD RC - ldr RC RD - spo RC - add RC RD RB + spo RB mov RA SP ldr RA RA spu RB jpr RA @label main - addi SP 4 SP + addi SP 3 SP ldi graphics_mode_addr_p RC ldr RC RC ldr RC RC spu RC ldi vt_stack_addr RA ldr RA RA - ldi 1 RB + ldi 0 RB add RA RB RA spo RB str RB RA @@ -121,13 +104,13 @@ spu RC ldi vt_stack_addr RA ldr RA RA - ldi 2 RB + ldi 1 RB add RA RB RA spo RB str RB RA ldi vt_stack_addr RA ldr RA RA - ldi 1 RB + ldi 0 RB add RA RB RA ldr RA RA ldi text_mode RB @@ -135,48 +118,66 @@ str RB RA ldi 0 RC spu RC - ldi 1 RC - spu RC - ldi 3 RC - spu RC - subi SP 3 RC - lpc RD - addi RD 3 RD - str RD RC - jpi func ldi vt_stack_addr RA ldr RA RA - ldi 3 RB + ldi 2 RB add RA RB RA spo RB str RB RA - ldi 0 RC - spu RC - ldi vt_stack_addr RA - ldr RA RA + ldi 0b111111111 RG +@label while_test_2 + ldi vt_stack_addr RB + ldr RB RB + ldi 2 RC + add RB RC RB + ldr RB RB + ldi int_5 RC + ldr RC RC + sub RB RC RB + bri carry Compare_true_6 ldi 0 RB - add RA RB RA - spo RB - str RB RA + spu RB + jpi Compare_end_7 +@label compare_true_6 + ldi 1 RB + spu RB +@label compare_end_7 + spo RA + addi RA 0 RA + bri zero While_else_3 ldi vt_stack_addr RA ldr RA RA - ldi 2 RB + ldi 1 RB add RA RB RA ldr RA RA spu RA ldi vt_stack_addr RA ldr RA RA - ldi 0 RB + ldi 2 RB add RA RB RA ldr RA RB spo RA add RA RB RA - ldi int_1 RB - ldr RB RB + spu RA + ldi 0 RA + spu RA + ldi vt_stack_addr RA + ldr RA RA + ldi 2 RB + add RA RB RA + ldr RA RA + spu RA + subi SP 2 RA + lpc RB + addi RB 3 RB + str RB RA + jpi nth_letter + spo RB + spo RA str RB RA ldi vt_stack_addr RC ldr RC RC - ldi 0 RD + ldi 2 RD add RC RD RC ldr RC RC ldi 1 RD @@ -184,31 +185,18 @@ spu RC ldi vt_stack_addr RA ldr RA RA - ldi 0 RB - add RA RB RA - spo RB - str RB RA - ldi vt_stack_addr RA - ldr RA RA ldi 2 RB add RA RB RA - ldr RA RA - spu RA - ldi vt_stack_addr RA - ldr RA RA - ldi 0 RB - add RA RB RA - ldr RA RB - spo RA - add RA RB RA - ldi int_2 RB - ldr RB RB + spo RB str RB RA -@label while_test_3 + jpi While_test_2 +@label while_else_3 +@label while_end_4 +@label while_test_8 ldi 1 RA addi RA 0 RA - bri zero While_else_4 - jpi While_test_3 -@label while_else_4 -@label while_end_5 - subi SP 4 SP
\ No newline at end of file + bri zero While_else_9 + jpi While_test_8 +@label while_else_9 +@label while_end_10 + subi SP 3 SP
\ No newline at end of file diff --git a/asm/test_py_src.py b/asm/test_py_src.py index ca816de..74ea60d 100644 --- a/asm/test_py_src.py +++ b/asm/test_py_src.py @@ -1,43 +1,28 @@ import atk16 + TEXT_MODE: atk16.ConstInt = 1 GRAPHICS_MODE_ADDR_P: atk16.ConstInt = 0x17 -graphics_mode_addr = atk16.load(GRAPHICS_MODE_ADDR_P) - TEXT_MEM_ADDR_P: atk16.ConstInt = 0x19 + +graphics_mode_addr = atk16.load(GRAPHICS_MODE_ADDR_P) text_mem_addr = atk16.load(TEXT_MEM_ADDR_P) atk16.store(graphics_mode_addr, TEXT_MODE) -def func(arg1: int, arg2: int) -> int: - a = arg1 - return a + a -b = func(1, 3) +def nth_letter(n: int) -> int: + return n + 65 i = 0 -atk16.store(text_mem_addr + i, atk16.ord("h")) -i = i + 1 -atk16.store(text_mem_addr + i, atk16.ord("i")) +atk16.asm("ldi 0b111111111 RG") +while i < 26: + # bug: stack frame offset for nth_letter is calculated + # one off because text_mem_addr + i takes up one + # stack slot + atk16.store(text_mem_addr + i, nth_letter(i)) + #atk16.store(text_mem_addr + i, i + 65) + i = i + 1 while True: pass - -# atk16.asm("@label keepalive") -# atk16.asm(" jpi keepalive") - -# TEXT_MODE: atk16.ConstInt = 1 -# GRAPHICS_MODE_ADDR: atk16.ConstInt = 0x17 - -# atk16.store(GRAPHICS_MODE_ADDR, TEXT_MODE) -# atk16.store(0xF800, 'H') -# atk16.store(0xF801, 'E') -# atk16.store(0xF802, 'L') -# atk16.store(0xF803, 'L') -# atk16.store(0xF804, 'O') - -# a = atk16.call_inline( -# atk16.load(0xF000) -# ) - -# atk16.asm("ldi 1 RA") diff --git a/digital/atk16_mem.dig b/digital/atk16_mem.dig index d09244e..629a6af 100644 --- a/digital/atk16_mem.dig +++ b/digital/atk16_mem.dig @@ -34,7 +34,7 @@ </entry> <entry> <string>Data</string> - <data>4014,2c00,6028,8000,8000,8000,8000,8000,8000,8000,8000,8000,8000,8000,8000,8000,001c,001a,001a,001a,8000,e000,e001,e002,e800,f800,4855,f000,3180,1d88,3188,1d88,4016,2000,2000,4215,2240,3040,1d89,2380,1d89,2180,e000,4017,2000,4200,3008,602c,0001,0017,0019,0068,0069,1d88,4414,2480,4605,0498,2480,3190,1d88,4014,2000,4207,0008,1d89,2380,3008,4014,2000,4204,0008,4414,2480,4607,0498,2480,3190,1d88,4414,2480,4607,0498,2680,1d89,2580,0298,1c00,2000,3188,1d88,5000,1da0,4431,2480,2480,3190,1d88,4014,2000,4201,0008,1d89,2380,3008,4432,2480,2480,3190,1d88,4014,2000,4202,0008,1d89,2380,3008,4014,2000,4201,0008,2000,4230,2240,3008,4400,3190,1d88,4401,3190,1d88,4403,3190,1d88,1599,9600,16d8,3098,61aa,4014,2000,4203,0008,1d89,2380,3008,4400,3190,1d88,4014,2000,4200,0008,1d89,2380,3008,4014,2000,4202,0008,2000,3180,1d88,4014,2000,4200,0008,2200,1d89,2180,0008,4233,2240,3008,4414,2480,4600,0498,2480,4601,0498,3190,1d88,4014,2000,4200,0008,1d89,2380,3008,4014,2000,4202,0008,2000,3180,1d88,4014,2000,4200,0008,2200,1d89,2180,0008,4234,2240,3008,4001,1000,8401,61fc,1da1</data> + <data>4014,2e00,6028,8000,8000,8000,8000,8000,8000,8000,8000,8000,8000,8000,8000,8000,001c,001a,001a,001a,8000,e000,e001,e002,e800,f800,4855,f000,31c0,1fc8,31c8,1fc8,4016,2000,2000,4215,2240,3040,1fc9,23c0,1fc9,21c0,e000,4017,2000,4200,3008,601a,0001,0017,0019,0041,001a,4014,2000,4204,0008,2000,4233,2240,0008,31c0,1fc8,4014,2000,4203,0008,1fc9,23c0,1e00,2000,31c8,1fc8,5000,1fd8,4431,2480,2480,31d0,1fc8,4014,2000,4200,0008,1fc9,23c0,3008,4432,2480,2480,31d0,1fc8,4014,2000,4201,0008,1fc9,23c0,3008,4014,2000,4200,0008,2000,4230,2240,3008,4400,31d0,1fc8,4014,2000,4202,0008,1fc9,23c0,3008,4dff,4214,2240,4402,0250,2240,4434,2480,0251,8004,4200,31c8,1fc8,6003,4201,31c8,1fc8,1fc9,21c0,1000,8436,4014,2000,4201,0008,2000,31c0,1fc8,4014,2000,4202,0008,2200,1fc9,21c0,0008,31c0,1fc8,4000,31c0,1fc8,4014,2000,4202,0008,2000,31c0,1fc8,11d1,9200,1258,3008,618b,1fc9,23c0,1fc9,21c0,3008,4414,2480,4602,0498,2480,4601,0498,31d0,1fc8,4014,2000,4202,0008,1fc9,23c0,3008,61b6,4001,1000,8401,61fc,1fd9</data> </entry> </elementAttributes> <pos x="740" y="100" /> diff --git a/src/asm_ops.py b/src/asm_ops.py index e09e0fd..885c275 100644 --- a/src/asm_ops.py +++ b/src/asm_ops.py @@ -3,11 +3,6 @@ from asm_eval import * from dataclasses import dataclass @dataclass -class Options: - stack_pointer = "rg" - csr_scratch = "rh" - -@dataclass class Meta: address: int diff --git a/src/asm_pass1.py b/src/asm_pass1.py index 5e6213a..0b06738 100644 --- a/src/asm_pass1.py +++ b/src/asm_pass1.py @@ -16,23 +16,15 @@ class Result1Line: @dataclass class Result1: lines: list[Result1Line] - options: Options operations: OpExpansionDict def pass_1(result0: Result0) -> Result1: - options = Options() result_lines: list[Result1Line] = [] operations: OpExpansionDict = default_expansions.copy() for line in result0.lines: keyword, *args = tokenize(line.line) match keyword: - case "@opt": - opt_name, opt_value = args - match opt_name: - case "stack_pointer": options.stack_pointer = opt_value - case "csr_scratch": options.csr_scratch = opt_value - case _: raise Exception("Unknown @opt: " + opt_name) case "@use": module_name, ops = args[0].split(":") ops_split = ops.split(",") @@ -52,6 +44,5 @@ def pass_1(result0: Result0) -> Result1: return Result1( operations=operations, - options=options, lines=result_lines ) diff --git a/src/asm_pass2.py b/src/asm_pass2.py index 7272dcf..e2ad4ec 100644 --- a/src/asm_pass2.py +++ b/src/asm_pass2.py @@ -13,11 +13,9 @@ class Result2Line: @dataclass class Result2: lines: list[Result2Line] - options: Options operations: OpExpansionDict def pass_2(result1: Result1) -> Result2: - options = Options() result_lines: list[Result2Line] = [] for line in result1.lines: @@ -38,6 +36,5 @@ def pass_2(result1: Result1) -> Result2: return Result2( operations=result1.operations, - options=options, lines=result_lines ) diff --git a/src/asm_pass3.py b/src/asm_pass3.py index 7fcb44d..9c8cb34 100644 --- a/src/asm_pass3.py +++ b/src/asm_pass3.py @@ -14,7 +14,6 @@ class Result3Line: @dataclass class Result3: lines: list[Result3Line] - options: Options operations: OpExpansionDict symbols: dict[str, int] @@ -57,7 +56,6 @@ def pass_3(result2: Result2) -> Result3: raise Exception(f"Overlapping segments: address 0x{result_line.address:>04x} has conflicting definitions:\n{formatted}") return Result3( operations=result2.operations, - options=result2.options, lines=result_lines, symbols=symbols, ) diff --git a/src/asm_pass4.py b/src/asm_pass4.py index bb30eb7..2fff870 100644 --- a/src/asm_pass4.py +++ b/src/asm_pass4.py @@ -15,16 +15,9 @@ class Result4Line: @dataclass class Result4: lines: list[Result4Line] - options: Options operations: OpExpansionDict symbols: dict[str, int] -def translate_opt(arg: str, options: Options) -> str: - match arg: - case "SP": return options.stack_pointer - case "CSR_SCRATCH": return options.csr_scratch - case _: return arg - def pass_4(result3: Result3) -> Result4: result_lines: list[Result4Line] = [] @@ -34,7 +27,6 @@ def pass_4(result3: Result3) -> Result4: address=line.address, ) - args = list(map(lambda a: translate_opt(a, result3.options), args)) text = " ".join([keyword, *args]) original_text = " ".join(line.original_parts) @@ -65,6 +57,5 @@ def pass_4(result3: Result3) -> Result4: return Result4( operations=result3.operations, symbols=result3.symbols, - options=result3.options, lines=result_lines, ) diff --git a/src/ast_compiler.py b/src/ast_compiler.py index e6e78bf..d3fd70e 100644 --- a/src/ast_compiler.py +++ b/src/ast_compiler.py @@ -28,9 +28,8 @@ class Reg(): return f"R{self.reg}" ALL_REGS: list[RegChar] = ["A", "B", "C", "D", "E", "F", "G", "H"] -STACK_POINTER_REG = "G" -CSR_SCRATCH_REG = "H" -SPECIAL_REGS: list[RegChar] = [STACK_POINTER_REG, CSR_SCRATCH_REG] +STACK_POINTER_REG = "H" +SPECIAL_REGS: list[RegChar] = [STACK_POINTER_REG] GENERIC_REGS: OrderedDict[RegChar, None] = OrderedDict() for char in ALL_REGS: if char not in SPECIAL_REGS: @@ -84,6 +83,7 @@ class Compiler(ast.NodeVisitor): self.currently_emitting_asm_list = self.program_asm self.frame_stack = FrameStack() + self.tmp_stack_values_n: int = 0 self.unique_name_counter = 0 self.latest_break_target: Label | None = None @@ -113,6 +113,14 @@ class Compiler(ast.NodeVisitor): self.currently_emitting_asm_list.append(asm) + def emit_stack_push(self, reg: str): + self.tmp_stack_values_n += 1 + self.emit(f"spu {reg}") + + def emit_stack_pop(self, reg: str): + self.tmp_stack_values_n -= 1 + self.emit(f"spo {reg}") + def emit_label(self, label_name: str): label_name = label_name.lower() self.emit(f"@label {label_name}") @@ -219,17 +227,15 @@ class Compiler(ast.NodeVisitor): stmts = node.body frame_names = self.collect_local_variables(stmts) - self.emit(f"; stack frame names: {frame_names}") - # Move stack pointer to accommodate local variables - - # TODO instead of self.stack_frame_size, use a proper stack for frames. - # That way, we can restore the top-level stack frame when returning + self.emit("; stack frame with offsets") frame_bindings: dict[str, Label | StackOffset] = {} for idx, name in enumerate(frame_names): offset = self.frame_stack.total_offset() + idx frame_bindings[name] = offset + self.emit(f"; {name} {offset}") + frame = Frame( names = frame_names, bindings = frame_bindings, @@ -238,15 +244,19 @@ class Compiler(ast.NodeVisitor): self.emit(f"addi SP {len(frame.names)} SP") for stmt in stmts: + if type(stmt) == ast.Expr and type(stmt.value) != ast.Call: + self.emit("; NOP top-level expression") + continue + self.visit(stmt) self.frame_stack.pop() self.emit(f"subi SP {len(frame.names)} SP") def visit_Expr(self, expr: ast.Expr): - if self.frame_stack.size == 1 and type(expr.value) != ast.Call: - self.emit("; NOP top-level expression") - return + # if self.frame_stack.size == 1 and type(expr.value) != ast.Call: + # self.emit("; NOP top-level expression") + # return self.visit(expr.value) @@ -381,16 +391,62 @@ class Compiler(ast.NodeVisitor): self.emit(f"bri zero {label_false}") for true_branch_stmt in node.body: + if type(true_branch_stmt) == ast.Expr and type(true_branch_stmt.value) != ast.Call: + self.emit("; NOP top-level expression") + continue + self.visit(true_branch_stmt) self.emit(f"jpi {label_end}") self.emit_label(label_false) for false_branch_stmt in node.orelse: + if type(false_branch_stmt) == ast.Expr and type(false_branch_stmt.value) != ast.Call: + self.emit("; NOP top-level expression") + continue + self.visit(false_branch_stmt) self.emit_label(label_end) + def visit_Compare(self, node: ast.Compare): + if len(node.ops) > 1: + raise Exception("Multiple compare ops not supported") + + if len(node.comparators) > 1: + raise Exception("Multiple comparators not supported") + + op = node.ops[0] + left = node.left + right = node.comparators[0] + + self.visit(left) + self.visit(right) + + label_true = self.get_unique_name("Compare_true") + label_end = self.get_unique_name("Compare_end") + + with self.allocated_reg() as reg_lhs, self.allocated_reg() as reg_rhs: + match op: + case ast.Lt(): # lhs < rhs + self.emit(f"spo {reg_rhs}") + self.emit(f"spo {reg_lhs}") + + self.emit(f"sub {reg_lhs} {reg_rhs} {reg_lhs}") + self.emit(f"bri carry {label_true}") + + # false branch + self.emit(f"ldi 0 {reg_lhs}") + self.emit(f"spu {reg_lhs}") + self.emit(f"jpi {label_end}") + + # true branch + self.emit_label(label_true) + self.emit(f"ldi 1 {reg_lhs}") + self.emit(f"spu {reg_lhs}") + + self.emit_label(label_end) + def visit_While(self, node: ast.While): self.emit(f"; {node}") @@ -409,6 +465,10 @@ class Compiler(ast.NodeVisitor): self.emit(f"bri zero {label_else}") for body_stmt in node.body: + if type(body_stmt) == ast.Expr and type(body_stmt.value) != ast.Call: + self.emit("; NOP top-level expression") + continue + self.visit(body_stmt) self.emit(f"jpi {label_test}") @@ -441,6 +501,7 @@ class Compiler(ast.NodeVisitor): raise Exception("Lambda functions not supported. Consider using a named function instead.") def collect_local_variables(self, stmts: list[ast.stmt]): + result: list[str] = [] symbols: list[str] = [] for stmt in stmts: match stmt: @@ -455,8 +516,11 @@ class Compiler(ast.NodeVisitor): symbols += self.collect_local_variables(fb) case other: pass - # remove duplicates - return list(set(symbols)) + for symbol in symbols: + if symbol not in result: + result.append(symbol) + + return result def visit_FunctionDef(self, node: ast.FunctionDef): prev_currently_emitting_asm_list = self.currently_emitting_asm_list @@ -478,16 +542,19 @@ class Compiler(ast.NodeVisitor): return_address_name = self.get_unique_name("return_address") local_var_names = self.collect_local_variables(fn_stmts) frame_names = [return_address_name] + fn_params + local_var_names - self.emit(f"; stack frame names: {frame_names}") # Move stack pointer to accommodate local variables - self.emit(f"addi SP {len(local_var_names)} SP") + if len(local_var_names) > 0: + self.emit(f"addi SP {len(local_var_names)} SP") + self.emit("; stack frame with offsets") frame_bindings: dict[str, Label | StackOffset] = {} for idx, name in enumerate(frame_names): offset = self.frame_stack.total_offset() + idx frame_bindings[name] = offset + self.emit(f"; {name} {offset}") + frame = Frame( names = frame_names, bindings = frame_bindings @@ -509,21 +576,24 @@ class Compiler(ast.NodeVisitor): frame = self.frame_stack.peek() ret = node.value + if ret is not None: + self.visit(ret) with self.allocated_reg() as reg1, self.allocated_reg() as reg2: - print(frame.names) ret_addr_offset = self.frame_stack.total_offset() - frame.size() self.emit(f"ldi vt_stack_addr {reg1}") # vector table address of stack segment address self.emit(f"ldr {reg1} {reg1}") # stack segment address self.emit(f"ldi {ret_addr_offset} {reg2}") # stack offset self.emit(f"add {reg1} {reg2} {reg1}") # stack address of return address = stack segment start + stack offset + self.emit(f"; stack address of return address is stored in reg {reg1}") if ret is not None: - self.visit(ret) self.emit(f"spo {reg2}") else: self.emit(f"ldi 0 {reg2}") + self.emit(f"; return value is stored in reg {reg2}") + self.emit(f"mov {reg1} SP") # reset stack pointer to return address position (i.e. start of stack frame) self.emit(f"ldr {reg1} {reg1}") # return address @@ -609,10 +679,12 @@ class Compiler(ast.NodeVisitor): if type(offset) != StackOffset: raise Exception(f"Invalid address {offset} for name {name}. Can only assign to stack offsets.") - self.emit(f"; assigning {name} to stack segment + offset {offset}") + self.emit(f"; assigning {name} at stack segment + {offset}") with self.allocated_reg() as reg1, self.allocated_reg() as reg2: + self.emit(f"; evaluating value to be assigned") self.visit(value) + self.emit(f"; assigning value to stack segment + {offset}") self.emit(f"ldi vt_stack_addr {reg1}") self.emit(f"ldr {reg1} {reg1}") self.emit(f"ldi {offset} {reg2}") diff --git a/src/bytecode_compiler.py b/src/bytecode_compiler.py index 2a5bc82..0492ddb 100644 --- a/src/bytecode_compiler.py +++ b/src/bytecode_compiler.py @@ -94,10 +94,8 @@ def emit_serialize_const(const: Any): print(f"warn: cannot serialize {type(const)} ({const}), emitting zero") emit(" 0") -STACK_POINTER_REG = Reg('G') -CSR_SCRATCH_REG = Reg('H') -emit(f"@opt stack_pointer {STACK_POINTER_REG}") -emit(f"@opt csr_scratch {CSR_SCRATCH_REG}") +STACK_POINTER_REG = Reg('H') +emit(f"@let SP {STACK_POINTER_REG}") emit("@use ext_std:*") emit("@include bootstrap") |
