aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/meta/compiler/language/lux/analysis/evaluation.lux
blob: ba7dea6b9c0038e385ae86fb5e9a1685843d28aa (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
... 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 https://mozilla.org/MPL/2.0/.

(.require
 [library
  [lux (.except)
   [abstract
    [monad (.only do)]]
   [control
    ["[0]" maybe]
    ["[0]" try]
    ["[0]" io]
    [concurrency
     ["[0]" atom (.only Atom)]]]
   [data
    [collection
     ["[0]" dictionary (.only Dictionary)]]]
   [math
    [number
     ["n" nat]
     ["[0]" i64]]]
   ["[0]" meta (.only)
    [type (.only sharing)]]]]
 ["[0]" // (.only Operation)
  ["[1][0]" type]
  ["[1][0]" scope]
  [//
   [phase
    ["[0]P" analysis]
    [//
     ["[0]" phase]
     ["[0]" synthesis]
     ["[0]" translation]
     [///
      [meta
       ["[0]" archive (.only Archive)
        ["[0]" module]]]]]]]])

(type .public Eval
  (-> Archive Type Code (Operation Any)))

(def evals
  (Atom (Dictionary module.ID Nat))
  (atom.atom (dictionary.empty n.hash)))

(def .public (evaluator analysis
                        [synthesis_state synthesis]
                        [translation_state translation])
  (All (_ anchor expression artifact)
    (-> //.Phase
        [synthesis.State
         (-> Lux synthesis.Phase)]
        [(translation.State anchor expression artifact)
         (-> Lux (translation.Phase anchor expression artifact))]
        Eval))
  (function (eval archive type exprC)
    (do phase.monad
      [exprA (<| (//type.expecting type)
                 //scope.reset
                 (analysis archive exprC))
       module meta.current_module_name
       lux meta.compiler_state]
      (<| phase.of_try
          (do try.monad
            [exprS (|> exprA
                       (synthesis lux archive)
                       (phase.result synthesis_state))])
          (phase.result translation_state)
          (do phase.monad
            [@module (sharing [anchor expression artifact]
                       (is (-> Lux (translation.Phase anchor expression artifact))
                           translation)
                       (is (translation.Operation anchor expression artifact module.ID)
                           (translation.module_id module archive)))
             .let [[evals _] (io.run! (atom.update! (dictionary.revised' @module 0 ++) ..evals))
                   @eval (maybe.else 0 (dictionary.value @module evals))]
             exprO (<| (translation.with_registry_shift (|> @module
                                                            (i64.left_shifted 16)
                                                            (i64.or @eval)
                                                            (i64.left_shifted 32)))
                       (translation lux archive exprS))]
            (translation.evaluate! [@module @eval] [{.#None} exprO]))))))