# relation1 string
# relation2 string
# bound2 ExprNode
+ # step ExprNode or None
# body StatNode
# else_clause StatNode or None
#
self.bound2.analyse_types(env)
self.bound1 = self.bound1.coerce_to_integer(env)
self.bound2 = self.bound2.coerce_to_integer(env)
+ if self.step is not None:
+ self.step.analyse_types(env)
+ self.step = self.step.coerce_to_integer(env)
if not (self.bound2.is_name or self.bound2.is_literal):
self.bound2 = self.bound2.coerce_to_temp(env)
target_type = self.target.type
ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
self.bound1.allocate_temps(env)
self.bound2.allocate_temps(env)
+ if self.step is not None:
+ self.step.allocate_temps(env)
if self.py_loopvar_node:
self.py_loopvar_node.allocate_temps(env)
self.target.allocate_target_temps(env)
self.else_clause.analyse_expressions(env)
self.bound1.release_temp(env)
self.bound2.release_temp(env)
+ if self.step is not None:
+ self.step.release_temp(env)
#env.recycle_pending_temps() # TEMPORARY
def generate_execution_code(self, code):
self.bound1.generate_evaluation_code(code)
self.bound2.generate_evaluation_code(code)
offset, incop = self.relation_table[self.relation1]
+ if self.step is not None:
+ self.step.generate_evaluation_code(code)
+ incop = "%s=%s" % (incop[0], self.step.result_code)
code.putln(
"for (%s = %s%s; %s %s %s; %s%s) {" % (
self.loopvar_name,
self.bound1.result_code, offset,
self.loopvar_name, self.relation2, self.bound2.result_code,
- incop, self.loopvar_name))
+ self.loopvar_name, incop))
if self.py_loopvar_node:
self.py_loopvar_node.generate_evaluation_code(code)
self.target.generate_assignment_code(self.py_loopvar_node, code)
code.put_label(break_label)
self.bound1.generate_disposal_code(code)
self.bound2.generate_disposal_code(code)
+ if self.step is not None:
+ self.step.generate_disposal_code(code)
relation_table = {
# {relop : (initial offset, increment op)}
rel2_pos = s.position()
rel2 = p_for_from_relation(s)
bound2 = p_bit_expr(s)
+ step = p_for_from_step(s)
if not target.is_name:
error(target.pos,
"Target of for-from statement must be a variable name")
'bound1': bound1,
'relation1': rel1,
'relation2': rel2,
- 'bound2': bound2 }
+ 'bound2': bound2,
+ 'step': step }
def p_for_from_relation(s):
if s.sy in inequality_relations:
return op
else:
s.error("Expected one of '<', '<=', '>' '>='")
+
+def p_for_from_step(s):
+ if s.sy == 'by':
+ s.next()
+ step = p_bit_expr(s)
+ return step
+ else:
+ return None
inequality_relations = ('<', '<=', '>', '>=')
"raise", "import", "exec", "try", "except", "finally",
"while", "if", "elif", "else", "for", "in", "assert",
"and", "or", "not", "is", "in", "lambda", "from",
- "NULL", "cimport"
+ "NULL", "cimport", "by"
]
class Method: