diff --git a/forge/sf.lisp b/forge/sf.lisp index ecb65a9..fcd43f9 100644 --- a/forge/sf.lisp +++ b/forge/sf.lisp @@ -7,13 +7,15 @@ (:local-nicknames (:iter :scopes/util/iter)) (:export #:*input* #:*stack* #:exec-list #:exec-input - #:reg #:reg2 + #:lit #:reg #:reg2 #:pushd #:popd #:peekd)) (in-package :scopes/forge/sf) (defvar *stack* nil) (defvar *input* nil) +(defvar *buffer* nil) +(defvar *code* nil) ;;;; core definitions @@ -21,30 +23,53 @@ (:method ((it t)) (pushd it)) (:method ((it symbol)) - (call-item (symbol-value it)))) + (exec-item (symbol-value it)))) -(defgeneric comp-item (it)) +(defgeneric comp-item (it) + (:method ((it t)) + (push #'lit *buffer*) + (push it *buffer*)) + (:method ((it symbol)) + (comp-item (symbol-value it)))) -(defgeneric call-item (it)) +;;;; class word (defclass word () ((func :reader func :initarg :func))) -(defmethod call-item ((w word)) +(defmethod exec-item ((w word)) (funcall (func w))) +(defmethod comp-item ((w word)) + (push (func w) *buffer*)) + +;;;; class comp-word + (defclass comp-word (word) ()) +(defmethod comp-item ((w word)) + (funcall (func w))) + +;;;; functions + (defun exec-list (lst) - (setf *input* (make-instance 'iter:list-iterator :data lst)) - (exec-input)) + (let ((*input* (make-instance 'iter:list-iterator :data lst))) + (exec-input))) (defun exec-input () (iter:process *input* #'exec-item)) +(defun comp-input () + (let ((*buffer* nil)) + (iter:process *input* #'comp-item) + (pushd (reverse *buffer*)))) + +(defun call (code) + (let ((*code* (make-instance 'iter:list-iterator :data code))) + (iter:process *code* #'funcall))) + (defun reg (sym fn) (setf (symbol-value sym) (make-instance 'word :func fn))) - ;(setf (symbol-value sym) fn)) (defun reg2 (sym fn) (reg sym #'(lambda () (pushd (funcall fn (popd) (popd)))))) @@ -58,13 +83,16 @@ (defun peekd () (car *stack*)) +(defun lit () + (pushd (iter:next-value *code*))) + ;;;; builtins (defpackage :sf-builtin (:use :common-lisp) (:local-nicknames (:f :scopes/forge/sf) (:iter :scopes/util/iter)) - (:export #:add #:mul #:dup #:in #:?)) + (:export #:add #:mul #:dup #:in #:? #:lit)) (in-package :sf-builtin) @@ -74,3 +102,5 @@ (f:reg 'dup #'(lambda () (f:pushd (f:peekd)))) (f:reg 'in #'(lambda () (f:pushd (iter:next-value f:*input*)))) + +(f:reg 'lit #'f:lit)