summaryrefslogtreecommitdiffstats
path: root/parser.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-12-21 20:24:58 -0800
committerKaz Kylheku <kaz@kylheku.com>2014-12-21 20:24:58 -0800
commit34d4a240a1c7db27d56e65cbe7a5e9030c5c0377 (patch)
tree74c1927a0ae51bd70edf5b7e5fd0e305f9a8fd80 /parser.c
parentfb4601cf61e5d4723f005ab130e1b00aa9b21ea3 (diff)
downloadtxr-34d4a240a1c7db27d56e65cbe7a5e9030c5c0377.tar.gz
txr-34d4a240a1c7db27d56e65cbe7a5e9030c5c0377.tar.bz2
txr-34d4a240a1c7db27d56e65cbe7a5e9030c5c0377.zip
* parser.c (open_txr_file, regex_parse, lisp_parse): Functions
moved here from parser.l. * parser.l (open_txr_file, regex_parse, lisp_parse): Functions moved from here to parser.c.
Diffstat (limited to 'parser.c')
-rw-r--r--parser.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/parser.c b/parser.c
index 47d14fcb..8a2a5d5b 100644
--- a/parser.c
+++ b/parser.c
@@ -82,6 +82,83 @@ val parser(val stream, val lineno)
return parser;
}
+void open_txr_file(val spec_file, val *name, val *stream)
+{
+ {
+ FILE *in = w_fopen(c_str(spec_file), L"r");
+ if (in == 0) {
+ spec_file = cat_str(list(spec_file, lit("txr"), nao), lit("."));
+ in = w_fopen(c_str(spec_file), L"r");
+ if (in == 0)
+ uw_throwf(file_error_s, lit("unable to open ~a"), spec_file, nao);
+ }
+ *stream = make_stdio_stream(in, spec_file);
+ *name = spec_file;
+ }
+}
+
+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;
+ val stream = make_string_byte_input_stream(parse_string);
+ parser_t parser;
+
+ error_stream = default_bool_arg(error_stream);
+ std_error = if3(error_stream == t, std_output, or2(error_stream, std_null));
+
+ {
+ int gc = gc_state(0);
+ val name = if3(std_error != std_null, lit("regex"), lit(""));
+ parse(stream, name, &parser);
+ gc_state(gc);
+ }
+ std_error = save_stream;
+ return parser.errors ? nil : parser.syntax_tree;
+}
+
+val lisp_parse(val source_in, val error_stream, val error_return_val)
+{
+ uses_or2;
+ val source = default_bool_arg(source_in);
+ val input_stream = if3(stringp(source),
+ make_string_byte_input_stream(source),
+ or2(source, std_input));
+ val secret_token_stream = make_string_byte_input_stream(lit("@\x01" "E"));
+ val name = if3(stringp(source),
+ lit("string"),
+ stream_get_prop(input_stream, name_k));
+ val stream = make_catenated_stream(list(secret_token_stream, input_stream, nao));
+ val saved_dyn = dyn_env;
+ parser_t parser;
+
+ dyn_env = make_env(nil, nil, dyn_env);
+
+ error_stream = default_bool_arg(error_stream);
+ error_stream = if3(error_stream == t, std_output, or2(error_stream, std_null));
+ class_check (error_stream, stream_s);
+
+ env_vbind(dyn_env, stderr_s, error_stream);
+
+ {
+ int gc = gc_state(0);
+ name = if3(std_error != std_null, name, lit(""));
+ parse(stream, name, &parser);
+ gc_state(gc);
+ }
+
+ dyn_env = saved_dyn;
+
+ if (parser.errors) {
+ if (missingp(error_return_val))
+ uw_throwf(syntax_error_s, lit("read: syntax error"), nao);
+ return error_return_val;
+ }
+
+ return parser.syntax_tree;
+}
+
void parse_init(void)
{
parser_s = intern(lit("parser"), user_package);