def js_inline(js): global inline_count inline_count = 0 result = o(jsparser.parse(js)) print "inlined %d function calls" % inline_count print "avoided allocating %d new vectors" % allocations_avoided return result
def __init__(self, filepath): self.filepath = filepath #List of functions by line # and set of names self.functions = defaultdict(set) with open(filepath) as myFile: self.source = myFile.read() self.root = jsparser.parse(self.source, self.filepath) self.visit(self.root)
def build(self, item): # Needs to be a JSParser tree. if type(item) == str: item = jsparser.parse(item) # Get the handler (eg: blocks._bitwise_and) kind = "_%s" % item.type.lower() fn = getattr(self, kind) if hasattr(self, kind) else self._other return fn(item)
def main(argv): try: filename = argv[1] source = file(filename, "r").read() except: print "Usage: %s <source.js>" % argv[0] print str(js.parse(source, filename)) return 0
def __init__(self, inputtext, librarytext, library): self.inputoffset = 0 self.output = [] self.inputtext = inputtext script = jsparser.parse(inputtext) self.librarytext = librarytext self.library = library self.crawlingSwitchDefault = False self.preput = '' self.walkbranch(script)
def __init__(self, filepath): self.filepath = filepath self.functions_list = [] #List of functions by line # and set of names self.functions = defaultdict(set) with open(filepath) as myFile: self.source = myFile.read() try: self.root = jsparser.parse(self.source, self.filepath) self.visit(self.root) except SyntaxError_: print("Syntax error in %s" % filepath)
def main(argv): try: testfiles = [argv[1]] except: testfiles = [os.path.join("source", x) for x in os.listdir("source") if x[-3:] == ".js"] for testfile in testfiles: try: sexp.convert(js.parse(file(testfile, 'r').read())) except Exception, e: print "Failure in converting %s to s-expressions\n%s" % (testfile, e) return 1 sys.stdout.write(".") sys.stdout.flush()
def main(argv): try: testfiles = [argv[1]] except: testfiles = [ os.path.join("source", x) for x in os.listdir("source") if x[-3:] == ".js" ] for testfile in testfiles: try: sexp.convert(js.parse(file(testfile, 'r').read())) except Exception, e: print "Failure in converting %s to s-expressions\n%s" % (testfile, e) return 1 sys.stdout.write(".") sys.stdout.flush()
def main(): import sys from runtime import Runtime file = sys.argv[1] code = open(file).read() asm = Program() runtime = Runtime() context = Context(Context.GLOBAL) compiler = Compiler(asm, runtime, context) ast = parse(code) fptr = compiler.compile(ast) import time start = time.clock() fptr() print time.clock() - start
def main(): with open(jsfile) as js: sys.stdout.write("File: {}\n".format(jsfile)) try: tree = flatten(sparse(sexp.convert(jsparser.parse(js.read())))) x = copy([i for i in clean(tree) if i in ops]) y = str(x) z = {i: y.count(i) for i in sorted(set(x))} data = [z[i] for i in sorted(z)] sys.stdout.write("Success:{}\n".format(z)) except jsparser.SyntaxError_: sys.stderr.write( "Failure {}: SyntaxError_ thrown by jsparser \n".format( jsfile)) sys.exit(1) sys.exit(0)
def main(): with open(jsfile) as js: sys.stdout.write("File: {}\n".format(jsfile)) try: tree = flatten( sparse( sexp.convert( jsparser.parse( js.read())))) x = copy([i for i in clean(tree) if i in ops]) y = str(x) z = {i:y.count(i) for i in sorted(set(x))} data = [z[i] for i in sorted(z)] sys.stdout.write("Success:{}\n".format(z)) except jsparser.SyntaxError_: sys.stderr.write("Failure {}: SyntaxError_ thrown by jsparser \n".format(jsfile)) sys.exit(1) sys.exit(0)
def parse(source): """Parses javascript and translates it into our object model.""" return _parse(jsparser.parse(source))
# print 'x', node if not self.clean: self.bytecode.append(("POP_STACK", None)) if self.main: self.bytecode.append(("END", None)) return self.bytecode to_bytecode = lambda xs: BytecodeGenerator()(xs) if __name__ == "__main__": from pprint import pprint with open("example.js") as fobj: instructions = parse(fobj.read()) bcg = BytecodeGenerator(True) bytecode = bcg(instructions) # pprint(bytecode) from interpreter import Interpreter ip = Interpreter() ip.execute(bytecode) # print 'locals', ip.namespace.locals
def js_to_ast(source): parsetree = jsparser.parse(source) tree = transform(parsetree) return tree
def inlineSingle(inputtext, librarytext): window = JSObject() window['window'] = window env = JSEnvironment(window, window) # window is root and this library = jsparser.parse(librarytext) functions = _crawlFunctions(env, library) class Crawler(): CHILD_ATTRS = ['thenPart', 'elsePart', 'expression', 'body', 'initializer'] def __init__(self, inputtext, librarytext, library): self.inputoffset = 0 self.output = [] self.inputtext = inputtext script = jsparser.parse(inputtext) self.librarytext = librarytext self.library = library self.crawlingSwitchDefault = False self.preput = '' self.walkbranch(script) def parsefunctiontypes(self, string): """ Given a string such as variable/*:type*/, othervar /* :mytype */, return a dictionary like {variable:'type', othervar:'mytype'} """ ret = {} params = string.split(',') for param in params: match = re.match(r'([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\/\*\s*:\s*([a-zA-Z_$][a-zA-Z0-9_$.]*)\s*\*\/', param) if match is None: continue groups = match.groups() ret[groups[0]] = groups[1] return ret def walkbranch(self, branch): #import pdb; pdb.set_trace() if not getattr(branch, 'end', None): branch.end = len(inputtext) if len(branch): for statement in branch: self.walkstatement(statement) else: self.walkstatement(branch) self.output.append(self.inputtext[self.inputoffset:branch.end]) self.inputoffset=branch.end def walkstatement(self, statement): #print("Looking at statement "+str(statement)) self.statementCalls = [] if statement.type == "VAR": # create a new variable child = getattr(statement[0], 'initializer', None) if child: name = _crawlIdentifier(statement[0], 'value') self.callcount = 0 self.preput = '' self.output.append(self.inputtext[self.inputoffset:statement.start]) self.inputoffset = statement.start index = len(self.output) self.walkexpression(child, name, True) if len(self.preput)>0: self.output.insert(index, self.preput) elif statement.type == 'SEMICOLON': child = getattr(statement, 'expression', None) if child: if statement.expression.type=='ASSIGN': name = _crawlIdentifier(statement.expression[0], 'value') else: name = statement.value self.callcount = 0 self.preput = '' self.output.append(self.inputtext[self.inputoffset:statement.start]) self.inputoffset=statement.start index = len(self.output) self.walkexpression(child, name, True if statement.expression.type=='ASSIGN' else False) if len(self.preput)>0: self.output.insert(index, self.preput) return elif statement.type == 'CALL': self.replacefunction(statement, statement[0].value) return elif statement.type == 'FOR': worked = self.unloopFor(statement) if not worked: self.walkbranch(statement.body) return elif statement.type == 'SWITCH': for case in statement.cases: if statement.defaultIndex>=0 and case == statement.cases[statement.defaultIndex]: self.crawlingSwitchDefault = True self.walkbranch(case.statements) self.crawlingSwitchDefault = False #else: #print("Unknown type of statement: "+str(statement)) for attr in Crawler.CHILD_ATTRS: child = getattr(statement, attr, None) if child and isinstance(child, jsparser.Node): self.walkbranch(child) def walkexpression(self, expression, name, usesReturn): #import pdb; pdb.set_trace() if expression.type=='CALL': retname = 'ret' + name.translate(None, transdel) + str(self.callcount) if not usesReturn: retname = None self.replacecall(expression, retname, usesReturn) self.callcount+=1 return elif expression.type=='ASSIGN' and expression[1].type=='FUNCTION': # defining a new function and assigning it to a variable # set up the environment inside the function parent = '.'.join(name.split('.')[0:-1]) parentobj = env.get(parent) env.pushThis(parentobj) env.pushScope() # handle any defined variables signature = self.inputtext[self.inputtext.find('(',expression[1].start)+1 : self.inputtext.find(')',expression[1].start)] params = self.parsefunctiontypes(signature) for param in params.keys(): fromname = params[param] + ".prototype" env.createLocal(param) env.set(param, JSObject(None, env.get(fromname))) # walk the function self.walkbranch(expression[1].body) env.popScope() env.popThis() return for piece in expression: # for each part of a line if piece.type=='CALL': retname = 'ret' + name.translate(None, transdel) + str(self.callcount) if not usesReturn: retname = None self.replacecall(piece, retname, usesReturn) self.callcount+=1 elif len(piece): self.walkexpression(piece, name, usesReturn) def replacecall(self, call, retname, usesReturn): #import pdb; pdb.set_trace() if call[0].type=='INDEX' or \ (call[0].type=='DOT' and call[0][0].type=='INDEX'): self.replacecallswitch(call, retname, usesReturn) return if call[0].type=='DOT' and call[0][-1].value=='call': funname = _crawlIdentifier(call[0], 'value') function = env.get(funname[:-5]) else: funname = _crawlIdentifier(call[0], 'value') function = env.get(funname) if function == None or function.getFunction() == None: return replacements={} arguments = ['"'+node.value+'"' if node.type=='STRING' else _crawlIdentifier(node, 'value') for node in call[1]] if call[0].type=='DOT' and call[0][-1].value=='call': replacements['this'] = arguments.pop(0) else: if len(funname.split('.'))>1: replacements['this'] = '.'.join(funname.split('.')[0:-1]) funparams = function.getFunction().params for i in range(0, len(funparams)): if i < len(arguments): replacements[funparams[i]] = arguments[i] else: replacements[funparams[i]] = 'undefined' functionout = replaceIdentifiers(self.librarytext, function.getFunction().body, replacements, retname, False) if functionout.needsRetVal: self.preput+=functionout.getOutput() self.output.append(self.inputtext[self.inputoffset:call.start]) self.output.append(functionout.retval) self.inputoffset = call.end else: if usesReturn: self.output.append(self.inputtext[self.inputoffset:call.start]+"(") self.output.append(functionout.getOutput()+")") else: self.output.append(self.inputtext[self.inputoffset:call.start]) self.output.append(functionout.getOutput()) self.inputoffset = call.end def replacecallswitch(self, call, retname, usesReturn): #import pdb; pdb.set_trace() curlayout = {} level = call[0] while True: if level.type=='INDEX': # ^object^[selector] curlayout['objectname'] = _crawlIdentifier(level[0], 'value') curlayout['keyvar'] = _crawlIdentifier(level[1], 'value') if level[0].type=='DOT': # ^object^.something[selector] level=level[0] elif level[0].type=='INDEX': curlayout = {'deeper': curlayout} level=level[0] else: break elif level.type=='DOT': if level[0].type=='INDEX': curlayout = {'deeper': curlayout, 'after': _crawlIdentifier(level[1], 'value')} level=level[0] else: break else: break origcall = self.inputtext[call.start:call.end] if self.crawlingSwitchDefault: return needsRetVal = [False] switchoutput=[] def generateswitch(layout): object = env.get(layout['objectname']) if object == None: raise NotImplementedError() if not len(object.keys()): raise NotImplementedError() origarguments = [] switchoutput.append("switch (%s) {\n"%layout['keyvar']) for key in object.keys(): switchoutput.append(' case "%s":\n'%key) try: if str(int(key)) == key: switchoutput.append(' case %s:\n'%key) except: pass if object[key].getFunction()!=None: replacements={} function=object[key].getFunction() origarguments = [_crawlIdentifier(node, 'value') for node in call[1]] arguments=origarguments[:] if call[0].type=='DOT' and call[0][0].type=='INDEX' and call[0][1].value=='call': replacements['this'] = arguments.pop(0) else: replacements['this'] = layout['objectname'] for i in range(0, len(arguments)): replacements[function.params[i]] = arguments[i] functionout = replaceIdentifiers(self.librarytext, function.body, replacements, retname, True) needsRetVal[0] = needsRetVal[0] or functionout.needsRetVal switchoutput.append(functionout.getOutput()) # If the function doesn't have a retval, add ending bits if not needsRetVal[0]: switchoutput.append(';\n') elif 'deeper' in layout and layout['deeper']: layout['deeper']['objectname']=layout['objectname'] + '.' + key if 'after' in layout and layout['after']: layout['deeper']['objectname'] += '.' + layout['after'] generateswitch(layout['deeper']) switchoutput.append('\tbreak;\n') switchoutput.append(" default:\n %s;\n}"%origcall) try: generateswitch(curlayout) except NotImplementedError: # could not handle it return if needsRetVal[0]: self.preput+=''.join(switchoutput)+"\n" self.output.append(self.inputtext[self.inputoffset:call.start]) self.output.append(retname) self.inputoffset = call.end else: if not usesReturn: self.output.append(self.inputtext[self.inputoffset:call.start]) self.output.append(''.join(switchoutput)) else: # Should never happen print("Impossible") self.inputoffset = call.end # Ignore any semicolons after non-return switches self.inputoffset+=1 if self.inputoffset<len(self.inputtext) and (self.inputtext[self.inputoffset]==';' or self.inputtext[self.inputoffset]==' '): self.inputoffset+=1 def unloopFor(self, loop): variable=None # variable to replace start=None # starting value cur=None # current value step=None # how much to add/subtract on each loop stop=None # function saying whether to stop maxiterations = 60 # how many times we will allow to unroll # parse the initialization setup = loop.setup if setup.type=='VAR': if setup[0].type=='IDENTIFIER' and \ setup[0].initializer.type=='NUMBER': variable = setup[0].value start = setup[0].initializer.value # parse the update update = loop.update if update.type=='INCREMENT': # i++ step=1 elif update.type=='DECREMENT': # i-- step=-1 elif update.type=='ASSIGN': # more complex update # i+=1 if update[0].type=='IDENTIFIER' and \ update[0].value==variable and \ update[1].type=='NUMBER': if update.value=='+': step=0+update[1].value elif update.value=='-': step=0-update[1].value # i=x+x if update[0].type=='IDENTIFIER' and \ update[0].value==variable and \ update[1].type=='PLUS': # i=i+1 if update[1][0].value==variable and \ update[1][1].type=='NUMBER': step=0+update[1][1].value # i=1+i if update[1][1].value==variable and \ update[1][0].type=='NUMBER': step=0+update[1][0].value # i=x-x if update[0].type=='IDENTIFIER' and \ update[0].value==variable and \ update[1].type=='MINUS': # i=i-1 if update[1][0].value==variable and \ update[1][1].type=='NUMBER': step=0-update[1][1].value # parse the ending criteria condition = loop.condition if condition.type in ['LT', 'LE', 'GT', 'GE'] and condition[0].type=='IDENTIFIER' and condition[0].value==variable: if condition.type=='LT' and step>0: stop=lambda i: i >= condition[1].value elif condition.type=='LE' and step>0: stop=lambda i: i > condition[1].value elif condition.type=='GT' and step<0: stop=lambda i: i <= condition[1].value elif condition.type=='GE' and step<0: stop=lambda i: i < condition[1].value # check that we parsed everything validly if start is None or step is None or stop is None: # could not parse something return False # how many iterations in the loop iterations = 0 cur = start while iterations < maxiterations and \ not stop(cur): iterations+=1 cur += step if iterations >= maxiterations: # too many loop unwinds return False # Do the unwinding iterations = 0 cur = start self.output.append(self.inputtext[self.inputoffset:loop.start]) self.inputoffset = loop.body.end while not stop(cur): bodyout = replaceIdentifiers(self.inputtext, loop.body, {variable:cur}, None, False) self.output.append(bodyout.getOutput()) cur += step if len(loop.body): self.output.append(self.inputtext[loop.body[len(loop.body)-1].end:loop.end-1]) if not stop(cur): self.output.append('\n') return True def getOutput(self): return ''.join(self.output) crawler = Crawler(inputtext, librarytext, library) return crawler.getOutput()
"%s" % (len(subnodes_), len(n), n.type)) def convert(parsetree, include_props=False): """Takes a PyNarcissus parse tree and returns a string of S-expressions Args: parsetree: the PyNarcissus parse tree include_props: if true, the s-expressions have additional information included via @ attribute expressions, such as line-number. Returns: string Raises: UnknownNode: if a node hasn't been properly accounted for in the conversion ProgrammerError: if the conversion routine wasn't written with the best understanding of the parse tree OtherError: if some other error happened we didn't understand. """ return o(parsetree, "", {"include_props": include_props}) + "\n" if __name__ == "__main__": try: include_props = (sys.argv[1] == "--props") except: include_props = False sys.stdout.write(convert(js.parse(sys.stdin.read()), include_props))
if len(subnodes_) != len(n): raise ProgrammerError, ("%d subnodes out of %d checked on node " "%s" % (len(subnodes_), len(n), n.type)) def convert(parsetree, include_props=False): """Takes a PyNarcissus parse tree and returns a string of S-expressions Args: parsetree: the PyNarcissus parse tree include_props: if true, the s-expressions have additional information included via @ attribute expressions, such as line-number. Returns: string Raises: UnknownNode: if a node hasn't been properly accounted for in the conversion ProgrammerError: if the conversion routine wasn't written with the best understanding of the parse tree OtherError: if some other error happened we didn't understand. """ return o(parsetree, "", {"include_props": include_props}) + "\n" if __name__ == "__main__": try: include_props = (sys.argv[1] == "--props") except: include_props = False sys.stdout.write(convert(js.parse(sys.stdin.read()), include_props))