2025-01-07 10:44:39 -06:00
|
|
|
|
(use-modules (d- test)
|
2025-09-05 09:58:11 -05:00
|
|
|
|
(scmvm assembler)
|
2026-02-15 13:24:30 -06:00
|
|
|
|
(scmvm vm forth)
|
2026-02-10 16:27:28 -06:00
|
|
|
|
(scmvm util stack)
|
2025-08-14 10:02:23 -05:00
|
|
|
|
(scmvm debugger)
|
2025-09-08 19:05:25 -05:00
|
|
|
|
(scmvm language assembly)
|
2025-11-25 17:45:18 -06:00
|
|
|
|
(scmvm language scheme)
|
2025-01-06 10:36:17 -06:00
|
|
|
|
(rnrs bytevectors)
|
2025-01-07 10:44:39 -06:00
|
|
|
|
(rnrs io ports)
|
|
|
|
|
|
((scheme base)
|
|
|
|
|
|
#:select (open-output-bytevector get-output-bytevector)))
|
|
|
|
|
|
|
|
|
|
|
|
;;; Data
|
2025-09-05 09:58:11 -05:00
|
|
|
|
(define adder-program-assembly
|
2025-06-05 14:22:12 -05:00
|
|
|
|
'((variable result 0)
|
|
|
|
|
|
(push 1)
|
2025-01-07 10:44:39 -06:00
|
|
|
|
(push 2)
|
|
|
|
|
|
(+)
|
2025-06-05 14:22:12 -05:00
|
|
|
|
(push result)
|
|
|
|
|
|
(!)
|
|
|
|
|
|
(bye)))
|
2025-01-07 10:44:39 -06:00
|
|
|
|
|
2025-09-05 09:58:11 -05:00
|
|
|
|
(define fib-program-assembly
|
2025-06-05 14:22:12 -05:00
|
|
|
|
'( (variable result 0)
|
2025-06-20 13:18:40 -05:00
|
|
|
|
(ref result)
|
2025-06-05 14:22:12 -05:00
|
|
|
|
(push fib)
|
|
|
|
|
|
(call)
|
|
|
|
|
|
(push cleanup)
|
|
|
|
|
|
(jmp)
|
2025-01-07 10:44:39 -06:00
|
|
|
|
fib
|
|
|
|
|
|
(dup)
|
|
|
|
|
|
(push 0)
|
|
|
|
|
|
(=)
|
2025-06-05 14:22:12 -05:00
|
|
|
|
(over)
|
2025-01-07 10:44:39 -06:00
|
|
|
|
(push 1)
|
|
|
|
|
|
(=)
|
2025-06-05 14:22:12 -05:00
|
|
|
|
(or)
|
|
|
|
|
|
(push recur)
|
2025-06-28 10:35:07 -05:00
|
|
|
|
(if)
|
2025-01-07 10:44:39 -06:00
|
|
|
|
(return)
|
2025-06-05 14:22:12 -05:00
|
|
|
|
recur
|
2025-01-07 10:44:39 -06:00
|
|
|
|
(dup)
|
|
|
|
|
|
(push 1)
|
|
|
|
|
|
(-)
|
2025-06-05 14:22:12 -05:00
|
|
|
|
(push fib)
|
|
|
|
|
|
(call)
|
|
|
|
|
|
(over)
|
|
|
|
|
|
(push 2)
|
|
|
|
|
|
(-)
|
|
|
|
|
|
(push fib)
|
|
|
|
|
|
(call)
|
2025-01-07 10:44:39 -06:00
|
|
|
|
(+)
|
2025-06-05 14:22:12 -05:00
|
|
|
|
(nip)
|
2025-01-07 10:44:39 -06:00
|
|
|
|
(return)
|
|
|
|
|
|
cleanup
|
2025-06-20 13:18:40 -05:00
|
|
|
|
(set! result)
|
2025-06-05 14:22:12 -05:00
|
|
|
|
(bye)))
|
2025-01-06 10:36:17 -06:00
|
|
|
|
|
2025-01-07 10:44:39 -06:00
|
|
|
|
(define adder-program-bytecode
|
2025-06-05 14:22:12 -05:00
|
|
|
|
#vu8(0 0 0 0 ; Memory address of the result
|
|
|
|
|
|
#x01 1 0 0 0 ; Push value "1"
|
2025-01-06 10:36:17 -06:00
|
|
|
|
#x01 2 0 0 0 ; Push value "2"
|
2025-06-05 14:22:12 -05:00
|
|
|
|
#x04 ; Perform "+"
|
|
|
|
|
|
#x01 1 0 0 0 ; Push the address of the result
|
|
|
|
|
|
#x02 ; Store the value
|
|
|
|
|
|
#xff ; Exit the program
|
2025-01-06 10:36:17 -06:00
|
|
|
|
))
|
|
|
|
|
|
|
2025-01-07 10:44:39 -06:00
|
|
|
|
(define fib-program-bytecode
|
2025-06-05 14:22:12 -05:00
|
|
|
|
#vu8(0 0 0 0 ; Memory address of the input, will also store the result
|
|
|
|
|
|
#x1 1 0 0 0 ; Push address of the input
|
|
|
|
|
|
#x03 ; Fetch "n"
|
|
|
|
|
|
#x1 23 0 0 0 ; Push address of "fib"
|
|
|
|
|
|
#x10 ; Call
|
|
|
|
|
|
#x01 74 0 0 0 ; Push address of "cleanup"
|
|
|
|
|
|
#x0e ; Jump
|
|
|
|
|
|
;; "fib" procedure ( n -- fib(n) )
|
|
|
|
|
|
#x16 ; Duplicate n
|
|
|
|
|
|
#x01 0 0 0 0 ; Push 0
|
|
|
|
|
|
#x0b ; Test equality
|
|
|
|
|
|
#x19 ; Over
|
|
|
|
|
|
#x01 1 0 0 0 ; Push 1
|
|
|
|
|
|
#x0b ; Test equality
|
|
|
|
|
|
#x07 ; OR the values of the last two tests
|
|
|
|
|
|
#x01 45 0 0 0 ; Push address of "recur"
|
|
|
|
|
|
#x0f ; Branch
|
|
|
|
|
|
#x11 ; Return
|
|
|
|
|
|
;; "recur" label
|
2025-01-06 17:42:06 -06:00
|
|
|
|
;; recursively calculate fib (n - 1)
|
2025-06-05 14:22:12 -05:00
|
|
|
|
#x16 ; Dupe "n"
|
|
|
|
|
|
#x01 1 0 0 0 ; Push 1
|
|
|
|
|
|
#x05 ; (n - 1)
|
|
|
|
|
|
#x01 23 0 0 0 ; Push address of "fib"
|
|
|
|
|
|
#x10 ; Call
|
2025-01-06 17:42:06 -06:00
|
|
|
|
;; recursively calculate fib (n - 2)
|
2025-06-05 14:22:12 -05:00
|
|
|
|
#x19 ; Dupe n over the result
|
|
|
|
|
|
#x01 2 0 0 0 ; Push 2
|
|
|
|
|
|
#x05 ; (n - 2)
|
|
|
|
|
|
#x01 23 0 0 0 ; Push address of fib
|
|
|
|
|
|
#x10 ; Call
|
|
|
|
|
|
#x04 ; (fib(n - 1) + fib (n - 2))
|
|
|
|
|
|
#x15 ; Nip the dupe of "n"
|
|
|
|
|
|
#x11 ; Return
|
2025-01-06 17:42:06 -06:00
|
|
|
|
;; cleanup
|
2025-06-05 14:22:12 -05:00
|
|
|
|
#x01 1 0 0 0 ; Push memory address of result
|
|
|
|
|
|
#x02 ; Store fib(n)
|
|
|
|
|
|
#xff ; Exit program
|
2025-01-06 17:42:06 -06:00
|
|
|
|
))
|
2025-01-07 10:44:39 -06:00
|
|
|
|
|
|
|
|
|
|
;;; Tests
|
2025-09-05 09:58:11 -05:00
|
|
|
|
(define-test-suite "assembly"
|
2025-01-07 10:44:39 -06:00
|
|
|
|
(define-test "adder"
|
|
|
|
|
|
(define out (open-output-bytevector))
|
2026-02-10 10:58:48 -06:00
|
|
|
|
(assemble adder-program-assembly forth-instruction-set out)
|
2025-01-07 10:44:39 -06:00
|
|
|
|
(assert-equal adder-program-bytecode (get-output-bytevector out)))
|
|
|
|
|
|
(define-test "fib"
|
|
|
|
|
|
(define out (open-output-bytevector))
|
2026-02-10 10:58:48 -06:00
|
|
|
|
(assemble fib-program-assembly forth-instruction-set out)
|
2025-01-07 10:44:39 -06:00
|
|
|
|
(assert-equal fib-program-bytecode (get-output-bytevector out))))
|
|
|
|
|
|
|
|
|
|
|
|
(define-test-suite "vm"
|
2025-01-06 10:36:17 -06:00
|
|
|
|
(define-test "adder"
|
2026-02-15 13:24:30 -06:00
|
|
|
|
(define my-vm (make-forth-vm forth-instruction-set))
|
|
|
|
|
|
(forth-vm-load-program! my-vm adder-program-bytecode)
|
|
|
|
|
|
(forth-vm-pc-set! my-vm 5)
|
|
|
|
|
|
(forth-vm-run! my-vm)
|
|
|
|
|
|
(assert-equal 3 (forth-vm-memory-ref my-vm 1)))
|
2025-01-06 17:42:06 -06:00
|
|
|
|
(define-test "fib"
|
2026-02-15 13:24:30 -06:00
|
|
|
|
(define my-vm (make-forth-vm forth-instruction-set))
|
|
|
|
|
|
(forth-vm-load-program! my-vm fib-program-bytecode)
|
|
|
|
|
|
(forth-vm-memory-set! my-vm 1 10)
|
|
|
|
|
|
(forth-vm-pc-set! my-vm 5)
|
|
|
|
|
|
(forth-vm-run! my-vm)
|
|
|
|
|
|
(assert-equal 55 (forth-vm-memory-ref my-vm 1))))
|
2025-08-14 10:02:23 -05:00
|
|
|
|
|
|
|
|
|
|
(define-test-suite "debugger"
|
|
|
|
|
|
(define-test "modify-running-program"
|
2026-02-10 10:58:48 -06:00
|
|
|
|
(define fib-program-asm (make-assembler forth-instruction-set))
|
|
|
|
|
|
(assemble-instructions! fib-program-asm fib-program-assembly)
|
|
|
|
|
|
(assembler-backpatch! fib-program-asm)
|
2026-02-15 13:24:30 -06:00
|
|
|
|
(define my-debugger (make-forth-debugger fib-program-asm))
|
2025-08-14 10:02:23 -05:00
|
|
|
|
(define my-vm (debugger-vm my-debugger))
|
2026-02-15 13:24:30 -06:00
|
|
|
|
(define my-data (forth-vm-data-stack my-vm))
|
|
|
|
|
|
(forth-vm-memory-set! my-vm 1 10)
|
|
|
|
|
|
(forth-vm-pc-set! my-vm 5)
|
2025-08-14 10:02:23 -05:00
|
|
|
|
(debugger-breakpoint-add! my-debugger 'fib)
|
|
|
|
|
|
(debugger-continue my-debugger)
|
|
|
|
|
|
(assert-equal 10 (stack-peek my-data))
|
|
|
|
|
|
(stack-pop my-data)
|
|
|
|
|
|
(stack-push my-data 1)
|
|
|
|
|
|
(debugger-continue my-debugger)
|
2026-02-15 13:24:30 -06:00
|
|
|
|
(assert-equal 1 (forth-vm-memory-ref my-vm 1)))
|
2025-08-25 17:26:11 -05:00
|
|
|
|
(define-test "stepping"
|
2026-02-10 10:58:48 -06:00
|
|
|
|
(define fib-program-asm (make-assembler forth-instruction-set))
|
|
|
|
|
|
(assemble-instructions! fib-program-asm fib-program-assembly)
|
|
|
|
|
|
(assembler-backpatch! fib-program-asm)
|
2026-02-15 13:24:30 -06:00
|
|
|
|
(define my-debugger (make-forth-debugger fib-program-asm))
|
2025-08-25 17:26:11 -05:00
|
|
|
|
(define my-vm (debugger-vm my-debugger))
|
2026-02-15 13:24:30 -06:00
|
|
|
|
(forth-vm-memory-set! my-vm 1 10)
|
|
|
|
|
|
(forth-vm-pc-set! my-vm 5)
|
2025-08-25 17:26:11 -05:00
|
|
|
|
(debugger-breakpoint-add! my-debugger 'fib)
|
|
|
|
|
|
(debugger-continue my-debugger)
|
2026-02-15 13:24:30 -06:00
|
|
|
|
(assert-equal 23 (forth-vm-pc my-vm))
|
2025-08-25 17:26:11 -05:00
|
|
|
|
(debugger-step my-debugger)
|
2026-02-15 13:24:30 -06:00
|
|
|
|
(assert-equal 24 (forth-vm-pc my-vm)) ;; dup is a 1 byte instruction
|
2025-08-25 17:26:11 -05:00
|
|
|
|
(debugger-step my-debugger)
|
2026-02-15 13:24:30 -06:00
|
|
|
|
(assert-equal 29 (forth-vm-pc my-vm)) ;; push is a 5 byte instruction
|
2025-08-25 17:26:11 -05:00
|
|
|
|
(debugger-continue my-debugger)
|
2026-02-15 13:24:30 -06:00
|
|
|
|
(assert-equal 23 (forth-vm-pc my-vm)) ;; continue stops stepping
|
2025-08-25 17:26:11 -05:00
|
|
|
|
))
|