From d6463cdd25222c86975a7d49980bab94ed49857b Mon Sep 17 00:00:00 2001 From: Colin Okay Date: Wed, 12 Oct 2022 11:37:12 -0500 Subject: Add: with-plists; initial commit --- derrida.asd | 10 ++++++++++ derrida.lisp | 42 ++++++++++++++++++++++++++++++++++++++++++ package.lisp | 5 +++++ 3 files changed, 57 insertions(+) create mode 100644 derrida.asd create mode 100644 derrida.lisp create mode 100644 package.lisp diff --git a/derrida.asd b/derrida.asd new file mode 100644 index 0000000..8527790 --- /dev/null +++ b/derrida.asd @@ -0,0 +1,10 @@ +;;;; derrida.asd + +(asdf:defsystem #:derrida + :description "Macros for desctructuring common data structures." + :author "Colin Okay " + :license "GPL-3.0" + :version "0.0.1" + :serial t + :components ((:file "package") + (:file "derrida"))) diff --git a/derrida.lisp b/derrida.lisp new file mode 100644 index 0000000..ce1abeb --- /dev/null +++ b/derrida.lisp @@ -0,0 +1,42 @@ +;;;; derrida.lisp + +(in-package #:derrida) + +(defmacro with-plist (keys plist &body body) + "KEYS is a list, each member of which is either a symbol or a pair of symbols. + +If a member is just a symbol, say KEY, then it is treated as the name +of a symbol-macro (defined using symbol-macrolet) that expands to the +expression (getf PLIST KEY). In this case, KEY is not allowed to be a +keyword symbol. + +If a member is a pair of symbols, it is of the form (VAR KEY). Here, +key is a valid key into the PLIST and VAR is the name of the symbol +macrolet that will be bound to (getf PLIST KEY). + +EXAMPLE: + +(let ((pl + (list 'name \"colin\" :age 40 :|currentJob| :crumb-bum))) + (hq:with-plist (name (age :age) (job :|currentJob|)) pl + (setf age (1+ age)) + (format t \"~a the ~a had a birthday, and is now ~a years old~%\" + name job age) + pl)) + +The above would print out: +colin the CRUMB-BUM had a birthday, and is now 41 years old + +And would return +(NAME \"colin\" :AGE 41 :|currentJob| :CRUMB-BUM)" + + (let* ((plist-var + (gensym)) + (macrolet-bindings + (loop for term in keys + when (consp term ) + collect (destructuring-bind (var key) term + `(,var (getf ,plist-var ',key))) + else + collect `(,term (getf ,plist-var ',term))))) + `(let ((,plist-var ,plist)) (symbol-macrolet ,macrolet-bindings ,@body)))) diff --git a/package.lisp b/package.lisp new file mode 100644 index 0000000..33d3860 --- /dev/null +++ b/package.lisp @@ -0,0 +1,5 @@ +;;;; package.lisp + +(defpackage #:derrida + (:use #:cl) + (:export #:with-plist)) -- cgit v1.2.3