Implemented and and or as macros.
[scheme.forth.jl.git] / scheme-library.scm
index 9a9358c..aad91f4 100644 (file)
 
 ; cond
 
+(define (cond-predicate clause) (car clause))
+(define (cond-actions clause) (cdr clause))
+(define (cond-else-clause? clause)
+  (eq? (cond-predicate clause) 'else))
+
+(define (expand-clauses clauses)
+  (if (null? clauses)
+    (none)
+    (let ((first (car clauses))
+          (rest (cdr clauses)))
+      (if (cond-else-clause? first)
+        (if (null? rest)
+          `(begin ,@(cond-actions first))
+          (error "else clause isn't last in cond expression."))
+        `(if ,(cond-predicate first)
+           (begin ,@(cond-actions first))
+           ,(expand-clauses rest))))))
+
+(define-macro (cond . clauses)
+              (if (null? clauses)
+                (error "cond requires at least one clause.")
+                (expand-clauses clauses)))
+
+; and
+
+(define (expand-and-expressions expressions)
+  (if (null? expressions)
+    #t
+    (let ((first (car expressions))
+          (rest (cdr expressions)))
+      `(if ,first
+         ,(expand-and-expressions rest)
+         #f))))
+
+(define-macro (and . expressions)
+              (expand-and-expressions expressions))
+
+; or
+
+(define (expand-or-expressions expressions)
+  (if (null? expressions)
+    #f
+    (let ((first (car expressions))
+          (rest (cdr expressions)))
+      `(if ,first
+         #t
+         ,(expand-or-expressions rest)))))
+
+(define-macro (or . expressions)
+              (expand-or-expressions expressions))
+
 
 ;; TESTING