diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2020-04-02 06:25:02 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2020-04-02 06:25:02 -0700 |
commit | dead4e05c9ea34c79047eba84949ec366a8ba6b2 (patch) | |
tree | f02f7c2625d226b2f49116d17618d9923d43fd9c /parser.c | |
parent | edd182e778e116f2c2c62fbc09102372b0c03500 (diff) | |
download | txr-dead4e05c9ea34c79047eba84949ec366a8ba6b2.tar.gz txr-dead4e05c9ea34c79047eba84949ec366a8ba6b2.tar.bz2 txr-dead4e05c9ea34c79047eba84949ec366a8ba6b2.zip |
New function: txr-parse.
txr-parse provides a way for Lisp code to programmatically
parse the TXR language and obtain the Lisp represenation.
This has hitherto not been available.
* eval.c (eval_init): Register txr-parse intrinsic.
* parser.c (txr_parse): New function.
* parser.h (txr_parse): Declared.
Diffstat (limited to 'parser.c')
-rw-r--r-- | parser.c | 41 |
1 files changed, 41 insertions, 0 deletions
@@ -783,6 +783,47 @@ val read_compiled_file(val self, val stream, val error_stream) return read_file_common(self, stream, error_stream, t); } +val txr_parse(val source_in, val error_stream, + val error_return_val, val name_in) +{ + uses_or2; + val self = lit("txr-parse"); + val source = default_null_arg(source_in); + val input_stream = if3(stringp(source), + make_string_byte_input_stream(source), + or2(source, std_input)); + val name = or2(default_null_arg(name_in), + if3(stringp(source), + lit("string"), + stream_get_prop(input_stream, name_k))); + int gc = gc_state(0); + val saved_dyn = dyn_env; + val parser_obj = ensure_parser(input_stream, name); + parser_t *pi = parser_get_impl(self, parser_obj); + + dyn_env = make_env(nil, nil, dyn_env); + error_stream = default_null_arg(error_stream); + error_stream = if3(error_stream == t, std_output, or2(error_stream, std_null)); + class_check (self, error_stream, stream_s); + + parse_once(self, input_stream, name); + + dyn_env = saved_dyn; + gc_state(gc); + + if (pi->errors || pi->syntax_tree == nao) { + if (missingp(error_return_val)) + uw_throwf(syntax_error_s, lit("~a: ~a: ~a"), self, name, + if3(pi->syntax_tree == nao, + lit("end of input reached without seeing object"), + lit("errors encountered")), nao); + + return error_return_val; + } + + return pi->syntax_tree; +} + #if HAVE_TERMIOS static void load_rcfile(val name) |