def patternMatching(): global _functions global _args global _pattern_functions for func in _functions: if len(_functions[func]) == 1: _functions[func] = _functions[func][func] _args[func] = _args[func][func] else: _pattern_functions[func] = True tree = _functions[func][func] argsList = _args[func][func] for patternKey in _functions[func]: if patternKey != func: argsValues = _args[func][patternKey] eqs = [] for (arg, value) in zip(argsList, argsValues): if arg != value: eqs += [ ast.Binop(ast.Identifier(arg), "==", value) ] cond = eqs[0] for i in range(1, len(eqs)): cond = ast.Binop(cond, "and", eqs[i]) tree = ast.Conditional(cond, _functions[func][patternKey], tree) _functions[func] = tree _args[func] = argsList
def p_conditional_else_expr(p): ''' conditional_else_expr : logical_or_expr TERNARY conditional_expr ELSE conditional_expr ''' if DEBUG: print("\nConditional Else: ", end="") # Note: doesn't have "ELSE" #p[0] = ("?", p[1], p[3],p[5]) #### NEED TO FIX p[0] = ast.Conditional(p[1], p[3], p[5])
def p_conditional_expr(p): ''' conditional_expr : logical_or_expr | conditional_else_expr ''' if DEBUG: print("\ncond expr: ", end="") for i in range(len(p)): print(i, " ", p[i], " ", end="") p[0] = ast.Conditional(p[1], None, None)
def parse_conditional(self): #Check for IF token self.step() cond = self.parse_expr() cons = self.parse_block() alt = None if isinstance(self.current, tokens.ELSE): self.step() alt = self.parse_block() return ast.Conditional(cond, cons, alt)
def p_conditional_expr_nobf(self, p): """ conditional_expr_nobf \ : logical_or_expr_nobf | logical_or_expr_nobf CONDOP assignment_expr COLON assignment_expr """ if len(p) == 2: p[0] = p[1] else: p[0] = ast.Conditional(predicate=p[1], consequent=p[3], alternative=p[5])
def optimizeConditional(C): # This one can handle further optimization for # if c: x = bar (foo (1)) # else: x = bar (foo (2)) # which is converted to # x = bar (foo (c ? 1 : 2)) # if expr_eq_base(C.expr1, C.expr2): CC = ast.Conditional(C.cond, stmts_get_diff(C.expr1), stmts_get_diff(C.expr2)) optimizeConditional(CC) make_copy(C, stmts_get_base(C.expr1)(CC))
def visitIf(self, node): # eliminate if-const # removables = [] trueconst = None visit = self.visit for test, body in node.tests: mark_targeted(test) visit(test) visit(body) if test.isconst: if not test.value: removables.append((test, body)) elif not trueconst: trueconst = test, body elif bool_final_not(test): # # convert "if a and not b --> if not (not a or b)" # we have a difficulty removing the UNARY_NOT in the first case... # make_copy( test, ast.Not((isinstance(test, ast.And) and ast.Or or ast.And)([neg_AST(i) for i in test.nodes]))) if node.else_: visit(node.else_) for i in removables: node.tests.remove(i) if not node.tests: if node.else_: make_copy(node, node.else_) else: make_copy(node, ast.Pass(node.lineno)) elif trueconst: if trueconst == node.tests[0]: make_copy(node, trueconst[1]) else: node.else_ = trueconst[1] node.tests = node.tests[:node.tests.index(trueconst)] if not isinstance(node, ast.If): return node.fallthrough = False if node.else_: for test, stmt in node.tests: if not stmts_eq_base(stmt, node.else_): break else: ## print '*', repr (node) basenode = stmts_get_base(node.else_.nodes[0]) N = stmts_get_diff(node.else_.nodes[0]) for test, stmt in reversed(node.tests): N = ast.Conditional(test, stmts_get_diff(stmt.nodes[0]), N) optimizeConditional(N) basenode = basenode(N) make_copy(node, basenode) ## print '*>>', repr (node) opt_progress(':?:') else: # fallthrough means that the end of the if block must not JUMP_FORWARD # past the POP_TOP. if isinstance(node.tests[-1][1].nodes[-1], ast.Discard): node.fallthrough = True opt_progress('fth') node.tests[-1][1].nodes[-1] = node.tests[-1][1].nodes[-1].expr
def p_expression_ifelse(t): '''expression : IF expression THEN expression ELSE expression %prec IFELSE''' t[0] = ast.Conditional(t[2], t[4], t[6])