aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--asm/ast_compiler_bootstrap.atk164
-rw-r--r--asm/ext_std.py20
-rw-r--r--asm/test_py_src.atk16286
-rw-r--r--asm/test_py_src.atk16_optimized146
-rw-r--r--asm/test_py_src.py41
-rw-r--r--digital/atk16_mem.dig2
-rw-r--r--src/asm_ops.py5
-rw-r--r--src/asm_pass1.py9
-rw-r--r--src/asm_pass2.py3
-rw-r--r--src/asm_pass3.py2
-rw-r--r--src/asm_pass4.py9
-rw-r--r--src/ast_compiler.py108
-rw-r--r--src/bytecode_compiler.py6
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")