forge/sf: fixes, improvements; work in progress: if, while, ...

This commit is contained in:
Helmut Merz 2024-09-14 10:11:52 +02:00
parent 78cce53f29
commit c85ab638a5
3 changed files with 44 additions and 19 deletions

View file

@ -11,11 +11,13 @@
#:word #:comp-word #:word #:comp-word
#:exec-list #:exec-input #:comp-input #:call #:exec-list #:exec-input #:comp-input #:call
#:comp-item #:comp-item
#:lit #:reg #:reg2 #:reg-code #:next #:reg #:reg2 #:reg-code
#:pushd #:popd #:peekd)) #:pushd #:popd #:peekd))
(in-package :scopes/forge/sf) (in-package :scopes/forge/sf)
;;;; common definitions
(defclass forge-env () (defclass forge-env ()
((vocabulary :reader vocabulary :initform (make-hash-table)) ((vocabulary :reader vocabulary :initform (make-hash-table))
(func-index :reader func-index :initform (make-hash-table)) (func-index :reader func-index :initform (make-hash-table))
@ -33,8 +35,6 @@
(print-unreadable-object (fn s) (format s "~s" sym)) (print-unreadable-object (fn s) (format s "~s" sym))
(call-next-method)))) (call-next-method))))
;;;; core definitions
(defgeneric exec-item (it) (defgeneric exec-item (it)
(:method ((it t)) (:method ((it t))
(pushd it)) (pushd it))
@ -45,7 +45,7 @@
(defgeneric comp-item (it) (defgeneric comp-item (it)
(:method ((it t)) (:method ((it t))
(push #'lit *buffer*) (push #'next *buffer*)
(push it *buffer*)) (push it *buffer*))
(:method ((it symbol)) (:method ((it symbol))
(let ((v (find-word it))) (let ((v (find-word it)))
@ -54,9 +54,12 @@
(comp-item v))))) (comp-item v)))))
(defun find-word (sym) (defun find-word (sym)
(gethash sym (vocabulary *forge-env*))) (multiple-value-bind (val found) (gethash sym (vocabulary *forge-env*))
(when (not found)
(util:lgw "not found" sym))
val))
;;;; class word* ;;;; class word
(defclass word () (defclass word ()
((func :reader func :initarg :func))) ((func :reader func :initarg :func)))
@ -74,10 +77,10 @@
(defmethod comp-item ((w comp-word)) (defmethod comp-item ((w comp-word))
(funcall (func w))) (funcall (func w)))
;;;; functions ;;;; code compilation and execution
(defun exec-list (lst) (defun exec-list (lst)
(let ((*input* (make-instance 'iter:list-iterator :data lst))) (let ((*input* (iter:list-iterator lst)))
(exec-input))) (exec-input)))
(defun exec-input () (defun exec-input ()
@ -89,9 +92,11 @@
(pushd (reverse *buffer*)))) (pushd (reverse *buffer*))))
(defun call (code) (defun call (code)
(let ((*code* (make-instance 'iter:list-iterator :data code)))
(util:lgi code) (util:lgi code)
(iter:process *code* #'funcall))) (let ((*code* code))
(do ((fn (pop *code*) (pop *code*)))
((null fn))
(funcall fn))))
(defun reg (sym fn &optional (cls 'word)) (defun reg (sym fn &optional (cls 'word))
(setf (gethash sym (vocabulary *forge-env*)) (make-instance cls :func fn)) (setf (gethash sym (vocabulary *forge-env*)) (make-instance cls :func fn))
@ -114,7 +119,7 @@
(defun peekd () (defun peekd ()
(car (stack *forge-env*))) (car (stack *forge-env*)))
(defun lit () (defun next ()
(pushd (iter:next-value *code*))) (pushd (iter:next-value *code*)))
;;;; builtins ;;;; builtins
@ -123,12 +128,28 @@
(:use :common-lisp) (:use :common-lisp)
(:local-nicknames (:f :scopes/forge/sf) (:local-nicknames (:f :scopes/forge/sf)
(:iter :scopes/util/iter)) (:iter :scopes/util/iter))
(:export #:add #:mul #:dup #:swp #:in #:? #:lit (:export #:add #:mul #:dup #:swp
#:comp-pop #:comp-in #:comp #:in #:next
#:call #:comp
#:<comp #:reg #:regc #:/>)) #:<comp #:reg #:regc #:/>))
(in-package :sf-builtin) (in-package :sf-builtin)
;;;; implementation functions
(defun call-if ()
(let ((code (f:popd)))
(if (f:popd)
(f:call code))))
(defun call-while ()
(let ((code (f:popd)))
(do ((cond (f:popd) (f:popd)))
((not cond))
(f:call code))))
;;;; lisp-code word definitions
(f:reg2 'add #'+) (f:reg2 'add #'+)
(f:reg2 'mul #'*) (f:reg2 'mul #'*)
@ -136,11 +157,10 @@
(f:reg 'swp #'(lambda () (let ((a (f:popd)) (b (f:popd))) (f:pushd a) (f:pushd b)))) (f:reg 'swp #'(lambda () (let ((a (f:popd)) (b (f:popd))) (f:pushd a) (f:pushd b))))
(f:reg 'in #'(lambda () (f:pushd (iter:next-value f:*input*)))) (f:reg 'in #'(lambda () (f:pushd (iter:next-value f:*input*))))
(f:reg 'lit #'f:lit) (f:reg 'next #'f:next)
(f:reg 'comp-pop #'(lambda () (f:comp-item (popd)))) (f:reg 'call #'(lambda () (f:call (popd))))
(f:reg 'comp-in #'(lambda () (f:comp-item (iter:next-value f:*input*)))) (f:reg 'comp #'(lambda () (f:comp-item (popd))))
(f:reg 'comp #'(lambda () (f:comp-item (iter:next-value f:*code*))))
(f:reg '<comp #'f:comp-input) (f:reg '<comp #'f:comp-input)
@ -148,3 +168,5 @@
(f:reg 'regc #'(lambda () (f:reg-code 'f:comp-word))) (f:reg 'regc #'(lambda () (f:reg-code 'f:comp-word)))
(f:reg '/> #'(lambda () (iter:stop f:*input*)) 'f:comp-word) (f:reg '/> #'(lambda () (iter:stop f:*input*)) 'f:comp-word)
;;;; forge-code word definitions

View file

@ -87,7 +87,7 @@
) )
(deftest test-util-iter () (deftest test-util-iter ()
(let ((it (make-instance 'iter:list-iterator :data '(1 2 3)))) (let ((it (iter:list-iterator '(1 2 3))))
(== (iter:value it) nil)) (== (iter:value it) nil))
) )

View file

@ -40,6 +40,9 @@
((data :reader data :initarg :data :initform nil) ((data :reader data :initarg :data :initform nil)
(cur :accessor cur))) (cur :accessor cur)))
(defun list-iterator (data)
(make-instance 'list-iterator :data data))
(defmethod initialize-instance :after ((it list-iterator) &key) (defmethod initialize-instance :after ((it list-iterator) &key)
(setf (cur it) (cons nil (data it)))) (setf (cur it) (cons nil (data it))))