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

[REBOL] The complete Rebol named argument passing

From: lmecir:mbox:vol:cz at: 26-Feb-2004 9:59

I wrote a function, that can create a block handling complete Rebol named argument passing. (i.e. values, refinements, "normal" arguments, fetched arguments and "unevaluated" arguments) The function supposes, that there is a context containing all locals of the function which refer to the values and refinements that shall be passed. I will be grateful for any tests, optimizations and improvements. Sample test: f: func ['x [any-type!]] [type? get/any 'x] b: pass-args 'x [] :f x: 1 do b ; == integer! unset 'x do b ; == unset! the function: comment [ ; the Pass-args function result ; looks as follows: [ path: to path! 'fn call: make block! 4 + length? prefix insert call prefix insert/only tail call path ; "unevaluated argument passing goes here ; ... ; args are "corresponding" argument values insert tail call args ; here goes refinement handling ; ref is a refinement if ref [ insert tail path 'ref insert tail call args ] ; ... do call ] ] pass-args: function [ {Compose a block passing arguments and refinements to the given function} context [word!] prefix [block!] f [any-function!] ] [item item2 args result result2] [ ; the result shall have its own 'fn, 'path and 'call variables use [fn path call] [ ; 'fn variable shall refer to the function fn: :f ; the ARGS block collects arguments for CALL args: make block! 0 result: copy [ path: to path! 'fn call: make block! 4 + length? prefix insert call prefix insert/only tail call path ; here is the place to handle "unevaluated" arguments ] result2: compose [ insert tail call (reduce [args]) ; here goes refinement handling ] parse first :f [ any [ set item word! ( ; normal argument passing item: bind to lit-word! item context insert tail args compose [get/any (:item)] ) | set item refinement! ( ; refinement handling item: bind to word! item context insert tail call (reduce [args]) ; create "fresh" argument block args: make block! 0 insert tail result2 compose/deep [ if (item) [ insert tail path (to lit-word! item) insert tail call (reduce [args]) ] ] ) | set item lit-word! ( ; "unevaluated" argument passing item: bind :item context item2: bind to get-word! :item context insert p: tail args none insert tail result compose/deep [ change (reduce [p]) either value? (:item) [ ; this handles any value except unset! type (item2) ] [ ; this handles unset! type value ] ] ) | set item get-word! ( ; "fetched" argument passing item: bind to word! item context insert tail args item ) | skip ] ] compose [(result) (result2) do call] ] ] p.s. (for Romano and Gabriele) this can be used as the basic part of SUBFUNC. It substitutes PREPARE-AR and makes FUNCALL unnecessary.