(.module: lux (lux (control codec monad) (data [text] (text format ["l" lexer "l/" Monad]) [number] ["e" error] (coll [list "L/" Functor])) (lang [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))