diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2013-12-14 23:46:32 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2013-12-14 23:46:32 -0800 |
commit | e5cd9bbd3de84e90d5602b83a0eb7780ec4b750e (patch) | |
tree | e5a35dda0dc080b69ff6b9042cdabcbd5dd2fa70 /parser.l | |
parent | f8ffbad0cec3ff0be1376a6352fe63a3c5e5f361 (diff) | |
download | txr-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.l | 32 |
1 files changed, 31 insertions, 1 deletions
@@ -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(); +} |