From 62db6cd6ef35a8dc465538706f89e658db09661a Mon Sep 17 00:00:00 2001
From: Eduardo Julian
Date: Tue, 1 May 2018 19:31:21 -0400
Subject: Allow giving names to loops that can be used instead of "recur".
---
stdlib/source/lux.lux | 75 +++++++++++++++++++++++++++++++--------------------
1 file changed, 46 insertions(+), 29 deletions(-)
diff --git a/stdlib/source/lux.lux b/stdlib/source/lux.lux
index 10e188769..dc469633f 100644
--- a/stdlib/source/lux.lux
+++ b/stdlib/source/lux.lux
@@ -4460,7 +4460,7 @@
## else-branch
\"???\")"}
(if (n/= +0 (n/% +2 (list/size tokens)))
- (fail "cond requires an even number of arguments.")
+ (fail "cond requires an uneven number of arguments.")
(case (list/reverse tokens)
(^ (list& else branches'))
(return (list (list/fold (: (-> [Code Code] Code Code)
@@ -5287,36 +5287,53 @@
x init]
(if (< 10 count)
(recur (i/inc count) (f x))
+ x))
+
+ "Loops can also be given custom names."
+ (loop my-loop
+ [count 0
+ x init]
+ (if (< 10 count)
+ (my-loop (i/inc count) (f x))
x)))}
- (case tokens
- (^ (list [_ (#Tuple bindings)] body))
- (let [pairs (as-pairs bindings)
- vars (list/map first pairs)
- inits (list/map second pairs)]
- (if (every? symbol? inits)
- (do Monad
- [inits' (: (Meta (List Ident))
- (case (monad/map Monad get-ident inits)
- (#Some inits') (return inits')
- #None (fail "Wrong syntax for loop")))
- init-types (monad/map Monad find-type inits')
- expected get-expected-type]
- (return (list (` (("lux check" (-> (~+ (list/map type-to-code init-types))
- (~ (type-to-code expected)))
- (function ((~ (symbol$ ["" "recur"])) (~+ vars))
- (~ body)))
- (~+ inits))))))
- (do Monad
- [aliases (monad/map Monad
- (: (-> Code (Meta Code))
- (function (_ _) (gensym "")))
- inits)]
- (return (list (` (let [(~+ (interleave aliases inits))]
- (.loop [(~+ (interleave vars aliases))]
- (~ body)))))))))
+ (let [?params (case tokens
+ (^ (list name [_ (#Tuple bindings)] body))
+ (#.Some [name bindings body])
+
+ (^ (list [_ (#Tuple bindings)] body))
+ (#.Some [(symbol$ ["" "recur"]) bindings body])
- _
- (fail "Wrong syntax for loop")))
+ _
+ #.None)]
+ (case ?params
+ (#.Some [name bindings body])
+ (let [pairs (as-pairs bindings)
+ vars (list/map first pairs)
+ inits (list/map second pairs)]
+ (if (every? symbol? inits)
+ (do Monad
+ [inits' (: (Meta (List Ident))
+ (case (monad/map Monad get-ident inits)
+ (#Some inits') (return inits')
+ #None (fail "Wrong syntax for loop")))
+ init-types (monad/map Monad find-type inits')
+ expected get-expected-type]
+ (return (list (` (("lux check" (-> (~+ (list/map type-to-code init-types))
+ (~ (type-to-code expected)))
+ (function ((~ name) (~+ vars))
+ (~ body)))
+ (~+ inits))))))
+ (do Monad
+ [aliases (monad/map Monad
+ (: (-> Code (Meta Code))
+ (function (_ _) (gensym "")))
+ inits)]
+ (return (list (` (let [(~+ (interleave aliases inits))]
+ (.loop [(~+ (interleave vars aliases))]
+ (~ body)))))))))
+
+ #.None
+ (fail "Wrong syntax for loop"))))
(macro: #export (^slots tokens)
{#.doc (doc "Allows you to extract record members as local variables with the same names."
--
cgit v1.2.3