Create a gist now

Instantly share code, notes, and snippets.

anonymous /js2py.py
Created Jul 14, 2010

import os, sys
PREAMBLE = '''# Preamble
import sys
def Array(n):
return [0]*n
# Body
'''
POSTAMBLE = ""
class Data:
def __init__(self, text):
if type(text) is not str:
print "Bad, bad", text
assert False
self.text = text
def indent(self):
return '\n'.join(map(lambda line: (' ' + line), self.text.split('\n')))
def getdepth(line):
return (len(line) - len(line.lstrip()))/2
## head - our head line
## clines - list of groups of lines of children. Each has a head line at front
def process(head, clines, indent, **kwargs):
# print "Head:", head
def datify(text=None):
cdatas = map(parse, clines)
ret = Data(('\n'.join(filter(lambda line: line.strip() != '', map(lambda cdata: cdata.text, cdatas)))) if text is None else text)
ret.cdatas = cdatas
return ret
def textify():
return datify().indent()
def untoken(line):
token = line.lstrip()
if token[:3] == 'TOK':
token = token[4:]
return token.split(':')[0]
def get(label):
ret = []
for lines in clines:
head_ = lines[0]
if untoken(head_) == label:
ret.append(': '.join(head_.split(': ')[1:]))
return ret
def pullprop(ret, prop):
# print "Pull", prop
found = False
for cdata in ret.cdatas:
if hasattr(cdata, prop):
# print "foundz it"
setattr(ret, prop, getattr(cdata, prop))
found = True
break
return found
token = untoken(head)
# print " "*indent, indent, token # XXX
if token in 'LC SEMI'.split(' '):
# print "Zzzzz", head
data = datify()
# print head, "childrens:", data.cdatas.__len__()
# for i in range(len(data.cdatas)):
# print i, data.cdatas[i].text
# print "Adn full is", data.text, "chz"
return data
elif token == 'UPVARS':
ret = datify()
# print "upvars:", ret.cdatas
pullprop(ret, 'args')
# print "ok?"
return ret
elif token in 'name upvar'.split(' '):
return Data('')
elif token == 'FUNCTION':
name = get('name')[0]
data = datify()
pullprop(data, 'args')
# print "Nameze:", name, data.args
return Data('def %s(%s):\n%s' % (name, ', '.join(data.args), data.indent()))
elif token == 'NAME':
name = get('name')[0]
# print "Name here:", head, name
ret = datify(name)
ret.name = name
# print "Needs equals"
pullprop(ret, 'equals')
# print "got it"
return ret
elif token == 'equals':
ret = datify()
ret.equals = ret.text
return ret
elif token == 'ARGSBODY': # Several NAME, then LC
# print "argsbody 1"#, clines
args = []
while True:
# print "argsbody 2"
if untoken(clines[0][0]) == 'NAME':
args += parse(clines[0]).text
else:
break
clines = clines[1:]
# print "argsbody 3", args
ret = datify()
# print "argsbody 4"
ret.args = args
# print "argsbody args:", ret.args
return ret
elif token == 'VAR':
data = datify()
if not pullprop(data, 'name'):
return data # We have a child, e.g. assign, which is all we are
pullprop(data, 'equals')
if not hasattr(data, 'equals'): return Data('')
return Data('%s = %s' % (data.name, data.equals))
elif token == 'LP': # left paren - perhaps function call
data = datify()
if len(data.cdatas) == 1:
return data
data.name = data.cdatas[0].name
data.args = []
for i in range(1, len(data.cdatas)):
data.args.append(data.cdatas[i].text)
if data.name == 'parseInt': data.name = 'int'
elif data.name == 'print':
return Data('print %s' % (', '.join(data.args)))
return Data('%s(%s)' % (data.name, ', '.join(data.args)))
elif token in 'MINUS PLUS'.split(' '):
op = {
'MINUS': '-',
'PLUS': '+',
}
data = datify()
return Data('(%s)' % ((' ' + op[token] + ' ').join(map(lambda cdata: cdata.text, data.cdatas))))
elif token in 'INC DEC'.split(' '):
op = {
'INC': '+=',
'DEC': '-=',
}
data = datify()
return Data('%s %s 1' % (data.cdatas[0].text, op[token]))
elif token in 'OR AND'.split(' '):
op = {
'OR': 'or',
'AND': 'and',
}
data = datify()
return Data('(%s %s %s)' % (data.cdatas[0].text, op[token], data.cdatas[1].text))
elif token in 'RELOP EQOP SHOP'.split(' '):
data = datify()
return Data('(%s %s %s)' % (data.cdatas[0].text, get('op')[0], data.cdatas[2].text))
elif token in 'UNARYOP'.split(' '):
op = {
'!': 'not',
}
data = datify()
return Data('(%s %s)' % (op[get('op')[0]], data.cdatas[1].text))
elif token == 'ASSIGN':
data = datify()
# print "assign:", data.cdatas[2].text
return Data('%s %s %s' % (data.cdatas[0].text, get('op')[0], data.cdatas[2].text))
elif token == 'LB': # left bracket - indexing op
data = datify()
subject = data.cdatas[0].text
if subject == 'arguments': subject = 'sys.argv[1:]'
return Data('%s[%s]' % (subject, data.cdatas[1].text))
elif token == 'NUMBER':
def prettify(num):
if int(eval(num)) == float(num):
return str(int(eval(num)))
else:
return num
return Data(prettify(get('value')[0]))
elif token == 'STRING':
return Data('"%s"' % get('string')[0])
elif token == 'PRIMARY':
val = get('primary')[0].split(' ')[1]
def conv(v):
if v == 'true': return 'True'
else: return v
return Data(conv(val))
elif token == 'DOT':
func = get('dotted')[0]
subject = datify().cdatas[0].text
if func == 'toString':
return Data('str(%s)' % subject)
return Data('(%s).%s()' % (subject, func))
elif token == 'FORHEAD':
data = datify()
data.init = data.cdatas[0]
data.condition = data.cdatas[1]
data.inc = data.cdatas[2]
# print "forhead:", data.init.text, "(((", data.condition.text, ')))', data.inc.text
return data
elif token == 'FOR':
data = datify()
forhead = data.cdatas[0]
semi = data.cdatas[1]
return Data(
'''%s
while %s:
%s
%s''' % (forhead.init.text, forhead.condition.indent(), semi.indent(), forhead.inc.indent()))
elif token == 'WHILE':
data = datify()
return Data(
'''while %s:
%s''' % (data.cdatas[0].text, data.cdatas[1].indent()))
elif token == 'IF':
data = datify()
data = Data(
'''if %s:
%s''' % (data.cdatas[0].text, data.cdatas[1].indent()))
# print "I am now:", data.text, "."
return data
elif token == 'RETURN':
return Data('return %s' % datify().cdatas[0].text)
elif token == 'BREAK':
return Data('break')
else:
return Data(token)
def parse(lines):
if len(lines) == 0: return None
head = lines[0]
depth = getdepth(head)
token = head.split(':')[0]
# print "Token:", " "*depth, token, lines
children = []
for i in range(1, len(lines)):
if getdepth(lines[i]) == depth+1:
children.append(i)
children.append(-1) # So last child has all the rest
# print "children:", children
clines = []
for i in range(len(children)-1):
# print "child:", lines, children[i], children[i+1], len(lines)
if children[i+1] != -1:
clines.append(lines[children[i]:children[i+1]])
else:
clines.append(lines[children[i]:])
# print clines[-1]
return process(head.lstrip(), clines, depth)
input_filename = sys.argv[1]
#output_filename = sys.argv[2]
generated = PREAMBLE + parse(map(lambda line: line.rstrip(), filter(lambda line: line[0:2] != '//', open(input_filename, 'r').readlines()))).text + POSTAMBLE
print generated
#f = open(output_filename, 'w')
#f.write(generated + '\n\n')
#f.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment