diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2012-02-24 04:26:35 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2012-02-24 04:26:35 -0800 |
commit | 9a178bcb364eeb8a9aa334f4de65d30722596cdb (patch) | |
tree | 580352b545115342e20a44c0af16897c3242b604 | |
parent | c4b87400ed9fb160ba5b282f1b58c62c057cbd50 (diff) | |
download | txr-9a178bcb364eeb8a9aa334f4de65d30722596cdb.tar.gz txr-9a178bcb364eeb8a9aa334f4de65d30722596cdb.tar.bz2 txr-9a178bcb364eeb8a9aa334f4de65d30722596cdb.zip |
First cut at @(load) directive. Incomplete: debug location info
needs to record file name, not only line number; absolute paths
not handled, etc.
* match.c (load_s): New symbol variable.
(v_load): New static function.
(syms_init): load_s initialized.
(dir_tables_init): Load directive registered.
* match.h (load_s): Declared.
* parser.h (parse_reset): New function declared.
* parser.l (spec_file_str): Global variable moved from txr.c.
(parse_reset): New function.
* parser.y (clause): Special handling for @(load ...) directive.
parent file path inserted into the syntax at parse time,
so when the load directive executes, it can load the file from
the same directory as the parent file.
* txr.c (spec_file_str): Global variable moved to parser.l.
-rw-r--r-- | ChangeLog | 25 | ||||
-rw-r--r-- | match.c | 29 | ||||
-rw-r--r-- | match.h | 3 | ||||
-rw-r--r-- | parser.h | 1 | ||||
-rw-r--r-- | parser.l | 14 | ||||
-rw-r--r-- | parser.y | 10 | ||||
-rw-r--r-- | txr.c | 1 |
7 files changed, 79 insertions, 4 deletions
@@ -1,3 +1,28 @@ +2012-02-24 Kaz Kylheku <kaz@kylheku.com> + + First cut at @(load) directive. Incomplete: debug location info + needs to record file name, not only line number; absolute paths + not handled, etc. + + * match.c (load_s): New symbol variable. + (v_load): New static function. + (syms_init): load_s initialized. + (dir_tables_init): Load directive registered. + + * match.h (load_s): Declared. + + * parser.h (parse_reset): New function declared. + + * parser.l (spec_file_str): Global variable moved from txr.c. + (parse_reset): New function. + + * parser.y (clause): Special handling for @(load ...) directive. + parent file path inserted into the syntax at parse time, + so when the load directive executes, it can load the file from + the same directory as the parent file. + + * txr.c (spec_file_str): Global variable moved to parser.l. + 2012-02-22 Kaz Kylheku <kaz@kylheku.com> * tests/010/seq.txr: New file. @@ -54,7 +54,7 @@ int opt_arraydims = 1; val decline_k, next_spec_k, repeat_spec_k; val mingap_k, maxgap_k, gap_k, mintimes_k, maxtimes_k, times_k; val lines_k, chars_k; -val text_s, choose_s, gather_s, do_s, mod_s, modlast_s, fuzz_s; +val text_s, choose_s, gather_s, do_s, mod_s, modlast_s, fuzz_s, load_s; val longest_k, shortest_k, greedy_k; val vars_k, resolve_k; val append_k, into_k, var_k, list_k, string_k, env_k, counter_k; @@ -3373,6 +3373,31 @@ static val v_do(match_files_ctx *c) return next_spec_k; } +static val v_load(match_files_ctx *c) +{ + spec_bind (specline, first_spec, c->spec); + val args = rest(first_spec); + val parent = first(args); + val target = txeval(specline, second(args), c->bindings); + + if (rest(specline)) + sem_error(specline, lit("unexpected material after load"), nao); + + { + val path = cat_str(nappend2(sub_list(split_str(parent, lit("/")), + zero, negone), + cons(target, nil)), lit("/")); + int gc = gc_state(0); + parse_reset(path); + yyparse(); + gc_state(gc); + { + val spec = get_spec(); + return match_files(mf_spec(*c, spec)); + } + } +} + static val h_do(match_line_ctx *c) { val elem = first(c->specline); @@ -3588,6 +3613,7 @@ static void syms_init(void) choose_s = intern(lit("choose"), user_package); gather_s = intern(lit("gather"), user_package); do_s = intern(lit("do"), user_package); + load_s = intern(lit("load"), user_package); longest_k = intern(lit("longest"), keyword_package); shortest_k = intern(lit("shortest"), keyword_package); greedy_k = intern(lit("greedy"), keyword_package); @@ -3648,6 +3674,7 @@ static void dir_tables_init(void) sethash(v_directive_table, filter_s, cptr((mem_t *) v_filter)); sethash(v_directive_table, eof_s, cptr((mem_t *) v_eof)); sethash(v_directive_table, do_s, cptr((mem_t *) v_do)); + sethash(v_directive_table, load_s, cptr((mem_t *) v_load)); sethash(h_directive_table, text_s, cptr((mem_t *) h_text)); sethash(h_directive_table, var_s, cptr((mem_t *) h_var)); @@ -24,7 +24,8 @@ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -extern val text_s, choose_s, gather_s, do_s, mod_s, modlast_s, counter_k; +extern val text_s, choose_s, gather_s, do_s; +extern val load_s, mod_s, modlast_s, counter_k; val format_field(val string_or_list, val modifier, val filter, val eval_fun); val match_filter(val name, val arg, val other_args); val match_fun(val name, val args, val input, val files); @@ -39,6 +39,7 @@ void end_of_regex(void); void end_of_char(void); int yylex(void); void parse_init(void); +void parse_reset(val spec_file); val source_loc(val form); val rl(val form, val lineno); INLINE val rlcp(val to, val from) @@ -66,6 +66,7 @@ cnum lineno = 1; int opt_loglevel = 1; /* 0 - quiet; 1 - normal; 2 - verbose */ int errors; +val spec_file_str; val form_to_ln_hash; @@ -693,3 +694,16 @@ void parse_init(void) form_to_ln_hash = make_hash(t, nil, nil); } + +void parse_reset(val spec_file) +{ + errors = 0; + lineno = 1; + spec_file_str = spec_file; + { + FILE *in = w_fopen(c_str(spec_file_str), L"r"); + if (in == 0) + uw_throwf(file_error_s, lit("unable to open ~a"), spec_file_str, nao); + yyin_stream = make_stdio_stream(in, spec_file_str, t, nil); + } +} @@ -141,7 +141,15 @@ clause : all_clause { $$ = list($1, nao); rlcp($$, $1); } rlcp($$, $1); } | try_clause { $$ = list($1, nao); rlcp($$, $1); } | output_clause { $$ = list($1, nao); rlcp($$, $1); } - | line { $$ = $1; } + | line { val elem = car($1); + + if (consp(elem) && car(elem) == load_s) + { elem = rlcp(cons(load_s, + cons(spec_file_str, + cdr(elem))), elem); + $$ = rlcp(cons(elem, cdr($1)), $1); } + else + { $$ = $1; } } | repeat_clause { $$ = nil; yyerror("repeat outside of output"); } ; @@ -46,7 +46,6 @@ const wchli_t *version = wli("57"); const wchar_t *progname = L"txr"; const wchar_t *spec_file = L"stdin"; -val spec_file_str; /* * Can implement an emergency allocator here from a fixed storage |