commit 9c7443d01202ac7b38a75f00b073cdbeb0f77821 Spenser Truex <spensertruexonline@gmail.com> 2018-12-05 20:31:20 -0800 ENV vars supported.
.gitignore | 1 + README.md | 19 ++++++++++++------- eforth.el | 12 ++++++------ 3 files changed, 19 insertions(+), 13 deletions(-)
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e4e5f6c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*~ \ No newline at end of file diff --git a/README.md b/README.md index f0e0a3a..c34cf51 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ eFORTH === -# What? -This is an implementation of an elisp-based FORTH. This means that elisp is used to write the function definitions. In fact, no FORTH function definitions are provided at all to the eforth macro from the library. +This is an implementation of an elisp-based FORTH. This means that elisp is used to write the function definitions. In fact, no FORTH function definitions are provided at all to the eforth macro from the library. **The main benefit comes from reducing the verbosity of elisp in a small Domain Specific Language the programmer defines.** # How? Forth code is gone through by the pointer moving through the call stack. When a non-function is found, it is added to the argument stack. When a function is found, it uses up the argument stack if it has arguments, or just runs if it is nullary. Nothing else is provided by the implementation. # Why? @@ -12,11 +11,11 @@ and there is no need to define a return stack. # Usage: example: -``` +```elisp (require 'eforth) (defun 8pan () (interactive) - (eforth ((n . (lambda () (switch-to-buffer nil))) + (eforth '((n . (lambda () (switch-to-buffer nil))) (d . split-window-below) (r . split-window-right) (wr . windmove-right) @@ -28,6 +27,7 @@ example: (nf . other-frame)) (cf del r r wr wr r d wr d wl wl d wl d wr n wr n wr n wl wl wl wd n wr n wr n wr n wl wl wl wu nf))) + ``` `M-x 8pan` will produce a new frame with eight panels (emacs-speak: "windows"). Here is how it works: @@ -36,9 +36,14 @@ example: that there are no arguments used, since all of these are nullary functions. Here is how you might use arguments: -``` -(eforth ((ff . find-file)) ("~/some-file" ff)) +```elisp +(eforth '((ff . find-file)) ("~/some-file" ff)) ``` -Here we ran `(find-file "~/some-file")`. +Here we ran `(find-file "~/some-file")`. If you need to reuse a forth, just define an `*env*` variable: +``` elisp +(defvar *env* '((>r . to-return-stack) ...)) +(eforth *env* (forth code here ...)) + +``` diff --git a/eforth.el b/eforth.el index 77adc3a..27df4a4 100644 --- a/eforth.el +++ b/eforth.el @@ -2,7 +2,7 @@ (let ((l)) (dolist (i list-of-lists (nreverse l)) (push (list it i) l)))) -(defmacro eforth (lang list) +(defmacro inner-eforth (lang list) "Forth without a return stack." `(progn ,@(let ((s) (l)) (dolist (i list (nreverse (add-to-each 'funcall l))) @@ -13,14 +13,14 @@ (setf s nil)) (push `(lambda () (,fn)) l))) (push i s)))))) -;; (defmacro eforth (lang list) -;; `(progn ,@(inner-eforth lang lsit))) -(eforth ((ff . find-file)) ("~/bogus/" ff)) -(eforth ((d . split-window-below)) +(defmacro eforth (lang list) + `(inner-eforth ,(cadr lang) ,list)) +(eforth '((ff . find-file)) ("~/bogus/" ff)) +(eforth '((d . split-window-below)) (d)) (defun 8pan () (interactive) - (eforth ((n . (lambda () (switch-to-buffer nil))) + (eforth '((n . (lambda () (switch-to-buffer nil))) (d . split-window-below) (r . split-window-right) (wr . windmove-right)