diff options
Diffstat (limited to 'stdlib/source/library/lux/control/exception.lux')
-rw-r--r-- | stdlib/source/library/lux/control/exception.lux | 53 |
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 |