From: Sam S. <sd...@gn...> - 2005-01-20 17:12:30
|
> * Bruno Haible <oe...@py...t> [2005-01-20 17:29:49 +0100]: > > Sam wrote: >> unfortunately, when I de-activate the initial special bindings and >> re-activate them at the end right before the implicit_progn(), >> I get some additional test failures instead. > > But at least this modification handles the "free SPECIAL declarations" > correctly. > > For the "bound SPECIAL declarations", i.e. those symbols with occur in > both variable lists, you need to set the active_bit already when the > corresponding binding is activated. When I look at funcall_iclosure / > bind_next_var, it looks like the code should already do this. it activates just the next binding, not the special binding done before. > Which bind-eval tests exactly are still failing? with this patch: --- eval.d 19 Jan 2005 15:50:06 -0500 1.184 +++ eval.d 20 Jan 2005 12:05:52 -0500 @@ -2375,6 +2375,8 @@ } var gcv_object_t* closure_ = &STACK_(frame_closure); /* &closure */ var gcv_object_t* frame_pointer; /* pointer to the frame */ + var gcv_object_t* bind_ptr; + var uintC bind_count; { /* 2nd step: build variable-binding-frame: */ var gcv_object_t* top_of_frame = STACK; /* Pointer to Frame */ var object vars = TheIclosure(closure)->clos_vars; /* Vector of variable-names */ @@ -2387,8 +2389,9 @@ /* the special-references first: */ dotimesC(count,spec_count, { pushSTACK(specdecl); /* SPECDECL as "value" */ - pushSTACK_symbolwithflags(*varptr++,wbit(active_bit_o)); /* active */ + pushSTACK_symbolwithflags(*varptr++,0); /* INactive */ }); + bind_ptr = args_end_pointer; bind_count = spec_count; frame_pointer = args_end_pointer; if (var_count-spec_count > 0) { var uintB* varflagsptr = &TheSbvector(TheIclosure(closure)->clos_varflags)->data[0]; @@ -2635,6 +2638,15 @@ } #undef bind_next_var } + /* activate the bindings: */ + for (;bind_count--;bind_ptr skipSTACKop varframe_binding_size) { + var gcv_object_t* markptr = &Before(bind_ptr); + var object symbol = *(markptr STACKop varframe_binding_sym); /* variable */ + var object newval = *(markptr STACKop varframe_binding_value); /* new value */ + *(markptr STACKop varframe_binding_value) = TheSymbolflagged(symbol)->symvalue; /* save old value in frame */ + *markptr = as_object(as_oint(*markptr) | wbit(active_bit_o)); /* activate binding */ + TheSymbolflagged(symbol)->symvalue = newval; /* new value */ + } /* 5th step: evaluate Body: */ implicit_progn(TheIclosure(closure)->clos_body,NIL); unwind(); /* unwind ENV-frame */ 2 tests fail: RUN-TEST: finished "tests/bind" (2 errors out of 32 tests) 32 ; 2 Form: (LET ((X 5)) (PROGV '(X) '(20) ((LAMBDA (&OPTIONAL (X (1+ X)) (Z (1+ X)))(DECLARE (SPECIAL X)) Z)))) CORRECT: 7 CLISP : 6 Form: (PROGN (DEFPARAMETER *GLOBAL-VAR-FOR-BIND.TST* 123) (LET ((*GLOBAL-VAR-FOR-BIND.TST* 5)) (LIST ((LAMBDA (*GLOBAL-VAR-FOR-BIND.TST*) (DECLARE (SPECIAL *GLOBAL-VAR-FOR-BIND.TST*)) *GLOBAL-VAR-FOR-BIND.TST*) (1+ *GLOBAL-VAR-FOR-BIND.TST*)) *GLOBAL-VAR-FOR-BIND.TST*))) CORRECT: (6 5) CLISP : (#<SPECIAL REFERENCE> 5) Differ at position 0: 6 vs #<SPECIAL REFERENCE> CORRECT: (6 5) CLISP : (#<SPECIAL REFERENCE> 5) if I put wbit(dynam_bit_o) instead of 0 in the second hunk, I get: RUN-TEST: finished "tests/bind" (7 errors out of 32 tests) 32 ; 7 Form: (LET ((X 5)) ((LAMBDA (X) (DECLARE (SPECIAL X)) X) (1+ X))) CORRECT: 6 CLISP : 5 Form: (BLOCK FOO (HANDLER-BIND ((UNBOUND-VARIABLE (LAMBDA (C) (PRINC-ERROR C) (RETURN-FROM FOO 'GOOD)))) (LET ((X (1+ X))) (DECLARE (SPECIAL X)) X))) CORRECT: GOOD CLISP : 7 Form: (BLOCK FOO (HANDLER-BIND ((UNBOUND-VARIABLE (LAMBDA (C) (PRINC-ERROR C) (RETURN-FROM FOO 'GOOD)))) (LET* ((X (1+ X))) (DECLARE (SPECIAL X)) X))) CORRECT: GOOD CLISP : 7 Form: (BLOCK FOO (HANDLER-BIND ((UNBOUND-VARIABLE (LAMBDA (C) (PRINC-ERROR C) (RETURN-FROM FOO 'GOOD)))) (MULTIPLE-VALUE-BIND (X) (1+ X) (DECLARE (SPECIAL X)) X))) CORRECT: GOOD CLISP : 7 Form: (BLOCK FOO (HANDLER-BIND ((UNBOUND-VARIABLE (LAMBDA (C) (PRINC-ERROR C) (RETURN-FROM FOO 'GOOD)))) ((LAMBDA (X) (DECLARE (SPECIAL X)) X) (1+ X)))) CORRECT: GOOD CLISP : #<SPECIAL REFERENCE> Form: (LET ((X 5)) (PROGV '(X) '(20) ((LAMBDA (&OPTIONAL (X (1+ X)) (Z (1+ X)))(DECLARE (SPECIAL X)) Z)))) CORRECT: 7 CLISP : 6 Form: (PROGN (DEFPARAMETER *GLOBAL-VAR-FOR-BIND.TST* 123) (LET ((*GLOBAL-VAR-FOR-BIND.TST* 5)) (LIST ((LAMBDA (*GLOBAL-VAR-FOR-BIND.TST*) (DECLARE (SPECIAL *GLOBAL-VAR-FOR-BIND.TST*)) *GLOBAL-VAR-FOR-BIND.TST*) (1+ *GLOBAL-VAR-FOR-BIND.TST*)) *GLOBAL-VAR-FOR-BIND.TST*))) CORRECT: (6 5) CLISP : (#<SPECIAL REFERENCE> 6) Differ at position 0: 6 vs #<SPECIAL REFERENCE> CORRECT: (6 5) CLISP : (#<SPECIAL REFERENCE> 6) if instead I add wbit(dynam_bit_o) to wbit(active_bit_o) in the last hunk, I get: RUN-TEST: finished "tests/bind" (7 errors out of 32 tests) 32 ; 7 Form: (LET ((X 5)) ((LAMBDA (X) (DECLARE (SPECIAL X)) X) (1+ X))) CORRECT: 6 CLISP : 5 Form: (BLOCK FOO (HANDLER-BIND ((UNBOUND-VARIABLE (LAMBDA (C) (PRINC-ERROR C) (RETURN-FROM FOO 'GOOD)))) (LET ((X (1+ X))) (DECLARE (SPECIAL X)) X))) CORRECT: GOOD CLISP : 7 Form: (BLOCK FOO (HANDLER-BIND ((UNBOUND-VARIABLE (LAMBDA (C) (PRINC-ERROR C) (RETURN-FROM FOO 'GOOD)))) (LET* ((X (1+ X))) (DECLARE (SPECIAL X)) X))) CORRECT: GOOD CLISP : 7 Form: (BLOCK FOO (HANDLER-BIND ((UNBOUND-VARIABLE (LAMBDA (C) (PRINC-ERROR C) (RETURN-FROM FOO 'GOOD)))) (MULTIPLE-VALUE-BIND (X) (1+ X) (DECLARE (SPECIAL X)) X))) CORRECT: GOOD CLISP : 7 Form: (BLOCK FOO (HANDLER-BIND ((UNBOUND-VARIABLE (LAMBDA (C) (PRINC-ERROR C) (RETURN-FROM FOO 'GOOD)))) ((LAMBDA (X) (DECLARE (SPECIAL X)) X) (1+ X)))) CORRECT: GOOD CLISP : #<SPECIAL REFERENCE> Form: (LET ((X 5)) (PROGV '(X) '(20) ((LAMBDA (&OPTIONAL (X (1+ X)) (Z (1+ X)))(DECLARE (SPECIAL X)) Z)))) CORRECT: 7 CLISP : 6 Form: (PROGN (DEFPARAMETER *GLOBAL-VAR-FOR-BIND.TST* 123) (LET ((*GLOBAL-VAR-FOR-BIND.TST* 5)) (LIST ((LAMBDA (*GLOBAL-VAR-FOR-BIND.TST*) (DECLARE (SPECIAL *GLOBAL-VAR-FOR-BIND.TST*)) *GLOBAL-VAR-FOR-BIND.TST*) (1+ *GLOBAL-VAR-FOR-BIND.TST*)) *GLOBAL-VAR-FOR-BIND.TST*))) CORRECT: (6 5) CLISP : (#<SPECIAL REFERENCE> 6) Differ at position 0: 6 vs #<SPECIAL REFERENCE> CORRECT: (6 5) CLISP : (#<SPECIAL REFERENCE> 6) >> I wonder if keeping two separate vectors of special vars and args >> and binding the specials only after argument processing right before the >> implicit_progn() is a cleaner solution. > > It would consume more memory - gratuitously. an interpreted closure is a rare beast, I wouldn't worry about this too much -- Sam Steingold (http://www.podval.org/~sds) running w2k <http://www.camera.org> <http://www.iris.org.il> <http://www.memri.org/> <http://www.mideasttruth.com/> <http://www.honestreporting.com> Bill Gates is not god and Microsoft is not heaven. |