summaryrefslogtreecommitdiffstats
path: root/parser.l
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2013-12-14 23:46:32 -0800
committerKaz Kylheku <kaz@kylheku.com>2013-12-14 23:46:32 -0800
commite5cd9bbd3de84e90d5602b83a0eb7780ec4b750e (patch)
treee5a35dda0dc080b69ff6b9042cdabcbd5dd2fa70 /parser.l
parentf8ffbad0cec3ff0be1376a6352fe63a3c5e5f361 (diff)
downloadtxr-e5cd9bbd3de84e90d5602b83a0eb7780ec4b750e.tar.gz
txr-e5cd9bbd3de84e90d5602b83a0eb7780ec4b750e.tar.bz2
txr-e5cd9bbd3de84e90d5602b83a0eb7780ec4b750e.zip
Support for parsing Lisp expression out of strings and streams.
New catenated streams make the Yacc hack possible. * eval.c (eval_init): Register lisp_parse as intrinsic. * parser.h (lisp_parse): Declared. * parser.l: New lexical hack to produce SECRET_ESCAPE_E token. (regex_parse): Move declaration before statements. (lisp_parse): New function. * parser.y (SECRET_ESCAPE_E): New token type. (spec): New production rule for single expression. * stream.c (cat_stream_print, cat_get_line, cat_get_char, cat_get_byte, cat_get_prop): New static functions. (cat_stream_ops): New static function. (make_catenated_stream): New function. * stream.h (make_catenated_stream): Declared.
Diffstat (limited to 'parser.l')
-rw-r--r--parser.l32
1 files changed, 31 insertions, 1 deletions
diff --git a/parser.l b/parser.l
index bdee6275..78e29408 100644
--- a/parser.l
+++ b/parser.l
@@ -682,6 +682,12 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U}
return SECRET_ESCAPE_R;
}
+<INITIAL>@\x01E {
+ yy_push_state(SPECIAL);
+ yy_push_state(NESTED);
+ return SECRET_ESCAPE_E;
+}
+
<INITIAL>^@[#;].*\n {
/* eat whole line comment */
lineno++;
@@ -837,10 +843,10 @@ val regex_parse(val string, val error_stream)
{
uses_or2;
val parse_string = cat_str(list(lit("@\x01R"), string, nao), nil);
+ val save_stream = std_error;
yyin_stream = make_string_byte_input_stream(parse_string);
errors = 0;
lineno = 1;
- val save_stream = std_error;
std_error = if3(error_stream == t, std_output, or2(error_stream, std_null));
{
int gc = gc_state(0);
@@ -854,3 +860,27 @@ val regex_parse(val string, val error_stream)
std_error = save_stream;
return errors ? nil : get_spec();
}
+
+val lisp_parse(val source, val error_stream)
+{
+ uses_or2;
+ val input_stream = if3(stringp(source), make_string_byte_input_stream(source), source);
+ val secret_token_stream = make_string_byte_input_stream(lit("@\x01" "E"));
+ val name = if3(stringp(source),
+ format(nil, lit("expr: ~s"), source, nao),
+ stream_get_prop(source, name_k));
+ val save_stream = std_error;
+ yyin_stream = make_catenated_stream(list(secret_token_stream, input_stream, nao));
+ errors = 0;
+ lineno = 1;
+ std_error = if3(error_stream == t, std_output, or2(error_stream, std_null));
+ {
+ int gc = gc_state(0);
+ spec_file_str = if3(std_error != std_null, name, lit(""));
+ yyparse();
+ yylex_destroy();
+ gc_state(gc);
+ }
+ std_error = save_stream;
+ return errors ? nil : get_spec();
+}