def p_functiondef_jsinline(p): # tbd: it would be *great* if i could specify that only "statement"s within # this context could include the "returnStatement"... 'functiondef : FUNCTION SYMBOL LPAREN paramList RPAREN LBRACE STRING STOP statements RBRACE' if p[7] == "inline": p[0] = node.FunctionDefinition(p[2], p[4], node.Block(p[9]), inline=True) else: block = node.Block(p[7]).append(p[9]) p[0] = node.FunctionDefinition(p[2], p[4], block)
def p_statements_multi(p): 'statements : statements cstatement' if not isinstance(p[1], node.Block): p[0] = node.Block(p[1]) else: p[0] = p[1] p[0].append(p[2])
def p_for_loop(p): '''statement : FOR LPAREN assign testExpression STOP assign RPAREN statement ''' initAssign = p[3] testExpression = p[4] statementBlock = node.Block(node.If(node.Not(testExpression), node.Break())) statementBlock.statements.append(p[8]) statementBlock.statements.append(p[6]) p[0] = node.Block(initAssign) p[0].statements.append( node.Assign( '_loop', node.List(node.Range(initAssign.value, testExpression.args[1])))) p[0].statements.append(node.ForEach(node.Variable('_loop'), statementBlock))
def p_vars_mixed(p): 'vars : sVARS xEND statements cVARS' if p[3] is not None: p[0] = node.Block( node.Output('<esi:vars>', raw=True), p[3], node.Output('</esi:vars>', raw=True), )
def p_functioncall(p): 'functioncall : SYMBOL LPAREN expressionList RPAREN' if not re.match('^print(raw|v)?$', p[1]): #TODO: check that we are in a function block. Otherwise we will need to wrap in `<esi:vars>`. p[0] = node.FunctionCall(p[1], *p[3]) return p[0] = node.Output(*p[3], raw=(p[1] == 'printraw')) if p[1].startswith('printv'): p[0] = node.Block(node.Output('<esi:vars>', raw=True), p[0], node.Output('</esi:vars>', raw=True))
def p_declarations(p): '''declarations : declaration | declarations declaration ''' if not isinstance(p[1], node.Block): p[0] = node.Block(p[1]) else: p[0] = p[1] if len(p) > 2: p[0].append(p[2])
def p_nvStatements(p): '''nvStatements : nvStatement | nvStatements nvStatement ''' if not isinstance(p[1], node.Block): p[0] = node.Block(p[1]) else: p[0] = p[1] if len(p) > 2: p[0].append(p[2])
def resolveImports(context, tree): frompath = context.filename for imp in node.util.allchildren(tree): if not isinstance(imp, node.Import): continue if imp.inline is not None: continue if context.options.verbose: context.errfp.write('[ ] resolving import of "%s" from "%s"...\n' % (imp.src, frompath)) fp = None for lib in context.lib + [os.path.dirname(frompath)]: path = os.path.abspath(os.path.join(lib, imp.src)) try: fp = io.open(path, 'r') except Exception as e: if context.options.verbose >= 3: if hasattr(e, 'errno') and e.errno == errno.ENOENT: context.errfp.write('[ ] tried "%s" and failed: file not found\n' % (path,)) else: context.errfp.write('[ ] tried "%s" and failed: %s\n' % (path, e)) fp = None continue break if fp is None: context.errfp.write('[**] ERROR: could not find import "%s"\n' % (imp.src,)) raise CompilationErrors(1) realpath = os.path.realpath(path) if not imp.force and realpath in context.imports: if context.options.verbose >= 2: context.errfp.write('[ ] skipping import of "%s" (already imported)\n' % (path,)) # tbd: *HACKALERT*... this is really just letting the "la imp.inline = node.Block() continue if context.options.verbose: context.errfp.write('[ ] importing "%s"...\n' % (path,)) context.filename = path subtree = js2node(context, fp) fp.close() context.imports.append(realpath) resolveImports(context, subtree) imp.inline = subtree
def p_statements_mt(p): 'statements : empty' p[0] = node.Block(p[1])
def p_factor_varref_ternary(p): 'factor : testExpression QUESTION expression COLON expression' iftrue = node.Block(node.Variable(p[1], default=p[4])) iffalse = node.Block(node.Variable(p[1], default=p[5])) p[0] = node.If(p[1], iftrue, noMatchStatement=iffalse)
def p_functiondef_inline(p): # tbd: it would be *great* if i could specify that only "statement"s within # this context could include the "returnStatement"... 'functiondef : FUNCTION SYMBOL LPAREN paramList RPAREN LBRACE INLINE statements RBRACE' p[0] = node.FunctionDefinition(p[2], p[4], node.Block(p[7]), inline=True)
def p_statement_block(p): 'statement : LBRACE statements RBRACE' p[0] = node.Block(p[2])