summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2023-05-31 19:36:06 -0700
committerKaz Kylheku <kaz@kylheku.com>2023-05-31 19:36:06 -0700
commit661531cdc4529078c15c222fafe2da025c02591d (patch)
tree41443235b4dbf6714c128dd13aa51063f84d3c51
parent6846740ce44659a1f31e01054b0f1bcc8dc04c7a (diff)
downloadtxr-661531cdc4529078c15c222fafe2da025c02591d.tar.gz
txr-661531cdc4529078c15c222fafe2da025c02591d.tar.bz2
txr-661531cdc4529078c15c222fafe2da025c02591d.zip
load: now establishes a block named load.
Files loaded from the command line or via the load function or @(load) directive now have a block named load in scope. Thus (return-from load <expr>) may be used to abort a load when it is finished. The load function will then return the value of <expr>. * eval.c (load): Bind a load block around the whole thing and use the captured return value as the function's return value. * match.c (v_load): Bind the load block here too. Ensure that if the block return is taken, the ret variable contains next_spec_k, so that processing continues with whatever directive follows the @(load). * txr.c (txr_main): Bind the block in severl cases that load code. * txr.1: Documented.
-rw-r--r--eval.c4
-rw-r--r--match.c7
-rw-r--r--txr.138
-rw-r--r--txr.c34
4 files changed, 67 insertions, 16 deletions
diff --git a/eval.c b/eval.c
index bed22691..397063cb 100644
--- a/eval.c
+++ b/eval.c
@@ -4755,6 +4755,7 @@ val load(val target)
val saved_dyn_env = dyn_env;
val load_dyn_env = make_env(nil, nil, dyn_env);
val rec = cdr(lookup_var(nil, load_recursive_s));
+ uw_block_begin (load_s, ret);
open_txr_file(path, &txr_lisp_p, &name, &stream, t, self);
@@ -4822,8 +4823,9 @@ val load(val target)
}
uw_catch_end;
+ uw_block_end;
- return nil;
+ return ret;
}
static val rt_load_for(struct args *args)
diff --git a/match.c b/match.c
index 29f634cf..0756ea8c 100644
--- a/match.c
+++ b/match.c
@@ -4628,10 +4628,11 @@ static val v_load(match_files_ctx *c)
path_cat(dir_name(parent), target));
val stream, name = target;
val txr_lisp_p = nil;
- val ret = nil;
+ val ret = next_spec_k;
val saved_dyn_env = dyn_env;
val load_dyn_env = make_env(nil, nil, dyn_env);
val rec = cdr(lookup_var(nil, load_recursive_s));
+ uw_block_begin (load_s, load_ret);
open_txr_file(path, &txr_lisp_p, &name, &stream, t, self);
@@ -4680,8 +4681,6 @@ static val v_load(match_files_ctx *c)
nao);
c->data = nil;
}
-
- ret = next_spec_k;
}
}
} else {
@@ -4715,6 +4714,8 @@ static val v_load(match_files_ctx *c)
uw_catch_end;
+ uw_block_end;
+
return ret;
}
}
diff --git a/txr.1 b/txr.1
index 5b35a049..d937f480 100644
--- a/txr.1
+++ b/txr.1
@@ -9357,7 +9357,18 @@ takes place prior to evaluation time, whereas
.code load
doesn't execute until evaluation time.
+Note:
+the
+.code load
+directive doesn't provide access to the value propagated by a
+.code return
+via the
+.code load
+block.
+
See also: the
+.code load
+function, and the
.codn self-path ,
.code stdlib
and
@@ -79885,6 +79896,33 @@ loaded file has the effect of altering the value of
that effect will be undone when the binding is removed
after the load completes.
+Over the evaluation of either a \*(TL, compiled file, or \*(TX file,
+.code load
+establishes a block named
+.codn load ,
+which makes it possible for the loaded module to abort the loading
+using the
+.mono
+.meti (return-from load << expr )
+.onom
+expression. In this situation, the value of
+.meta expr
+will appear as the return value of the
+.code load
+function. A block named
+.code load
+is also established by the
+.code @(load)
+directive in the pattern language, that that directive provides
+no access to the returned value. The block is also visible to the
+file processed from the command line. When a such a file aborts
+the load via
+.codn return ,
+the returned value is discarded. If the interactive option
+.code -i
+was specified, the interactive listener will be entered, otherwise
+the process will terminate successfully.
+
When the
.code load
function terminates normally after processing a file,
diff --git a/txr.c b/txr.c
index 9515f937..fcad523a 100644
--- a/txr.c
+++ b/txr.c
@@ -1259,19 +1259,29 @@ int txr_main(int argc, char **argv)
reg_varl(car(binding), cdr(binding));
}
- if (txr_lisp_p == chr('o')) {
- val result = read_compiled_file_noerr(self, parse_stream, spec_file_str,
- std_error);
- if (!enter_repl)
+ {
+ if (txr_lisp_p == chr('o')) {
+ val result = nil;
+ uw_block_begin (load_s, ret);
+ result = read_compiled_file_noerr(self, parse_stream, spec_file_str,
+ std_error);
+ uw_block_end;
+ if (!enter_repl)
+ return result ? 0 : EXIT_FAILURE;
+ } else if (enter_repl) {
+ uw_block_begin (load_s, ret);
+ read_eval_stream_noerr(self, parse_stream, spec_file_str, std_error);
+ uw_block_end;
+ close_stream(parse_stream, nil);
+ run_load_hooks(dyn_env);
+ uw_release_deferred_warnings();
+ } else {
+ val result = nil;
+ uw_block_begin (load_s, ret);
+ result = read_eval_stream(self, parse_stream, std_error);
+ uw_block_end;
return result ? 0 : EXIT_FAILURE;
- } else if (enter_repl) {
- read_eval_stream_noerr(self, parse_stream, spec_file_str, std_error);
- close_stream(parse_stream, nil);
- run_load_hooks(dyn_env);
- uw_release_deferred_warnings();
- } else {
- val result = read_eval_stream(self, parse_stream, std_error);
- return result ? 0 : EXIT_FAILURE;
+ }
}
repl: