aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/jvm/reference.lux
blob: b7428004d7ed9f3f70d5127ce8d16d9d52e1a01f (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
(.require
 [library
  [lux (.except)
   [abstract
    [monad (.only do)]]
   [data
    [text
     ["%" \\format (.only format)]]]
   [target
    [jvm
     ["_" bytecode (.only Bytecode)]
     ["[0]" type]
     [encoding
      ["[0]" unsigned]]]]]]
 ["[0]" //
  ["[1][0]" runtime (.only Operation)]
  ["[1][0]" value]
  ["[1][0]" type]
  ["//[1]" ///
   [//
    ["[0]" generation]
    [///
     ["[1]" phase (.use "operation#[0]" monad)]
     [reference
      ["[0]" variable (.only Register Variable)]]
     [meta
      [archive (.only Archive)]]]]]])

(def .public this
  (Bytecode Any)
  _.aload_0)

(with_template [<name> <prefix>]
  [(def .public <name>
     (-> Register Text)
     (|>> %.nat (format <prefix>)))]

  [foreign_name "f"]
  [partial_name "p"]
  )

(def (foreign archive variable)
  (-> Archive Register (Operation (Bytecode Any)))
  (do [! ////.monad]
    [bytecode_name (at ! each //runtime.class_name
                       (generation.context archive))]
    (in (all _.composite
             ..this
             (_.getfield (type.class bytecode_name (list))
                         (..foreign_name variable)
                         //type.value)))))

(def .public (variable archive variable)
  (-> Archive Variable (Operation (Bytecode Any)))
  (case variable
    {variable.#Local variable}
    (operation#in (_.aload variable))
    
    {variable.#Foreign variable}
    (..foreign archive variable)))

(def .public (constant archive name)
  (-> Archive Symbol (Operation (Bytecode Any)))
  (do ////.monad
    [[@definition |abstraction|] (generation.definition archive name)
     .let [:definition: (type.class (//runtime.class_name @definition) (list))]]
    (in (case |abstraction|
          {.#Some [_ {.#Some [expected_arity @abstraction]}]}
          (let [:abstraction: (type.class (//runtime.class_name @abstraction) (list))]
            (_.getstatic :definition: //value.field :abstraction:))
          
          _
          (_.getstatic :definition: //value.field //type.value)))))