diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2019-01-14 15:42:48 -0800 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2019-01-14 15:43:24 -0800 |
| commit | c1c32688a4afc43f6addb99b8b5fa878944a70e3 (patch) | |
| tree | c886f21b5b08a9053aa74fcba4b241dae5ede76d /lib/tools/find.nom | |
| parent | 2309b696fc34b24f05f6658b94f9105ca8ee76e4 (diff) | |
Overhaul in progress, mostly working. Moved all the nomsu packages into
lib/, including core/*. Changes to how nomsu environments and importing
work.
Diffstat (limited to 'lib/tools/find.nom')
| -rwxr-xr-x | lib/tools/find.nom | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/lib/tools/find.nom b/lib/tools/find.nom new file mode 100755 index 0000000..aa4bc7b --- /dev/null +++ b/lib/tools/find.nom @@ -0,0 +1,95 @@ +#!/usr/bin/env nomsu -V6.14 +# + This is a tool to find syntax trees matching a pattern. "*" is a wildcard + that will match any subtree, and "**" is a wildcard that will match any + 0 or more subtrees. "**" is greedy, so extra arguments after it will + not match. + + nomsu -t find [flags] "* squared" file1 file2... + + Flags: + -l List only the names of the files with matches + --wildcard=<wildcard> Specify a custom wildcard (in case you need to + match an action with a "*" in the name) + + Output: + <filename>:<line number>: + <matching lines> + +use "filesystem" +use "consolecolor" +use "commandline" + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +command line program with $args: + $wildcard = ($args.wildcard or "%*") + $pattern = $args.extras.1 + if (any of [not $pattern, $pattern == "*", $pattern == "**"]): + usage (" + nomsu -t find [-l] [--wildcard=<wildcard>] <pattern>, where <pattern> is valid Nomsu code + ") + $pattern = ($pattern, with "\$wildcard\$wildcard" -> "$multi_wildcard") + $pattern = ($pattern, with $wildcard -> "$wildcard") + $pattern_tree = ($pattern parsed) + ($tree matches $patt) means: + when: + (not ($tree is syntax tree)): return (no) + (($patt.type == "Var") and ($patt.1 == "wildcard")): return (yes) + ($tree.type != $patt.type): return (no) + ($tree.type == "Action"): + if (($tree, get stub) != ($patt, get stub)): return (no) + + for $ in 1 to (#$patt): + if ($patt.$ is syntax tree): + if ($patt.$ == \$multi_wildcard): return (yes) + unless ($tree.$ matches $patt.$): return (no) + ..else: + unless ($tree.$ == $patt.$): return (no) + + if ((#$tree) != (#$patt)): return (no) + return (yes) + $filenames = ($args.extras, from 2 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: + fail "File does not exist: \$filename" + $code = (NomsuCode from ($Source $filename 1 (size of $file)) $file) + try: + $tree = ($code parsed) + ..if it fails $msg: + say + red (" + \$filename failed to parse: + \$msg + ") + $tree = (nil) + + unless $tree: + do next $filename + + $results = [] + for $t in recursive $tree: + if ($t matches $pattern_tree): + $line_num = ($file, line number at $t.source.start) + $results, add { + .line = $line_num, .text = "\(blue "\$filename:\$line_num:")\n\(source lines of $t)" + } + + for $sub in $t: + if ($sub is syntax tree): + recurse $t on $sub + + if $args.l: + if ((#$results) > 0): + say $filename + ..else: + sort $results by $ -> $.line + for $ in $results: + say $.text |
