Initial checkin --> to head
control-flow.lisp
Thu Mar 8 05:15:58 UTC 2012 pix@kepibu.org
* Rename notes.org to README.org
Mon Jul 20 18:34:17 UTC 2009 pix@kepibu.org
* see other links, and add reference to cl-syntax-sugar
Mon Jul 20 07:07:16 UTC 2009 pix@kepibu.org
* Some org-mode syntaxisms
Mon Jul 20 06:58:45 UTC 2009 pix@kepibu.org
* Update bug list to include reader bug
Mon Jul 20 01:31:17 UTC 2009 pix@kepibu.org
tagged VERSION 0.1.3
Mon Jul 20 01:31:10 UTC 2009 pix@kepibu.org
* Bump version
Mon Jul 20 01:14:10 UTC 2009 pix@kepibu.org
* Improved feature readers
It turns out #+/#- also need to do their thing under *read-suppress*, rather
than simply skipping two forms.
E.g.,
'(#+(or) #+(not a b) a b c) => '(c)
'(#+(or) #+(and) a b c) => '(b c)
(Not that such constructions are practically portable anyway, but meh.)
Regardless, this fixes that as best I can. Unfortunately, it also forces
the normal package problems within feature expressions:
#+(or) #+(notapackage:foo) 'a => PACKAGE-ERROR
#+(or) #+(cl:notexported) 'a => PACKAGE-ERROR
This is, so far as I can tell, portably unavoidable. However, some (all?)
implementations /already/ have this problem, so at least it's nothing new.
Mon Jul 20 01:09:25 UTC 2009 pix@kepibu.org
* Better reporting of undefined-feature-tests.
Sun Jul 19 13:58:44 UTC 2009 pix@kepibu.org
tagged VERSION 0.1.2
Sun Jul 19 13:58:33 UTC 2009 pix@kepibu.org
* Bump version
Sun Jul 19 13:58:20 UTC 2009 pix@kepibu.org
* Use consp to avoid treating nil as a list
Sun Jul 19 12:31:43 UTC 2009 pix@kepibu.org
tagged VERSION 0.1.1
Sun Jul 19 12:28:28 UTC 2009 pix@kepibu.org
* Take *read-suppress* into account
Sun Jul 19 12:27:37 UTC 2009 pix@kepibu.org
* Minor changes to the notes file
Fri Jul 17 05:24:52 UTC 2009 pix@kepibu.org
* Initial checkin
--- old-portaCL/control-flow.lisp 1970-01-01 00:00:00.000000000 +0000
+++ new-portaCL/control-flow.lisp 2013-06-27 16:07:24.000000000 +0000
@@ -0,0 +1,89 @@
+(in-package #:portaCL)
+
+(defmacro feature-cond (&body clauses)
+ "Some things are best shown by example. Suppose you have:
+ #+clisp (do-clisp-thing-1)
+ #+clisp (do-clisp-thing-2)
+ #+sbcl (do-sbcl-thing)
+ #-(or clisp sbcl) (error \"not implemented\")
+Using feature-cond, that would be:
+ (feature-cond
+ (:clisp (do-clisp-thing-1)
+ (do-clisp-thing-2))
+ (:sbcl (do-sbcl-thing))
+ (t (error \"not implemented\")))
+
+Accordingly, putting cl:t into *features* is not recommended.
+
+In general, this probably won't be very useful: read-time conditionals are
+often used to read symbols from packages which may not exist across
+implementations. And, of course, because this is a macro, it cannot appear
+in places where it won't be macroexpanded (e.g., the conditions of case).
+
+By the time you're in a position where this is actually useful,
+ #-(or a b c) (otherwise-clause)
+doesn't seem so bad. At least it'll look the same as your other feature
+conditionals!
+
+Note also that this does NOT provide a run-time check of *features*, but is
+instead a macroexpansion-time check."
+ (let* ((last-clause (car (last clauses)))
+ (otherwise-clause (when (member (car last-clause) '(t otherwise) :test #'eq)
+ last-clause)))
+ (when otherwise-clause (setf clauses (butlast clauses)))
+ `(progn
+ ,@(or (loop :for (cond . body) :in clauses
+ :when (featurep cond)
+ :return body)
+ (cdr otherwise-clause)))))
+
+(defmacro feature-econd (&body clauses)
+ "Like feature-cond, but automatically adds a final clause issuing a
+not-implemented error."
+ `(feature-cond ,@clauses (t (error 'not-implemented))))
+
+(defmacro feature-if (feature-expression true-form &optional else-form)
+ `(if (featurep ,feature-expression)
+ ,true-form
+ ,else-form))
+
+(defmacro feature-when (feature-expression &body body)
+ `(when (featurep ,feature-expression) ,@body))
+
+(defmacro feature-unless (feature-expression &body body)
+ `(unless (featurep ,feature-expression) ,@body))
+
+#+nil
+(feature-cond
+ (:clisp (do-clisp-thing-1)
+ (do-clisp-thing-2))
+ (:sbcl (do-sbcl-thing))
+ (t (error "not implemented")))
+
+#+nil
+(feature-cond
+ ((not :clisp) (do-clisp-thing-1)
+ (do-clisp-thing-2))
+ (:sbcl (do-sbcl-thing))
+ (t (error "not implemented")))
+
+#+nil
+(feature-cond
+ ((or :sbcl :clisp) (do-clisp-thing-1)
+ (do-clisp-thing-2))
+ (:clisp (do-sbcl-thing))
+ (t (error "not implemented")))
+
+#+nil
+(feature-cond
+ ((and (not :windows) :sbcl)
+ (do-sbcl-thing))
+ ((and (or :windows :win32) :clisp)
+ (do-clisp-thing-1)
+ (do-clisp-thing-2))
+ (t (error "not implemented")))
+
+#+nil
+(feature-econd
+ (:sbcl (do-sbcl-thing))
+ (:posix (do-posix-thing)))
\ No newline at end of file