aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/control/exception.lux
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib/source/library/lux/control/exception.lux')
-rw-r--r--stdlib/source/library/lux/control/exception.lux53
1 files changed, 31 insertions, 22 deletions
diff --git a/stdlib/source/library/lux/control/exception.lux b/stdlib/source/library/lux/control/exception.lux
index 7515cb9fb..a7d5a5871 100644
--- a/stdlib/source/library/lux/control/exception.lux
+++ b/stdlib/source/library/lux/control/exception.lux
@@ -7,8 +7,8 @@
[abstract
[monad (#+ do)]]
[control
- ["p" parser
- ["s" code (#+ Parser)]]]
+ ["<>" parser ("#\." monad)
+ ["<.>" code (#+ Parser)]]]
[data
["." maybe]
["." product]
@@ -18,7 +18,6 @@
[macro
["." code]
[syntax (#+ syntax:)
- ["|.|" export]
["|.|" input]
["." type #_
["|#_.|" variable]]]]
@@ -28,17 +27,17 @@
[//
["//" try (#+ Try)]])
-(type: #export (Exception a)
+(type: .public (Exception a)
{#.doc "An exception provides a way to decorate error messages."}
{#label Text
#constructor (-> a Text)})
-(def: #export (match? exception error)
+(def: .public (match? exception error)
{#.doc (doc "Is this exception the cause of the error message?")}
(All [e] (-> (Exception e) Text Bit))
(text.starts_with? (get@ #label exception) error))
-(def: #export (catch exception then try)
+(def: .public (catch exception then try)
{#.doc (doc "If a particular exception is detected on a possibly-erroneous value, handle it."
"If no exception was detected, or a different one from the one being checked, then pass along the original value.")}
(All [e a]
@@ -57,7 +56,7 @@
then))
(#//.Failure error)))))
-(def: #export (otherwise else try)
+(def: .public (otherwise else try)
{#.doc "If no handler could be found to catch the exception, then run a function as a last-resort measure."}
(All [a]
(-> (-> Text a) (Try a) a))
@@ -68,47 +67,57 @@
(#//.Failure error)
(else error)))
-(def: #export (return value)
+(def: .public (return value)
{#.doc "A way to lift normal values into the error-handling context."}
(All [a] (-> a (Try a)))
(#//.Success value))
-(def: #export (error exception message)
+(def: .public (error exception message)
{#.doc "Constructs an error message from an exception."}
(All [e] (-> (Exception e) e Text))
((get@ #..constructor exception) message))
-(def: #export (except exception message)
+(def: .public (except exception message)
{#.doc "Decorate an error message with an Exception and lift it into the error-handling context."}
(All [e a] (-> (Exception e) e (Try a)))
(#//.Failure (..error exception message)))
-(def: #export (assertion exception message test)
+(def: .public (assertion exception message test)
(All [e] (-> (Exception e) e Bit (Try Any)))
(if test
(#//.Success [])
(..except exception message)))
-(syntax: #export (exception: {export |export|.parser}
- {t_vars (p.else (list) (s.tuple (p.some |type_variable|.parser)))}
- {[name inputs] (p.either (p.and s.local_identifier (in (list)))
- (s.form (p.and s.local_identifier (p.some |input|.parser))))}
- {body (p.maybe s.any)})
+(def: exception
+ (Parser [Code (List |type_variable|.Variable) [Text (List |input|.Input)] (Maybe Code)])
+ (let [private (: (Parser [(List |type_variable|.Variable) [Text (List |input|.Input)] (Maybe Code)])
+ ($_ <>.and
+ (<>.else (list) (<code>.tuple (<>.some |type_variable|.parser)))
+ (<>.either (<code>.form (<>.and <code>.local_identifier (<>.some |input|.parser)))
+ (<>.and <code>.local_identifier (<>\in (list))))
+ (<>.maybe <code>.any)
+ ))]
+ ($_ <>.either
+ (<>.and <code>.any private)
+ (<>.and (<>\in (` .private)) private)
+ )))
+
+(syntax: .public (exception: {[export_policy t_vars [name inputs] body] ..exception})
{#.doc (doc "Define a new exception type."
"It mostly just serves as a way to tag error messages for later catching."
""
"Simple case:"
- (exception: #export some_exception)
+ (exception: .public some_exception)
""
"Complex case:"
- (exception: #export [arbitrary type variables] (some_exception {optional Text} {arguments Int})
+ (exception: .public [arbitrary type variables] (some_exception {optional Text} {arguments Int})
optional_body))}
(macro.with_gensyms [g!descriptor]
(do meta.monad
[current_module meta.current_module_name
.let [descriptor ($_ text\compose "{" current_module "." name "}" text.new_line)
g!self (code.local_identifier name)]]
- (in (list (` (def: (~+ (|export|.format export))
+ (in (list (` (def: (~ export_policy)
(~ g!self)
(All [(~+ (list\map |type_variable|.format t_vars))]
(..Exception [(~+ (list\map (get@ #|input|.type) inputs))]))
@@ -149,7 +158,7 @@
(on_entry head)
tail))))
-(syntax: #export (report {entries (p.many (s.tuple (p.and s.any s.any)))})
+(syntax: .public (report {entries (<>.many (<code>.tuple (<>.and <code>.any <code>.any)))})
{#.doc (doc "An error report."
(: Text
(report ["Row 0" value/0]
@@ -160,7 +169,7 @@
(list\map (function (_ [header message])
(` [(~ header) (~ message)])))))))))))
-(def: #export (listing format entries)
+(def: .public (listing format entries)
{#.doc (doc "A numbered report of the entries on a list."
"NOTE: 0-based numbering.")}
(All [a]
@@ -190,7 +199,7 @@
..separator
error))
-(def: #export (with exception message computation)
+(def: .public (with exception message computation)
{#.doc (doc "If a computation fails, prepends the exception to the error.")}
(All [e a] (-> (Exception e) e (Try a) (Try a)))
(case computation