diff options
Diffstat (limited to 'new-luxc/source/luxc/env.lux')
-rw-r--r-- | new-luxc/source/luxc/env.lux | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/new-luxc/source/luxc/env.lux b/new-luxc/source/luxc/env.lux index be68f84e9..338375a29 100644 --- a/new-luxc/source/luxc/env.lux +++ b/new-luxc/source/luxc/env.lux @@ -5,9 +5,12 @@ text/format [maybe #+ Monad<Maybe> "Maybe/" Monad<Maybe>] [product] - (coll [list "L/" Fold<List> Monoid<List>]))) + ["E" error] + (coll [list "L/" Fold<List> Monoid<List>])) + [macro]) (luxc ["&" base])) +(type: Locals (Bindings Text [Type Nat])) (type: Captured (Bindings Text [Type Ref])) (def: (pl::contains? key mappings) @@ -104,3 +107,35 @@ (#;Right [(set@ #;scopes scopes compiler) (#;Some [ref-type ref])])) )))) + +(def: #export (with-local [name type] action) + (All [a] (-> [Text Type] (Lux a) (Lux a))) + (function [compiler] + (case (get@ #;scopes compiler) + (#;Cons head tail) + (let [old-mappings (get@ [#;locals #;mappings] head) + new-var-id (get@ [#;locals #;counter] head) + new-head (update@ #;locals + (: (-> Locals Locals) + (|>. (update@ #;counter n.inc) + (update@ #;mappings (pl::put name [type new-var-id])))) + head)] + (case (macro;run' (set@ #;scopes (#;Cons new-head tail) compiler) + action) + (#E;Success [compiler' output]) + (case (get@ #;scopes compiler') + (#;Cons head' tail') + (let [scopes' (#;Cons (set@ #;locals (get@ #;locals head) head') + tail')] + (#E;Success [(set@ #;scopes scopes' compiler') + output])) + + _ + (error! "Invalid scope alteration.")) + + (#E;Error error) + (#E;Error error))) + + _ + (#E;Error "Cannot create local binding without a scope.")) + )) |