(.module: [lux (#- Type) [abstract ["." monad (#+ do)]] [control ["ex" exception (#+ exception:)]] [data [number ["n" nat]] [text ["%" format (#+ format)]] [collection ["." list]]] [target [jvm ["$t" type (#+ Type)]]] [tool [compiler [synthesis (#+ Synthesis)] ["." phase]]]] [luxc [lang [host [jvm (#+ Inst Operation Phase) ["_" inst]]]]] ["." //]) (exception: #export (not-a-tuple {size Nat}) (ex.report ["Expected size" ">= 2"] ["Actual size" (%.nat size)])) (def: $Object ($t.class "java.lang.Object" (list))) (def: #export (tuple generate members) (-> Phase (List Synthesis) (Operation Inst)) (do phase.monad [#let [size (list.size members)] _ (phase.assert not-a-tuple size (n.>= 2 size)) membersI (|> members list.enumerate (monad.map @ (function (_ [idx member]) (do @ [memberI (generate member)] (wrap (|>> _.DUP (_.int (.int idx)) memberI _.AASTORE))))) (:: @ map _.fuse))] (wrap (|>> (_.int (.int size)) (_.array $Object) membersI)))) (def: (flagI right?) (-> Bit Inst) (if right? (_.string "") _.NULL)) (def: #export (variant generate lefts right? member) (-> Phase Nat Bit Synthesis (Operation Inst)) (do phase.monad [memberI (generate member)] (wrap (|>> (_.int (.int (if right? (.inc lefts) lefts))) (flagI right?) memberI (_.INVOKESTATIC //.runtime-class "variant_make" ($t.method (list $t.int $Object $Object) (#.Some ($t.array 1 $Object)) (list)) #0)))))