From 660af6ed504bac0258834f6e4c58ad81454dbad8 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sat, 7 Nov 2015 10:21:42 -0800 Subject: New iread function. The read function no longer works like it used to on an interactive terminal because of the support for .. and . syntax on a top-level expression. The iread function is provided which uses a modified syntax that doesn't support these operators on a top-level expression. The parser thus doesn't look one token ahead, and so iread can return immediately. * eval.c (eval_init): Register iread intrinsic function. * parser.c (prime_parser): Only push back the recently seen token when priming for a regular Lisp read. Handle the prime_interactive method by preparing a SECRET_ESCAPE_I token. (lisp_parse_impl): New static function, formed from previous lisp_parse. Takes a boolean argument indicating interactive mode. (prime_parser_post): New function. (lisp_parse): Now a wrapper for lisp_parse_impl which passes a nil to indicate noninteractive read. (iread): New function. * parser.h (enum prime_parser): New member, prime_interactive. (scrub_scanner, iread, prime_parser_post): Declared. * parser.l (prime_scanner): Handle the prime_interactive case the same way as prime_lisp. (scrub_scanner): New function. * parser.y (SECRET_ESCAPE_I): New token type. (i_expr): New nonterminal symbol. Like n_expr, but doesn't support dot or dotdot operators, except in nested subexpressions. (spec): Handle SECRET_ESCAPE_I by way of i_expr. (sym_helper): Before freeing the token lexeme, call scrub_scanner. If the token is registered as the scanner's most recently seen token, the scanner must forget that registration, because it is no longer valid. (parse): Call prime_parser_post. * txr.1: Documented iread. --- parser.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) (limited to 'parser.c') diff --git a/parser.c b/parser.c index 5e607fd5..1924cad0 100644 --- a/parser.c +++ b/parser.c @@ -176,6 +176,9 @@ void prime_parser(parser_t *p, val name, enum prime_parser prim) case prime_lisp: sec_tok.yy_char = SECRET_ESCAPE_E; break; + case prime_interactive: + sec_tok.yy_char = SECRET_ESCAPE_I; + break; case prime_regex: sec_tok.yy_char = SECRET_ESCAPE_R; break; @@ -188,6 +191,12 @@ void prime_parser(parser_t *p, val name, enum prime_parser prim) set(mkloc(p->name, p->parser), name); } +void prime_parser_post(parser_t *p, enum prime_parser prim) +{ + if (prim == prime_interactive) + p->recent_tok.yy_char = 0; +} + void open_txr_file(val spec_file, val *txr_lisp_p, val *name, val *stream) { enum { none, tl, txr } suffix; @@ -277,8 +286,8 @@ val regex_parse(val string, val error_stream) return parser.errors ? nil : parser.syntax_tree; } -val lisp_parse(val source_in, val error_stream, val error_return_val, - val name_in, val lineno) +static val lisp_parse_impl(val interactive, val source_in, val error_stream, + val error_return_val, val name_in, val lineno) { uses_or2; val source = default_bool_arg(source_in); @@ -309,7 +318,8 @@ val lisp_parse(val source_in, val error_stream, val error_return_val, { int gc = gc_state(0); - parse(pi, if3(std_error != std_null, name, lit("")), prime_lisp); + enum prime_parser prime = if3(interactive, prime_interactive, prime_lisp); + parse(pi, if3(std_error != std_null, name, lit("")), prime); gc_state(gc); parsed = t; } @@ -335,6 +345,20 @@ val lisp_parse(val source_in, val error_stream, val error_return_val, return pi->syntax_tree; } +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, + 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, + name_in, lineno); +} + val read_eval_stream(val stream, val error_stream, val hash_bang_support) { val error_val = gensym(nil); -- cgit v1.2.3