aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/lux/tool/compiler/phase/generation/jvm/function.lux
blob: 12e1bc460113c9d19e02d5f0a5e56e612ef334b1 (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
(.module:
  [lux #*
   [abstract
    ["." monad (#+ do)]]
   [control
    [state (#+ State)]]
   [data
    [number
     ["." i32]
     ["n" nat]]
    [collection
     ["." list ("#@." monoid functor)]
     ["." row]]]
   [target
    [jvm
     ["." descriptor (#+ Descriptor Value Return)]
     ["." modifier (#+ Modifier) ("#@." monoid)]
     ["." field (#+ Field)]
     ["." method (#+ Method)]
     ["_" instruction (#+ Label Instruction) ("#@." monad)]
     ["." constant
      [pool (#+ Pool)]]
     [encoding
      [name (#+ External)]
      ["." unsigned]]]]]
  ["." / #_
   ["#." abstract]
   ["#." arity]
   ["#." field
    ["#/." foreign]
    ["#/." partial
     ["#/." count]]]
   ["#." method #_
    ["#/." new]
    ["#/." reset]
    ["#/." implementation]
    ["#/." apply]]
   ["/#" // #_
    [runtime (#+ Operation Phase)]
    ["#." value]
    ["#." reference]
    [////
     [reference (#+ Register)]
     [analysis (#+ Environment)]
     [synthesis (#+ Synthesis Abstraction Apply)]
     ["." arity (#+ Arity)]
     ["." phase]]]])

(def: #export (apply generate [abstractionS argsS])
  (-> Phase Apply (Operation (Instruction Any)))
  (do phase.monad
    [abstractionG (generate abstractionS)
     argsG (monad.map @ generate argsS)]
    (wrap ($_ _.compose
              abstractionG
              (|> argsG
                  (list.split-all /arity.maximum)
                  (monad.map _.monad
                             (function (_ batchG)
                               ($_ _.compose
                                   (_.checkcast /abstract.class)
                                   (monad.seq _.monad batchG)
                                   (_.invokevirtual /abstract.class /method/apply.name (/method/apply.type (list.size batchG)))
                                   ))))))))