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