aboutsummaryrefslogtreecommitdiff
path: root/new-luxc/source/luxc/env.lux
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--new-luxc/source/luxc/env.lux37
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."))
+ ))