aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/target/jvm/method.lux
blob: 11e8e1c0666c86b40b774a3d6e79aaf8cdc54acf (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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
(.module:
  [library
   [lux {"-" [Type static public private]}
    [abstract
     [equivalence {"+" [Equivalence]}]
     ["[0]" monad {"+" [do]}]]
    [control
     ["[0]" try]]
    [data
     ["[0]" product]
     ["[0]" format "_"
      ["[1]" binary {"+" [Writer]} ("[1]\[0]" monoid)]]
     [collection
      ["[0]" row {"+" [Row]}]]]]]
  ["[0]" // "_"
   ["[1][0]" modifier {"+" [Modifier modifiers:]}]
   ["[1][0]" index {"+" [Index]}]
   ["[1][0]" attribute {"+" [Attribute]}
    ["[1]/[0]" code]]
   ["[1][0]" constant {"+" [UTF8]}
    ["[1]/[0]" pool {"+" [Pool Resource]}]]
   ["[1][0]" bytecode {"+" [Bytecode]}
    ["[1]/[0]" environment {"+" [Environment]}]
    ["[1]/[0]" instruction]]
   ["[1][0]" type {"+" [Type]}
    ["[1]/[0]" category]
    ["[1][0]" descriptor {"+" [Descriptor]}]]])

(type: .public Method
  (Rec Method
    (Record
     [#modifier (Modifier Method)
      #name (Index UTF8)
      #descriptor (Index (Descriptor //type/category.Method))
      #attributes (Row Attribute)])))

(modifiers: Method
  ["0001" public]
  ["0002" private]
  ["0004" protected]
  ["0008" static]
  ["0010" final]
  ["0020" synchronized]
  ["0040" bridge]
  ["0080" var_args]
  ["0100" native]
  ["0400" abstract]
  ["0800" strict]
  ["1000" synthetic]
  )

(def: .public (method modifier name type attributes code)
  (-> (Modifier Method) UTF8 (Type //type/category.Method) (List (Resource Attribute)) (Maybe (Bytecode Any))
      (Resource Method))
  (do [! //constant/pool.monad]
    [@name (//constant/pool.utf8 name)
     @descriptor (//constant/pool.descriptor (//type.descriptor type))
     attributes (|> attributes
                    (monad.all !)
                    (\ ! each row.of_list))
     attributes (case code
                  (#.Some code)
                  (do !
                    [environment (case (if (//modifier.has? static modifier)
                                         (//bytecode/environment.static type)
                                         (//bytecode/environment.virtual type))
                                   (#try.Success environment)
                                   (in environment)
                                   
                                   (#try.Failure error)
                                   (function (_ _) (#try.Failure error)))
                     [environment exceptions instruction output] (//bytecode.resolve environment code)
                     .let [bytecode (|> instruction //bytecode/instruction.result format.instance)]
                     @code (//attribute.code [#//attribute/code.limit (value@ #//bytecode/environment.limit environment)
                                              #//attribute/code.code bytecode
                                              #//attribute/code.exception_table exceptions
                                              #//attribute/code.attributes (row.row)])]
                    (in (row.suffix @code attributes)))
                  
                  #.None
                  (in attributes))]
    (in [#modifier modifier
         #name @name
         #descriptor @descriptor
         #attributes attributes])))

(def: .public equivalence
  (Equivalence Method)
  ($_ product.equivalence
      //modifier.equivalence
      //index.equivalence
      //index.equivalence
      (row.equivalence //attribute.equivalence)
      ))

(def: .public (writer field)
  (Writer Method)
  (`` ($_ format\composite
          (~~ (template [<writer> <slot>]
                [(<writer> (value@ <slot> field))]

                [//modifier.writer #modifier]
                [//index.writer #name]
                [//index.writer #descriptor]
                [(format.row/16 //attribute.writer) #attributes]))
          )))