Skip to content

Instantly share code, notes, and snippets.

@rebolek

rebolek/build.r

Created Jun 1, 2019
Embed
What would you like to do?
Rebol [
Title: "Build"
Author: ["Ladislav Mecir" "Brian Hawley"]
File: %build.r
Date: 2-May-2006/13:36:38+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}
]
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 using given values}
block [block! paren! path! lit-path! set-path!]
/with
values [block!]
/local context inner
] [
values: any [values [only: :encl ins: :dtto]]
context: make object! values
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
]
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment