def _if_gt(value): if value >= 0: comparators = [Constant(value=value, kind=None)] else: comparators = [ UnaryOp( op=USub(), operand=Constant(value=abs(value), kind=None), ), ] return [ If( test=Compare( left=Call( func=Name(id='int', ctx=Load()), args=[Name(id='value', ctx=Load())], keywords=[], ), ops=[Gt()], comparators=comparators, ), body=[ Return(value=Constant(value=False, kind=None), ), ], orelse=[], ) ]
def _if_pattern(self, pattern): self.imported.add('re') # fix known ietf regex use pattern = pattern.replace('\\p{N}\\p{L}', '\\w') return [ If( test=UnaryOp( op=Not(), operand=Call( func=Attribute( value=Name(id='re', ctx=Load()), attr='match', ctx=Load(), ), args=[ Constant(value=pattern, kind=None), Name(id='value', ctx=Load()), Attribute( value=Name(id='re', ctx=Load()), attr='UNICODE', ctx=Load(), ), ], keywords=[], ), ), body=[ Return(value=Constant(value=False, kind=None), ), ], orelse=[], ), ]
def compile_choosenode(self, srcnode, parent): if srcnode.test is None or srcnode.test.strip() == '': srcnode.test = 'True' choosevar = self.unique_id('choose') chooseflag = self.unique_id('chosen') parent.body.append(self.annotate_runtime_errors( parse_and_strip(u'{} = False\n' u'{} = {}\n'.format(chooseflag, choosevar, srcnode.test)), srcnode)) for item in srcnode.children: if isinstance(item, im.WhenNode): comparison = get_comparison(u'{} is False and {} == ({})' .format(chooseflag, choosevar, item.test)) if_ = If(test=comparison, body=[], orelse=[]) if_.body.extend( parse_and_strip('{} = True'.format(chooseflag))) set_pos(if_, item) parent.body.append(self.annotate_runtime_errors(if_, srcnode)) for sub in item.children: self._compile(sub, if_) elif isinstance(item, im.OtherwiseNode): comparison = get_comparison('{} is False'.format(chooseflag)) if_ = If(test=comparison, body=[], orelse=[]) set_pos(if_, item) parent.body.append(if_) for sub in item.children: self._compile(sub, if_) if if_.body == []: if_.body = [Pass()] else: self._compile(item, parent)
def compile_ifnode(self, srcnode, parent): comparison = get_comparison('{}'.format(srcnode.test)) if_ = If(test=comparison, body=[], orelse=[]) parent.body.append(self.annotate_runtime_errors(if_, srcnode)) for item in srcnode.children: self._compile(item, if_) if srcnode.else_: m = Module(body=[]) for item in srcnode.else_.children: self._compile(item, m) if_.orelse = m.body if if_.body == []: if_.body = [Pass()]
def parseIfStatement(parser): parser.check(lexeme=keywords['IF']) lineo = parser.currentToken[2] parser.next(lexeme='(') parser.next() predicate = parsePredicate(parser) parser.check(lexeme=')') parser.next() stm = parseStatement(parser) elsestm = "" if parser.matchLexeme(keywords['ELSE']): parser.next() elsestm = parseStatement(parser) ifstm = If(predicate, stm, elsestm, lineo=lineo) return ifstm
def handle_when(self, when, *others): test, body = when.get_source_expressions() if others: if others[0].__class__.__name__ == "When": orelse = [self.handle_when(*others)] else: # Can we ever have other expressions after the default? orelse = [ Return(value=self.build_expression(others[0]), **self.file) ] else: orelse = [] return If( test=self.build_expression(test), body=[Return(value=self.build_expression(body), **self.file)], orelse=orelse, **self.file, )
def _union(self, node): values = [] generated = [] for union in node: for what, sub in union.items(): if ':' in what: if what in generated: # only generate any imported function once continue generated.append(what) name = what yield self._type(what, name, sub) else: # this is a build_in type (and my have been refined) # therefore generate one function per type name = self._unique(what) yield self._function(name, self._type(what, what, sub)) values += [ UnaryOp( op=Not(), operand=Call( func=Name(id=self._python_name(name), ctx=Load()), args=[Name(id='value', ctx=Load())], keywords=[], ), ), ] yield [ If( test=BoolOp( op=And(), values=values, ), body=[ Return(value=Constant(value=False, kind=None), ), ], orelse=[], ), ]
def command(self): """ c ::= skip | x := e | if b then c1 else c2 | while b do c """ if self.current_token.type == '{': self.eat('{') c = self.comma_command() self.eat('}') return c if self.current_token.type == 'skip': self.eat('skip') return Skip() if self.current_token.type == 'if': self.eat('if') b = self.b_or() self.eat('then') c1 = self.comma_command() self.eat('else') c2 = self.comma_command() return If(b, c1, c2) if self.current_token.type == 'while': # print("current token:", self.current_token.type, self.current_token.value) self.eat('while') # print("current token:", self.current_token.type, self.current_token.value) b = self.b_or() # print(b, b.token, b.value) # print("current token:", self.current_token.type, self.current_token.value) self.eat('do') # print("current token:", self.current_token.type, self.current_token.value) c = self.command() # print(c) # print("current token:", self.current_token.type, self.current_token.value) return While(b, c) if self.current_token.type == VAR: x = Var(self.current_token.value) self.eat(VAR) self.eat(':=') e = self.aexp() return Assign(x, e)
def register_binding(withstmt, mode, kind): assert mode in ("block", "expr") assert kind in ("barename", "template") ctxmanager = withstmt.items[0].context_expr optvars = withstmt.items[0].optional_vars if not optvars: assert False, "'with {}:': expected an as-part".format( mode) # pragma: no cover if type(optvars) is not Name: assert False, "'with {}:': expected exactly one name in the as-part".format( mode) # pragma: no cover name = optvars.id if name in names_seen: assert False, "duplicate '{}'; as-parts in the same let_syntax block must be unique".format( name) # pragma: no cover if kind == "template": _, args = _analyze_lhs( ctxmanager ) # syntactic limitation, can't place formal parameter list on the as-part else: # kind == "barename": args = [] if mode == "block": value = If( test=Num(n=1), # TODO: Python 3.8+: ast.Constant, no ast.Num body=withstmt.body, orelse=[], lineno=stmt.lineno, col_offset=stmt.col_offset) else: # mode == "expr": if len(withstmt.body) != 1: assert False, "'with expr:' expected a one-item body (use a do[] if need more)" # pragma: no cover theexpr = withstmt.body[0] if type(theexpr) is not Expr: assert False, "'with expr:' expected an expression body, got a statement" # pragma: no cover value = theexpr.value # discard Expr wrapper in definition names_seen.add(name) target = templates if args else barenames target.append((name, args, value, mode))
def _if_digit(): return [ If( test=UnaryOp( op=Not(), operand=Call( func=Attribute( value=Name(id='value', ctx=Load()), attr='isdigit', ctx=Load(), ), args=[], keywords=[], ), ), body=[ Return(value=Constant(value=False, kind=None), ), ], orelse=[], ) ]
def p_ifelse_statement(self, p): '''if_statement : IF LPAREN logical_expression RPAREN block_statement ELSE block_statement %prec ELSE''' p[0] = If(p[3], p[5], p[7])
def p_if_statement(self, p): '''if_statement : IF LPAREN logical_expression RPAREN block_statement %prec IFX''' p[0] = If(p[3], p[5], None)
def make_continuation(owner, callcc, contbody): targets, starget, condition, thecall, altcall = analyze_callcc(callcc) # no-args special case: allow but ignore one arg so there won't be arity errors # from a "return None"-generated None being passed into the cc # (in Python, a function always has a return value, though it may be None) if not targets and not starget: targets = ["_ignored_arg"] posargdefaults = [q[None]] else: posargdefaults = [] # Name the continuation: f_cont, f_cont1, f_cont2, ... # if multiple call_cc[]s in the same function body. if owner: # TODO: robustness: use regexes, strip suf and any numbers at the end, until no match. # return prefix of s before the first occurrence of suf. def strip_suffix(s, suf): n = s.find(suf) if n == -1: return s return s[:n] basename = "{}_cont".format(strip_suffix(owner.name, "_cont")) else: basename = "cont" contname = gen_sym(basename) # Set our captured continuation as the cc of f and g in # call_cc[f(...)] # call_cc[f(...) if p else g(...)] def prepare_call(tree): if tree: tree.keywords = [keyword(arg="cc", value=q[name[contname]]) ] + tree.keywords else: # no call means proceed to cont directly, with args set to None tree = q[name[contname](*([None] * u[len(targets)]), cc=name["cc"])] return tree thecall = prepare_call(thecall) if condition: altcall = prepare_call(altcall) # Create the continuation function, set contbody as its body. # # Any return statements in the body have already been transformed, # because they appear literally in the code at the use site, # and our main processing logic runs the return statement transformer # before transforming call_cc[]. FDef = type( owner ) if owner else FunctionDef # use same type (regular/async) as parent function locref = callcc # bad but no better source location reference node available non = q[None] non = copy_location(non, locref) maybe_capture = IfExp(test=hq[name["cc"] is not identity], body=q[name["cc"]], orelse=non, lineno=locref.lineno, col_offset=locref.col_offset) funcdef = FDef( name=contname, args=arguments(args=[arg(arg=x) for x in targets], kwonlyargs=[arg(arg="cc"), arg(arg="_pcc")], vararg=(arg(arg=starget) if starget else None), kwarg=None, defaults=posargdefaults, kw_defaults=[hq[identity], maybe_capture]), body=contbody, decorator_list=[], # patched later by transform_def returns=None, # return annotation not used here lineno=locref.lineno, col_offset=locref.col_offset) # in the output stmts, define the continuation function... newstmts = [funcdef] if owner: # ...and tail-call it (if currently inside a def) def jumpify(tree): tree.args = [tree.func] + tree.args tree.func = hq[jump] jumpify(thecall) if condition: jumpify(altcall) newstmts.append( If(test=condition, body=[Return(value=q[ast_literal[thecall]])], orelse=[Return(value=q[ast_literal[altcall]])])) else: newstmts.append(Return(value=q[ast_literal[thecall]])) else: # ...and call it normally (if at the top level) if condition: newstmts.append( If(test=condition, body=[Expr(value=q[ast_literal[thecall]])], orelse=[Expr(value=q[ast_literal[altcall]])])) else: newstmts.append(Expr(value=q[ast_literal[thecall]])) return newstmts