summaryrefslogtreecommitdiffstats
path: root/parser.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2022-02-13 12:05:22 -0800
committerKaz Kylheku <kaz@kylheku.com>2022-02-13 12:05:22 -0800
commit6221390e43375c054a2d556edfbfb4af44ea2361 (patch)
tree9cd6e4762a89a42080afd15225f05769242f3466 /parser.c
parentd8135249e0662157cb6e85c16dfc0a3a8553c10a (diff)
downloadtxr-6221390e43375c054a2d556edfbfb4af44ea2361.tar.gz
txr-6221390e43375c054a2d556edfbfb4af44ea2361.tar.bz2
txr-6221390e43375c054a2d556edfbfb4af44ea2361.zip
load: support loading catenated .tlo files.
* parser.c (read_file_common): Tolerate the presence of version expressions, as long as they match the initial version under equal. Thus a larger .tlo file can be made of two or more .tlo files by simple catenation; it will load as long as they have exactly the same version.
Diffstat (limited to 'parser.c')
-rw-r--r--parser.c33
1 files changed, 20 insertions, 13 deletions
diff --git a/parser.c b/parser.c
index 4609546b..2937ecd8 100644
--- a/parser.c
+++ b/parser.c
@@ -755,6 +755,7 @@ static val read_file_common(val self, val stream, val error_stream, val compiled
val big_endian = nil;
val parser = ensure_parser(stream, name);
val not_compiled = null(compiled);
+ val version_form = nil;
if (compiled) {
parser_t *pi = parser_get_impl(self, parser);
@@ -779,20 +780,26 @@ static val read_file_common(val self, val stream, val error_stream, val compiled
stream, nao);
big_endian = caddr(form);
first = nil;
+ version_form = form;
} else if (compiled) {
- for (; form; form = cdr(form)) {
- val item = car(form);
- val nlevels = pop(&item);
- val nregs = pop(&item);
- val bytecode = pop(&item);
- val datavec = pop(&item);
- val funvec = car(item);
- val desc = vm_make_desc(nlevels, nregs, bytecode, datavec, funvec);
- if ((big_endian && HAVE_LITTLE_ENDIAN) ||
- (!big_endian && !HAVE_LITTLE_ENDIAN))
- buf_swap32(bytecode);
- (void) vm_execute_toplevel(desc);
- gc_hint(desc);
+ if (consp(car(form))) {
+ for (; form; form = cdr(form)) {
+ val item = car(form);
+ val nlevels = pop(&item);
+ val nregs = pop(&item);
+ val bytecode = pop(&item);
+ val datavec = pop(&item);
+ val funvec = car(item);
+ val desc = vm_make_desc(nlevels, nregs, bytecode, datavec, funvec);
+ if ((big_endian && HAVE_LITTLE_ENDIAN) ||
+ (!big_endian && !HAVE_LITTLE_ENDIAN))
+ buf_swap32(bytecode);
+ (void) vm_execute_toplevel(desc);
+ gc_hint(desc);
+ }
+ } else if (nequal(form, version_form)) {
+ uw_throwf(error_s, lit("~s: mismatched version ~s in combined .tlo file"),
+ stream, form, nao);
}
} else {
(void) eval_intrinsic(form, nil);