blob: 90be7d330a8f1cd431231b832eafa5d10e59c24e (
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
36
37
38
39
40
41
42
|
(ns lux.analyser.record
(:require clojure.core.match
clojure.core.match.array
(lux [base :as & :refer [|let |do return |case]]
[type :as &type])
(lux.analyser [base :as &&]
[module :as &&module])))
;; [Exports]
(defn order-record [pairs]
"(-> (List (, Syntax Syntax)) (Lux (List Syntax)))"
(|do [[tag-group tag-type] (|case pairs
(&/$Nil)
(return (&/T [&/$Nil &/$UnitT]))
(&/$Cons [[_ (&/$Tag tag1)] _] _)
(|do [[module name] (&&/resolved-ident tag1)
tags (&&module/tag-group module name)
type (&&module/tag-type module name)]
(return (&/T [tags type])))
_
(&/fail-with-loc "[Analyser Error] Wrong syntax for records. Odd elements must be tags."))
=pairs (&/map% (fn [kv]
(|case kv
[[_ (&/$Tag k)] v]
(|do [=k (&&/resolved-ident k)]
(return (&/T [(&/ident->text =k) v])))
_
(&/fail-with-loc "[Analyser Error] Wrong syntax for records. Odd elements must be tags.")))
pairs)
_ (let [num-expected (&/|length tag-group)
num-got (&/|length =pairs)]
(&/assert! (= num-expected num-got)
(str "[Analyser Error] Wrong number of record members. Expected " num-expected ", but got " num-got ".")))
=members (&/map% (fn [tag]
(if-let [member (&/|get tag =pairs)]
(return member)
(&/fail-with-loc (str "[Analyser Error] Missing tag: " tag))))
(&/|map &/ident->text tag-group))]
(return (&/T [=members tag-type]))))
|