#!/usr/bin/env python
""" depth.py - Calculate nesting depth of a JavaScript program
This finds the most-nested point in the file and prints the starting
line of each block that contains it, then prints the filename and
the nesting depth.
(This is useful in debugging the `reduce-depth` function in the
compiler, scm/compiler/transform.scm. That function is necessary
because JavaScript has a hard limit of something like 100 levels
of nesting.)
"""
import re
class Tokens:
ws_re = re.compile(r'\s*')
token_re = re.compile(r'''(?x)
[a-zA-Z0-9_]+
| "(?:[^\\"]|\\.)*"
| .
''')
def __init__(self, filename):
self.filename = filename
def skipws(self, text, i):
m = Tokens.ws_re.match(text, i)
return m.end()
def __iter__(self):
f = open(self.filename, 'r')
lineno = 0
for line in f:
lineno += 1
self.line = (lineno, line)
i = 0
while True:
i = self.skipws(line, i)
if i >= len(line):
break
m = Tokens.token_re.match(line, i)
if m is None:
raise Exception("Match not found at %d in %r" % (i, line))
yield m.group(0)
i = m.end()
self.line = None
f.close()
def depth(file):
startLines = []
longest = []
tokens = Tokens(file)
for f in tokens:
if f == '{':
startLines.append(tokens.line)
if len(startLines) > len(longest):
longest = list(startLines)
elif f == '}':
startLines.pop()
return longest
if __name__ == '__main__':
import sys
if len(sys.argv) < 2:
print "usage: depth.py <file>.js"
else:
for filename in sys.argv[1:]:
longest = depth(filename)
for lineno, line in longest:
print "%5d: %s" % (lineno, line.rstrip('\r\n'))
print "%s: %d" % (filename, len(longest))