commit 670cc87c19b74a4d5b0c955e7f8c28c94043bb5e Spenser Truex <spensertruexonline@gmail.com> 2019-06-22 20:25:44 -0700 Comments in COMMENTary.
eforth.el | 243 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 122 insertions(+), 121 deletions(-)
diff --git a/eforth.el b/eforth.el index 9eeb74b..37d06a6 100644 --- a/eforth.el +++ b/eforth.el @@ -5,7 +5,7 @@ ;; Version: 0.0.1 ;; Package-Requires: ((emacs "24")) ;; Keywords: -;; URL: https:// +;; URL: https://spensertruex.com/eforth ;; Homepage: ;; This file is not part of GNU Emacs. ;; This file is free software. @@ -14,126 +14,127 @@ ;; <https://www.gnu.org/licenses/>. ;;; Commentary: ;; - -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. - - (require 'eforth) - (defun 8pan () - (interactive) - (eforth '((n . (lambda () (switch-to-buffer nil))) - (d . split-window-below) - (r . split-window-right) - (wr . windmove-right) - (wl . windmove-left) - (wd . windmove-down) - (wu . windmove-up) - (del . delete-other-windows) - (cf . make-frame-command) - (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))) - - - -HOW DOES A FORTH WORK? - - -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? - - -Needing to simulate a long set of keypresses to create an eight panel -frame (37 in total), the best option seemeed to be obviously to create a -miniature language with 1 or 2 letter abbreviations for each. Any -arguments to a function can be passed before it in the list, and there -is no need to define a return stack. - - - -USAGE: EXAMPLE: - - - (require 'eforth) - (defun 8pan () - (interactive) - (eforth '((n . (lambda () (switch-to-buffer nil))) - (d . split-window-below) - (r . split-window-right) - (wr . windmove-right) - (wl . windmove-left) - (wd . windmove-down) - (wu . windmove-up) - (del . delete-other-windows) - (cf . make-frame-command) - (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: - -eforth is called with two arguments: the environment, name to function -bindings, and the eforth code list. You can see in this 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)) - -Here we ran (find-file "~/some-file"). If you need to reuse a forth, -just define an *env* variable: - - (defvar *env* '((>r . to-return-stack) ...)) - (eforth *env* (forth code here ...)) - - - -BENEFITS - - -Concise code. - -Elisp's convention of names like: - - org--insert-structure-template-unique-keys - -(a real function in the org mode) result in extremely verbose code. -Using short, lexical names can reduce code size by a large portion. - - -Compiles to Elisp. - -Elisp is hated by many, and for good reason. It is an outdated and -clunky lisp. Many have tried and failed to port Emacs to Common Lisp, -without success. Forth, unlike modern lisps, is designed to be easy to -implement. Writing a forth compiler is in fact a trivial exercise. - - - -DRAWBACKS - - -Elispers might not want to read your eFORTH code - - -eForth is not stable - - -Isn't verbose code self-documenting? - -NO. Documented code is documented. Using short names with the bindings -handily available in the same form is equally explicit as writing them -out every time. +;; 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. +;; +;; (require 'eforth) +;; (defun 8pan () +;; (interactive) +;; (eforth '((n . (lambda () (switch-to-buffer nil))) +;; (d . split-window-below) +;; (r . split-window-right) +;; (wr . windmove-right) +;; (wl . windmove-left) +;; (wd . windmove-down) +;; (wu . windmove-up) +;; (del . delete-other-windows) +;; (cf . make-frame-command) +;; (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))) +;; +;; +;; +;; HOW DOES A FORTH WORK? +;; +;; +;; 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? +;; +;; +;; Needing to simulate a long set of keypresses to create an eight panel +;; frame (37 in total), the best option seemeed to be obviously to create a +;; miniature language with 1 or 2 letter abbreviations for each. Any +;; arguments to a function can be passed before it in the list, and there +;; is no need to define a return stack. +;; +;; +;; +;; USAGE: EXAMPLE: +;; +;; +;; (require 'eforth) +;; (defun 8pan () +;; (interactive) +;; (eforth '((n . (lambda () (switch-to-buffer nil))) +;; (d . split-window-below) +;; (r . split-window-right) +;; (wr . windmove-right) +;; (wl . windmove-left) +;; (wd . windmove-down) +;; (wu . windmove-up) +;; (del . delete-other-windows) +;; (cf . make-frame-command) +;; (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: +;; +;; eforth is called with two arguments: the environment, name to function +;; bindings, and the eforth code list. You can see in this 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)) +;; +;; Here we ran (find-file "~/some-file"). If you need to reuse a forth, +;; just define an *env* variable: +;; +;; (defvar *env* '((>r . to-return-stack) ...)) +;; (eforth *env* (forth code here ...)) +;; +;; +;; +;; BENEFITS +;; +;; +;; Concise code. +;; +;; Elisp's convention of names like: +;; +;; org--insert-structure-template-unique-keys +;; +;; (a real function in the org mode) result in extremely verbose code. +;; Using short, lexical names can reduce code size by a large portion. +;; +;; +;; Compiles to Elisp. +;; +;; Elisp is hated by many, and for good reason. It is an outdated and +;; clunky lisp. Many have tried and failed to port Emacs to Common Lisp, +;; without success. Forth, unlike modern lisps, is designed to be easy to +;; implement. Writing a forth compiler is in fact a trivial exercise. +;; +;; +;; +;; DRAWBACKS +;; +;; +;; Elispers might not want to read your eFORTH code +;; +;; +;; eForth is not stable +;; +;; +;; Isn't verbose code self-documenting? +;; +;; NO. Documented code is documented. Using short names with the bindings +;; handily available in the same form is equally explicit as writing them +;; out every time. ;;; Code: (require 'cl-lib)