code / nomsu

Lines6.6K Lua5.1K PEG1.3K make117
2 others 83
Markdown60 Bourne Again Shell23
(106 lines)
1 #!/usr/bin/env nomsu -V7.0.0
2 ###
3 This is a tool to find syntax trees matching a pattern. "*" is a wildcard
4 that will match any subtree, and "**" is a wildcard that will match any
5 0 or more subtrees. "**" is greedy, so extra arguments after it will
6 not match.
8 nomsu -t find [flags] "* squared" file1 file2...
10 Flags:
11 -l List only the names of the files with matches
12 --wildcard=<wildcard> Specify a custom wildcard (in case you need to
13 match an action with a "*" in the name)
15 Output:
16 <filename>:<line number>:
17 <matching lines>
19 use "filesystem"
20 use "consolecolor"
21 use "commandline"
23 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25 command line program with $args:
26 $wildcard = ($args.wildcard or "%*")
27 $pattern = $args.extras.1
28 if (any of [not $pattern, $pattern == "*", $pattern == "**"]):
29 usage ("
30 nomsu -t find [-l] [--wildcard=<wildcard>] <pattern>, where <pattern> is valid Nomsu code
31 ")
32 $pattern = ($pattern, with "\$wildcard\$wildcard" -> "$multi_wildcard")
33 $pattern = ($pattern, with $wildcard -> "$wildcard")
34 $pattern_tree = ($pattern parsed)
35 ($tree matches $patt) means:
36 when:
37 (not ($tree is syntax tree)): return (no)
38 (($patt.type == "Var") and ($patt.1 == "wildcard")): return (yes)
39 ($tree.type != $patt.type): return (no)
40 ($tree.type == "Action"):
41 if (($tree, get stub) != ($patt, get stub)): return (no)
43 for $ in (1 to #$patt):
44 if ($patt.$ is syntax tree):
45 if ($patt.$ == \$multi_wildcard): return (yes)
46 unless ($tree.$ matches $patt.$): return (no)
47 ..else:
48 unless ($tree.$ == $patt.$): return (no)
50 if (#$tree != #$patt):
51 return (no)
53 return (yes)
54 $filenames = ($args.extras, from 2 to -1)
55 if (#$filenames == 0):
56 say ("
57 Warning: searching stdin (ctrl-d to abort). To avoid this message, use nomsu -t find -
58 ")
59 $filenames = ["stdin"]
61 for $filename in $filenames:
62 $file = (read file $filename)
63 unless $file:
64 fail "File does not exist: \$filename"
65 $code = (NomsuCode from ($Source $filename 1 #$file) $file)
66 try:
67 $tree = ($code parsed)
68 ..if it fails with $msg:
69 say
70 red ("
71 \$filename failed to parse:
72 \$msg
73 ")
74 $tree = (nil)
76 unless $tree:
77 do next $filename
79 $results = []
80 for $t in recursive $tree:
81 if ($t matches $pattern_tree):
82 $line_num = ($file, line number at $t.source.start)
84 $source = (source lines of $t)
85 $indent = ($source, matching "^ *")
86 $source = ($source, from (#$indent + 1), with "\n\$indent" -> "\n")
88 $results, add {
89 .line = $line_num
90 .text = ("
91 \(blue "\$filename:\$line_num:")
92 \$source
93 ")
96 for $sub in $t:
97 if ($sub is syntax tree):
98 recurse $t on $sub
100 if $args.l:
101 if (#$results > 0):
102 say $filename
103 ..else:
104 sort $results by $ -> $.line
105 for $ in $results:
106 say $.text