diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-12-29 16:52:52 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-12-29 16:52:52 -0800 |
commit | 9361473290d317186768bd9d709ae76adf9d85b8 (patch) | |
tree | b4f649994b1491d2749b164cb8b05c308355b7fc /parser.c | |
parent | 079cf1d067ec21e590f0ec025cbc282f8290e2fa (diff) | |
download | txr-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.c | 24 |
1 files changed, 20 insertions, 4 deletions
@@ -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)); } |