Rebol [ Title: "Build" Author: ["Ladislav Mecir" "Brian Hawley"] File: %build.r Date: 9-Apr-2007/23:51:01+2:00 History: [ 7/apr/2003/19:02 {using INSERT and ONLY keywords} 30/Oct/2004/12:55 {intermediate version - alpha} 31/Oct/2004/9:49 {intermediate - word - insert/only, :word - insert} 4/Nov/2004/6:55 {word - insert and evaluate, :word - insert/only} 4/Nov/2004/15:00 {/with - refinement name} 2-May-2006/10:51:09+2:00 { lit-path preservation, 'ENCL and 'DTTO made local examples added } 2-May-2006/13:08:57+2:00 {one more lit-path related change by Brian} 2-May-2006/13:36:38+2:00 {example correction by Brian} 9-Apr-2007/23:51:01+2:00 {function description improved} ] Purpose: {Build a block comfortably} ] comment [ ; Usage ; This dialect looks very human-readable, doesn't it? ; (I found a lot of possible usages for it). build/with [x (y) [z] :u v] [ x: 1 y: 1 + 1 z: 1 + 2 u: [contents of u] v: [contents of v] ] ; == [1 (2) [3] [contents of u] contents of v] ; You can easily "stack" it like: build/with [let's see what] build/with [what: [the rise of the (y)]] [ y: 'sun ] ; == [let's see the rise of the (sun)] ; or use the evaluation feature like: build [ins 2 + 2] ; == [4] build [only reduce [3 * 4 5 + 6]] ; == [[12 11]] ; you can even define and use your own functions the same way ; using the /WITH refinement ] use [encl dtto spc] [ ; patch the IN function if needed spc: find/only third :in reduce [word!] if spc [change spc/1 any-word!] encl: func [ {"a value in a block" function} value [any-type!] ] [head insert/only copy [] get/any 'value] dtto: func [ {a "pass the value over" function} value [any-type!] ] [return get/any 'value] build: func [ { Build a block comfortably. Using 'INS and 'ONLY "keywords" by default. INS inserts the following value (similar to INSERT) ONLY inserts a series as one item (similar to INSERT/ONLY) } block [block! paren! path! set-path! lit-path!] /with {use the "keywords" given below} keywords [block!] /local context inner ] [ keywords: any [keywords [only: :encl ins: :dtto]] context: make object! keywords inner: func [block /local item item' pos result] [ result: make :block length? :block parse :block [ any [ pos: set item word! ( either all [item': in context item item <> 'self] [ change pos item' set/any [item pos] do/next pos insert tail :result get/any 'item ] [insert tail :result item pos: next pos] ) :pos | set item get-word! ( either all [item': in context item item <> 'self] [ insert/only tail :result get/any item' ] [insert tail :result item] ) | set item [ block! | paren! | path! | set-path! | lit-path! ] ( insert/only tail :result inner :item ) | set item skip (insert/only tail :result get/any 'item) ] ] :result ] inner :block ] ]