/*---------------------------------------------------------------------------
  Copyright 2012-2024, Microsoft Research, Daan Leijen.

  This is free software; you can redistribute it and/or modify it under the
  terms of the Apache License, Version 2.0. A copy of the License can be
  found in the LICENSE file at the root of this distribution.
---------------------------------------------------------------------------*/

// Standard exception (`:exn`) effect.
module std/core/exnstd/core/exn

import std/core/typesstd/core/types
import std/core/hndstd/core/hnd

extern import
  c  file "inline/exn"
  js file "inline/exn.js"


// Exceptions
pubstd/core/exn/exn: (E, V) -> V effect exnstd/core/exn/exn: (E, V) -> V
  // Throw an exception
  final ctl throw-exn( exnexn: exception : exceptionstd/core/exn/exception: V ) : aa: V

// Raise a pattern match exception. This is function is used internally by the
// compiler to generate error messages on pattern match failures.
pub fun error-patternstd/core/exn/error-pattern: forall<a> (location : string, definition : string) -> exn a(locationlocation: string : stringstd/core/types/string: V, definitiondefinition: string : stringstd/core/types/string: V)result: -> exn 477 : exnstd/core/exn/exn: (E, V) -> V aa: V
  throwstd/core/exn/throw: (message : string, info : ? exception-info) -> exn $425(locationlocation: string ++std/core/types/(++): (x : string, y : string) -> exn string ": "literal: string
count= 2
++std/core/types/(++): (x : string, y : string) -> exn string definitiondefinition: string ++std/core/types/(++): (x : string, y : string) -> exn string ": pattern match failure"literal: string
count= 23
, ExnPatternstd/core/exn/ExnPattern: (location : string, definition : string) -> exception-info(locationlocation: string,definitiondefinition: string)
) // The exception data type pub value struct exceptionstd/core/exn/exception: V( messagestd/core/exn/exception/message: (exception : exception) -> string :stringstd/core/types/string: V, infostd/core/exn/exception/info: (exception : exception) -> exception-info :exception-infostd/core/exn/exception-info: V ) // Exception information pub open type exception-infostd/core/exn/exception-info: V ExnErrorstd/core/exn/ExnError: exception-info // Generic error ExnAssertstd/core/exn/ExnAssert: exception-info ExnTodostd/core/exn/ExnTodo: exception-info ExnRangestd/core/exn/ExnRange: exception-info ExnPatternstd/core/exn/ExnPattern: (location : string, definition : string) -> exception-info( location : stringstd/core/types/string: V, definition : stringstd/core/types/string: V ) ExnSystemstd/core/exn/ExnSystem: (errno : int) -> exception-info( errno : intstd/core/types/int: V ) ExnInternalstd/core/exn/ExnInternal: (name : string) -> exception-info( name : stringstd/core/types/string: V ) // Show the exception message pub fun showstd/core/exn/show: (exn : exception) -> string( exnexn: exception : exceptionstd/core/exn/exception: V )result: -> total string : stringstd/core/types/string: V exnexn: exception.messagestd/core/exn/exception/message: (exception : exception) -> string // Throw an exception with a specified message. pub fun throwstd/core/exn/throw: forall<a> (message : string, info : ? exception-info) -> exn a( messagemessage: string: stringstd/core/types/string: V, infoinfo: ? exception-info : exception-infostd/core/exn/exception-info: V = ExnErrorstd/core/exn/ExnError: exception-info )result: -> exn 420 : exnstd/core/exn/exn: (E, V) -> V aa: V throw-exnstd/core/exn/throw-exn: (exn : exception) -> exn $396(Exceptionstd/core/exn/Exception: (message : string, info : exception-info) -> exception(messagemessage: string,infoinfo: exception-info)) // Catch any exception raised in `action` and handle it. // Use `on-exit` when appropriate. pub fun handle/trystd/core/exn/handle/try: forall<a,e> (action : () -> <exn|e> a, hndl : (exception) -> e a) -> e a( actionaction: () -> <exn|$571> $570 : () -> <exnstd/core/exn/exn: (E, V) -> V|std/core/types/effect-extend: (X, E) -> Eee: E> aa: V, hndlhndl: (exception) -> $571 $570: exceptionstd/core/exn/exception: V -> ee: E aa: V )result: -> 657 656 : ee: E aa: V withhandler: (() -> <exn|$571> $570) -> $571 $570 final ctl throw-exnthrow-exn: (exn : exception) -> $571 $570(exnexn: exception) hndlhndl: (exception) -> $571 $570(exnexn: exception) actionaction: () -> <exn|$571> $570() // Catch an exception raised by `throw` and handle it. // This is `try` but with the arguments reversed, and is // often convenient to use as `with catch fn(e) ...` pub inline fun catchstd/core/exn/catch: forall<a,e> (hndl : (exception) -> e a, action : () -> <exn|e> a) -> e a(hndlhndl: (exception) -> $713 $712: exceptionstd/core/exn/exception: V -> ee: E aa: V, actionaction: () -> <exn|$713> $712 : () -> <exnstd/core/exn/exn: (E, V) -> V|std/core/types/effect-extend: (X, E) -> Eee: E> aa: V)result: -> 736 735 : ee: E aa: V trystd/core/exn/handle/try: (action : () -> <exn|$713> $712, hndl : (exception) -> $713 $712) -> $713 $712(actionaction: () -> <exn|$713> $712,hndlhndl: (exception) -> $713 $712) // An `:error` type represents a first-class exception result. pub value type errorstd/core/exn/error: V -> V<aa: V> Errorstd/core/exn/Error: forall<a> (exception : exception) -> error<a>( exception : exceptionstd/core/exn/exception: V ) Okstd/core/exn/Ok: forall<a> (result : a) -> error<a>( result : aa: V ) // Transform an exception effect to an `:error` type. pub fun error/trystd/core/exn/error/try: forall<a,e> (action : () -> <exn|e> a) -> e error<a>( actionaction: () -> <exn|$665> $664 : () -> <exnstd/core/exn/exn: (E, V) -> V|std/core/types/effect-extend: (X, E) -> Eee: E> aa: V )result: -> 705 error<704> : ee: E errorstd/core/exn/error: V -> V<aa: V> trystd/core/exn/handle/try: (action : () -> <exn|$665> error<$664>, hndl : (exception) -> $665 error<$664>) -> $665 error<$664>({ Okstd/core/exn/Ok: forall<a> (result : a) -> error<a>(actionaction: () -> <exn|$665> $664()) }, fnfn: (exn : exception) -> $665 error<$664>(exnexn: exception){ Errorstd/core/exn/Error: forall<a> (exception : exception) -> error<a>(exnexn: exception) }) // Transform an `:error` type back to an `exn` effect. pub fun untrystd/core/exn/untry: forall<a> (err : error<a>) -> exn a( errerr: error<$779> : errorstd/core/exn/error: V -> V<aa: V> )result: -> exn 805 : exnstd/core/exn/exn: (E, V) -> V aa: V match errerr: error<$779> Errorstd/core/exn/Error: forall<a> (exception : exception) -> error<a>(exnexn: exception) -> throw-exnstd/core/exn/throw-exn: (exn : exception) -> exn $779(exnexn: exception) Okstd/core/exn/Ok: forall<a> (result : a) -> error<a>(xx: $779) -> xx: $779 // Transform an `:error` type back to an `exn` effect. pub fun exnstd/core/exn/exn: forall<a> (err : error<a>) -> exn a( errerr: error<$810> : errorstd/core/exn/error: V -> V<aa: V> )result: -> exn 825 : exnstd/core/exn/exn: (E, V) -> V aa: V untrystd/core/exn/untry: (err : error<$810>) -> exn $810(errerr: error<$810>) // Use default value `def` in case of an error. pub fun defaultstd/core/exn/default: forall<a> (t : error<a>, def : a) -> a( tt: error<$830> : errorstd/core/exn/error: V -> V<aa: V>, defdef: $830 : aa: V )result: -> total 851 : astd/core/types/total: E match tt: error<$830> Errorstd/core/exn/Error: forall<a> (exception : exception) -> error<a> -> defdef: $830 Okstd/core/exn/Ok: forall<a> (result : a) -> error<a>(xx: $830) -> xx: $830 // Transform an `:error` type to a `:maybe` value. pub fun maybestd/core/exn/maybe: forall<a> (t : error<a>) -> maybe<a>( tt: error<$856> : errorstd/core/exn/error: V -> V<aa: V> )result: -> total maybe<886> : maybestd/core/types/maybe: V -> V<aa: V> match tt: error<$856> Errorstd/core/exn/Error: forall<a> (exception : exception) -> error<a> -> Nothingstd/core/types/Nothing: forall<a> maybe<a> Okstd/core/exn/Ok: forall<a> (result : a) -> error<a>(xx: $856) -> Juststd/core/types/Just: forall<a> (value : a) -> maybe<a>(xx: $856) // Transform an `:error` type to an `:either` value. pub fun eitherstd/core/exn/either: forall<a> (t : error<a>) -> either<exception,a>( tt: error<$891> : errorstd/core/exn/error: V -> V<aa: V> )result: -> total either<exception,930> : eitherstd/core/types/either: (V, V) -> V<exceptionstd/core/exn/exception: V,aa: V> match tt: error<$891> Errorstd/core/exn/Error: forall<a> (exception : exception) -> error<a>(exnexn: exception) -> Leftstd/core/types/Left: forall<a,b> (left : a) -> either<a,b>(exnexn: exception) Okstd/core/exn/Ok: forall<a> (result : a) -> error<a>(xx: $891) -> Rightstd/core/types/Right: forall<a,b> (right : b) -> either<a,b>(xx: $891) /* // Set a `hndler` that is called only when an exception is raised in the `action` block. pub fun on-exn( hndler : exception -> <exn|e> (), action : () -> <exn|e> a ) : <exn|e> a // prim-try-some( action, fn(exn){ hndler(exn); throw(exn) }) match mask<exn>{ try(action) } TryOk(x) { x TryExn(exn) { hndler(exn); throw(exn) */ // Set a `hndler` that is always called when the `action` finishes (either normally or with an exception). pub fun on-exitstd/core/exn/on-exit: forall<a,e> (hndler : () -> e (), action : () -> e a) -> e a( hndlerhndler: () -> $936 () : () -> ee: E (std/core/types/unit: V)std/core/types/unit: V, actionaction: () -> $936 $935 : () -> ee: E aa: V )result: -> 957 956 : ee: E aa: V finallystd/core/hnd/finally: (fin : () -> $936 (), action : () -> $936 $935) -> $936 $935(hndlerhndler: () -> $936 (),actionaction: () -> $936 $935) pub fun exn-error-rangestd/core/exn/exn-error-range: forall<a> () -> exn a()result: -> exn 987 : exnstd/core/exn/exn: (E, V) -> V aa: V throwstd/core/exn/throw: (message : string, info : ? exception-info) -> exn $964("index out-of-range"literal: string
count= 18
, ExnRangestd/core/exn/ExnRange: exception-info
) // // _Unsafe_. This function removes the exception effect (`:exn`) from the effect of an action // pub fun unsafe-no-exn( action : () -> <exn|e> a ) : e a // unsafe-total( action ) // Prepend `exn`'s message with `pre`. pub fun prependstd/core/exn/prepend: (exn : exception, pre : string) -> exception( exnexn: exception : exceptionstd/core/exn/exception: V, prepre: string : stringstd/core/types/string: V )result: -> total exception : exceptionstd/core/exn/exception: V Exceptionstd/core/exn/Exception: (message : string, info : exception-info) -> exception(prepre: string ++std/core/types/(++): (x : string, y : string) -> string ": "literal: string
count= 2
++std/core/types/(++): (x : string, y : string) -> string exnexn: exception.messagestd/core/exn/exception/message: (exception : exception) -> string, exnexn: exception.infostd/core/exn/exception/info: (exception : exception) -> exception-info
)