Warning: this is an htmlized version!
The original is here, and
the conversion rules are here.
;; This file:
;;   http://angg.twu.net/elisp/eev-rcd-tap-1.el.html
;;   http://angg.twu.net/elisp/eev-rcd-tap-1.el
;;           (find-angg "elisp/eev-rcd-tap-1.el")
;; Author: Eduardo Ochs <eduardoochs@gmail.com>
;;
;; Version: 2023jan04
;; Sorry for the lack of comments!
;; Demo: http://angg.twu.net/eev-videos/2023-eev-rcd-tap-1.mp4
;; See:  https://lists.gnu.org/archive/html/help-gnu-emacs/2023-01/msg00027.html Edrx 1
;;       https://lists.gnu.org/archive/html/help-gnu-emacs/2023-01/msg00047.html Edrx 2
;;
;; (defun e () (interactive) (find-angg "elisp/eev-rcd-tap-1.el"))
;;
;; (load (buffer-file-name))




;; An intepreter of "hprograms", that are programs that identify what
;; we have "here" and decide how to handle that. My main example of an
;; hprogram is this,
;;
;;   (find-eev "eev-hlinks.el" "ee-fhl-main-program")
;;
;; but Jean Louis is interested in using hprograms to handle the
;; thing-at-point, so I rewrote my code.
;;
;; Tests:
;; (ee-hlang-:lisp '(+ 20 3) '(+ 40 5))
;; (ee-hlang-:or   '(:lisp nil) '(:lisp nil) '(:lisp 42) '(:lisp 99))
;; (ee-hlang-:if   '(< 1 2) '(list 'lt))
;; (ee-hlang-:if   '(> 1 2) '(list 'gt))
;;
;; (ee-hlang-eval  '(:lisp (+ 20 3) (+ 40 5)))
;; (ee-hlang-eval  '(:or (:lisp nil) (:lisp nil) (:lisp 42) (:lisp 99)))
;; (ee-hlang-eval  '(:if (< 1 2) (list 'lt)))
;; (ee-hlang-eval  '(:if (> 1 2) (list 'gt)))
;; (ee-hlang-eval  '(:or (:if (< 1 2) (list 'lt)) (:if (> 1 2) (list 'gt))))
;; (ee-hlang-eval  '(:or (:if (> 1 2) (list 'gt)) (:if (< 1 2) (list 'lt))))

;; The Three Variables.
(defvar ee-hlang-sexp1-result nil "See `ee-hlang-:if'.")
(defvar ee-hlang-sexp1        nil "See `ee-hlang-:if'.")
(defvar ee-hlang-sexp2        nil "See `ee-hlang-:if'.")

(defun ee-hlang-eval (hsexp)
  "If HSEXP is (:foo bar plic ploc), run (ee-hlang-:foo bar plic ploc)."
  (let* ((kw   (car hsexp))
	 (args (cdr hsexp))
	 (f    (ee-intern "ee-hlang-%s" kw)))
    (apply f args)))

(defun ee-hlang-:lisp (&rest sexps)
  "Eval (progn . SEXPS) and return the result. This is mainly for tests."
  (eval (cons 'progn sexps)))

(defun ee-hlang-:or (&rest hsexps)
  "Run `ee-hlang-eval' on each hsexp in HSEXPS until on succeeds.
On success return the result of that hsexp. On failure return nil."
  (cl-loop for hsexp in hsexps
	   for hresult = (ee-hlang-eval hsexp)
	   until hresult
           finally return hresult))

(defun ee-hlang-:if (sexp1 sexp2)
  "If (eval SEXP1) is true, return (list SEXP1 SEXP2).
Note that on success:
  a) we save the result of SEXP1 into `ee-hlang-sexp1-result',
  b) we save SEXP1 into `ee-hlang-sexp1',
  c) we save SEXP2 into `ee-hlang-sexp2',
  d) we DO NOT evaluate SEXP2,
  e) we return (list SEXP1 SEXP2) instead of (eval SEXP2).
This semantics is weird but it makes debugging of hprograms very easy."
  (let ((result (eval sexp1)))
    (when result
      (setq ee-hlang-sexp1-result result)
      (setq ee-hlang-sexp1 sexp1)
      (setq ee-hlang-sexp2 sexp2)
      (list sexp1 sexp2))))

(defun ee-hlang-run (hprogram)
  "Clear the Three Variables and run (ee-hlang-eval HPROGRAM).
HPROGRAM is usually an hsexp of the form (:or hsexp1 ... hsexpn).
This is my preferred way of running an hprogram: the first (:if
sexp1 sexp2) in the hprogram that succeeds will have its sexp1,
sexp2 and the result of sexp1 stored in the Three Variables, and
it will make the hprogram abort. If no (:if)s in the hprogram
succeed then the Three Variables will be nil, and this returns
nil."
  (setq ee-hlang-sexp1-result nil)
  (setq ee-hlang-sexp1 nil)
  (setq ee-hlang-sexp2 nil)
  (ee-hlang-eval hprogram))

;; Variants of thing-at-point.
;; "Swp" means "string with properties".
;; Most of them return strings without properties.

(defun ee-tap-uuid ()
  (let ((swp (thing-at-point 'uuid)))
    (and swp (ee-no-properties swp))))

(defun ee-tap-email ()
  (let ((swp (thing-at-point 'email)))
    (and swp (ee-no-properties swp))))

(defun ee-tap-symbol-name ()
  (let ((swp (thing-at-point 'symbol)))
    (and swp (ee-no-properties swp))))

(defun ee-tap-interned-symbol-name ()
  (let* ((swp       (thing-at-point 'symbol))
	 (s         (and swp (ee-no-properties swp)))
	 (internedp (and s (or (equal s "nil") (intern-soft s)))))
    (and internedp s)))

(defun ee-tap-boundp-name ()
  (let* ((s  (ee-tap-interned-symbol-name))
	 (bp (and s (boundp (intern s)))))
    (and bp s)))

(defun ee-tap-fboundp-name ()
  (let* ((s   (ee-tap-interned-symbol-name))
	 (fbp (and s (fboundp (intern s)))))
    (and fbp s)))


(defvar ee-tap-hprogram
  '(:or
    (:if (ee-tap-uuid)         (ee-tap-show))
    (:if (ee-tap-email)        (ee-tap-show))
    (:if (ee-tap-fboundp-name) (ee-tap-show))
    (:if (ee-tap-boundp-name)  (ee-tap-show))
    ))

;; Test this by running `M-x hs' on:
;; this e-mail:        eduardoochs@gmail.com
;; this uuid:          05fe48a3-b1c7-434e-b00e-713459bc6e26
;; this function name: next-line
;; this variable name: ee-hlang-sexp1

(defun hs ()
  "Run the hprogram in `ee-tap-hprogram' and show the result.
Note that this function does not run ee-hlang-sexp2."
  (interactive)
  (if (ee-hlang-run ee-tap-hprogram)
      (message "%S" (list ee-hlang-sexp1 ee-hlang-sexp1-result))
    (error "What?")))





;; Local Variables:
;; coding:  utf-8-unix
;; End: