diff options
Diffstat (limited to 'stdlib/source/lux/debug.lux')
-rw-r--r-- | stdlib/source/lux/debug.lux | 157 |
1 files changed, 155 insertions, 2 deletions
diff --git a/stdlib/source/lux/debug.lux b/stdlib/source/lux/debug.lux index 63a46aff4..43d3f4762 100644 --- a/stdlib/source/lux/debug.lux +++ b/stdlib/source/lux/debug.lux @@ -1,14 +1,31 @@ (.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]] - ["." host (#+ import:)]]) + ["." template]]]) (import: #long java/lang/String) @@ -73,3 +90,139 @@ #.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 + [_ (<type>.exactly Any)] + (wrap (function.constant "[]"))) + + (~~ (template [<type> <formatter>] + [(do <>.monad + [_ (<type>.sub <type>)] + (wrap (|>> (:coerce <type>) <formatter>)))] + + [Bit %b] + [Nat %n] + [Int %i] + [Rev %r] + [Frac %f] + [Text %t]))))) + +(def: (special-representation representation) + (-> (Parser Representation) (Parser Representation)) + (`` ($_ <>.either + (~~ (template [<type> <formatter>] + [(do <>.monad + [_ (<type>.sub <type>)] + (wrap (|>> (:coerce <type>) <formatter>)))] + + [Type %type] + [Code %code] + [Instant %instant] + [Duration %duration] + [Date %date] + [JSON %json] + [XML %xml])) + + (do <>.monad + [[_ elemT] (<type>.apply (<>.and (<type>.exactly List) <type>.any)) + elemR (<type>.local (list elemT) representation)] + (wrap (|>> (:coerce (List Any)) (%list elemR)))) + + (do <>.monad + [[_ elemT] (<type>.apply (<>.and (<type>.exactly Maybe) <type>.any)) + elemR (<type>.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+ (<type>.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+ (<type>.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+] (<type>.apply (<>.and <type>.any (<>.many <type>.any)))] + (case (type.apply inputsT+ funcT) + (#.Some outputT) + (<type>.local (list outputT) representation) + + #.None + (<>.fail ""))) + + (do <>.monad + [[name anonymous] <type>.named] + (<type>.local (list anonymous) representation)) + + (<>.fail "") + )))) + +(def: #export (represent type value) + (-> Type Any (Error Text)) + (case (<type>.run type ..representation) + (#error.Success representation) + (#error.Success (representation value)) + + (#error.Failure error) + (exception.throw cannot-represent-value type))) |