summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2025-04-17 20:30:21 -0700
committerKaz Kylheku <kaz@kylheku.com>2025-04-17 20:30:21 -0700
commit05477c10a764b0deb160708eb91587695d965a49 (patch)
tree831298a0fb01652817f091cc04c8adc3d6055f85
parent4d68e3c2f2162a7c513c5c2c4a3c7c2c22a9e3be (diff)
downloadtxr-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.c22
-rw-r--r--txr.135
2 files changed, 50 insertions, 7 deletions
diff --git a/parser.c b/parser.c
index d36ea13d..d83fbd97 100644
--- a/parser.c
+++ b/parser.c
@@ -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);
diff --git a/txr.1 b/txr.1
index 741f15d7..7461f7ec 100644
--- a/txr.1
+++ b/txr.1
@@ -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