Skip to content

Instantly share code, notes, and snippets.

@dockimbel
Forked from ifgem/template.red
Created January 14, 2017 15:01
Show Gist options
  • Save dockimbel/031a45e28342d57bd63fad3db98f6841 to your computer and use it in GitHub Desktop.
Save dockimbel/031a45e28342d57bd63fad3db98f6841 to your computer and use it in GitHub Desktop.
Red [
Author: "ifgem"
]
#do [
macro: context [
make-object-spec: function [words] [
spec: copy []
foreach word words [
append spec reduce [
to set-word! word
none
]
]
spec
]
to-spec-rule: function [spec body] [
rule: copy []
words: copy []
copy-or-set: func [pattern] [
either any [
pattern/1 = 'any
pattern/1 = 'some
integer? pattern/1
] ['copy] ['set]
]
make-rule: func [name pattern] [
either name [
append rule reduce [
copy-or-set pattern
name
pattern
]
append words name
] [
append/only rule pattern
]
]
parse spec [
any [
set name opt word!
set pattern block!
(make-rule name pattern)
]
]
; hide words used in the rule:)
hidden-context: make object! make-object-spec words
bind rule hidden-context
bind body hidden-context
rule
]
local: function [body [block!]] [
local-words: copy []
parse body [
any [
remove ['local set val [word! | block!]]
(append local-words val)
| change ['local set val set-word!]
(append local-words to word! val
val)
| skip
]
]
local-words
]
replacement: []
quote: func [
block [block!]
/local val
] [
block: copy block
parse block [
any [
change only ['unquote set val [word! | block!]] (
either block? val [
do val
] [
get val
]
)
| skip
]
]
append replacement block
]
]
]
#macro [
set template-recursive? opt 'recursive
'template
set template-name opt word!
set template-spec block!
set template-body block!
] func [[manual] start end /local name?] [
quote: :macro/quote ;bad!!!
bind template-body 'quote
either template-name [
name?: to lit-word! template-name
] [
name?: 'none
]
change/part start
compose/deep [
#macro [
(name?)
(macro/to-spec-rule template-spec template-body)
] func [
[manual] start end
/local
macro-end
(macro/local template-body)
] [
macro/replacement: copy []
(template-body)
macro-end: change/part start
macro/replacement
end
(either template-recursive? [
'start
] [
'macro-end
])
]
]
end
start ; process generated macro
]
recursive template [times [integer!] ['times | 'раз] counter [opt word!] body [block!]] [
either not counter [
quote [
loop unquote times unquote body
]
] [
quote [
repeat unquote counter unquote times unquote body
]
]
]
5 times val [
prin val
print "/"
5 раз mal [
prin mal
print "wow"
]
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment