;; -*- Mode: Irken -*-
;; derived expressions
(defmacro and
(and) -> #t
(and test) -> test
(and test1 test2 ...) -> (if test1 (and test2 ...) #f)
)
;; *not* the same as a Scheme <or>, this returns a boolean.
(defmacro or
(or) -> #f
(or test) -> test
(or test1 test2 ...) -> (if test1 #t (or test2 ...))
)
(defmacro let
(let () body ...)
-> (begin body ...)
;; normal <let> here, we just rename it to our core
;; binding construct, <let_splat>
(let ((name val) ...) body1 body2 ...)
-> (let_splat ((name val) ...) body1 body2 ...)
;; named let, strict version
;; http://groups.google.com/group/comp.lang.scheme/msg/3e2d267c8f0ef180
;; bad: this causes all recursive functions to 'escape' and thus lose tr_call!
;; (let tag ((name val) ...) body1 body2 ...)
;; -> ((letrec ((tag (lambda (name ...) body1 body2 ...)))
;; tag) val ...)
;; not-strict version
(let tag ((name val) ...) body1 body2 ...)
-> (letrec ((tag (lambda (name ...) body1 body2 ...)))
(tag val ...))
)
;; simplified <cond>
(defmacro cond
(cond (<else> e1 e2 ...)) -> (begin e1 e2 ...)
(cond ( test e1 e2 ...)) -> (if test (begin e1 e2 ...))
(cond ( test e1 e2 ...)
c1 c2 ...) -> (if test
(begin e1 e2 ...)
(cond c1 c2 ...)))
(defmacro while
(while test body ...)
-> (let $loop ()
(if test
(begin body ... ($loop))
#u)))
(defmacro for-range
(for-range vname num body ...)
-> (let (($n num))
(let $loop ((vname 0))
(if (= vname $n)
#u
(begin body ...
($loop (+ vname 1)))))))
;; because we have pattern matching, we don't really *need* <case>.
;; however, without or-patterns it's not quite as compact.
;; the right solution is to add or-patterns, not to use <case>.
;; XXX cannot be done with the macro system (yet), mostly
;; because of my use of %thing/hack0/hack1/...
;;
;; nvcase
;; match
;;
;; This converts vcase into &vcase, a primapp that uses success and
;; failure continuations, which simplifies typing a bit. Similar
;; to a cond->if transformation...
(defmacro notvcase
(vcase var)
-> (%vfail var)
(vcase var (<else> body0 ...))
-> (begin body0 ...)
(vcase var (((<colon> ignore label) bind0 ...) body0 ...) clause0 ...)
-> (&vcase (label)
(lambda (bind0 ...) body0 ...)
(lambda (vval) (vcase vval clause0 ...))
var
)
)