;; Forth interpreter loop — interpret mode only (Phase 1). ;; Reads whitespace-delimited words, looks them up, executes. ;; Numbers (parsed via BASE) push onto the data stack. ;; Unknown words raise "?". (define forth-execute-word (fn (state word) (dict-set! word "call-count" (+ 1 (or (get word "call-count") 0))) (let ((body (get word "body"))) (body state)))) (define forth-hot-words (fn (state threshold) (forth-hot-walk (keys (get state "dict")) (get state "dict") threshold (list)))) (define forth-hot-walk (fn (names dict threshold acc) (if (= (len names) 0) acc (let ((n (first names))) (let ((w (get dict n))) (let ((c (or (get w "call-count") 0))) (forth-hot-walk (rest names) dict threshold (if (>= c threshold) (cons (list n c) acc) acc)))))))) (define forth-interpret-token (fn (state tok) (let ((w (forth-lookup state tok))) (if (not (nil? w)) (forth-execute-word state w) (let ((n (forth-parse-number tok (get (get state "vars") "base")))) (if (not (nil? n)) (forth-push state n) (forth-error state (str tok " ?")))))))) (define forth-interpret (fn (state src) (for-each (fn (tok) (forth-interpret-token state tok)) (forth-tokens src)) state)) ;; Convenience: build a fresh state with primitives loaded. (define forth-boot (fn () (let ((s (forth-make-state))) (forth-install-primitives! s) s))) ;; Run source on a fresh state and return (state, output, stack-top-to-bottom). (define forth-run (fn (src) (let ((s (forth-boot))) (forth-interpret s src) (list s (get s "output") (reverse (get s "dstack"))))))