Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

[REBOL] Words, Bindings and Contexts. (7)

From: lmecir:geocities at: 25-Jul-2000 22:37

I see, that the fact, that my series didn't explain the behaviour of functions WRT Recursion and Binding is a flaw. Here is the continuation (a model of the behaviour): ; Model of Rebol function: ; **************************** sim-function!: make object! [ ; every function has got a Context attribute context: none ; every function has got a Spec attribute spec: none ; every function has got a Body attribute body: none ; every function has got a provision for Recursion recursion-level: 0 stack: none ] ; Model of Func function: ; *************************** sim-func: func [ {create a Sim-function!} spec [block!] body [block!] /local context-init spec-too body-too ] [ ; first of all, the function context should be created context-init: make block! 1 + length? spec foreach word spec [ append context-init to set-word! word ] append context-init none spec-too: spec body-too: body make sim-function! [ ; create context context: make object! context-init ; a simplification here spec: bind/copy spec-too in context 'self ; this is the secret of "Context Hierachy" body: bind/copy body-too in context 'self ; Create a stack for storing values during recursive calls stack: copy [] ] ] ; Model of the function body execution: ; ****************************************** do-body: func [body] [do body] ; Model of the return from function: ; ************************************** sim-return: func [ sim-f value [any-type!] ] [ ; restore the former values from stack, if needed if (sim-f/recursion-level: sim-f/recursion-level - 1) > 0 [ set/any sim-f/spec first sim-f/stack ; finish the stack-pop sim-f/stack: remove sim-f/stack ] ; return the value return get/any 'value ] ; Model of function Evaluation: ; ********************************* sim-evaluate: func [ {evaluate a sim-function contained in a block with its arguments} block [block!] /local sim-f actual-values ] [ ; evaluate the arguments block: reduce block ; the executed sim-function is first sim-f: first block ; detect recursion if (sim-f/recursion-level: sim-f/recursion-level + 1) > 1 [ ; get the actual values of local words actual-values: copy [] foreach word sim-f/spec [ append/only actual-values get/any word ] ; push the actual values to stack sim-f/stack: head insert/only sim-f/stack actual-values ] ; give local words the supplied values set/any sim-f/spec next block ; execute the function body and return the result return sim-return sim-f do-body sim-f/body ] ; Some tests: ; ************** blk: copy [] probeblk: func [] [ prin mold blk prin ": " print mold reduce blk ] recfun: sim-func [x] [ append blk 'x either x <= 1 [ probeblk ] [ sim-evaluate [recfun x - 1] ] ] sim-evaluate [recfun 3] probeblk