(106 lines)
1 #!/usr/bin/env nomsu -V7.0.02 ###3 This is a tool to find syntax trees matching a pattern. "*" is a wildcard4 that will match any subtree, and "**" is a wildcard that will match any5 0 or more subtrees. "**" is greedy, so extra arguments after it will6 not match.8 nomsu -t find [flags] "* squared" file1 file2...10 Flags:11 -l List only the names of the files with matches12 --wildcard=<wildcard> Specify a custom wildcard (in case you need to13 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.128 if (any of [not $pattern, $pattern == "*", $pattern == "**"]):29 usage ("30 nomsu -t find [-l] [--wildcard=<wildcard>] <pattern>, where <pattern> is valid Nomsu code31 ")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 say70 red ("71 \$filename failed to parse:72 \$msg73 ")74 $tree = (nil)76 unless $tree:77 do next $filename79 $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_num90 .text = ("91 \(blue "\$filename:\$line_num:")92 \$source93 ")94 }96 for $sub in $t:97 if ($sub is syntax tree):98 recurse $t on $sub100 if $args.l:101 if (#$results > 0):102 say $filename103 ..else:104 sort $results by $ -> $.line105 for $ in $results:106 say $.text