// input is sequence of symbols // CallbackT must be callable with (size_t what, size_t where) // template <typename InputIterT, typename CallbackT> void search( char const *input_it, char const *input_end, results<std::vector<std::string> >& callback) { for ( ; input_it != input_end; ++input_it, where_++) { char const& input = *input_it; { state_t next; while ((next = goto_(state_, input)) == AC_FAIL_STATE) { state_ = fail_(state_); } state_ = next; } { std::set<std::size_t> const& out_node = output_[state_]; typename std::set<size_t>::const_iterator output_it; for (output_it = out_node.begin(); output_it != out_node.end(); ++output_it) { callback(*output_it, where_); } } } }
instruction while_(loop_condition const & cond, labeldescr const & body) { label test, next; instruction const rv = goto_(test); { scope _ = test; llvm::IRBuilder<> & bldr = current_builder(); SPRITE_APICALL( bldr.CreateCondBr(cond.get().ptr(), body.ptr(), next.ptr()) ); } scope::update_current_label_after_branch(next); scope::set_continuation(body, test, MD_LOOP); // Perform codegen only after the continuations are set. body.codegen(); return rv; }
instruction break_() { // Follow implied terminators until a loopback is encountered. llvm::BasicBlock * bb = scope::current_label().ptr(); while(true) { // The Sprite branching constructs add implied continuations to every // successor in the CFG. If there is no terminator, then this must // have been called outside of any branch (e.g., in the function entry // block). llvm::TerminatorInst * term = bb->getTerminator(); if(!term) throw compile_error("break_ used outside of a loop(1)."); metadata md = instruction(term).get_metadata(SPRITE_IMPLIED_METADATA); if(!md.ptr()) throw compile_error("break_ used outside of a loop(2)."); else bb = term->getSuccessor(0); assert(bb); // If this is a loopback, then we've found the loop escape. The // loopback goes to the basic block that evaluates the condition // and the target of this break is the false branch of its // terminator. if(md.size() && valueof<int>(md[0]) == MD_LOOP) { term = bb->getTerminator(); assert(term); assert(term->getNumSuccessors() == 2); label target(term->getSuccessor(1)); return goto_(target); } } }