aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/meta/compiler/language/lux/phase/translation/jvm/function/method/apply.lux
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib/source/library/lux/meta/compiler/language/lux/phase/translation/jvm/function/method/apply.lux')
-rw-r--r--stdlib/source/library/lux/meta/compiler/language/lux/phase/translation/jvm/function/method/apply.lux159
1 files changed, 159 insertions, 0 deletions
diff --git a/stdlib/source/library/lux/meta/compiler/language/lux/phase/translation/jvm/function/method/apply.lux b/stdlib/source/library/lux/meta/compiler/language/lux/phase/translation/jvm/function/method/apply.lux
new file mode 100644
index 000000000..34a552ba6
--- /dev/null
+++ b/stdlib/source/library/lux/meta/compiler/language/lux/phase/translation/jvm/function/method/apply.lux
@@ -0,0 +1,159 @@
+(.require
+ [library
+ [lux (.except Type Label Synthesis)
+ [abstract
+ ["[0]" monad (.only do)]]
+ [control
+ ["[0]" try]]
+ [data
+ [collection
+ ["[0]" list (.use "[1]#[0]" monoid functor)]]]
+ [math
+ [number
+ ["n" nat]
+ ["i" int]
+ ["[0]" i32]]]
+ [meta
+ [target
+ [jvm
+ ["_" bytecode (.only Label Bytecode) (.use "[1]#[0]" monad)]
+ ["[0]" method (.only Method)]
+ [constant
+ [pool (.only Resource)]]
+ [encoding
+ ["[0]" signed]]
+ ["[0]" type (.only Type)
+ ["[0]" category (.only Class)]]]]]]]
+ ["[0]" // (.only)
+ ["[1][0]" reset]
+ ["[1][0]" implementation]
+ ["[1][0]" init]
+ ["/[1]" //
+ ["[1][0]" abstract]
+ [field
+ [constant
+ ["[1][0]" arity]]
+ [variable
+ ["[1][0]" partial]
+ ["[1][0]" count]
+ ["[1][0]" foreign]]]
+ ["/[1]" //
+ ["[1][0]" runtime]
+ ["[1][0]" value]
+ ["[1][0]" reference]
+ [////
+ [analysis (.only Environment)]
+ [synthesis (.only Synthesis)]
+ [///
+ [arity (.only Arity)]
+ [reference
+ [variable (.only Register)]]]]]]])
+
+(def (increment by)
+ (-> Nat (Bytecode Any))
+ (all _.composite
+ (<| _.int .i64 by)
+ _.iadd))
+
+(def (inputs offset amount)
+ (-> Register Nat (Bytecode Any))
+ (all _.composite
+ (|> amount
+ list.indices
+ (monad.each _.monad (|>> (n.+ offset) _.aload)))
+ (_#in [])
+ ))
+
+(def (apply offset amount)
+ (-> Register Nat (Bytecode Any))
+ (let [arity (n.min amount ///arity.maximum)]
+ (all _.composite
+ (_.checkcast ///abstract.class)
+ (..inputs offset arity)
+ (_.invokevirtual ///abstract.class ////runtime.apply::name (////runtime.apply::type arity))
+ (if (n.> ///arity.maximum amount)
+ (apply (n.+ ///arity.maximum offset)
+ (n.- ///arity.maximum amount))
+ (_#in []))
+ )))
+
+(def this_offset 1)
+
+(def .public (method class environment function_arity @begin apply_arity)
+ (-> (Type Class) (Environment Synthesis) Arity Label Arity (Resource Method))
+ (let [num_partials (-- function_arity)
+ over_extent (i.- (.int apply_arity)
+ (.int function_arity))]
+ (method.method //.modifier ////runtime.apply::name
+ false (////runtime.apply::type apply_arity)
+ (list)
+ {.#Some (when num_partials
+ 0 (all _.composite
+ ////reference.this
+ (..inputs ..this_offset apply_arity)
+ (//implementation.call class function_arity)
+ _.areturn)
+ _ (do _.monad
+ [@default _.new_label
+ @labelsH _.new_label
+ @labelsT (|> _.new_label
+ (list.repeated (-- num_partials))
+ (monad.all _.monad))
+ .let [cases (|> (list#composite {.#Item [@labelsH @labelsT]}
+ (list @default))
+ list.enumeration
+ (list#each (function (_ [stage @case])
+ (let [current_partials (|> (list.indices stage)
+ (list#each (///partial.get class))
+ (monad.all _.monad))
+ already_partial? (n.> 0 stage)
+ exact_match? (i.= over_extent (.int stage))
+ has_more_than_necessary? (i.> over_extent (.int stage))]
+ (all _.composite
+ (_.set_label @case)
+ (cond exact_match?
+ (all _.composite
+ ////reference.this
+ (if already_partial?
+ (_.invokevirtual class //reset.name (//reset.type class))
+ (_#in []))
+ current_partials
+ (..inputs ..this_offset apply_arity)
+ (//implementation.call class function_arity)
+ _.areturn)
+
+ has_more_than_necessary?
+ (let [arity_inputs (|> function_arity (n.- stage))
+ additional_inputs (|> apply_arity (n.- arity_inputs))]
+ (all _.composite
+ ////reference.this
+ (_.invokevirtual class //reset.name (//reset.type class))
+ current_partials
+ (..inputs ..this_offset arity_inputs)
+ (//implementation.call class function_arity)
+ (apply (n.+ ..this_offset arity_inputs) additional_inputs)
+ _.areturn))
+
+ ... (i.< over_extent (.int stage))
+ (let [current_environment (|> (list.indices (list.size environment))
+ (list#each (///foreign.get class))
+ (monad.all _.monad))
+ missing_partials (|> _.aconst_null
+ (list.repeated (|> num_partials (n.- apply_arity) (n.- stage)))
+ (monad.all _.monad))]
+ (all _.composite
+ (_.new class)
+ _.dup
+ current_environment
+ ///count.value
+ (..increment apply_arity)
+ current_partials
+ (..inputs ..this_offset apply_arity)
+ missing_partials
+ (_.invokespecial class //init.name (//init.type environment function_arity))
+ _.areturn)))))))
+ (monad.all _.monad))]]
+ (all _.composite
+ ///count.value
+ (_.tableswitch (try.trusted (signed.s4 +0)) @default [@labelsH @labelsT])
+ cases)))})))