(;module: lux (lux (control codec monad) (data [text] (text format ["l" lexer "l/" Monad]) [char] [number] error (coll [list "L/" Functor])) [type "Type/" Eq]) ["&" ../common]) (do-template [ ] [(def: &;Signal )] [type-signal "T"] [host-signal "^"] [void-signal "0"] [unit-signal "1"] [product-signal "*"] [sum-signal "+"] [function-signal ">"] [application-signal "%"] [uq-signal "U"] [eq-signal "E"] [bound-signal "$"] [ex-signal "!"] [var-signal "?"] [named-signal "@"] ) (def: (encode-type type) (-> Type Text) (if (or (is Type type) (Type/= Type type)) type-signal (case type (#;HostT name params) (format host-signal name &;stop-signal (&;encode-list encode-type params)) #;VoidT void-signal #;UnitT unit-signal (^template [ ] ( left right) (format (encode-type left) (encode-type right))) ([#;ProdT product-signal] [#;SumT sum-signal] [#;FunctionT function-signal] [#;AppT application-signal]) (^template [ ] ( env body) (format (&;encode-list encode-type env) (encode-type body))) ([#;UnivQ uq-signal] [#;ExQ eq-signal]) (^template [ ] ( idx) (format (%i (nat-to-int idx)) &;stop-signal)) ([#;BoundT bound-signal] [#;ExT ex-signal] [#;VarT var-signal]) (#;NamedT [module name] type*) (format named-signal module &;ident-separator name &;stop-signal (encode-type type*)) ))) (def: type-decoder (l;Lexer Type) (l;rec (function [type-decoder] (let% [ (do-template [ ] [(|> (l/wrap ) (l;after (l;text )))] [Type type-signal] [#;VoidT void-signal] [#;UnitT unit-signal]) (do-template [ ] [(do l;Monad [_ (l;text ) left type-decoder right type-decoder] (wrap ( left right)))] [#;ProdT product-signal] [#;SumT sum-signal] [#;FunctionT function-signal] [#;AppT application-signal]) (do-template [ ] [(do l;Monad [_ (l;text ) env (&;decode-list type-decoder) body type-decoder] (wrap ( env body)))] [#;UnivQ uq-signal] [#;ExQ eq-signal]) (do-template [ ] [(do l;Monad [_ (l;text ) id (l;codec number;Codec (l;some' l;digit)) _ (l;text &;stop-signal)] (wrap ( (int-to-nat id))))] [#;BoundT bound-signal] [#;ExT ex-signal] [#;VarT var-signal])] ($_ l;either (do l;Monad [_ (l;text host-signal) name (l;many' (l;none-of &;stop-signal)) _ (l;text &;stop-signal) params (&;decode-list type-decoder)] (wrap (#;HostT name params))) (do l;Monad [_ (l;text named-signal) module (l;some' (l;none-of &;ident-separator)) _ (l;text &;ident-separator) name (l;many' (l;none-of &;stop-signal)) _ (l;text &;stop-signal) unnamed type-decoder] (wrap (#;NamedT [module name] unnamed))) ))))) (def: (decode-type input) (-> Text (Error Type)) (|> type-decoder (l;before l;end) (l;run input))) (struct: #export _ (Codec Text Type) (def: encode encode-type) (def: decode decode-type))