(;module: lux (lux (control codec monad) (data [text] (text format ["l" lexer "l/" Monad]) [number] ["e" error] (coll [list "L/" Functor])) (meta [type "type/" Eq])) ["&" ../common]) (do-template [ ] [(def: &;Signal )] [type-signal "T"] [primitive-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 (#;Primitive name params) (format primitive-signal name &;stop-signal (&;encode-list encode-type params)) #;Void void-signal #;Unit unit-signal (^template [ ] ( left right) (format (encode-type left) (encode-type right))) ([#;Product product-signal] [#;Sum sum-signal] [#;Function function-signal] [#;App 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)) ([#;Bound bound-signal] [#;Ex ex-signal] [#;Var var-signal]) (#;Named [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] (with-expansions [ (do-template [ ] [(|> (l/wrap ) (l;after (l;text )))] [Type type-signal] [#;Void void-signal] [#;Unit unit-signal]) (do-template [ ] [(do l;Monad [_ (l;text ) left type-decoder right type-decoder] (wrap ( left right)))] [#;Product product-signal] [#;Sum sum-signal] [#;Function function-signal] [#;App 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))))] [#;Bound bound-signal] [#;Ex ex-signal] [#;Var var-signal])] ($_ l;either (do l;Monad [_ (l;text primitive-signal) name (l;many' (l;none-of &;stop-signal)) _ (l;text &;stop-signal) params (&;decode-list type-decoder)] (wrap (#;Primitive 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 (#;Named [module name] unnamed))) ))))) (def: (decode-type input) (-> Text (e;Error Type)) (|> type-decoder (l;before l;end) (l;run input))) (struct: #export _ (Codec Text Type) (def: encode encode-type) (def: decode decode-type))