-
-
Save dockimbel/031a45e28342d57bd63fad3db98f6841 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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