diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2025-04-17 20:30:21 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2025-04-17 20:30:21 -0700 |
commit | 05477c10a764b0deb160708eb91587695d965a49 (patch) | |
tree | 831298a0fb01652817f091cc04c8adc3d6055f85 | |
parent | 4d68e3c2f2162a7c513c5c2c4a3c7c2c22a9e3be (diff) | |
download | txr-05477c10a764b0deb160708eb91587695d965a49.tar.gz txr-05477c10a764b0deb160708eb91587695d965a49.tar.bz2 txr-05477c10a764b0deb160708eb91587695d965a49.zip |
listener: auto infix mode.
* parser.c (listener_auto_infix_s): New symbol variable
for *listener-auto-infix-s* special.
(repl): After potentially transforming the input line
via auto compound mode, check for auto infix mode.
If turned on, wrap the expression in ifx.
(parse_init): Initialize listener_auto_infix_s.
Register the special variable named by the symbol.
-rw-r--r-- | parser.c | 22 | ||||
-rw-r--r-- | txr.1 | 35 |
2 files changed, 50 insertions, 7 deletions
@@ -77,6 +77,7 @@ val parser_s, unique_s, circref_s; val listener_hist_len_s, listener_multi_line_p_s, listener_sel_inclusive_p_s; val listener_pprint_s, listener_greedy_eval_s, listener_auto_compound_s; +val listener_auto_infix_s; val rec_source_loc_s, read_unknown_structs_s, read_bad_json_s, read_json_int_s; val json_s; val intr_s; @@ -1651,6 +1652,7 @@ val repl(val bindings, val in_stream, val out_stream, val env) val ppriv_s = intern(lit("path-strictly-private-to-me-p"), user_package); val psafe_s = intern(lit("path-components-safe"), user_package); #endif + val ifx_s = intern(lit("ifx"), user_package); val result_hash = make_hash(hash_weak_none, nil); val done = nil; val counter = one; @@ -1670,6 +1672,7 @@ val repl(val bindings, val in_stream, val out_stream, val env) val pprint_var = lookup_global_var(listener_pprint_s); val greedy_eval = lookup_global_var(listener_greedy_eval_s); val auto_parens = lookup_global_var(listener_auto_compound_s); + val auto_infix = lookup_global_var(listener_auto_infix_s); val rw_f = func_f1v(out_stream, repl_warning); val saved_dyn_env = set_dyn_env(make_env(nil, nil, dyn_env)); val brackets = mkstring(num_fast(repl_level), chr('>')); @@ -1814,14 +1817,17 @@ val repl(val bindings, val in_stream, val out_stream, val env) hist_save(ls, in_stream, out_stream, histfile, histfile_w, hist_len_var); counter = prev_counter; } else { - val expr = if2(form != read_k, - if3(consp(forms), - if3(cdr(auto_parens) && cdr(forms), - forms, - cons(progn_s, forms)), - forms)); + val expr0 = if2(form != read_k, + if3(consp(forms), + if3(cdr(auto_parens) && cdr(forms), + forms, + cons(progn_s, forms)), + forms)); + val expr1 = if2(form != read_k, + if3(cdr(auto_infix), cons(ifx_s, cons(expr0, nil)), + expr0)); val value = if3(form != read_k, - eval_intrinsic(expr, nil, env), + eval_intrinsic(expr1, nil, env), read_eval_ret_last(nil, prev_counter, in_stream, out_stream)); val pprin = cdr(pprint_var); @@ -2093,6 +2099,7 @@ void parse_init(void) listener_pprint_s = intern(lit("*listener-pprint-p*"), user_package); listener_greedy_eval_s = intern(lit("*listener-greedy-eval-p*"), user_package); listener_auto_compound_s = intern(lit("*listener-auto-compound-p*"), user_package); + listener_auto_infix_s = intern(lit("*listener-auto-infix-p*"), user_package); rec_source_loc_s = intern(lit("*rec-source-loc*"), user_package); read_unknown_structs_s = intern(lit("*read-unknown-structs*"), user_package); read_bad_json_s = intern(lit("*read-bad-json*"), user_package); @@ -2118,6 +2125,7 @@ void parse_init(void) reg_var(listener_pprint_s, nil); reg_var(listener_greedy_eval_s, nil); reg_var(listener_auto_compound_s, nil); + reg_var(listener_auto_infix_s, nil); reg_var(rec_source_loc_s, nil); reg_var(read_unknown_structs_s, nil); reg_var(read_bad_json_s, nil); @@ -96656,6 +96656,41 @@ being calculated. When a single expression is input, it is evaluated as-is, and thus in that case auto compound expression mode makes no difference. +.coNP Special Variable @ *listener-auto-infix-p* +.desc +The special variable +.code *listener-auto-infix-p* +controls whether or the listener is operating in "auto infix" +mode. The default value is +.codn nil , +disabling the feature. + +When the feature is enabled, each expression is evaluated as if it +were implicitly embedded in an +.code ifx +macro form. For instance, the expression +.code "(x + y)" +is evaluated as if it were +.code "(ifx (x + y))" +and therefore transformed into +.codn "(+ x y)" . + +Note that this feature coordinates with auto compound mode, +which is enabled by +.code *listener-auto-compound-p* +described in the previous section. + +If auto compound mode is enabled together with auto infix mode, +then infix expressions may be entered without parentheses. +For example, the input line +.code "- x + y" +is first turned by auto compound mode into +.code "(- x + y)" +and then this is treated by auto infix mode as +.codn "(ifx (- x + y))" , +ultimately expanding to +.codn "(+ (- x) y))" . + .coNP Special Variable @ *doc-url* .desc The special variable |