From e7c14e74668d15f0403c868847779d795d167c8a Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Tue, 17 Jul 2018 06:12:10 -0700 Subject: 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. --- eval.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/eval.c b/eval.c index 7199272b..50c6fbc7 100644 --- a/eval.c +++ b/eval.c @@ -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)); -- cgit v1.2.3