diff options
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.lux | 159 |
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)))}))) |