blob: d75f6afef52fa6ae87a39f9d3bfa12992fb05a20 (
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
;; Copyright (c) Eduardo Julian. All rights reserved.
;; This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
;; If a copy of the MPL was not distributed with this file,
;; You can obtain one at http://mozilla.org/MPL/2.0/.
(ns lux.compiler.type
(:require clojure.core.match
clojure.core.match.array
(lux [base :as & :refer [|do return* return fail fail* |let |case]]
[type :as &type])
[lux.analyser.base :as &a]))
;; [Utils]
(defn ^:private variant$ [tag body]
"(-> Text Analysis Analysis)"
(&/T (&/V &a/$variant (&/T tag body))
&type/$Void))
(defn ^:private tuple$ [members]
"(-> (List Analysis) Analysis)"
(&/T (&/V &a/$tuple members)
&type/$Void))
(defn ^:private int$ [value]
"(-> Int Analysis)"
(&/T (&/V &a/$int value)
&type/$Void))
(defn ^:private text$ [text]
"(-> Text Analysis)"
(&/T (&/V &a/$text text)
&type/$Void))
(def ^:private $Nil
"Analysis"
(variant$ &/$Nil (tuple$ (&/|list))))
(defn ^:private Cons$ [head tail]
"(-> Analysis Analysis Analysis)"
(variant$ &/$Cons (tuple$ (&/|list head tail))))
;; [Exports]
(defn ->analysis [type]
"(-> Type Analysis)"
(|case type
(&/$DataT ?class)
(variant$ &/$DataT (text$ ?class))
(&/$TupleT ?members)
(variant$ &/$TupleT
(&/fold (fn [tail head]
(Cons$ (->analysis head) tail))
$Nil
(&/|reverse ?members)))
(&/$VariantT ?members)
(variant$ &/$VariantT
(&/fold (fn [tail head]
(Cons$ (->analysis head) tail))
$Nil
(&/|reverse ?members)))
(&/$LambdaT ?input ?output)
(variant$ &/$LambdaT (tuple$ (&/|list (->analysis ?input) (->analysis ?output))))
(&/$UnivQ ?env ?body)
(variant$ &/$UnivQ
(tuple$ (&/|list (&/fold (fn [tail head]
(Cons$ (->analysis head) tail))
$Nil
(&/|reverse ?env))
(->analysis ?body))))
(&/$BoundT ?idx)
(variant$ &/$BoundT (int$ ?idx))
(&/$AppT ?fun ?arg)
(variant$ &/$AppT (tuple$ (&/|list (->analysis ?fun) (->analysis ?arg))))
(&/$NamedT [?module ?name] ?type)
(variant$ &/$NamedT (tuple$ (&/|list (tuple$ (&/|list (text$ ?module) (text$ ?name)))
(->analysis ?type))))
_
(assert false (&type/show-type type))
))
|