aboutsummaryrefslogtreecommitdiff
path: root/src/lux/analyser/def.clj
blob: e83bbb85d460797bdba5057ebabad189ae4fce9b (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
26
27
28
29
30
31
32
33
34
35
(ns lux.analyser.def
  (:require (clojure [template :refer [do-template]])
            [clojure.core.match :as M :refer [matchv]]
            clojure.core.match.array
            (lux [base :as & :refer [exec return return* fail]])
            [lux.analyser.base :as &&]))

;; [Exports]
(def init-module
  (&/R "defs" (&/|table)
       "macros" (&/|table)))

(do-template [<name> <category>]
  (defn <name> [module name]
    (fn [state]
      (return* state
               (->> state (&/get$ "modules") (&/|get module) (&/get$ <category>) (&/|get name) boolean))))

  defined? "defs"
  macro?   "macros"
  )

(defn declare-macro [module name]
  (fn [state]
    (return* (&/update$ "modules" (fn [ms] (&/|update module (fn [m] (&/update$ "macros" #(&/|put name true %) m)) ms)) state)
             nil)))

(defn define [module name type]
  (fn [state]
    (let [full-name (str module &/+name-separator+ name)
          bound (&/V "Expression" (&/T (&/V "global" (&/T module name)) type))]
      (return* (->> state
                    (&/update$ "modules" (fn [ms] (&/|update module (fn [m] (&/update$ "defs" #(&/|put name type %) m)) ms)))
                    (&/update$ "global-env" #(&/|merge (&/|table full-name bound, name bound) %)))
               nil))))