aboutsummaryrefslogtreecommitdiff
path: root/new-luxc/source/luxc/lang/translation/jvm/structure.jvm.lux
blob: bc4a3cb952c9891fc62b337808caf4cc3d01bf4c (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
(.module:
  [lux #*
   [control
    [monad (#+ do)]
    ["ex" exception (#+ exception:)]]
   [data
    [text
     format]
    [collection
     ["." list]]]
   [language
    ["." compiler
     [synthesis (#+ Synthesis)]]]]
  [luxc
   [lang
    [host
     ["." jvm (#+ Inst Operation Compiler)
      ["$t" type]
      ["$i" inst]]]]]
  [//])

(exception: #export (not-a-tuple {size Nat})
  (ex.report ["Expected size" ">= 2"]
             ["Actual size" (%n size)]))

(def: $Object jvm.Type ($t.class "java.lang.Object" (list)))

(def: #export (tuple translate members)
  (-> Compiler (List Synthesis) (Operation Inst))
  (do compiler.Monad<Operation>
    [#let [size (list.size members)]
     _ (compiler.assert not-a-tuple size
                        (n/>= +2 size))
     membersI (|> members
                  list.enumerate
                  (monad.map @ (function (_ [idx member])
                                 (do @
                                   [memberI (translate member)]
                                   (wrap (|>> $i.DUP
                                              ($i.int (.int idx))
                                              memberI
                                              $i.AASTORE)))))
                  (:: @ map $i.fuse))]
    (wrap (|>> ($i.int (.int size))
               ($i.array $Object)
               membersI))))

(def: (flagI tail?)
  (-> Bit Inst)
  (if tail?
    ($i.string "")
    $i.NULL))

(def: #export (variant translate tag tail? member)
  (-> Compiler Nat Bit Synthesis (Operation Inst))
  (do compiler.Monad<Operation>
    [memberI (translate member)]
    (wrap (|>> ($i.int (.int tag))
               (flagI tail?)
               memberI
               ($i.INVOKESTATIC //.runtime-class
                                "variant_make"
                                ($t.method (list $t.int $Object $Object)
                                           (#.Some ($t.array +1 $Object))
                                           (list))
                                #0)))))