From ae4495e9393b52e0578f823d087302b9fdadff9f Mon Sep 17 00:00:00 2001 From: Helmut Merz Date: Mon, 9 Sep 2024 12:05:55 +0200 Subject: [PATCH] forge/sf: store words in sf-builtin:... variables; work in progress: use generic functions/methods --- forge/sf.lisp | 46 ++++++++++++++++++++++++++------------------- scopes-core.asd | 2 +- test/test-core.lisp | 2 ++ test/test-sf.lisp | 7 ++++--- util/iter.lisp | 19 +++++++++++++++++-- 5 files changed, 51 insertions(+), 25 deletions(-) diff --git a/forge/sf.lisp b/forge/sf.lisp index fd5abbd..8186fe8 100644 --- a/forge/sf.lisp +++ b/forge/sf.lisp @@ -6,13 +6,10 @@ (:use :common-lisp) (:local-nicknames (:iter :scopes/util/iter)) (:export #:*input* #:*stack* - #:proc-list #:proc-input - #:add #:mul #:dup + #:exec-list #:exec-input + #:reg #:reg2 #:pushd #:popd #:peekd)) -(defpackage :sf-builtin) -(defpackage :sf-user) - (in-package :scopes/forge/sf) (defvar *stack* nil) @@ -20,24 +17,28 @@ ;;;; core definitions -(defun proc-list (lst) +(defclass word () ()) + +(defclass comp-word (word) ()) + +(defun exec-list (lst) (setf *input* (make-instance 'iter:list-iterator :data lst)) - (proc-input)) + (exec-input)) -(defun proc-input () - (let ((inp *input*)) - (do ((end (iter:next inp) (iter:next inp))) - (end) - (proc-item (iter:value inp))))) +(defun exec-input () + (iter:process *input* #'exec-item)) -(defun proc-item (item) +(defun exec-item (item) (typecase item - (symbol (funcall item)) + (function (funcall item)) + (symbol (funcall (symbol-value item))) (t (pushd item)))) +(defun reg (sym fn) + (setf (symbol-value sym) fn)) + (defun reg2 (sym fn) - (setf (fdefinition sym) - #'(lambda () (pushd (funcall fn (popd) (popd)))))) + (reg sym #'(lambda () (pushd (funcall fn (popd) (popd)))))) (defun pushd (v) (push v *stack*)) @@ -50,7 +51,14 @@ ;;;; builtins -(reg2 'add #'+) -(reg2 'mul #'*) +(defpackage :sf-builtin + (:use :common-lisp) + (:local-nicknames (:f :scopes/forge/sf)) + (:export #:add #:mul #:dup)) -(defun dup () (pushd (peekd))) +(in-package :sf-builtin) + +(f:reg2 'add #'+) +(f:reg2 'mul #'*) + +(f:reg 'dup #'(lambda () (pushd (peekd)))) diff --git a/scopes-core.asd b/scopes-core.asd index 9499c58..0b2ee87 100644 --- a/scopes-core.asd +++ b/scopes-core.asd @@ -33,5 +33,5 @@ :perform (test-op (o c) (symbol-call :scopes/test-config :run) (symbol-call :scopes/test-core :run) - (symbol-call :scopes/test-forge :run) + ;(symbol-call :scopes/test-forge :run) (symbol-call :scopes/test-sf :run))) diff --git a/test/test-core.lisp b/test/test-core.lisp index 0337a1f..6617040 100644 --- a/test/test-core.lisp +++ b/test/test-core.lisp @@ -87,6 +87,8 @@ ) (deftest test-util-iter () + (let ((it (make-instance 'iter:list-iterator :data '(1 2 3)))) + (== (iter:value it) nil)) ) (deftest test-shape() diff --git a/test/test-sf.lisp b/test/test-sf.lisp index bc7f02b..b6c7643 100644 --- a/test/test-sf.lisp +++ b/test/test-sf.lisp @@ -3,7 +3,8 @@ ;;;; testing facility for scopes/forge (defpackage :scopes/test-sf - (:use :common-lisp) + (:use :common-lisp + :sf-builtin) (:local-nicknames (:forge :scopes/forge/sf) (:util :scopes/util) (:t :scopes/testing)) @@ -20,8 +21,8 @@ (test-exec))) (deftest test-exec () - ;(forge:proc-str "4 2 add") - (forge:proc-list '(4 2 forge:add)) + ;(forge:exec-str "4 2 add") + (forge:exec-list '(4 2 add)) (util:lgi forge:*stack*) (== (forge:popd) 6) (t:show-result)) diff --git a/util/iter.lisp b/util/iter.lisp index 7fc5e06..b0f4bf3 100644 --- a/util/iter.lisp +++ b/util/iter.lisp @@ -5,17 +5,32 @@ (defpackage :scopes/util/iter (:use :common-lisp) - (:export #:next #:value + (:export #:next #:value #:process #:list-iterator)) (in-package :scopes/util/iter) ;;;; iterators +(defclass abstract-iterator () ()) + (defgeneric next (it)) (defgeneric value (it)) -(defclass list-iterator () +(defgeneric next-value (it) + (:method ((it abstract-iterator)) + (next it) + (value it))) + +(defgeneric process (it fn &optional stop) + (:method ((it abstract-iterator) fn &optional (stop (constantly nil))) + (do ((eoi (next it) (next it))) + ((or eoi (funcall stop))) + (funcall fn (value it))))) + +;;;; list iterator implementation + +(defclass list-iterator (abstract-iterator) ((data :reader data :initarg :data :initform nil) (cur :accessor cur)))