def _for_list(self, node): target = self.visit(node.target) iterobj = self.visit(node.iter) begin_node = vtypes.Int(0) end_node = vtypes.Int(len(iterobj)) step_node = vtypes.Int(1) iter_node = self.getTmpVariable() cond_node = vtypes.LessThan(iter_node, end_node) update_node = vtypes.Plus(iter_node, step_node) node_body = node.body patterns = [] for i, obj in enumerate(iterobj): if not isinstance(obj, vtypes.numerical_types): raise TypeError("unsupported type for for-statement") patterns.append((iter_node == i, obj)) patterns.append((None, vtypes.IntX())) target_update = (target, vtypes.PatternMux(*patterns)) return self._for_range_fsm(begin_node, end_node, step_node, iter_node, cond_node, update_node, node_body, target_update)
def _for_range(self, node): if len(node.iter.args) == 0: raise ValueError('not enough arguments') if node.iter.keywords: raise TypeError("range() does not take keyword arguments") begin_node = (vtypes.Int(0) if len(node.iter.args) == 1 else self.visit(node.iter.args[0])) end_node = (self.visit(node.iter.args[0]) if len(node.iter.args) == 1 else self.visit(node.iter.args[1])) step_node = (vtypes.Int(1) if len(node.iter.args) < 3 else self.visit( node.iter.args[2])) iter_name = self.visit(node.target) iter_node = self.getVariable(iter_name, store=True) cond_node = vtypes.LessThan(iter_node, end_node) update_node = vtypes.Plus(iter_node, step_node) node_body = node.body return self._for_range_fsm(begin_node, end_node, step_node, iter_node, cond_node, update_node, node_body)
def _for_range(self, node): if len(node.iter.args) == 0: raise ValueError('not enough arguments') begin_node = (vtypes.Int(0) if len(node.iter.args) == 1 else self.visit(node.iter.args[0])) end_node = (self.visit(node.iter.args[0]) if len(node.iter.args) == 1 else self.visit(node.iter.args[1])) step_node = (vtypes.Int(1) if len(node.iter.args) < 3 else self.visit( node.iter.args[2])) iter_node = self.visit(node.target) cond_node = vtypes.LessThan(iter_node, end_node) update_node = vtypes.Plus(iter_node, step_node) node_body = node.body return self._for_range_fsm(begin_node, end_node, step_node, iter_node, cond_node, update_node, node_body)
def visit_Plus(self, node): left = self.visit(node.left) right = self.visit(node.right) return vtypes.Plus(left, right)
def visit_For(self, node): if self.skip(): return if (isinstance(node.iter, ast.Call) and isinstance(node.iter.func, ast.Name) and node.iter.func.id == 'range'): # typical for-loop if len(node.iter.args) == 0: raise TypeError() begin_node = (vtypes.Int(0) if len(node.iter.args) == 1 else self.visit(node.iter.args[0])) end_node = (self.visit(node.iter.args[0]) if len(node.iter.args) == 1 else self.visit(node.iter.args[1])) step_node = (vtypes.Int(1) if len(node.iter.args) < 3 else self.visit(node.iter.args[2])) iter_node = self.visit(node.target) cond_node = vtypes.LessThan(iter_node, end_node) update_node = vtypes.Plus(iter_node, step_node) self.pushScope() # initialize self.setBind(iter_node, begin_node) self.setFsm() self.incFsmCount() # condition check check_count = self.getFsmCount() self.incFsmCount() body_begin_count = self.getFsmCount() for b in node.body: self.visit(b) self.popScope() body_end_count = self.getFsmCount() # update self.setBind(iter_node, update_node) self.incFsmCount() loop_exit_count = self.getFsmCount() self.setFsm(body_end_count, check_count) self.setFsm(check_count, body_begin_count, cond_node, loop_exit_count) unresolved_break = self.getUnresolvedBreak() for b in unresolved_break: self.setFsm(b, loop_exit_count) unresolved_continue = self.getUnresolvedContinue() for c in unresolved_continue: self.setFsm(c, body_end_count) self.clearBreak() self.clearContinue() self.setFsmLoop(check_count, body_end_count, iter_node, step_node)