Created
September 2, 2018 01:53
-
-
Save cryptorick/ee5d2f50dd61bef9edcf8f775d73d07f to your computer and use it in GitHub Desktop.
Print a tree of include filenames in depth-first order and indented
This file contains hidden or 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
#!/usr/bin/env oh | |
#-------------------------------------------------------------------------- | |
# Utilities | |
define defun: syntax (name args: body) e = { | |
e::eval: list define $name : list method (list @$args) = @$body | |
} | |
define fn: syntax (args: body) e = { | |
# Example: `fn (x): add 42 x` is a method (function object) that | |
# you can pass around | |
e::eval: list method (list @$args) = @$body | |
} | |
defun I (x) : return $x # The identity function. | |
define mapl: syntax (f) e = { | |
e::eval: list while (list define ln (list readline)) (list $f (quote $ln)) | |
} | |
define maplp: syntax (f) e = { | |
e::eval: list while (list define ln (list readline)) (list echo (list $f (quote $ln))) | |
} | |
defun string-last (s) { | |
s::slice : sub (s::length) 1 | |
} | |
defun string-but-last (s) { | |
s::slice 0 : sub (s::length) 1 | |
} | |
defun strip-CR (s) { | |
if (eq "\r" : string-last $s) { | |
string-but-last $s | |
} else { | |
return $s | |
} | |
} | |
defun nth-word (n s) { | |
(" "::split $s)::get $n | |
} | |
defun member (x xs) { | |
if (or (is-null $xs) (eq $x : xs::head)) { | |
return $xs | |
} else { | |
member $x : xs::tail | |
} | |
} | |
defun member? (:args) : boolean : member @$args | |
defun file-readable? (File): boolean: test -r $File | |
#-------------------------------------------------------------------------- | |
# Application | |
define things-seen: method () =: object { | |
define what-seen: list | |
export show: method self () = { | |
echo $self::what-seen | |
} | |
export seen-this?: method self (this) = { | |
member? $this $self::what-seen | |
} | |
export see-this: method self (this) = { | |
if (not: seen-this? $this) { | |
set $self::what-seen: cons $this $self::what-seen | |
} | |
return $this | |
} | |
} | |
defun indent-by (n s) { | |
if (gt $n 0) { | |
return: ("%%%ss$s"::sprintf $n)::sprintf " " | |
} else: return $s | |
} | |
defun print-includes (File) { | |
grep -E '^[ \t]*include(_once)* ' $File | | |
maplp strip-CR | | |
maplp: fn (ln): nth-word 1 $ln | |
} | |
defun print-tree (File) { | |
define Indent 4 | |
define seen: things-seen | |
defun loop (File Depth) { | |
define outstr: indent-by (mul $Indent $Depth) $File | |
if (not: file-readable? $File) { | |
echo $outstr "(FILE NOT FOUND!)" | |
} else: if (seen::seen-this? $File) { | |
echo $outstr "(ALREADY SAW THIS EARLIER; Skipping ...)" | |
} else { | |
echo $outstr | |
echo $File | | |
maplp seen::see-this | | |
mapl print-includes | | |
mapl: fn (Dep): loop $Dep (add 1 $Depth) | |
} | |
} | |
loop $File 0 | |
} | |
print-tree @$_args_ |
Here are the function versions of mapl
and maplp
:
defun mapl (f): while (define ln: readline): $f $ln
defun maplp (f): while (define ln: readline): echo: $f $ln
They're less noisy than their syntax counter parts, but I was getting a subtle error using them in the function print-tree
at the expression maplp seen::see-this
(and of course, when you replace maplp
with the function/method version, the call has to be changed to maplp $seen::see-this
). Here's the error I would get.
$ print-include-tree.oh foo.src
foo.src
print-include-tree.oh: 72: error/runtime: 'what-seen' undefined
It's really wigged out: it's lost track of its own slot in the object. idk.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
What a super-fun programming/scripting language! (I'm sure I'm not doing some things correctly, but I learned a lot.)