aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/lux/debug.lux
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib/source/lux/debug.lux')
-rw-r--r--stdlib/source/lux/debug.lux157
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)))