summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2015-06-12 22:00:38 -0700
committerKaz Kylheku <kaz@kylheku.com>2015-06-12 22:00:38 -0700
commit06e69904744f6349dc4be58f36bd4575497f2106 (patch)
tree452270e12baac8590f716a4ef079b78a8058306a
parentfbf525ae910ae48b1e6401fd2307772e214b1baa (diff)
downloadtxr-06e69904744f6349dc4be58f36bd4575497f2106.tar.gz
txr-06e69904744f6349dc4be58f36bd4575497f2106.tar.bz2
txr-06e69904744f6349dc4be58f36bd4575497f2106.zip
@(load) and @(include) now load Lisp code.
* match.c (v_load): Check txr_lisp_p flag coming out of open_txr_file and handle the Lisp case usin read_eval_stream. * parser.c (read_eval_stream, get_parser, parser_errors): New functions. * parser.h (read_eval_stream, get_parser, parser_errors): Declared.
-rw-r--r--ChangeLog13
-rw-r--r--match.c65
-rw-r--r--parser.c30
-rw-r--r--parser.h3
4 files changed, 82 insertions, 29 deletions
diff --git a/ChangeLog b/ChangeLog
index 548a99df..ac77e4b9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2015-06-12 Kaz Kylheku <kaz@kylheku.com>
+
+ @(load) and @(include) now load Lisp code.
+
+ * match.c (v_load): Check txr_lisp_p flag coming out of
+ open_txr_file and handle the Lisp case usin read_eval_stream.
+
+ * parser.c (read_eval_stream, get_parser, parser_errors):
+ New functions.
+
+ * parser.h (read_eval_stream, get_parser, parser_errors):
+ Declared.
+
2015-06-10 Kaz Kylheku <kaz@kylheku.com>
Preparing for lisp loading.
diff --git a/match.c b/match.c
index ccc1fa37..cfb1ec2a 100644
--- a/match.c
+++ b/match.c
@@ -3720,47 +3720,54 @@ static val v_load(match_files_ctx *c)
cat_str(nappend2(sub_list(split_str(parent, lit("/")),
zero, negone),
cons(target, nil)), lit("/")));
- int gc = gc_state(0);
val stream, name;
- parser_t parser;
val txr_lisp_p = nil;
open_txr_file(path, &txr_lisp_p, &name, &stream);
- parse_once(stream, name, &parser);
- gc_state(gc);
- if (parser.errors)
- sem_error(specline, lit("~s: errors encountered in ~s"), sym, path, nao);
+ if (!txr_lisp_p) {
+ int gc = gc_state(0);
+ parser_t parser;
+ parse_once(stream, name, &parser);
+ gc_state(gc);
- if (sym == include_s) {
- return parser.syntax_tree;
- } else {
- val spec = parser.syntax_tree;
- val result = match_files(mf_spec(*c, spec));
+ if (parser.errors)
+ sem_error(specline, lit("~s: errors encountered in ~s"), sym, path, nao);
- if (!result) {
- debuglf(specline, lit("load: ~s failed"), path, nao);
- return nil;
+ if (sym == include_s) {
+ return parser.syntax_tree;
} else {
- cons_bind (new_bindings, success, result);
+ val spec = parser.syntax_tree;
+ val result = match_files(mf_spec(*c, spec));
- c->bindings = new_bindings;
-
- if (consp(success)) {
- debuglf(specline,
- lit("load: ~s matched; "
- "advancing from line ~a to ~a"),
- path, c->data_lineno, cdr(success), nao);
- c->data = car(success);
- c->data_lineno = cdr(success);
+ if (!result) {
+ debuglf(specline, lit("load: ~s failed"), path, nao);
+ return nil;
} else {
- debuglf(specline, lit("load: ~s consumed entire file"), path,
- nao);
- c->data = nil;
- }
+ cons_bind (new_bindings, success, result);
- return next_spec_k;
+ c->bindings = new_bindings;
+
+ if (consp(success)) {
+ debuglf(specline,
+ lit("load: ~s matched; "
+ "advancing from line ~a to ~a"),
+ path, c->data_lineno, cdr(success), nao);
+ c->data = car(success);
+ c->data_lineno = cdr(success);
+ } else {
+ debuglf(specline, lit("load: ~s consumed entire file"), path,
+ nao);
+ c->data = nil;
+ }
+
+ return next_spec_k;
+ }
}
+ } else {
+ if (!read_eval_stream(stream, std_error))
+ sem_error(specline, lit("load: ~s contains errors"), path, nao);
+ return (sym == include_s) ? nil : next_spec_k;
}
}
}
diff --git a/parser.c b/parser.c
index 2cebed04..86511fdf 100644
--- a/parser.c
+++ b/parser.c
@@ -251,6 +251,36 @@ val lisp_parse(val source_in, val error_stream, val error_return_val, val name_i
return pi->syntax_tree;
}
+val read_eval_stream(val stream, val error_stream)
+{
+ val error_val = gensym(nil);
+
+ for (;;) {
+ val form = lisp_parse(stream, error_stream, error_val, nil);
+
+ if (form == error_val) {
+ if (parser_errors(get_parser(stream)) == zero)
+ break;
+ return nil;
+ }
+
+ (void) eval_intrinsic(form, nil);
+ }
+
+ return t;
+}
+
+val get_parser(val stream)
+{
+ return gethash(stream_parser_hash, stream);
+}
+
+val parser_errors(val parser)
+{
+ parser_t *p = coerce(parser_t *, cobj_handle(parser, parser_s));
+ return num(p->errors);
+}
+
void parse_init(void)
{
parser_s = intern(lit("parser"), user_package);
diff --git a/parser.h b/parser.h
index bf1c1025..ce276132 100644
--- a/parser.h
+++ b/parser.h
@@ -71,5 +71,8 @@ INLINE val rlcp(val to, val from)
val rlcp_tree(val to, val from);
val regex_parse(val string, val error_stream);
val lisp_parse(val source, val error_stream, val error_return_val, val name);
+val read_eval_stream(val stream, val error_stream);
val parser(val stream, val lineno, val primer);
+val get_parser(val stream);
+val parser_errors(val parser);
void parse_init(void);