(.module: [lux #* ["." type] ["." host (#+ import:)] [abstract [monad (#+ do)]] [control ["." function] ["." exception (#+ exception:)] ["<>" parser ["<.>" type (#+ Parser)]] pipe] [data ["." error (#+ Error)] ["." text format] [format [xml (#+ XML)] [json (#+ JSON)]] [collection ["." array (#+ Array)] ["." list ("#@." functor)]]] [time [instant (#+ Instant)] [duration (#+ Duration)] [date (#+ Date)]] [macro ["." template]]]) (import: #long java/lang/String) (import: #long (java/lang/Class a) (getCanonicalName [] java/lang/String)) (import: #long java/lang/Object (new []) (toString [] java/lang/String) (getClass [] (java/lang/Class java/lang/Object))) (import: #long java/lang/Integer (longValue [] java/lang/Long)) (import: #long java/lang/Long (intValue [] java/lang/Integer)) (import: #long java/lang/Number (intValue [] java/lang/Integer) (longValue [] long) (doubleValue [] double)) (def: #export (inspect value) (-> Any Text) (let [object (:coerce java/lang/Object value)] (`` (<| (~~ (template [ ] [(case (host.check object) (#.Some value) (`` (|> value (~~ (template.splice )))) #.None)] [java/lang/Boolean [%b]] [java/lang/String [%t]] [java/lang/Long [.int %i]] [java/lang/Number [java/lang/Number::doubleValue %f]] )) (case (host.check (Array java/lang/Object) object) (#.Some value) (let [value (:coerce (Array java/lang/Object) value)] (case (array.read 0 value) (^multi (#.Some tag) [(host.check java/lang/Integer tag) (#.Some tag)] [[(array.read 1 value) (array.read 2 value)] [last? (#.Some choice)]]) (let [last? (case last? (#.Some _) #1 #.None #0)] (|> (format (%n (.nat (java/lang/Integer::longValue tag))) " " (%b last?) " " (inspect choice)) (text.enclose ["(" ")"]))) _ (|> value array.to-list (list@map inspect) (text.join-with " ") (text.enclose ["[" "]"])))) #.None) (java/lang/Object::toString object))) )) (exception: #export (cannot-represent-value {type Type}) (exception.report ["Type" (%type type)])) (type: Representation (-> Any Text)) (def: primitive-representation (Parser Representation) (`` ($_ <>.either (do <>.monad [_ (.exactly Any)] (wrap (function.constant "[]"))) (~~ (template [ ] [(do <>.monad [_ (.sub )] (wrap (|>> (:coerce ) )))] [Bit %b] [Nat %n] [Int %i] [Rev %r] [Frac %f] [Text %t]))))) (def: (special-representation representation) (-> (Parser Representation) (Parser Representation)) (`` ($_ <>.either (~~ (template [ ] [(do <>.monad [_ (.sub )] (wrap (|>> (:coerce ) )))] [Type %type] [Code %code] [Instant %instant] [Duration %duration] [Date %date] [JSON %json] [XML %xml])) (do <>.monad [[_ elemT] (.apply (<>.and (.exactly List) .any)) elemR (.local (list elemT) representation)] (wrap (|>> (:coerce (List Any)) (%list elemR)))) (do <>.monad [[_ elemT] (.apply (<>.and (.exactly Maybe) .any)) elemR (.local (list elemT) representation)] (wrap (|>> (:coerce (Maybe Any)) (case> #.None "#.None" (#.Some elemV) (format "(#.Some " (elemR elemV) ")")))))))) (def: (variant-representation representation) (-> (Parser Representation) (Parser Representation)) (do <>.monad [membersR+ (.variant (<>.many representation))] (wrap (function (_ variantV) (let [[lefts right? sub-repr] (loop [lefts 0 representations membersR+ variantV variantV] (case representations (#.Cons leftR (#.Cons rightR extraR+)) (case (:coerce (| Any Any) variantV) (#.Left left) [lefts #0 (leftR left)] (#.Right right) (case extraR+ #.Nil [lefts #1 (rightR right)] extraR+ (recur (inc lefts) (#.Cons rightR extraR+) right))) _ (undefined)))] (format "(" (%n lefts) " " (%b right?) " " sub-repr ")")))))) (def: (tuple-representation representation) (-> (Parser Representation) (Parser Representation)) (do <>.monad [membersR+ (.tuple (<>.many representation))] (wrap (function (_ tupleV) (let [tuple-body (loop [representations membersR+ tupleV tupleV] (case representations #.Nil "" (#.Cons lastR #.Nil) (lastR tupleV) (#.Cons headR tailR) (let [[leftV rightV] (:coerce [Any Any] tupleV)] (format (headR leftV) " " (recur tailR rightV)))))] (format "[" tuple-body "]")))))) (def: representation (Parser Representation) (<>.rec (function (_ representation) ($_ <>.either primitive-representation (special-representation representation) (variant-representation representation) (tuple-representation representation) (do <>.monad [[funcT inputsT+] (.apply (<>.and .any (<>.many .any)))] (case (type.apply inputsT+ funcT) (#.Some outputT) (.local (list outputT) representation) #.None (<>.fail ""))) (do <>.monad [[name anonymous] .named] (.local (list anonymous) representation)) (<>.fail "") )))) (def: #export (represent type value) (-> Type Any (Error Text)) (case (.run type ..representation) (#error.Success representation) (#error.Success (representation value)) (#error.Failure error) (exception.throw cannot-represent-value type)))