-
Notifications
You must be signed in to change notification settings - Fork 126
parser
Phil Hagelberg edited this page Aug 14, 2024
·
3 revisions
Parse a file and determine the length of all the functions inside it.
(local fennel (require :fennel))
(fn walk-tree [root f custom-iterator] ; stolen from fennel.utils
(fn walk [iterfn parent idx node]
(when (f idx node parent)
(each [k v (iterfn node)]
(walk iterfn node k v))))
(walk (or custom-iterator pairs) nil nil root)
root)
(fn find-functions [read results]
(fn walk-node [results idx node parent]
(when (and (= :table (type node)) (not (fennel.sym? node)))
(when (= :fn (tostring (. node 1)))
(table.insert results node))
true))
(let [(ok? parsed) (read)]
(when ok?
(if (= :table (type parsed))
(walk-tree parsed (partial walk-node results))
results)
(find-functions read results))))
(fn find-max-line [max-line idx node parent]
(when (and (= :table (type node))
(= :number (type node.line))
(< (. max-line 1) node.line))
(tset max-line 1 node.line))
(and (= :table (type node)) (not (fennel.sym? node))))
(fn find-lengths [filename]
(with-open [f (assert (io.open filename :r))]
(let [contents (assert (f:read :*all))
read (fennel.parser (fennel.string-stream contents))
results {}]
(find-functions read results)
(each [_ f (ipairs results)]
(let [first-line (. f 1 :line)
second (. f 2)
max-line [first-line]
name (if (fennel.sym? second)
(tostring second)
"#<anonymous>")]
;; TODO: subtract docstrings
(walk-tree f (partial find-max-line max-line))
(print name (- (. max-line 1) first-line -1)))))))
(match arg
[filename] (find-lengths filename)
_ (print "Usage: function-length.fnl FILENAME"))