summaryrefslogtreecommitdiffstats
path: root/share
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-10-21 06:13:14 -0700
committerKaz Kylheku <kaz@kylheku.com>2014-10-21 06:13:14 -0700
commit81f7dcca6528252c1f0a57d3b5581c628efa4bf1 (patch)
tree71d3457395914ae14b7423cc7b3c9aff21525437 /share
parentc8b05c1e80d9b17a4fb002ee2cd8683632e6184d (diff)
downloadtxr-81f7dcca6528252c1f0a57d3b5581c628efa4bf1.tar.gz
txr-81f7dcca6528252c1f0a57d3b5581c628efa4bf1.tar.bz2
txr-81f7dcca6528252c1f0a57d3b5581c628efa4bf1.zip
* share/txr/stdlib/txr-case.txr: New file.
* txr.1: Document txr-if, txr-when and txr-case. * genvim.txr: Added new macro names. * tests/011/txr-case.expected: New file. * tests/011/txr-case.txr: New file. * txr.vim: Regenerated.
Diffstat (limited to 'share')
-rw-r--r--share/txr/stdlib/txr-case.txr48
1 files changed, 48 insertions, 0 deletions
diff --git a/share/txr/stdlib/txr-case.txr b/share/txr/stdlib/txr-case.txr
new file mode 100644
index 00000000..4d0081b3
--- /dev/null
+++ b/share/txr/stdlib/txr-case.txr
@@ -0,0 +1,48 @@
+@(do
+ (macro-time
+ (defun bindable (obj)
+ (and obj
+ (symbolp obj)
+ (not (keywordp obj))
+ (not (eq t obj)))))
+
+ (defmacro txr-if (name args input : then else)
+ (let ((syms [keep-if bindable args])
+ (arg-exprs [mapcar [iffi symbolp (ret ^',@1)] args])
+ (result (gensym "res-"))
+ (bindings (gensym "bindings-"))
+ (insym (gensym "input-")))
+ ^(let* ((,insym ,input)
+ (,result (match-fun ',name (list ,*arg-exprs)
+ (if (stringp ,insym) (list ,insym) ,insym)
+ nil)))
+ (if ,result
+ (let ((,bindings (car ,result)))
+ (let (,*[mapcar (ret ^(,@1 (cdr (assoc ',@1 ,bindings))))
+ syms])
+ ,then))
+ ,else))))
+
+ (defmacro txr-when (name args input . body)
+ ^(txr-if ,name ,args ,input (progn ,*body)))
+
+ (defmacro txr-case-impl (sym . clauses)
+ (tree-case clauses
+ (((name args . body) . other-clauses)
+ (if (eq name t) :
+ ^(txr-if ,name ,args ,sym
+ (progn ,*body)
+ (txr-case-impl ,sym ,*other-clauses))))
+ (((sym . rest) . other-clauses)
+ (if (eq sym t)
+ (if other-clauses
+ (error "txr-case: clauses after (t ...) clause ignored")
+ ^(progn ,*rest))
+ (error "txr-case: bad syntax: ~s" (car clauses))))
+ (atom
+ (error "txr-case: unexpected atom in syntax: ~s" atom))))
+
+ (defmacro txr-case (input-expr . clauses)
+ (let ((input (gensym "input-")))
+ ^(let ((,input ,input-expr))
+ (txr-case-impl ,input ,*clauses)))))