Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions doc/es.1
Original file line number Diff line number Diff line change
Expand Up @@ -1973,12 +1973,18 @@ Exits the current loop.
.I Value
is used as the return value for the loop command.
.TP
.Cr "catch \fIcatcher body\fP"
.Cr "catch \fR[\fP\fIexception\fP\fR]\fP \fIcatcher body\fP"
Runs
.IR body .
If it raises an exception,
If it raises an exception, and
.IR exception
is either not provided or matches the first term of the exception,
.IR catcher
is run and passed the exception as an argument.
If
.IR exception
is provided, then the passed argument does not include the first term
of the exception, which has already been matched.
Signals are blocked during the execution of
.IR catcher
and signal exceptions will only be raised after it has finished running.
Expand Down
13 changes: 3 additions & 10 deletions initial.es
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,6 @@

fn-. = $&dot
fn-access = $&access
fn-break = $&break
fn-catch = $&catch
fn-echo = $&echo
fn-exec = $&exec
fn-forever = $&forever
Expand All @@ -75,6 +73,7 @@ fn-if = $&if
fn-newpgrp = $&newpgrp
fn-result = $&result
fn-throw = $&throw
fn-catch = $&catch
fn-umask = $&umask
fn-wait = $&wait

Expand Down Expand Up @@ -170,10 +169,7 @@ fn var { for (i = <={%var $*}) echo $i }
fn whatis {
let (result = ) {
for (i = $*) {
catch @ e from message {
if {!~ $e error} {
throw $e $from $message
}
catch error @ from message {
echo >[1=2] $message
result = $result 1
} {
Expand All @@ -190,10 +186,7 @@ fn whatis {
# does not catch the return exception. It does, however, catch break.

fn-while = $&noreturn @ cond body {
catch @ e value {
if {!~ $e break} {
throw $e $value
}
catch break @ value {
result $value
} {
let (result = <=true)
Expand Down
21 changes: 17 additions & 4 deletions prim-ctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,18 @@ PRIM(throw) {

PRIM(catch) {
Atomic retry;
int argc = length(list);

if (list == NULL)
fail("$&catch", "usage: catch catcher body");
if (argc != 2 && argc != 3)
fail("$&catch", "usage: catch [exception] catcher body");

Ref(List *, result, NULL);
Ref(List *, lp, list);
Ref(char *, exc, NULL);
if (argc == 3) {
exc = getstr(lp->term);
lp = lp->next;
}

do {
List *e = NULL;
Expand All @@ -62,7 +68,14 @@ PRIM(catch) {

result = eval(lp->next, NULL, evalflags);

CatchException (frombody)
CatchException (volatile frombody)

if (exc != NULL) {
if (termeq(frombody->term, exc))
frombody = frombody->next;
else
throw(frombody);
}

blocksignals();
ExceptionHandler
Expand All @@ -89,7 +102,7 @@ PRIM(catch) {
throw(e);

} while (retry);
RefEnd(lp);
RefEnd2(exc, lp);
RefReturn(result);
}

Expand Down
8 changes: 2 additions & 6 deletions share/path-cache.es
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,8 @@ fn recache progs {
fn precache progs {
let (result = ())
for (p = $progs) {
catch @ e type msg {
if {~ $e error} {
echo >[1=2] $msg
} {
throw $e $type $msg
}
catch error @ _ msg {
echo >[1=2] $msg
} {
result = $result <={%pathsearch $p}
}
Expand Down
8 changes: 3 additions & 5 deletions share/status.es
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,9 @@ fn %interactive-loop {
noexport = $noexport status
status = <=true
fn-%dispatch = $&noreturn @ {
catch @ e rest {
if {~ $e return} {
status = $rest
}
throw $e $rest
catch return @ value {
status = $value
return $value
} {
status = <={$d $*}
}
Expand Down