summaryrefslogtreecommitdiffstats
path: root/parser.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-12-29 16:52:52 -0800
committerKaz Kylheku <kaz@kylheku.com>2017-12-29 16:52:52 -0800
commit9361473290d317186768bd9d709ae76adf9d85b8 (patch)
treeb4f649994b1491d2749b164cb8b05c308355b7fc /parser.c
parent079cf1d067ec21e590f0ec025cbc282f8290e2fa (diff)
downloadtxr-9361473290d317186768bd9d709ae76adf9d85b8.tar.gz
txr-9361473290d317186768bd9d709ae76adf9d85b8.tar.bz2
txr-9361473290d317186768bd9d709ae76adf9d85b8.zip
read, iread: source location recording now conditional.
Recording of source location info incurs a time and space penalty. We don't want to impose this on programs which are just reading large amounts of Lisp data that isn't code. * eval.c (eval_init): Register lisp-parse and read functions to the newly introduced nread function rather than lisp_parse. lisp_parse continues to record source location info unconditionally. * parser.c (rec_source_loc_s): New symbol variable. (parser_common_init): Set the new member of the parser structure, rec_source_loc, according to the current value of the special var *rec-source-loc*. (lisp_parse_impl): New second argument, rlcp_p. If true, it overrides the rec_source_loc member of the parser structure to true. (lisp_parse): Pass true argument to rlcp_p parameter of lisp_parse_impl, so parsing via lisp_parse always records source loc info. (nread): New function. (iread): Pass true argument to rlcp_p parameter of lisp_parse_impl, so *rec-source-loc* controls whether source location info is recorded. (parse_init): Initilize rec_source_loc_s symbol variable, and register the *rec-source-loc* special var. * parser.h (struct parser): New member, rec_source_loc. (rec_source_loc_s, nread): Declared. * parser.y (rlcp_parser): New static function. Like rlcp but does nothing if parser->rec_source_loc is false. (rlc): New macro. (grammar): Replace rlcp uses with rlc, which expands to a call to rlcp_parser. (rlrec): Do nothing if source loc recording is not enabled in the parser. (make_expr, uref_helper): Replace rlcp with rlc. This is possible because these functions have a parser local variable that the macro expansion can refer to. (parse_once): Override rec_source_loc in the parser to 1, so that source loc info is always recorded when parsing is invoked through this function. * txr.1: Documented *rec-source-loc* and added text under read and iread.
Diffstat (limited to 'parser.c')
-rw-r--r--parser.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/parser.c b/parser.c
index d09e4dea..4aa9fdeb 100644
--- a/parser.c
+++ b/parser.c
@@ -62,6 +62,7 @@
val parser_s, unique_s, circref_s;
val listener_hist_len_s, listener_multi_line_p_s, listener_sel_inclusive_p_s;
+val rec_source_loc_s;
val intr_s;
static val stream_parser_hash;
@@ -107,6 +108,7 @@ void parser_common_init(parser_t *p)
{
int i;
yyscan_t yyscan;
+ val rec_source_loc_var = lookup_var(nil, rec_source_loc_s);
p->parser = nil;
p->lineno = 1;
@@ -128,6 +130,7 @@ void parser_common_init(parser_t *p)
p->tok_pushback[i].yy_lval.val = 0;
}
p->tok_idx = 0;
+ p->rec_source_loc = !nilp(cdr(rec_source_loc_var));
}
void parser_cleanup(parser_t *p)
@@ -498,8 +501,9 @@ val regex_parse(val string, val error_stream)
return parser.syntax_tree;
}
-static val lisp_parse_impl(val interactive, val source_in, val error_stream,
- val error_return_val, val name_in, val lineno)
+static val lisp_parse_impl(val interactive, val rlcp_p, val source_in,
+ val error_stream, val error_return_val, val name_in,
+ val lineno)
{
uses_or2;
val source = default_null_arg(source_in);
@@ -515,6 +519,9 @@ static val lisp_parse_impl(val interactive, val source_in, val error_stream,
parser_t *pi = get_parser_impl(parser);
volatile val parsed = nil;
+ if (rlcp_p)
+ pi->rec_source_loc = 1;
+
uw_simple_catch_begin;
dyn_env = make_env(nil, nil, dyn_env);
@@ -566,14 +573,21 @@ static val lisp_parse_impl(val interactive, val source_in, val error_stream,
val lisp_parse(val source_in, val error_stream, val error_return_val,
val name_in, val lineno)
{
- return lisp_parse_impl(nil, source_in, error_stream, error_return_val,
+ return lisp_parse_impl(nil, t, source_in, error_stream, error_return_val,
+ name_in, lineno);
+}
+
+val nread(val source_in, val error_stream, val error_return_val,
+ val name_in, val lineno)
+{
+ return lisp_parse_impl(nil, nil, source_in, error_stream, error_return_val,
name_in, lineno);
}
val iread(val source_in, val error_stream, val error_return_val,
val name_in, val lineno)
{
- return lisp_parse_impl(t, source_in, error_stream, error_return_val,
+ return lisp_parse_impl(t, nil, source_in, error_stream, error_return_val,
name_in, lineno);
}
@@ -1310,6 +1324,7 @@ void parse_init(void)
listener_hist_len_s = intern(lit("*listener-hist-len*"), user_package);
listener_multi_line_p_s = intern(lit("*listener-multi-line-p*"), user_package);
listener_sel_inclusive_p_s = intern(lit("*listener-sel-inclusive-p*"), user_package);
+ rec_source_loc_s = intern(lit("*rec-source-loc*"), user_package);
unique_s = gensym(nil);
prot1(&stream_parser_hash);
prot1(&unique_s);
@@ -1318,5 +1333,6 @@ void parse_init(void)
reg_var(listener_hist_len_s, num_fast(500));
reg_var(listener_multi_line_p_s, t);
reg_var(listener_sel_inclusive_p_s, nil);
+ reg_var(rec_source_loc_s, nil);
reg_fun(circref_s, func_n1(circref));
}