Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
upper_type = iter_type = "long "
upper_value = self.visit(args[upper_arg])
if args[upper_arg] in self.pure_expressions:
upper_bound = upper_value # compatible with collapse
else:
upper_bound = "__target{0}".format(id(node))
# If variable is local to the for body keep it local...
if node.target.id in self.scope[node] and not hasattr(self, 'yields'):
loop = list()
else:
# For yield function, upper_bound is globals.
iter_type = ""
# Back one step to keep Python behavior (except for break)
loop = [If("{} == {}".format(local_iter, upper_bound),
Statement("{} -= {}".format(local_iter, step)))]
comparison = self.handle_real_loop_comparison(args, local_iter,
upper_bound)
forloop = For("{0} {1}={2}".format(iter_type, local_iter, lower_bound),
comparison,
"{0} += {1}".format(local_iter, step),
loop_body)
loop.insert(0, self.process_omp_attachements(node, forloop))
# Store upper bound value if needed
if upper_bound is upper_value:
header = []
else:
assgnt = self.make_assign(upper_type, upper_bound, upper_value)
def visit_Print(self, node):
values = [self.visit(n) for n in node.values]
stmt = Statement("pythonic::__builtin__::print{0}({1})".format(
"" if node.nl else "_nonl",
", ".join(values))
)
return self.process_omp_attachements(node, stmt)
def visit_Expr(self, node):
stmt = Statement(self.visit(node.value))
return self.process_locals(node,
self.process_omp_attachements(node, stmt))
def visit_Return(self, node):
return Block([Statement("{0} = -1".format(CxxGenerator.StateHolder)),
Statement("goto {0}".format(CxxGenerator.FinalStatement))
])
class AnnotatedStatement(object):
def __init__(self, stmt, annotations):
self.stmt = stmt
self.annotations = annotations
def generate(self):
for directive in self.annotations:
pragma = "#pragma " + directive.s
yield pragma.format(*directive.deps)
for s in self.stmt.generate():
yield s
class ReturnStatement(Statement):
def generate(self):
yield "return " + self.text + ";"
class EmptyStatement(Statement):
def __init__(self):
Statement.__init__(self, "")
class Assign(object):
def __init__(self, lvalue, rvalue):
self.lvalue = lvalue
self.rvalue = rvalue
def generate(self):
yield "%s = %s;" % (self.lvalue, self.rvalue)
def visit_Break(self, _):
"""
Generate break statement in most case and goto for orelse clause.
See Also : cxx_loop
"""
if self.break_handlers and self.break_handlers[-1]:
return Statement("goto {0}".format(self.break_handlers[-1]))
else:
return Statement("break")
def visit_FunctionDef(self, node):
tmp = self.prepare_functiondef_context(node)
operator_body, formal_types, formal_args = tmp
tmp = self.prepare_types(node)
dflt_argv, dflt_argt, result_type, callable_type, pure_type = tmp
# a generator has a call operator that returns the iterator
next_name = "__generator__{0}".format(cxxid(node.name))
instanciated_next_name = "{0}{1}".format(
next_name,
"<{0}>".format(", ".join(formal_types)) if formal_types else "")
operator_body.append(Statement("{}: return result_type()".format(
CxxGenerator.FinalStatement)))
next_declaration = [
FunctionDeclaration(Value("result_type", "next"), []),
EmptyStatement()] # empty statement to force a comma ...
# the constructors
next_constructors = [
FunctionBody(
FunctionDeclaration(Value("", next_name), []),
Line(': pythonic::yielder() {}')
)]
if formal_types:
# If all parameters have a default value, we don't need default
# constructor
if dflt_argv and all(dflt_argv):
def process_locals(self, node, node_visited, *skipped):
"""
Declare variable local to node and insert declaration before.
Not possible for function yielding values.
"""
local_vars = self.scope[node].difference(skipped)
local_vars = local_vars.difference(self.openmp_deps)
if not local_vars:
return node_visited # no processing
locals_visited = []
for varname in local_vars:
vartype = self.typeof(varname)
decl = Statement("{} {}".format(vartype, varname))
locals_visited.append(decl)
self.ldecls.difference_update(local_vars)
return Block(locals_visited + [node_visited])
Block([ReturnStatement(
"pythonic::types::generator_iterator<{0}>()"
.format(next_name))]))
]
next_signature = templatize(
FunctionDeclaration(
Value(
"typename {0}::result_type".format(
instanciated_next_name),
"{0}::next".format(instanciated_next_name)),
[]),
formal_types)
next_body = operator_body
# the dispatch table at the entry point
next_body.insert(0, Statement("switch({0}) {{ {1} }}".format(
CxxGenerator.StateHolder,
" ".join("case {0}: goto {1};".format(num, where)
for (num, where) in sorted(
self.yields.values(),
key=lambda x: x[0])))))
ctx = CachedTypeVisitor(self.lctx)
next_members = ([Statement("{0} {1}".format(ft, fa))
for (ft, fa) in zip(formal_types, formal_args)] +
[Statement("{0} {1}".format(
self.types[self.local_names[k]].generate(ctx),
k))
for k in self.ldecls] +
[Statement("{0} {1}".format(v, k))
for k, v in self.extra_declarations] +
[Statement(
It the case of not local variable, typing for `i` disappear and typing
is removed for iterator in case of yields statement in function.
"""
# Choose target variable for iterator (which is iterator type)
local_target = "__target{0}".format(id(node))
local_target_decl = self.types.builder.IteratorOfType(local_iter_decl)
# If variable is local to the for body it's a ref to the iterator value
# type
if node.target.id in self.scope[node] and not hasattr(self, 'yields'):
local_type = "auto&&"
else:
local_type = ""
# Assign iterable value
loop_body_prelude = Statement("{} {}= *{}".format(local_type,
target,
local_target))
# Create the loop
assign = self.make_assign(local_target_decl, local_target, local_iter)
loop = For("{}.begin()".format(assign),
"{0} < {1}.end()".format(local_target, local_iter),
"++{0}".format(local_target),
Block([loop_body_prelude, loop_body]))
return [self.process_omp_attachements(node, loop)]