Skip to content

Commit

Permalink
Rewrite the (while ..) macro.
Browse files Browse the repository at this point in the history
This now allows the use of an arbitrary body, as can be seen
in the following test:

```
(set! p 4)

(while (<= p 10)
    (print "Pxx: %s" p)
    (set! p (+ p 1) true)
)
```

The new approach defines a local lambda, with a random name, and
calls that recursively when the conditional is true.

This closes #21, though we still need to use the three-argument
form of (set!) as our scoping/environment is confused - that is
tracked in #22.
  • Loading branch information
skx committed Oct 9, 2022
1 parent a43ebbc commit 3c99c1c
Showing 1 changed file with 8 additions and 13 deletions.
21 changes: 8 additions & 13 deletions stdlib/mal.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,18 @@
(defmacro! when (fn* (pred &rest) `(if ~pred (do ~@rest))))

;;
;; Part of our while-implementation.
;; If the specified predicate is true, then run the body.
;;
;; NOTE: This recurses, so it will eventually explode the stack.
;;
(define while-fun (lambda (predicate body)
(when (predicate)
(body)
(while-fun predicate body))))

;;
;; Now a macro to use the while-fun body as part of a while-function
;;
(defmacro! while (fn* (expression body)
(list 'while-fun
(list 'lambda '() expression)
(list 'lambda '() body))))
(defmacro! while (fn* (condition &body)
(let* (inner-sym (gensym))
`(let* (~inner-sym (fn* ()
(if ~condition
(do
~@body
(~inner-sym)))))
(~inner-sym)))))


;;
Expand Down

0 comments on commit 3c99c1c

Please sign in to comment.