diff --git a/src/rose/rose_build_bytecode.cpp b/src/rose/rose_build_bytecode.cpp index 6c3b1844..fe090380 100644 --- a/src/rose/rose_build_bytecode.cpp +++ b/src/rose/rose_build_bytecode.cpp @@ -1256,36 +1256,42 @@ bool hasNonSmallBlockOutfix(const vector &outfixes) { return false; } -static -aligned_unique_ptr buildOutfix(RoseBuildImpl &tbi, OutfixInfo &outfix) { - assert(!outfix.is_dead()); // should not be marked dead. +namespace { +class OutfixBuilder : public boost::static_visitor> { +public: + explicit OutfixBuilder(const RoseBuildImpl &build_in) : build(build_in) {} - const CompileContext &cc = tbi.cc; - const ReportManager &rm = tbi.rm; + aligned_unique_ptr operator()(boost::blank&) const { + return nullptr; + }; - aligned_unique_ptr n; - if (auto *rdfa = outfix.rdfa()) { + aligned_unique_ptr operator()(unique_ptr &rdfa) const { // Unleash the McClellan! - n = mcclellanCompile(*rdfa, cc); - } else if (auto *haig = outfix.haig()) { + return mcclellanCompile(*rdfa, build.cc); + } + + aligned_unique_ptr operator()(unique_ptr &haig) const { // Unleash the Goughfish! - n = goughCompile(*haig, tbi.ssm.somPrecision(), cc); - } else if (auto *holder = outfix.holder()) { + return goughCompile(*haig, build.ssm.somPrecision(), build.cc); + } + + aligned_unique_ptr operator()(unique_ptr &holder) const { + const CompileContext &cc = build.cc; + const ReportManager &rm = build.rm; + NGHolder &h = *holder; assert(h.kind == NFA_OUTFIX); // Build NFA. - if (!n) { - const map fixed_depth_tops; /* no tops */ - const map>> triggers; /* no tops */ - bool compress_state = cc.streaming; - n = constructNFA(h, &rm, fixed_depth_tops, triggers, compress_state, - cc); - } + const map fixed_depth_tops; /* no tops */ + const map>> triggers; /* no tops */ + bool compress_state = cc.streaming; + auto n = constructNFA(h, &rm, fixed_depth_tops, triggers, + compress_state, cc); // Try for a DFA upgrade. - if (n && cc.grey.roseMcClellanOutfix - && !has_bounded_repeats_other_than_firsts(*n)) { + if (n && cc.grey.roseMcClellanOutfix && + !has_bounded_repeats_other_than_firsts(*n)) { auto rdfa = buildMcClellan(h, &rm, cc.grey); if (rdfa) { auto d = mcclellanCompile(*rdfa, cc); @@ -1294,11 +1300,27 @@ aligned_unique_ptr buildOutfix(RoseBuildImpl &tbi, OutfixInfo &outfix) { } } } - } else if (auto *mpv = outfix.mpv()) { - assert(mpv->puffettes.empty()); + + return n; } - if (n && tbi.cc.grey.reverseAccelerate) { + aligned_unique_ptr operator()(UNUSED MpvProto &mpv) const { + // MPV construction handled separately. + assert(mpv.puffettes.empty()); + return nullptr; + } + +private: + const RoseBuildImpl &build; +}; +} + +static +aligned_unique_ptr buildOutfix(RoseBuildImpl &build, OutfixInfo &outfix) { + assert(!outfix.is_dead()); // should not be marked dead. + + auto n = boost::apply_visitor(OutfixBuilder(build), outfix.proto); + if (n && build.cc.grey.reverseAccelerate) { buildReverseAcceleration(n.get(), outfix.rev_info, outfix.minWidth); }