1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
#!/usr/bin/env nomsu -V6.13.12.8
#
This is a tool to replace syntax trees with something new.
Usage:
nomsu -t replace [-i] [--literal="$v1 $v2..."] <pattern> <replacement> file1 file2...
Example:
nomsu -t replace "($1 and $2) and $3" "all of [$1, $2, $3]" my_file.nom
If the "-i" flag is used, the file(s) will be edited in-place.
When editing in-place, if the "-f" flag is not used, each change will be
run past the user first.
If no files are passed in, this will read from stdin.
use "lib/os.nom"
use "lib/consolecolor.nom"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if ((#$(COMMAND LINE ARGS).extras) < 2):
barf ("
Usage: nomsu -t replace [--literal="$v1 $v2..."] <pattern> <replacement> file1 file2...
")
$pattern = $(COMMAND LINE ARGS).extras.1
$replacement = $(COMMAND LINE ARGS).extras.2
$pattern_tree = ($pattern parsed)
$replacement_tree = ($replacement parsed)
$literal_vars = {}
if $(COMMAND LINE ARGS).literal:
for $var in ($(COMMAND LINE ARGS).literal, all matches of "$([^ ]*)"):
$literal_vars.$var = (yes)
if (($pattern_tree.type == "Var") and (not $literal_vars.($pattern_tree.1))):
barf "Pattern matches every part of the file."
$pattern_vars = {
: for $ in recursive $pattern_tree:
if (($.type == "Var") and (not $literal_vars.($.1))): add $.1
for $child in $:
if ($child is a "Syntax Tree"):
recurse $ on $child
}
($tree matches $patt with $substitution_values) means:
# TODO: optimize
$substitution_values = {: for $k = $v in $substitution_values: add $k = $v}
when:
(not ($tree is syntax tree)): return (no)
(($patt.type == "Var") and $pattern_vars.($patt.1)):
if $substitution_values.($patt.1):
if ($tree == $substitution_values.($patt.1)):
return $substitution_values
..else:
return (nil)
..else:
$substitution_values.($patt.1) = $tree
return $substitution_values
($tree.type != $patt.type): return (nil)
($tree.type == "Action"):
if (($tree, get stub) != ($patt, get stub)): return (nil)
for $ in 1 to (#$patt):
if ($patt.$ is syntax tree):
$new_values = ($tree.$ matches $patt.$ with $substitution_values)
unless $new_values:
return (nil)
for $k = $v in $new_values:
$substitution_values.$k = $v
..else:
unless ($tree.$ == $patt.$): return (nil)
if ((#$tree) != (#$patt)): return (nil)
return $substitution_values
$filenames = ($(COMMAND LINE ARGS).extras, from 3 to -1)
if ((#$filenames) == 0):
say ("
Warning: searching stdin (ctrl-d to abort). To avoid this message, use nomsu -t find -
")
$filenames = ["stdin"]
for $filename in $filenames:
$file = (read file $filename)
unless $file:
barf "File does not exist: \$filename"
$code = (NomsuCode from ($Source $filename 1 (size of $file)) $file)
try:
$tree = ($code parsed)
..and if it barfs $msg:
say
red ("
\$filename failed to parse:
\$msg
")
$tree = (nil)
unless $tree:
do next $filename
$replaced = {}
$matched = {}
$user_answers = {}
($tree with replacements) means
$tree, map
for $t:
$values = ($t matches $pattern_tree with {})
if $values:
$matched.$t = (yes)
for $k = $v in $values:
$values.$k = ($v with replacements)
$ret = ($replacement_tree with vars $values)
if ($(COMMAND LINE ARGS).i and (not $(COMMAND LINE ARGS).f)):
if ($user_answers.$t == (nil)):
if ((#$user_answers) > 0): say ""
$user_answers.$t = "n"
say "\(bright)Should this:"
say ("
\(bright)\(yellow)\("\(($t with replacements) as nomsu)", with "\n" -> "\n ")\
..\(reset color)
")
say "\(bright)..be replaced with:"
say ("
\(bright)\(blue)\("\($ret as nomsu)", with "\n" -> "\n ")\(reset color)
")
$user_answers.$t = (ask "\(bright)..? [Y/n]\(reset color) ")
if ($user_answers.$t == "n"): return (nil)
$replaced.$t = (yes)
return $ret
$tree2 = ($tree with replacements)
if $(COMMAND LINE ARGS).i:
if ((#$user_answers) > 0): say ""
say ("
\(#$replaced)/\(#$matched) replacement\("" if ((#$replaced) == 1) else "s") in \$filename
")
if ((#$replaced) > 0):
write "\($tree2 as nomsu)" to file $filename
..else:
say ($tree2 as nomsu)
|