Files
scm-to-vm/tests.scm

171 lines
5.2 KiB
Scheme
Raw Permalink Normal View History

2025-01-07 10:44:39 -06:00
(use-modules (d- test)
(scmvm assembler)
2026-02-15 13:24:30 -06:00
(scmvm vm forth)
(scmvm util stack)
2025-08-14 10:02:23 -05:00
(scmvm debugger)
2025-09-08 19:05:25 -05:00
(scmvm language assembly)
(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
(define adder-program-assembly
'((variable result 0)
(push 1)
2025-01-07 10:44:39 -06:00
(push 2)
(+)
(push result)
(!)
(bye)))
2025-01-07 10:44:39 -06:00
(define fib-program-assembly
'( (variable result 0)
(ref result)
(push fib)
(call)
(push cleanup)
(jmp)
2025-01-07 10:44:39 -06:00
fib
(dup)
(push 0)
(=)
(over)
2025-01-07 10:44:39 -06:00
(push 1)
(=)
(or)
(push recur)
2025-06-28 10:35:07 -05:00
(if)
2025-01-07 10:44:39 -06:00
(return)
recur
2025-01-07 10:44:39 -06:00
(dup)
(push 1)
(-)
(push fib)
(call)
(over)
(push 2)
(-)
(push fib)
(call)
2025-01-07 10:44:39 -06:00
(+)
(nip)
2025-01-07 10:44:39 -06:00
(return)
cleanup
(set! result)
(bye)))
2025-01-06 10:36:17 -06:00
2025-01-07 10:44:39 -06:00
(define adder-program-bytecode
#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"
#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
#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
;; recursively calculate fib (n - 1)
#x16 ; Dupe "n"
#x01 1 0 0 0 ; Push 1
#x05 ; (n - 1)
#x01 23 0 0 0 ; Push address of "fib"
#x10 ; Call
;; recursively calculate fib (n - 2)
#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
;; cleanup
#x01 1 0 0 0 ; Push memory address of result
#x02 ; Store fib(n)
#xff ; Exit program
))
2025-01-07 10:44:39 -06:00
;;; Tests
(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)))
(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
))