bad26979f2d4

Add destructuring
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Thu, 12 Jan 2017 11:14:27 +0000
parents b646793b8d97
children 2898f6fe4376
branches/tags (none)
files .lispwords examples/story.lisp src/chancery.lisp

Changes

--- a/.lispwords	Thu Jan 12 10:42:36 2017 +0000
+++ b/.lispwords	Thu Jan 12 11:14:27 2017 +0000
@@ -0,0 +1,1 @@
+(1 bind bind*)
--- a/examples/story.lisp	Thu Jan 12 10:42:36 2017 +0000
+++ b/examples/story.lisp	Thu Jan 12 11:14:27 2017 +0000
@@ -85,3 +85,42 @@
 
 ; (iterate (repeat 30) (pr (sentence)))
 
+
+;;;; Pronoun agreement through binding
+(defun pronoun (gender)
+  (case gender
+    (:female "she")
+    (:male "he")
+    (:neuter "it")
+    (t "they")))
+
+(defun posessive-pronoun (gender)
+  (case gender
+    (:female "her")
+    (:male "his")
+    (:neuter "its")
+    (t "their")))
+
+(define-rule hero
+  (list "freyja" :female)
+  (list "loki" :male)
+  (list "time" :neuter)
+  (list "frobboz" :frobbian))
+
+(define-rule weapon
+  "axe" "sword" "banana")
+
+(define-rule animal
+  "mouse" "squirrel" "beaver" "antelope" "rabbit" "elk")
+
+(define-rule story%
+  ([name cap] "took up" posessive "mighty" weapon "and went forth."
+   [pronoun cap] "slew the dragon and the people rejoiced.")
+  ("Once upon a time there was" [animal a] "named" [name cap] :. "."
+   [pronoun cap] "went to the village and was very happy."))
+
+(define-rule story
+  (bind* (((name gender) hero)
+          (pronoun [gender pronoun])
+          (posessive [gender posessive-pronoun]))
+    (story%)))
--- a/src/chancery.lisp	Thu Jan 12 10:42:36 2017 +0000
+++ b/src/chancery.lisp	Thu Jan 12 11:14:27 2017 +0000
@@ -47,13 +47,22 @@
     (apply #'append <>)))
 
 
+(deftype non-keyword-symbol ()
+  '(and symbol (not keyword)))
+
+
 ;;;; Guts ---------------------------------------------------------------------
 (defparameter *bindings* nil)
 
 
 (defun create-binding (binding)
-  (destructuring-bind (symbol expr) binding
-    (list symbol (evaluate-expression expr))))
+  (destructuring-bind (target expr) binding
+    (let ((value (evaluate-expression expr)))
+      (etypecase target
+        (non-keyword-symbol (list target value))
+        (cons (loop :for symbol :in target
+                    :for val :in value
+                    :append (list symbol val)))))))
 
 (defun evaluate-bind (bindings expr)
   (let* ((new-bindings (mapcan (rcurry #'create-binding) bindings))
@@ -98,6 +107,10 @@
 (defun evaluate-lisp (expr)
   (eval expr))
 
+
+(defun evaluate-list (list)
+  (mapcar #'evaluate-expression list))
+
 (defun evaluate-expression (expr)
   (typecase expr
     ((or string keyword null) expr)
@@ -108,6 +121,7 @@
             (bind (evaluate-bind (second expr) (cddr expr)))
             (bind* (evaluate-bind* (second expr) (cddr expr)))
             (eval (evaluate-lisp (second expr)))
+            (list (evaluate-list (rest expr)))
             (t (evaluate-combination expr))))
     (t expr)))
 
@@ -176,3 +190,5 @@
          "'"
          "'s")))
 
+
+;;;; Scratch ------------------------------------------------------------------