aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Tuomi <jan@jantuomi.fi>2025-03-05 22:08:17 +0200
committerJan Tuomi <jan@jantuomi.fi>2025-03-05 22:08:17 +0200
commitff8a3bc4ac48f8025d793c078f4c6d2ffbce4019 (patch)
tree1acef1429d0a4776a6eb2450732a8d8c570c1a71
parent4932c084731d87bf6039535f28dd7c0a40af73bc (diff)
Add procedure declaration & call macros
-rw-r--r--atk16_schasm/macros.scm54
-rw-r--r--atk16_schasm/main.scm19
2 files changed, 65 insertions, 8 deletions
diff --git a/atk16_schasm/macros.scm b/atk16_schasm/macros.scm
index 1a32cd4..38aa26b 100644
--- a/atk16_schasm/macros.scm
+++ b/atk16_schasm/macros.scm
@@ -72,7 +72,7 @@
(define-syntax %if
(syntax-rules ()
- ((_ pred tb)
+ ((_ pred body body* ...)
(let* ((lhs (eval (car 'pred)))
(op (cadr 'pred))
(rhs (eval (caddr 'pred)))
@@ -82,6 +82,56 @@
(emit-inverted-test *macro-scratch-reg* op rhs sym-end)
- tb
+ body body* ...
+
(def-label sym-end)))))
+(define-syntax %while
+ (syntax-rules ()
+ ((_ pred body body* ...)
+ (let* ((lhs (eval (car 'pred)))
+ (op (cadr 'pred))
+ (rhs (eval (caddr 'pred)))
+ (n (next-unique))
+ (sym-test (string->symbol (format "~A-test" n)))
+ (sym-end (string->symbol (format "~A-end" n))))
+ (ld *macro-scratch-reg* lhs)
+
+ (def-label sym-test)
+ (emit-inverted-test *macro-scratch-reg* op rhs sym-end)
+
+ body body* ...
+
+ (ld PC (label sym-test))
+ (def-label sym-end)))))
+
+(define *procedures* '())
+
+(define-syntax %def-proc
+ (syntax-rules ()
+ ((_ name params* ...)
+ (set! *procedures*
+ (cons (list 'name 'params* ...) *procedures*)))))
+
+(define-syntax %call
+ (syntax-rules ()
+ ((_ name args* ...)
+ (let* ((params (or (assocdr 'name *procedures*)
+ (error "proc not defined" 'name)))
+ (args (list args* ...))
+ (n (next-unique))
+ (sym-ret (string->symbol (format "~A-ret" n))))
+
+ (unless (= (length params) (length args))
+ (error (format "incorrect args, expected ~A, got ~A" params args)))
+
+ (let loop ((i 0))
+ (when (< i (length args))
+ (let* ((rn (reg i)))
+ (ld rn (list-ref args i)))
+ (loop (+ 1 i))))
+
+ (st SP (label sym-ret) push: #t)
+ (ld PC (label 'name))
+ (def-label sym-ret)
+ ))))
diff --git a/atk16_schasm/main.scm b/atk16_schasm/main.scm
index 3258a7f..a3f16ad 100644
--- a/atk16_schasm/main.scm
+++ b/atk16_schasm/main.scm
@@ -47,7 +47,7 @@
(def-label 'branch-true
(emit-word 2))
-;; use macros for convenience
+;; use macros like %if, %while for convenience
(let ((x #x5678))
(%if-else (R1 == R2)
(emit-word #x1234)
@@ -56,11 +56,18 @@
(%if (R1 <= (u16 #xFF))
(emit-word #xbeef))
-(comment
- (ld R1 (u16 10))
- (%while (R1 > (u16 0))
- (%call println (label 'text-data))
- (sub R1 (u16 1))))
+;; procedure declarations
+(%def-proc println str)
+(def-label 'println
+ ;; R0 := str
+ ;; ...
+ (ld PC SP pop: #t indirect: 1))
+
+;; procedure calls
+(ld R1 (u16 10))
+(%while (R1 > (u16 0))
+ (%call println (label 'text-data))
+ (sub R1 (u16 1)))
;; compile to a 128KB image file
(write-image-to "out.bin")