(.require [library [lux (.except Info Code Type #info) [abstract [monad (.only do)] ["[0]" equivalence (.only Equivalence)]] [control ["[0]" try]] [data ["[0]" sum] ["[0]" product] ["[0]" binary ["[1]F" \\format (.only Format)]]] [math [number ["n" nat]]] [meta [macro ["^" pattern]]]]] ["[0]" // ["[1][0]" index (.only Index)] ["[1][0]" type (.only Type) ["[2][0]" signature (.only Signature)]] [encoding ["[1][0]" unsigned (.only U2 U4)]] ["[1][0]" constant (.only UTF8 Class Value) ["[2][0]" pool (.only Pool Resource) (.use "[1]#[0]" monad)]]] ["[0]" / ["[1][0]" constant (.only Constant)] ["[1][0]" code] ["[1][0]" line_number_table (.only Line_Number_Table)]]) (type .public (Info about) (Record [#name (Index UTF8) #length U4 #info about])) (def .public (info_equivalence Equivalence) (All (_ about) (-> (Equivalence about) (Equivalence (Info about)))) (all product.equivalence //index.equivalence //unsigned.equivalence Equivalence)) (def (info_format format) (All (_ about) (-> (Format about) (Format (Info about)))) (function (_ [name length info]) (let [[nameS nameT] (//index.format name) [lengthS lengthT] (//unsigned.format/4 length) [infoS infoT] (format info)] [(all n.+ nameS lengthS infoS) (|>> nameT lengthT infoT)]))) (with_expansions [ (these (/code.Code Attribute))] (type .public Attribute (Rec Attribute (Variant {#Constant (Info (Constant Any))} {#Code (Info )} {#Signature (Info (Index UTF8))} {#Source_File (Info (Index UTF8))} {#Line_Number_Table (Info Line_Number_Table)}))) (type .public Code ) ) (def .public equivalence (Equivalence Attribute) (equivalence.rec (function (_ equivalence) (all sum.equivalence (info_equivalence /constant.equivalence) (info_equivalence (/code.equivalence equivalence)) (info_equivalence //index.equivalence) (info_equivalence //index.equivalence) (info_equivalence /line_number_table.equivalence) )))) (def common_attribute_length (all n.+ ... u2 attribute_name_index; //unsigned.bytes/2 ... u4 attribute_length; //unsigned.bytes/4 )) (def (length attribute) (-> Attribute Nat) (when attribute (^.with_template [] [{ [name length info]} (|> length //unsigned.value (n.+ ..common_attribute_length))]) ([#Constant] [#Code] [#Signature] [#Source_File] [#Line_Number_Table]))) ... 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)] (//pool#each (signature' it) (//pool.utf8 "Signature")))) ... TODO: Inline ASAP (def (source_file' it @name) (-> (Index UTF8) (Index UTF8) Attribute) {#Source_File [#name @name ... https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.10 #length (|> //index.length //unsigned.u4 try.trusted) #info it]}) (def .public (source_file it) (-> Text (Resource Attribute)) (do //pool.monad [it (//pool.utf8 it)] (//pool#each (source_file' it) (//pool.utf8 "SourceFile")))) ... TODO: Inline ASAP (def (line_number_table' it @name) (-> Line_Number_Table (Index UTF8) Attribute) {#Line_Number_Table [#name @name ... https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.12 #length (|> it /line_number_table.length //unsigned.u4 try.trusted) #info it]}) (def .public (line_number_table it) (-> Line_Number_Table (Resource Attribute)) (//pool#each (line_number_table' it) (//pool.utf8 "LineNumberTable"))) (def .public (format it) (Format Attribute) (when it {#Constant it} ((info_format /constant.format) it) {#Code it} ((info_format (/code.format format)) it) {#Signature it} ((info_format //index.format) it) {#Source_File it} ((info_format //index.format) it) {#Line_Number_Table it} ((info_format /line_number_table.format) it)))