69 lines
1.9 KiB
Org Mode
69 lines
1.9 KiB
Org Mode
* rationale?
|
|
|
|
previously, the VM's stack was used for storing local variables across blocks; a Scheme procedure was split into several low-level routines (one for the procedure itself and one for each continuation), and the stack was used as a communication channel for these separate routines. in contrast, registers were local to each routine. this aligns with Wasm's model of functions pretty well, with Wasm /locals/ acting as the VM's /registers/, and a global mutable stack serving as fallback.
|
|
|
|
this worked quite well until it became time to implement ~call/cc~.
|
|
|
|
we are considering making the following alterations to the VM:
|
|
- explicitly segment the stack into frames.
|
|
- passing procedures and return addresses on the stack.
|
|
|
|
* scratchpad
|
|
|
|
** Scheme source
|
|
|
|
#+begin_src scheme
|
|
(* 2 (call/cc
|
|
(λ (cc)
|
|
(begin (cc 6)
|
|
3))))
|
|
#+end_src
|
|
|
|
** CPS
|
|
|
|
#+begin_src scheme
|
|
(λ (ktail0)
|
|
(letrec ((with-cc
|
|
(λ (cc ktail1)
|
|
(letrec ((k0 (κ (_)
|
|
(continue ktail1 3))))
|
|
(cc 6 k0)))))
|
|
(prim (call/cc with-cc)
|
|
(κ (x1)
|
|
(prim (* 2 x1)
|
|
(κ (x2) (continue ktail0 x2)))))))
|
|
#+end_src
|
|
|
|
** stack VM
|
|
|
|
#+begin_src scheme
|
|
;; (call n) expects `n' values on the stack as arguments. then the
|
|
;; procedure is expected at index `n', and the return continuation
|
|
;; should be at `n+1'.
|
|
|
|
(define $k0
|
|
(pop! %_) ; [ _ ret ]
|
|
(push! 3) ; [ ret ]
|
|
(tail-call 1) ; [ 3 ret ]
|
|
)
|
|
|
|
(define $with-cc
|
|
(pop! %cc) ; [ cc ret ]
|
|
(push! $k0) ; [ ret ]
|
|
(push! %cc) ; [ $k0 ret ]
|
|
(push! 6) ; [ cc $k0 ret ]
|
|
;; call a procedure with one argument.
|
|
(call 1) ; [ 6 cc $k0 ret ]
|
|
)
|
|
|
|
(define $main
|
|
(pop! %ktail0) ; [ ret ]
|
|
(prim %x1 (call/cc $with-cc)) ; []
|
|
(prim %x2 (* 2 %x1)) ; []
|
|
(push! %ktail0) ; []
|
|
(push! %x2) ; [ ret ]
|
|
(tail-call 1) ; [ %x2 ret ]
|
|
)
|
|
#+end_src
|
|
|