aboutsummaryrefslogtreecommitdiff
path: root/src/lux/compiler/type.clj
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))
    ))