diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2018-07-17 06:12:10 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2018-07-17 06:12:10 -0700 |
commit | e7c14e74668d15f0403c868847779d795d167c8a (patch) | |
tree | 998039c1f4e5be608390b2048a33deb13bcdebcc /eval.c | |
parent | d879eb7226e928e41c45c1702ed3685e0b8e1757 (diff) | |
download | txr-e7c14e74668d15f0403c868847779d795d167c8a.tar.gz txr-e7c14e74668d15f0403c868847779d795d167c8a.tar.bz2 txr-e7c14e74668d15f0403c868847779d795d167c8a.zip |
eval: handle top-level incrementally.
Like in some other Lisp dialects, evaluation of top-level
forms should deal with forms like:
(progn (defmacro a () 42) (a))
where the (a) will correctly reference the macro earlier
in the progn.
* eval.c (eval_only_s, compile_only_s): New symbol variables.
(expand_eval): New static function, based on previous code of
eval_intrinsic.
(eval_intrinsic): Rewritten to perform incremental
macroexpand, similarly to compile-file, and recurse. If a
form, after macro-expansion, is a progn, eval-only or
compile-only, then its constituents are individually evaluated
through expand_eval as separate forms: each one is fully
expanded and evaluated before the next one is processed. If
the form isn't a progn, eval-only or compile-only, then it is
treated as a single expansion and evaluation.
(eval_init): Initialize new symbol variables and use their
values in registering their respective operators.
Diffstat (limited to 'eval.c')
-rw-r--r-- | eval.c | 33 |
1 files changed, 30 insertions, 3 deletions
@@ -102,6 +102,7 @@ val defsymacro_s, symacrolet_s, prof_s, switch_s; val fbind_s, lbind_s, flet_s, labels_s; val load_path_s, load_recursive_s; val load_time_s, load_time_lit_s; +val eval_only_s, compile_only_s; val special_s, unbound_s; val whole_k, form_k, symacro_k; @@ -1378,7 +1379,7 @@ val funcall_interp(val interp_fun, struct args *args) return ret; } -val eval_intrinsic(val form, val env) +static val expand_eval(val form, val env) { val lfe_save = last_form_evaled; val lfx_save = last_form_expanded; @@ -1392,6 +1393,30 @@ val eval_intrinsic(val form, val env) return ret; } +static val macroexpand(val form, val menv); + +val eval_intrinsic(val form, val env) +{ + val form_ex = macroexpand(form, env); + val op; + + if (consp(form_ex) && + ((op = car(form_ex)) == progn_s || op == eval_only_s || + op == compile_only_s)) + { + val res = nil, next = cdr(form_ex); + + while (next) { + res = expand_eval(car(next), env); + next = cdr(next); + } + + return res; + } + + return expand_eval(form_ex, env); +} + val eval_intrinsic_noerr(val form, val env, val *error_p) { val result = nil; @@ -6064,6 +6089,8 @@ void eval_init(void) load_recursive_s = intern(lit("*load-recursive*"), system_package); load_time_s = intern(lit("load-time"), user_package); load_time_lit_s = intern(lit("load-time-lit"), system_package); + eval_only_s = intern(lit("eval-only"), user_package); + compile_only_s = intern(lit("compile-only"), user_package); qquote_init(); @@ -6119,8 +6146,8 @@ void eval_init(void) reg_op(prof_s, op_prof); reg_op(switch_s, op_switch); reg_op(intern(lit("upenv"), system_package), op_upenv); - reg_op(intern(lit("compile-only"), user_package), op_progn); - reg_op(intern(lit("eval-only"), user_package), op_progn); + reg_op(compile_only_s, op_progn); + reg_op(eval_only_s, op_progn); reg_op(load_time_lit_s, op_load_time_lit); reg_mac(defvar_s, func_n2(me_def_variable)); |