(.using [library [lux {"-" Info Code Type} [abstract [monad {"+" do}] ["[0]" equivalence {"+" Equivalence}]] [control ["[0]" try] ["[0]" exception {"+" exception:}]] [data ["[0]" sum] ["[0]" product] [format ["[0]F" binary {"+" Writer}]]] [math [number ["n" nat]]]]] ["[0]" // "_" ["[1][0]" index {"+" Index}] ["[1][0]" type {"+" Type} ["[2][0]" signature {"+" Signature}]] [encoding ["[1][0]" unsigned {"+" U2 U4}]] ["[1][0]" constant {"+" UTF8 Class Value} ["[2][0]" pool {"+" Pool Resource} ("[1]#[0]" monad)]]] ["[0]" / "_" ["[1][0]" constant {"+" Constant}] ["[1][0]" code]]) (type: .public (Info about) (Record [#name (Index UTF8) #length U4 #info about])) (def: .public (info_equivalence Equivalence) (All (_ about) (-> (Equivalence about) (Equivalence (Info about)))) ($_ product.equivalence //index.equivalence //unsigned.equivalence Equivalence)) (def: (info_writer writer) (All (_ about) (-> (Writer about) (Writer (Info about)))) (function (_ [name length info]) (let [[nameS nameT] (//index.writer name) [lengthS lengthT] (//unsigned.writer/4 length) [infoS infoT] (writer info)] [($_ n.+ nameS lengthS infoS) (|>> nameT lengthT infoT)]))) (with_expansions [ (as_is (/code.Code Attribute))] (type: .public Attribute (Rec Attribute (Variant {#Constant (Info (Constant Any))} {#Code (Info )} {#Signature (Info (Index UTF8))}))) (type: .public Code ) ) (def: .public equivalence (Equivalence Attribute) (equivalence.rec (function (_ equivalence) ($_ sum.equivalence (info_equivalence /constant.equivalence) (info_equivalence (/code.equivalence equivalence)) (info_equivalence //index.equivalence) )))) (def: common_attribute_length ($_ n.+ ... u2 attribute_name_index; //unsigned.bytes/2 ... u4 attribute_length; //unsigned.bytes/4 )) (def: (length attribute) (-> Attribute Nat) (case attribute (^template [] [{ [name length info]} (|> length //unsigned.value (n.+ ..common_attribute_length))]) ([#Constant] [#Code] [#Signature]))) ... TODO: Inline ASAP (def: (constant' index @name) (-> (Constant Any) (Index UTF8) Attribute) {#Constant [#name @name ... https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.2 #length (|> /constant.length //unsigned.u4 try.trusted) #info index]}) (def: .public (constant index) (-> (Constant Any) (Resource Attribute)) (//pool#each (constant' index) (//pool.utf8 "ConstantValue"))) ... TODO: Inline ASAP (def: (code' specification @name) (-> Code (Index UTF8) Attribute) {#Code [#name @name ... https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.3 #length (|> specification (/code.length ..length) //unsigned.u4 try.trusted) #info specification]}) (def: .public (code specification) (-> Code (Resource Attribute)) (//pool#each (code' specification) (//pool.utf8 "Code"))) ... TODO: Inline ASAP (def: (signature' it @name) (-> (Index UTF8) (Index UTF8) Attribute) {#Signature [#name @name ... https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.9 #length (|> //index.length //unsigned.u4 try.trusted) #info it]}) (def: .public (signature it) (All (_ category) (-> (Signature category) (Resource Attribute))) (do [! //pool.monad] [it (|> it //signature.signature //pool.utf8)] (# ! each (signature' it) (//pool.utf8 "Signature")))) (def: .public (writer it) (Writer Attribute) (case it {#Constant it} ((info_writer /constant.writer) it) {#Code it} ((info_writer (/code.writer writer)) it) {#Signature it} ((info_writer //index.writer) it)))