;; -*- Mode: Irken -*- ;; unfortunately we need pretty much have to implement a byte-level stack ;; because of the need for internal pointers etc. ;; having second thoughts now. the spec says "the call frame may not exist as a byte sequence", ;; so it sounds like in principle we can use real data structures. ;; so, considering that... what kinds of things are stored on the stack? ;; ;; * frames ;; * locals ;; * 32-bit push/pop vals ;; * 'call stubs' (which sounds like a continuation). (require "lib/basis.scm") (require "lib/codecs/hex.scm") ;; multiple senses of 'stack' here: ;; 'vstack': this is the value stack used within a frame/function ;; 'gstack': this is the stack of frames/save/continuations/etc. ;; XXX: consider 'mstack' ('machine stack') rather than 'gstack'. ;; 'dest-type/addr'. at first glance, this looks like a copy of the ;; addressing mode pair. But it's not... it encodes the type info ;; into 0..3, but ALSO includes some other values related to string ;; 'execution' contexts. So... yeah, I'll have to put that back. (typealias vstack {len=int val=(list int)}) (typealias frame {locals=(vector int) vstack=vstack}) (datatype gstack (:frame frame gstack) ;; frame, next (:save mode int int gstack) ;; dest-mode, dest-val, pc, next (:nil) ) (define (make-vstack) {len=0 val=(list:nil)}) (define (vstack/push! vs v) (set! vs.val (list:cons v vs.val)) (set! vs.len (+ 1 vs.len)) ) (define (vstack/pop! vs) (match vs.val with (hd . tl) -> (begin (set! vs.val tl) (set! vs.len (- vs.len 1)) hd) () -> (raise (:VStackUnderflow)) )) (define (vstack/stkcopy! vs n) (let ((vals (take vs.val n))) (for-list val (reverse vals) (vstack/push! vs val)))) (define (make-frame locals vstack) {locals=locals vstack=vstack} )