macros
This commit is contained in:
+52
-16
@@ -1,5 +1,37 @@
|
||||
(define nil ())
|
||||
|
||||
(define pe
|
||||
(macro (expr)
|
||||
(print expr)
|
||||
(print " evaluates to -> ")
|
||||
(print (eval expr))
|
||||
(print "
|
||||
")
|
||||
nil))
|
||||
|
||||
|
||||
(define apply
|
||||
(lambda (fun seq)
|
||||
(eval (pair fun seq))))
|
||||
|
||||
(define defun
|
||||
(macro (name params :rest body)
|
||||
(printf "name" params "params" params "body" body)
|
||||
(define name
|
||||
(lambda (params) body))))
|
||||
|
||||
(define when
|
||||
(macro (test :rest body)
|
||||
(if (eval test)
|
||||
(apply prog body)
|
||||
nil)))
|
||||
|
||||
(define unless
|
||||
(macro (test :rest body)
|
||||
(if (eval test)
|
||||
nil
|
||||
(apply prog body))))
|
||||
|
||||
(define nil?
|
||||
(lambda (x)
|
||||
"Checks if the argument is nil."
|
||||
@@ -41,14 +73,14 @@ defined by the key 'from' and ends with the number defined in
|
||||
nil)))
|
||||
|
||||
(define map
|
||||
(lambda (function sequence)
|
||||
(lambda (fun seq)
|
||||
"Takes a sequence and a function as arguments and returns a
|
||||
new sequence which contains the results of using the first
|
||||
sequences elemens as argument to that function."
|
||||
(if (nil? sequence)
|
||||
sequence
|
||||
(pair (function (first sequence))
|
||||
(map (rest sequence) function)))))
|
||||
(if (nil? seq)
|
||||
seq
|
||||
(pair (fun (first seq))
|
||||
(map fun (rest seq))))))
|
||||
|
||||
(define reduce
|
||||
(lambda (function sequence)
|
||||
@@ -56,7 +88,7 @@ sequences elemens as argument to that function."
|
||||
function to the argument sequence. This only works correctly if the
|
||||
given function accepts a variable amount of parameters. If your
|
||||
funciton is limited to two arguments, use `reduce-binary' instead."
|
||||
(eval (pair function sequence))))
|
||||
(apply function sequence)))
|
||||
|
||||
(define reduce-binary
|
||||
(lambda (function sequence)
|
||||
@@ -78,15 +110,19 @@ as compared to `reduce'."
|
||||
(filter (rest sequence) function))
|
||||
(filter (rest sequence) function)))))
|
||||
|
||||
(define printf
|
||||
(lambda (:keys sep :defaults-to " " end :defaults-to "\n" :rest args)
|
||||
(if (and (nil? (first args)) (nil? (rest args)))
|
||||
(print end)
|
||||
(define printf-quoted
|
||||
(macro (:keys sep :defaults-to " " end :defaults-to "\n" :rest args)
|
||||
(if (nil? args)
|
||||
(prog (print (eval end)) nil)
|
||||
(prog
|
||||
(print (first args))
|
||||
(if (not (nil? (rest args)))
|
||||
(print sep))
|
||||
;; TODO(Felix): later we should use `extend' here:
|
||||
;; (eval (extend (quote (printf :sep sep :end end)) (rest args)))
|
||||
(eval (extend '(printf :sep sep :end end) (rest args)))
|
||||
nil))))
|
||||
(when (not (nil? (rest args))) (print (eval sep)))
|
||||
(define command-args (list :sep (eval sep) :end (eval end)))
|
||||
(append command-args (rest args))
|
||||
(apply printf-quoted command-args)))))
|
||||
|
||||
(define printf
|
||||
(lambda (:keys sep :defaults-to " " end :defaults-to "\n" :rest args)
|
||||
(define command-args (list :sep (eval sep) :end (eval end)))
|
||||
(append command-args args)
|
||||
(apply printf-quoted command-args)))
|
||||
|
||||
Reference in New Issue
Block a user