aboutsummaryrefslogtreecommitdiff
path: root/lux-bootstrapper/src/lux/analyser/function.clj
diff options
context:
space:
mode:
Diffstat (limited to 'lux-bootstrapper/src/lux/analyser/function.clj')
-rw-r--r--lux-bootstrapper/src/lux/analyser/function.clj28
1 files changed, 28 insertions, 0 deletions
diff --git a/lux-bootstrapper/src/lux/analyser/function.clj b/lux-bootstrapper/src/lux/analyser/function.clj
new file mode 100644
index 000000000..3db24acef
--- /dev/null
+++ b/lux-bootstrapper/src/lux/analyser/function.clj
@@ -0,0 +1,28 @@
+(ns lux.analyser.function
+ (:require clojure.core.match
+ clojure.core.match.array
+ (lux [base :as & :refer [|let |do return |case]]
+ [host :as &host])
+ (lux.analyser [base :as &&]
+ [env :as &env])))
+
+;; [Resource]
+(defn with-function [self self-type arg arg-type body]
+ (&/with-closure
+ (|do [scope-name &/get-scope-name]
+ (&env/with-local self self-type
+ (&env/with-local arg arg-type
+ (|do [=return body
+ =captured &env/captured-vars]
+ (return (&/T [scope-name =captured =return]))))))))
+
+(defn close-over [scope name register frame]
+ (|let [[[register-type register-location] _] register
+ register* (&&/|meta register-type register-location
+ (&&/$captured (&/T [scope
+ (->> frame (&/get$ &/$captured) (&/get$ &/$counter))
+ register])))]
+ (&/T [register* (&/update$ &/$captured #(->> %
+ (&/update$ &/$counter inc)
+ (&/update$ &/$mappings (fn [mps] (&/|put name (&/T [register-type register*]) mps))))
+ frame)])))