(.module: [library [lux (#- Type) ["." ffi (#+ import:)] [abstract ["." monad (#+ do)]] [control ["." exception (#+ exception:)]] [data [text ["%" format (#+ format)]] [collection ["." list]]] [math [number ["n" nat] ["i" int]]] [target [jvm ["." type (#+ Type) ["." category (#+ Void Value Return Primitive Object Class Array Var Parameter Method)] ["." descriptor (#+ Descriptor)] ["." signature (#+ Signature)]]]] [tool [compiler ["." phase] [meta [archive (#+ Archive)]] [language [lux [synthesis (#+ Synthesis)]]]]]]] [luxc [lang [host [jvm (#+ Inst Operation Phase Generator) ["_" inst]]]]] ["." // ["#." runtime]]) (exception: .public (not_a_tuple {size Nat}) (exception.report ["Expected size" ">= 2"] ["Actual size" (%.nat size)])) (def: .public (tuple generate archive members) (Generator (List Synthesis)) (do {@ phase.monad} [.let [size (list.size members)] _ (phase.assertion ..not_a_tuple size (n.>= 2 size)) membersI (|> members list.enumeration (monad.map @ (function (_ [idx member]) (do @ [memberI (generate archive member)] (in (|>> _.DUP (_.int (.int idx)) memberI _.AASTORE))))) (\ @ map _.fuse))] (in (|>> (_.int (.int size)) (_.array //runtime.$Value) membersI)))) (import: java/lang/Byte ["#::." (#static MAX_VALUE byte) (#static MIN_VALUE byte)]) (import: java/lang/Short ["#::." (#static MAX_VALUE short) (#static MIN_VALUE short)]) (def: .public (tagI lefts right?) (-> Nat Bit Inst) (case (if right? (.++ lefts) lefts) 0 _.ICONST_0 1 _.ICONST_1 2 _.ICONST_2 3 _.ICONST_3 4 _.ICONST_4 5 _.ICONST_5 tag (let [tag (.int tag)] (cond (and (i.>= (java/lang/Byte::MIN_VALUE) tag) (i.<= (java/lang/Byte::MAX_VALUE) tag)) (_.BIPUSH tag) (and (i.>= (java/lang/Short::MIN_VALUE) tag) (i.<= (java/lang/Short::MAX_VALUE) tag)) (_.SIPUSH tag) ... else (_.int tag))))) (def: .public leftI _.NULL) (def: .public rightI (_.string "")) (def: .public (flagI right?) (-> Bit Inst) (if right? ..rightI ..leftI)) (def: .public (variant generate archive [lefts right? member]) (Generator [Nat Bit Synthesis]) (do phase.monad [memberI (generate archive member) .let [tagI (..tagI lefts right?)]] (in (|>> tagI (flagI right?) memberI (_.INVOKESTATIC //.$Runtime "variant_make" (type.method [(list) (list //runtime.$Tag //runtime.$Flag //runtime.$Value) //.$Variant (list)]))))))