diff options
Diffstat (limited to 'libguile/eval.c')
-rw-r--r-- | libguile/eval.c | 130 |
1 files changed, 29 insertions, 101 deletions
diff --git a/libguile/eval.c b/libguile/eval.c index 6047d6d75..f5e1524c7 100644 --- a/libguile/eval.c +++ b/libguile/eval.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2013 +/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004, + * 2005,2006,2007,2008,2009,2010,2011,2012,2013 * Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or @@ -39,7 +40,6 @@ #include "libguile/eq.h" #include "libguile/expand.h" #include "libguile/feature.h" -#include "libguile/fluids.h" #include "libguile/goops.h" #include "libguile/hash.h" #include "libguile/hashtab.h" @@ -230,10 +230,9 @@ eval (SCM x, SCM env) mx = SCM_MEMOIZED_ARGS (x); switch (SCM_MEMOIZED_TAG (x)) { - case SCM_M_BEGIN: - for (; !scm_is_null (CDR (mx)); mx = CDR (mx)) - eval (CAR (mx), env); - x = CAR (mx); + case SCM_M_SEQ: + eval (CAR (mx), env); + x = CDR (mx); goto loop; case SCM_M_IF: @@ -265,42 +264,6 @@ eval (SCM x, SCM env) scm_define (CAR (mx), EVAL1 (CDR (mx), env)); return SCM_UNSPECIFIED; - case SCM_M_DYNWIND: - { - SCM in, out, res, old_winds; - in = EVAL1 (CAR (mx), env); - out = EVAL1 (CDDR (mx), env); - scm_call_0 (in); - old_winds = scm_i_dynwinds (); - scm_i_set_dynwinds (scm_acons (in, out, old_winds)); - res = eval (CADR (mx), env); - scm_i_set_dynwinds (old_winds); - scm_call_0 (out); - return res; - } - - case SCM_M_WITH_FLUIDS: - { - long i, len; - SCM *fluidv, *valuesv, walk, wf, res; - len = scm_ilength (CAR (mx)); - fluidv = alloca (sizeof (SCM)*len); - for (i = 0, walk = CAR (mx); i < len; i++, walk = CDR (walk)) - fluidv[i] = EVAL1 (CAR (walk), env); - valuesv = alloca (sizeof (SCM)*len); - for (i = 0, walk = CADR (mx); i < len; i++, walk = CDR (walk)) - valuesv[i] = EVAL1 (CAR (walk), env); - - wf = scm_i_make_with_fluids (len, fluidv, valuesv); - scm_i_swap_with_fluids (wf, SCM_I_CURRENT_THREAD->dynamic_state); - scm_i_set_dynwinds (scm_cons (wf, scm_i_dynwinds ())); - res = eval (CDDR (mx), env); - scm_i_swap_with_fluids (wf, SCM_I_CURRENT_THREAD->dynamic_state); - scm_i_set_dynwinds (CDR (scm_i_dynwinds ())); - - return res; - } - case SCM_M_APPLY: /* Evaluate the procedure to be applied. */ proc = EVAL1 (CAR (mx), env); @@ -436,22 +399,28 @@ eval (SCM x, SCM env) return SCM_UNSPECIFIED; } - case SCM_M_PROMPT: + case SCM_M_CALL_WITH_PROMPT: { - SCM vm, res; - /* We need the prompt and handler values after a longjmp case, - so make sure they are volatile. */ - volatile SCM handler, prompt; + SCM vm, k, res; + scm_i_jmp_buf registers; + /* We need the handler after nonlocal return to the setjmp, so + make sure it is volatile. */ + volatile SCM handler; - vm = scm_the_vm (); - prompt = scm_c_make_prompt (EVAL1 (CAR (mx), env), - SCM_VM_DATA (vm)->fp, - SCM_VM_DATA (vm)->sp, SCM_VM_DATA (vm)->ip, - 0, -1, scm_i_dynwinds ()); + k = EVAL1 (CAR (mx), env); handler = EVAL1 (CDDR (mx), env); - scm_i_set_dynwinds (scm_cons (prompt, scm_i_dynwinds ())); + vm = scm_the_vm (); - if (SCM_PROMPT_SETJMP (prompt)) + /* Push the prompt onto the dynamic stack. */ + scm_dynstack_push_prompt (&SCM_I_CURRENT_THREAD->dynstack, + SCM_F_DYNSTACK_PROMPT_ESCAPE_ONLY, + k, + SCM_VM_DATA (vm)->fp, + SCM_VM_DATA (vm)->sp, + SCM_VM_DATA (vm)->ip, + ®isters); + + if (SCM_I_SETJMP (registers)) { /* The prompt exited nonlocally. */ proc = handler; @@ -459,8 +428,8 @@ eval (SCM x, SCM env) goto apply_proc; } - res = eval (CADR (mx), env); - scm_i_set_dynwinds (CDR (scm_i_dynwinds ())); + res = scm_call_0 (eval (CADR (mx), env)); + scm_dynstack_pop (&SCM_I_CURRENT_THREAD->dynstack); return res; } @@ -601,47 +570,6 @@ scm_apply_3 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM args) SCM_EOL); } -/* This code processes the arguments to apply: - - (apply PROC ARG1 ... ARGS) - - Given a list (ARG1 ... ARGS), this function conses the ARG1 - ... arguments onto the front of ARGS, and returns the resulting - list. Note that ARGS is a list; thus, the argument to this - function is a list whose last element is a list. - - Apply calls this function, and applies PROC to the elements of the - result. apply:nconc2last takes care of building the list of - arguments, given (ARG1 ... ARGS). - - Rather than do new consing, apply:nconc2last destroys its argument. - On that topic, this code came into my care with the following - beautifully cryptic comment on that topic: "This will only screw - you if you do (scm_apply scm_apply '( ... ))" If you know what - they're referring to, send me a patch to this comment. */ - -SCM_DEFINE (scm_nconc2last, "apply:nconc2last", 1, 0, 0, - (SCM lst), - "Given a list (@var{arg1} @dots{} @var{args}), this function\n" - "conses the @var{arg1} @dots{} arguments onto the front of\n" - "@var{args}, and returns the resulting list. Note that\n" - "@var{args} is a list; thus, the argument to this function is\n" - "a list whose last element is a list.\n" - "Note: Rather than do new consing, @code{apply:nconc2last}\n" - "destroys its argument, so use with care.") -#define FUNC_NAME s_scm_nconc2last -{ - SCM *lloc; - SCM_VALIDATE_NONEMPTYLIST (1, lst); - lloc = &lst; - while (!scm_is_null (SCM_CDR (*lloc))) - lloc = SCM_CDRLOC (*lloc); - SCM_ASSERT (scm_ilength (SCM_CAR (*lloc)) >= 0, lst, SCM_ARG1, FUNC_NAME); - *lloc = SCM_CAR (*lloc); - return lst; -} -#undef FUNC_NAME - SCM scm_map (SCM proc, SCM arg1, SCM args) @@ -968,16 +896,16 @@ static int boot_closure_print (SCM closure, SCM port, scm_print_state *pstate) { SCM args; - scm_puts ("#<boot-closure ", port); - scm_uintprint ((scm_t_bits)SCM2PTR (closure), 16, port); - scm_putc (' ', port); + scm_puts_unlocked ("#<boot-closure ", port); + scm_uintprint (SCM_UNPACK (closure), 16, port); + scm_putc_unlocked (' ', port); args = scm_make_list (scm_from_int (BOOT_CLOSURE_NUM_REQUIRED_ARGS (closure)), scm_from_latin1_symbol ("_")); if (!BOOT_CLOSURE_IS_FIXED (closure) && BOOT_CLOSURE_HAS_REST_ARGS (closure)) args = scm_cons_star (scm_from_latin1_symbol ("_"), args); /* FIXME: optionals and rests */ scm_display (args, port); - scm_putc ('>', port); + scm_putc_unlocked ('>', port); return 1; } |