def render_PepFor(value, env): # TODO: should only ct_eval here evald_it = value.iterator.evaluate(env) # .evaluate( if evald_it.evaluated_type(env).value is PepRange: if evald_it.__class__ is PepRange: step = evald_it.step begin = evald_it.begin end = evald_it.end elif evald_it.__class__ is PepRuntimeUserFunction and evald_it.user_function is builtins.range_function: # TODO: surely there's a cleverer way to do this than knowing the impl # of the range function? begin = evald_it.args[0] end = evald_it.args[1] if len(evald_it.args) > 2: step = evald_it.args[2] else: step = PepInt("1") else: # TODO: support evaluating unknown functions that return ranges? raise Exception("Can't (currently) support iterating over " + "functions that return ranges.") else: # TODO Can only iterate over ranges raise Exception("Can only iterate over ranges so far, not " + str(evald_it.evaluated_type(env).value) + ".") # TODO: Only handles numeric values so far, and only incrementing the # iteration variable. arg_types_and_names = ((value.variable_type, value.variable_name),) args = (PepVariable(PepType(PepInt), value.variable_name.name()),) newenv = execution_environment(arg_types_and_names, args, False, env) # TODO: should only ct_eval here if step.evaluate(env).value == "1": # .evaluate( modify_code = "++{variable_name}" else: modify_code = "{variable_name} += {step}" modify_code = modify_code.format(variable_name=value.variable_name.symbol_name, step=step.render(env)) return """for( {variable_type} {variable_name} = {begin}; {variable_name} < {end}; {modify_code} ) {{ {body_statements} }}""".format( modify_code=modify_code, variable_type=value.variable_type.render(env), variable_name=value.variable_name.symbol_name, begin=begin.render(env), end=end.render(env), body_statements=render_statements(value.body_stmts, " ", newenv), )
def do_evaluate( self, env ): it = self.iterator.evaluate( env ) if it.is_known( env ): for item in it: newenv = execution_environment( ( ( self.variable_type, self.variable_name ), ), ( item, ), True, env ) for stmt in self.body_stmts: ev_st = stmt.evaluate( newenv ) # TODO: handle return from inside for #if ev_st.__class__ == PepReturn: # return ev_st.value.evaluate( newenv ) return pep_none else: return self
def execution_environment( self, args, known, env ): return execution_environment( self.arg_types_and_names, args, known, env )