aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source
diff options
context:
space:
mode:
authorEduardo Julian2019-08-10 22:35:13 -0400
committerEduardo Julian2019-08-10 22:35:13 -0400
commitc06ee7d55123c4f87cd15e15f8d25b9ab08ea3f3 (patch)
tree619727ee7354d1eb7d8519e9c4fa839b0a480957 /stdlib/source
parentd0c938888b3dd00cfdb27bb9444401b9e5913490 (diff)
WIP: JVM function generation.
Diffstat (limited to 'stdlib/source')
-rw-r--r--stdlib/source/lux/data/collection/list.lux52
-rw-r--r--stdlib/source/lux/tool/compiler/arity.lux6
-rw-r--r--stdlib/source/lux/tool/compiler/phase/generation/jvm.lux16
-rw-r--r--stdlib/source/lux/tool/compiler/phase/generation/jvm/function.lux64
-rw-r--r--stdlib/source/lux/tool/compiler/phase/generation/jvm/function/abstract.lux4
-rw-r--r--stdlib/source/lux/tool/compiler/phase/generation/jvm/function/arity.lux10
-rw-r--r--stdlib/source/lux/tool/compiler/phase/generation/jvm/function/field.lux29
-rw-r--r--stdlib/source/lux/tool/compiler/phase/generation/jvm/function/field/foreign.lux33
-rw-r--r--stdlib/source/lux/tool/compiler/phase/generation/jvm/function/field/partial.lux53
-rw-r--r--stdlib/source/lux/tool/compiler/phase/generation/jvm/function/field/partial/count.lux27
-rw-r--r--stdlib/source/lux/tool/compiler/phase/generation/jvm/function/method.lux13
-rw-r--r--stdlib/source/lux/tool/compiler/phase/generation/jvm/function/method/apply.lux60
-rw-r--r--stdlib/source/lux/tool/compiler/phase/generation/jvm/function/method/implementation.lux37
-rw-r--r--stdlib/source/lux/tool/compiler/phase/generation/jvm/function/method/init.lux28
-rw-r--r--stdlib/source/lux/tool/compiler/phase/generation/jvm/function/method/new.lux91
-rw-r--r--stdlib/source/lux/tool/compiler/phase/generation/jvm/function/method/reset.lux58
-rw-r--r--stdlib/source/test/lux/target/jvm.lux2
17 files changed, 548 insertions, 35 deletions
diff --git a/stdlib/source/lux/data/collection/list.lux b/stdlib/source/lux/data/collection/list.lux
index 1e00ee529..cec488e95 100644
--- a/stdlib/source/lux/data/collection/list.lux
+++ b/stdlib/source/lux/data/collection/list.lux
@@ -25,7 +25,7 @@
#.Nil
init
- (#.Cons [x xs'])
+ (#.Cons x xs')
(fold f (f x init) xs'))))
(def: #export (reverse xs)
@@ -42,7 +42,7 @@
#.Nil
#.Nil
- (#.Cons [x xs'])
+ (#.Cons x xs')
(if (keep? x)
(#.Cons x (filter keep? xs'))
(filter keep? xs'))))
@@ -57,16 +57,16 @@
(#.Cons head tail)
(let [[in out] (partition satisfies? tail)]
(if (satisfies? head)
- [(list& head in) out]
- [in (list& head out)]))))
+ [(#.Cons head in) out]
+ [in (#.Cons head out)]))))
(def: #export (as-pairs xs)
{#.doc (doc "Cut the list into pairs of 2."
"Caveat emptor: If the list has an uneven number of elements, the last one will be skipped.")}
(All [a] (-> (List a) (List [a a])))
(case xs
- (^ (#.Cons [x1 (#.Cons [x2 xs'])]))
- (#.Cons [[x1 x2] (as-pairs xs')])
+ (^ (list& x1 x2 xs'))
+ (#.Cons [x1 x2] (as-pairs xs'))
_
#.Nil))
@@ -80,11 +80,11 @@
#.Nil
#.Nil
- (#.Cons [x xs'])
+ (#.Cons x xs')
<then>)
<else>))]
- [take (#.Cons [x (take (dec n) xs')]) #.Nil]
+ [take (#.Cons x (take (dec n) xs')) #.Nil]
[drop (drop (dec n) xs') xs]
)
@@ -96,12 +96,12 @@
#.Nil
#.Nil
- (#.Cons [x xs'])
+ (#.Cons x xs')
(if (predicate x)
<then>
<else>)))]
- [take-while (#.Cons [x (take-while predicate xs')]) #.Nil]
+ [take-while (#.Cons x (take-while predicate xs')) #.Nil]
[drop-while (drop-while predicate xs') xs]
)
@@ -113,9 +113,9 @@
#.Nil
[#.Nil #.Nil]
- (#.Cons [x xs'])
+ (#.Cons x xs')
(let [[tail rest] (split (dec n) xs')]
- [(#.Cons [x tail]) rest]))
+ [(#.Cons x tail) rest]))
[#.Nil xs]))
(def: (split-with' predicate ys xs)
@@ -125,9 +125,9 @@
#.Nil
[ys xs]
- (#.Cons [x xs'])
+ (#.Cons x xs')
(if (predicate x)
- (split-with' predicate (#.Cons [x ys]) xs')
+ (split-with' predicate (#.Cons x ys) xs')
[ys xs])))
(def: #export (split-with predicate xs)
@@ -153,7 +153,7 @@
(All [a]
(-> Nat a (List a)))
(if (n.> 0 n)
- (#.Cons [x (repeat (dec n) x)])
+ (#.Cons x (repeat (dec n) x))
#.Nil))
(def: (iterate' f x)
@@ -161,7 +161,7 @@
(-> (-> a (Maybe a)) a (List a)))
(case (f x)
(#.Some x')
- (list& x (iterate' f x'))
+ (#.Cons x (iterate' f x'))
#.None
(list)))
@@ -172,7 +172,7 @@
(-> (-> a (Maybe a)) a (List a)))
(case (f x)
(#.Some x')
- (list& x (iterate' f x'))
+ (#.Cons x (iterate' f x'))
#.None
(list x)))
@@ -185,7 +185,7 @@
#.Nil
#.None
- (#.Cons [x xs'])
+ (#.Cons x xs')
(if (predicate x)
(#.Some x)
(find predicate xs'))))
@@ -197,7 +197,7 @@
#.Nil
#.None
- (#.Cons [x xs'])
+ (#.Cons x xs')
(case (check x)
(#.Some output)
(#.Some output)
@@ -212,7 +212,7 @@
#.Nil
#.None
- (#.Cons [x xs'])
+ (#.Cons x xs')
(case (check x)
(#.Some output)
(#.Cons output (search-all check xs'))
@@ -228,11 +228,11 @@
#.Nil
xs
- (#.Cons [x #.Nil])
+ (#.Cons x #.Nil)
xs
- (#.Cons [x xs'])
- (#.Cons [x (#.Cons [sep (interpose sep xs')])])))
+ (#.Cons x xs')
+ (list& x sep (interpose sep xs'))))
(def: #export (size list)
(All [a] (-> (List a) Nat))
@@ -267,7 +267,7 @@
#.Nil
#.None
- (#.Cons [x xs'])
+ (#.Cons x xs')
(if (n.= 0 i)
(#.Some x)
(nth (dec i) xs'))))
@@ -343,11 +343,11 @@
{#.doc "Generates an inclusive interval of values [from, to]."}
(-> <type> <type> (List <type>))
(cond (<lt> to from)
- (list& from (<name> (inc from) to))
+ (#.Cons from (<name> (inc from) to))
## > GT
(<lt> from to)
- (list& from (<name> (dec from) to))
+ (#.Cons from (<name> (dec from) to))
## (= to from)
(list from)))]
diff --git a/stdlib/source/lux/tool/compiler/arity.lux b/stdlib/source/lux/tool/compiler/arity.lux
index 2e6b07490..54b50cab2 100644
--- a/stdlib/source/lux/tool/compiler/arity.lux
+++ b/stdlib/source/lux/tool/compiler/arity.lux
@@ -6,9 +6,9 @@
(type: #export Arity Nat)
-(template [<name> <comparison>]
+(template [<comparison> <name>]
[(def: #export <name> (-> Arity Bit) (<comparison> 1))]
- [mono? n.=]
- [poly? n.>]
+ [n.= unary?]
+ [n.> multiary?]
)
diff --git a/stdlib/source/lux/tool/compiler/phase/generation/jvm.lux b/stdlib/source/lux/tool/compiler/phase/generation/jvm.lux
index 9a4847165..23f3defea 100644
--- a/stdlib/source/lux/tool/compiler/phase/generation/jvm.lux
+++ b/stdlib/source/lux/tool/compiler/phase/generation/jvm.lux
@@ -6,15 +6,16 @@
[runtime (#+ Phase)]
["#." primitive]
["#." structure]
- ## ["." reference ("#@." system)]
- ## ["." function]
+ ["#." reference]
+ ["#." function]
## ["." case]
## ["." loop]
["//#" ///
## ["." extension]
[//
[analysis (#+)]
- ["." synthesis]]]])
+ ["." synthesis]
+ ["." reference]]]])
(def: #export (generate synthesis)
Phase
@@ -33,8 +34,13 @@
(^ (synthesis.tuple members))
(/structure.tuple generate members)
- ## (#synthesis.Reference value)
- ## (/reference@reference value)
+ (#synthesis.Reference reference)
+ (case reference
+ (#reference.Variable variable)
+ (/reference.variable variable)
+
+ (#reference.Constant constant)
+ (/reference.constant constant))
## (^ (synthesis.branch/case case))
## (/case.case generate case)
diff --git a/stdlib/source/lux/tool/compiler/phase/generation/jvm/function.lux b/stdlib/source/lux/tool/compiler/phase/generation/jvm/function.lux
new file mode 100644
index 000000000..12e1bc460
--- /dev/null
+++ b/stdlib/source/lux/tool/compiler/phase/generation/jvm/function.lux
@@ -0,0 +1,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)))
+ ))))))))
diff --git a/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/abstract.lux b/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/abstract.lux
new file mode 100644
index 000000000..79cede3a4
--- /dev/null
+++ b/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/abstract.lux
@@ -0,0 +1,4 @@
+(.module:
+ [lux #*])
+
+(def: #export class "LuxFunction")
diff --git a/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/arity.lux b/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/arity.lux
new file mode 100644
index 000000000..08954a7c0
--- /dev/null
+++ b/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/arity.lux
@@ -0,0 +1,10 @@
+(.module:
+ [lux (#- type)
+ [target
+ [jvm
+ ["." descriptor]]]])
+
+(def: #export field "arity")
+(def: #export type descriptor.int)
+(def: #export minimum 1)
+(def: #export maximum 8)
diff --git a/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/field.lux b/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/field.lux
new file mode 100644
index 000000000..849d9a663
--- /dev/null
+++ b/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/field.lux
@@ -0,0 +1,29 @@
+(.module:
+ [lux (#- type)
+ [target
+ [jvm
+ ["." modifier (#+ Modifier) ("#@." monoid)]
+ ["." field (#+ Field)]
+ ["_" instruction (#+ Instruction)]
+ [encoding
+ [name (#+ External)]]]]]
+ ["." /// #_
+ [runtime (#+ Operation)]
+ ["#." value]
+ ["#." reference]])
+
+(def: #export type ///value.type)
+
+(def: #export (field class name)
+ (-> External Text (Instruction Any))
+ ($_ _.compose
+ ///reference.this
+ (_.getfield class name ..type)
+ ))
+
+(def: #export modifier
+ (Modifier Field)
+ ($_ modifier@compose
+ field.private
+ field.final
+ ))
diff --git a/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/field/foreign.lux b/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/field/foreign.lux
new file mode 100644
index 000000000..b4fa6727e
--- /dev/null
+++ b/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/field/foreign.lux
@@ -0,0 +1,33 @@
+(.module:
+ [lux #*
+ [control
+ [state (#+ State)]]
+ [data
+ [collection
+ ["." list ("#@." functor)]
+ ["." row]]]
+ [target
+ [jvm
+ [descriptor (#+ Descriptor Value)]
+ ["." field (#+ Field)]
+ [constant
+ [pool (#+ Pool)]]]]]
+ ["." //
+ ["//#" /// #_
+ ["#." value]
+ ["#." reference]
+ [////
+ [analysis (#+ Environment)]]]])
+
+(def: #export (closure environment)
+ (-> Environment (List (Descriptor (Value Any))))
+ (list.repeat (list.size environment) ////value.type))
+
+(def: #export fields
+ (-> Environment (List (State Pool Field)))
+ (|>> list.enumerate
+ (list@map (function (_ [index source])
+ (field.field //.modifier
+ (////reference.foreign-name index)
+ //.type
+ (row.row))))))
diff --git a/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/field/partial.lux b/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/field/partial.lux
new file mode 100644
index 000000000..0f3c9ced5
--- /dev/null
+++ b/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/field/partial.lux
@@ -0,0 +1,53 @@
+(.module:
+ [lux #*
+ [abstract
+ ["." monad]]
+ [control
+ [state (#+ State)]]
+ [data
+ [number
+ ["n" nat]]
+ [collection
+ ["." list ("#@." functor)]
+ ["." row]]]
+ [target
+ [jvm
+ ["." field (#+ Field)]
+ ["_" instruction (#+ Label Instruction) ("#@." monad)]
+ [constant
+ [pool (#+ Pool)]]]]]
+ ["." / #_
+ ["#." count]
+ ["/#" //
+ ["/#" // #_
+ ["#." arity]
+ ["/#" // #_
+ ["#." reference]
+ [////
+ ["." arity (#+ Arity)]]]]]])
+
+(def: #export (initial amount)
+ (-> Nat (Instruction Any))
+ ($_ _.compose
+ (|> _.aconst-null
+ (list.repeat amount)
+ (monad.seq _.monad))
+ (_@wrap [])))
+
+(def: #export fields
+ (-> Arity (List (State Pool Field)))
+ (|>> (n.- ///arity.minimum)
+ list.indices
+ (list@map (function (_ index)
+ (field.field //.modifier
+ (////reference.partial-name index)
+ //.type
+ (row.row))))))
+
+(def: #export (new arity)
+ (-> Arity (Instruction Any))
+ (if (arity.multiary? arity)
+ ($_ _.compose
+ /count.initial
+ (initial (n.- ///arity.minimum arity)))
+ (_@wrap [])))
diff --git a/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/field/partial/count.lux b/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/field/partial/count.lux
new file mode 100644
index 000000000..625cad78d
--- /dev/null
+++ b/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/field/partial/count.lux
@@ -0,0 +1,27 @@
+(.module:
+ [lux (#- type)
+ [target
+ [jvm
+ ["." descriptor]
+ ["_" instruction (#+ Instruction) ("#@." monad)]
+ [encoding
+ [name (#+ External)]
+ ["." unsigned]]]]]
+ ["." //// #_
+ ["#." abstract]
+ ["/#" // #_
+ ["#." reference]]])
+
+(def: #export field "partials")
+(def: #export type descriptor.int)
+
+(def: #export initial
+ (Instruction Any)
+ (_.bipush (unsigned.u1 0)))
+
+(def: #export value
+ (Instruction Any)
+ ($_ _.compose
+ /////reference.this
+ (_.getfield ////abstract.class ..field ..type)
+ ))
diff --git a/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/method.lux b/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/method.lux
new file mode 100644
index 000000000..2fd419d18
--- /dev/null
+++ b/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/method.lux
@@ -0,0 +1,13 @@
+(.module:
+ [lux #*
+ [target
+ [jvm
+ ["." modifier (#+ Modifier) ("#@." monoid)]
+ ["." method (#+ Method)]]]])
+
+(def: #export modifier
+ (Modifier Method)
+ ($_ modifier@compose
+ method.public
+ method.strict
+ ))
diff --git a/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/method/apply.lux b/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/method/apply.lux
new file mode 100644
index 000000000..3971610ff
--- /dev/null
+++ b/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/method/apply.lux
@@ -0,0 +1,60 @@
+(.module:
+ [lux (#- type)
+ [abstract
+ ["." monad]]
+ [data
+ [number
+ ["n" nat]
+ ["." i32]]
+ [collection
+ ["." list]]]
+ [target
+ [jvm
+ ["." descriptor (#+ Descriptor Value Return)]
+ ["_" instruction (#+ Instruction) ("#@." monad)]
+ ["." constant]
+ [encoding
+ ["." unsigned]]]]]
+ ["." /// #_
+ ["#." abstract]
+ ["#." arity]
+ ["/#" // #_
+ ["#." value]
+ [////
+ [reference (#+ Register)]
+ [arity (#+ Arity)]]]])
+
+(def: #export name "apply")
+
+(def: #export (type arity)
+ (-> Arity [(List (Descriptor (Value Any))) (Descriptor (Return Any))])
+ [(list.repeat arity ////value.type)
+ ////value.type])
+
+(def: (increment by)
+ (-> Nat (Instruction Any))
+ ($_ _.compose
+ (<| _.ldc/integer constant.integer i32.i32 .i64 by)
+ _.iadd))
+
+(def: (inputs offset amount)
+ (-> Register Nat (Instruction Any))
+ ($_ _.compose
+ (|> amount
+ list.indices
+ (monad.map _.monad (|>> (n.+ offset) unsigned.u1 _.aload)))
+ (_@wrap [])
+ ))
+
+(def: #export (instruction offset amount)
+ (-> Register Nat (Instruction Any))
+ (let [arity (n.min amount ///arity.maximum)]
+ ($_ _.compose
+ (_.checkcast ///abstract.class)
+ (..inputs offset arity)
+ (_.invokevirtual ///abstract.class ..name (..type arity))
+ (if (n.> ///arity.maximum amount)
+ (instruction (n.+ ///arity.maximum offset)
+ (n.- ///arity.maximum amount))
+ (_@wrap []))
+ )))
diff --git a/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/method/implementation.lux b/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/method/implementation.lux
new file mode 100644
index 000000000..9b8a19b59
--- /dev/null
+++ b/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/method/implementation.lux
@@ -0,0 +1,37 @@
+(.module:
+ [lux (#- type)
+ [control
+ [state (#+ State)]]
+ [data
+ [collection
+ ["." list]]]
+ [target
+ [jvm
+ ["." descriptor (#+ Descriptor)]
+ ["." method (#+ Method)]
+ ["_" instruction (#+ Label Instruction)]
+ [constant
+ [pool (#+ Pool)]]]]]
+ ["." //
+ ["//#" /// #_
+ ["#." value]
+ [////
+ [arity (#+ Arity)]]]])
+
+(def: #export name "impl")
+
+(def: #export (type arity)
+ (-> Arity (Descriptor descriptor.Method))
+ (descriptor.method [(list.repeat arity ////value.type)
+ ////value.type]))
+
+(def: #export (method arity @begin body)
+ (-> Arity Label (Instruction Any) (State Pool Method))
+ (method.method //.modifier ..name
+ (..type arity)
+ (list)
+ ($_ _.compose
+ (_.set-label @begin)
+ body
+ _.areturn
+ )))
diff --git a/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/method/init.lux b/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/method/init.lux
new file mode 100644
index 000000000..0489b8f12
--- /dev/null
+++ b/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/method/init.lux
@@ -0,0 +1,28 @@
+(.module:
+ [lux (#- type)
+ [target
+ [jvm
+ ["." descriptor (#+ Descriptor Value Return)]
+ ["_" instruction (#+ Instruction)]
+ [encoding
+ ["." unsigned]]]]]
+ ["." /// #_
+ ["#." abstract]
+ ["#." arity]
+ ["/#" // #_
+ [////
+ ["." arity (#+ Arity)]]]])
+
+(def: #export type
+ [(List (Descriptor (Value Any)))
+ (Descriptor (Return Any))]
+ [(list ///arity.type) descriptor.void])
+
+(def: #export (instruction environment-size arity)
+ (-> Nat Arity (Instruction Any))
+ (let [arity-register (inc environment-size)]
+ ($_ _.compose
+ (if (arity.unary? arity)
+ (_.bipush (unsigned.u1 0))
+ (_.iload (unsigned.u1 arity-register)))
+ (_.invokespecial ///abstract.class "<init>" ..type))))
diff --git a/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/method/new.lux b/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/method/new.lux
new file mode 100644
index 000000000..c0bf6e44b
--- /dev/null
+++ b/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/method/new.lux
@@ -0,0 +1,91 @@
+(.module:
+ [lux (#- type)
+ [abstract
+ ["." monad (#+ do)]]
+ [control
+ [state (#+ State)]]
+ [data
+ [number
+ ["n" nat]]
+ [collection
+ ["." list ("#@." monoid)]]]
+ [target
+ [jvm
+ ["." descriptor (#+ Descriptor Value Return)]
+ ["." modifier (#+ Modifier) ("#@." monoid)]
+ ["." field (#+ Field)]
+ ["." method (#+ Method)]
+ ["_" instruction (#+ Instruction)]
+ ["." constant
+ [pool (#+ Pool)]]
+ [encoding
+ [name (#+ External)]
+ ["." unsigned]]]]]
+ ["." //
+ ["#." init]
+ ["/#" // #_
+ ["#." arity]
+ ["#." field
+ ["#/." foreign]
+ ["#/." partial]]
+ ["/#" // #_
+ [runtime (#+ Operation)]
+ ["#." value]
+ ["#." reference]
+ [////
+ [analysis (#+ Environment)]
+ ["." arity (#+ Arity)]
+ ["." phase]]]]])
+
+(def: (arguments arity)
+ (-> Arity (List (Descriptor (Value Any))))
+ (list.repeat (dec arity) ////value.type))
+
+(def: #export (type environment arity)
+ (-> Environment Arity [(List (Descriptor (Value Any)))
+ (Descriptor (Return Any))])
+ [(list@compose (///field/foreign.closure environment)
+ (if (arity.multiary? arity)
+ (list& ///arity.type (arguments arity))
+ (list)))
+ descriptor.void])
+
+(def: #export (instance class environment arity)
+ (-> External Environment Arity (Operation (Instruction Any)))
+ (do phase.monad
+ [foreign* (monad.map @ ////reference.variable environment)]
+ (wrap ($_ _.compose
+ (_.new class)
+ _.dup
+ (monad.seq _.monad foreign*)
+ (///field/partial.new arity)
+ (_.invokespecial class "<init>" (..type environment arity))))))
+
+(def: #export (method class environment arity)
+ (-> External Environment Arity (State Pool Method))
+ (let [after-this (: (-> Nat Nat)
+ (n.+ 1))
+ environment-size (list.size environment)
+ after-environment (: (-> Nat Nat)
+ (|>> after-this (n.+ environment-size)))
+ after-arity (: (-> Nat Nat)
+ (|>> after-environment (n.+ 1)))]
+ (method.method //.modifier "<init>"
+ (descriptor.method (..type environment arity))
+ (list)
+ ($_ _.compose
+ ////reference.this
+ (//init.instruction environment-size arity)
+ (monad.map _.monad (function (_ register)
+ ($_ _.compose
+ ////reference.this
+ (_.aload (unsigned.u1 (after-this register)))
+ (_.putfield class (////reference.foreign-name register) ////value.type)))
+ (list.indices environment-size))
+ (monad.map _.monad (function (_ register)
+ ($_ _.compose
+ ////reference.this
+ (_.aload (unsigned.u1 (after-arity register)))
+ (_.putfield class (////reference.partial-name register) ////value.type)))
+ (list.indices (n.- ///arity.minimum arity)))
+ _.areturn))))
diff --git a/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/method/reset.lux b/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/method/reset.lux
new file mode 100644
index 000000000..7aee9e428
--- /dev/null
+++ b/stdlib/source/lux/tool/compiler/phase/generation/jvm/function/method/reset.lux
@@ -0,0 +1,58 @@
+(.module:
+ [lux (#- type)
+ [abstract
+ ["." monad]]
+ [control
+ [state (#+ State)]]
+ [data
+ [collection
+ ["." list]]]
+ [target
+ [jvm
+ [modifier (#+ Modifier)]
+ ["." descriptor (#+ Descriptor)]
+ ["." method (#+ Method)]
+ ["_" instruction]
+ [constant
+ [pool (#+ Pool)]]
+ [encoding
+ [name (#+ External)]]]]]
+ ["." //
+ ["#." new]
+ ["/#" // #_
+ ["#." arity]
+ ["#." field
+ ["#/." partial]]
+ ["/#" // #_
+ ["#." value]
+ ["#." reference]
+ [////
+ [analysis (#+ Environment)]
+ [reference (#+ Register)]
+ ["." arity (#+ Arity)]]]]])
+
+(def: #export name "reset")
+
+(def: #export type
+ (-> External (Descriptor descriptor.Method))
+ (|>> descriptor.object [(list)] descriptor.method))
+
+(def: #export (method class environment arity)
+ (-> External Environment Arity (State Pool Method))
+ (method.method //.modifier ..name
+ (..type class)
+ (list)
+ ($_ _.compose
+ (if (arity.multiary? arity)
+ ($_ _.compose
+ (_.new class)
+ _.dup
+ (monad.map _.monad (function (_ source)
+ ($_ _.compose
+ ////reference.this
+ (_.getfield class (////reference.foreign-name source) ////value.type)))
+ (list.indices (list.size environment)))
+ (///field/partial.new arity)
+ (_.invokespecial class "<init>" (//new.type environment arity)))
+ ////reference.this)
+ _.areturn)))
diff --git a/stdlib/source/test/lux/target/jvm.lux b/stdlib/source/test/lux/target/jvm.lux
index 18469e74e..4dd3ee4b3 100644
--- a/stdlib/source/test/lux/target/jvm.lux
+++ b/stdlib/source/test/lux/target/jvm.lux
@@ -131,7 +131,7 @@
/method.public
/method.static)
method-name
- (/descriptor.method inputsJT outputJT)
+ (/descriptor.method [inputsJT outputJT])
(list)
(do /instruction.monad
[_ (/instruction.ldc/long (/constant.long expected))