Mercurial > hg > CbC > CbC_gcc
diff gcc/d/dmd/sapply.c @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gcc/d/dmd/sapply.c Thu Feb 13 11:34:05 2020 +0900 @@ -0,0 +1,155 @@ + +/* Compiler implementation of the D programming language + * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved + * written by Walter Bright + * http://www.digitalmars.com + * Distributed under the Boost Software License, Version 1.0. + * http://www.boost.org/LICENSE_1_0.txt + * https://github.com/D-Programming-Language/dmd/blob/master/src/sapply.c + */ + +#include "root/dsystem.h" + +#include "mars.h" +#include "statement.h" +#include "visitor.h" + + +/************************************** + * A Statement tree walker that will visit each Statement s in the tree, + * in depth-first evaluation order, and call fp(s,param) on it. + * fp() signals whether the walking continues with its return value: + * Returns: + * 0 continue + * 1 done + * It's a bit slower than using virtual functions, but more encapsulated and less brittle. + * Creating an iterator for this would be much more complex. + */ + +class PostorderStatementVisitor : public StoppableVisitor +{ +public: + StoppableVisitor *v; + PostorderStatementVisitor(StoppableVisitor *v) : v(v) {} + + bool doCond(Statement *s) + { + if (!stop && s) + s->accept(this); + return stop; + } + bool applyTo(Statement *s) + { + s->accept(v); + stop = v->stop; + return true; + } + + void visit(Statement *s) + { + applyTo(s); + } + void visit(PeelStatement *s) + { + doCond(s->s) || applyTo(s); + } + void visit(CompoundStatement *s) + { + for (size_t i = 0; i < s->statements->dim; i++) + if (doCond((*s->statements)[i])) + return; + applyTo(s); + } + void visit(UnrolledLoopStatement *s) + { + for (size_t i = 0; i < s->statements->dim; i++) + if (doCond((*s->statements)[i])) + return; + applyTo(s); + } + void visit(ScopeStatement *s) + { + doCond(s->statement) || applyTo(s); + } + void visit(WhileStatement *s) + { + doCond(s->_body) || applyTo(s); + } + void visit(DoStatement *s) + { + doCond(s->_body) || applyTo(s); + } + void visit(ForStatement *s) + { + doCond(s->_init) || doCond(s->_body) || applyTo(s); + } + void visit(ForeachStatement *s) + { + doCond(s->_body) || applyTo(s); + } + void visit(ForeachRangeStatement *s) + { + doCond(s->_body) || applyTo(s); + } + void visit(IfStatement *s) + { + doCond(s->ifbody) || doCond(s->elsebody) || applyTo(s); + } + void visit(PragmaStatement *s) + { + doCond(s->_body) || applyTo(s); + } + void visit(SwitchStatement *s) + { + doCond(s->_body) || applyTo(s); + } + void visit(CaseStatement *s) + { + doCond(s->statement) || applyTo(s); + } + void visit(DefaultStatement *s) + { + doCond(s->statement) || applyTo(s); + } + void visit(SynchronizedStatement *s) + { + doCond(s->_body) || applyTo(s); + } + void visit(WithStatement *s) + { + doCond(s->_body) || applyTo(s); + } + void visit(TryCatchStatement *s) + { + if (doCond(s->_body)) + return; + + for (size_t i = 0; i < s->catches->dim; i++) + if (doCond((*s->catches)[i]->handler)) + return; + applyTo(s); + } + void visit(TryFinallyStatement *s) + { + doCond(s->_body) || doCond(s->finalbody) || applyTo(s); + } + void visit(OnScopeStatement *s) + { + doCond(s->statement) || applyTo(s); + } + void visit(DebugStatement *s) + { + doCond(s->statement) || applyTo(s); + } + void visit(LabelStatement *s) + { + doCond(s->statement) || applyTo(s); + } +}; + +bool walkPostorder(Statement *s, StoppableVisitor *v) +{ + PostorderStatementVisitor pv(v); + s->accept(&pv); + return v->stop; +}