aboutsummaryrefslogtreecommitdiff
path: root/src/lux/analyser/lambda.clj
blob: 61daa5e5f443b1ffe9ee7bfa6734c6b5948a11df (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
(ns lux.analyser.lambda
  (:require [clojure.core.match :refer [match]]
            (lux [base :as & :refer [exec return fail
                                     try-all-m map-m mapcat-m reduce-m
                                     assert!]])
            (lux.analyser [base :as &&]
                          [env :as &env])))

;; [Resource]
(defn with-lambda [self self-type arg arg-type body]
  (&/with-closure
    (exec [scope-name &/get-scope-name]
      (&env/with-local self self-type
        (&env/with-local arg arg-type
          (exec [=return body
                 =captured &env/captured-vars]
            (return [scope-name =captured =return])))))))

(defn close-over [scope ident register frame]
  (match register
    [::&&/Expression _ register-type]
    (let [register* [::&&/Expression [::&&/captured scope (get-in frame [:closure :counter]) register] register-type]]
      [register* (update-in frame [:closure] #(-> %
                                                  (update-in [:counter] inc)
                                                  (assoc-in [:mappings ident] register*)))])))