mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-12 19:03:13 +01:00
211 lines
4.9 KiB
C
211 lines
4.9 KiB
C
|
|
// Compiler implementation of the D programming language
|
|
// Copyright (c) 1999-2013 by Digital Mars
|
|
// All Rights Reserved
|
|
// written by Walter Bright
|
|
// http://www.digitalmars.com
|
|
// License for redistribution is by either the Artistic License
|
|
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
|
// See the included readme.txt for details.
|
|
|
|
#include <stdio.h>
|
|
#include <assert.h>
|
|
|
|
#include "mars.h"
|
|
#include "statement.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.
|
|
*/
|
|
|
|
typedef bool (*sapply_fp_t)(Statement *, void *);
|
|
|
|
bool Statement::apply(sapply_fp_t fp, void *param)
|
|
{
|
|
return (*fp)(this, param);
|
|
}
|
|
|
|
/******************************
|
|
* Perform apply() on an t if not null
|
|
*/
|
|
#define scondApply(t, fp, param) (t ? t->apply(fp, param) : 0)
|
|
|
|
|
|
|
|
bool PeelStatement::apply(sapply_fp_t fp, void *param)
|
|
{
|
|
return s->apply(fp, param) ||
|
|
(*fp)(this, param);
|
|
}
|
|
|
|
bool CompoundStatement::apply(sapply_fp_t fp, void *param)
|
|
{
|
|
for (size_t i = 0; i < statements->dim; i++)
|
|
{ Statement *s = (*statements)[i];
|
|
|
|
bool r = scondApply(s, fp, param);
|
|
if (r)
|
|
return r;
|
|
}
|
|
return (*fp)(this, param);
|
|
}
|
|
|
|
bool UnrolledLoopStatement::apply(sapply_fp_t fp, void *param)
|
|
{
|
|
for (size_t i = 0; i < statements->dim; i++)
|
|
{ Statement *s = (*statements)[i];
|
|
|
|
bool r = scondApply(s, fp, param);
|
|
if (r)
|
|
return r;
|
|
}
|
|
return (*fp)(this, param);
|
|
}
|
|
|
|
bool ScopeStatement::apply(sapply_fp_t fp, void *param)
|
|
{
|
|
return scondApply(statement, fp, param) ||
|
|
(*fp)(this, param);
|
|
}
|
|
|
|
bool WhileStatement::apply(sapply_fp_t fp, void *param)
|
|
{
|
|
return scondApply(body, fp, param) ||
|
|
(*fp)(this, param);
|
|
}
|
|
|
|
bool DoStatement::apply(sapply_fp_t fp, void *param)
|
|
{
|
|
return scondApply(body, fp, param) ||
|
|
(*fp)(this, param);
|
|
}
|
|
|
|
bool ForStatement::apply(sapply_fp_t fp, void *param)
|
|
{
|
|
return scondApply(init, fp, param) ||
|
|
scondApply(body, fp, param) ||
|
|
(*fp)(this, param);
|
|
}
|
|
|
|
bool ForeachStatement::apply(sapply_fp_t fp, void *param)
|
|
{
|
|
return scondApply(body, fp, param) ||
|
|
(*fp)(this, param);
|
|
}
|
|
|
|
#if DMDV2
|
|
bool ForeachRangeStatement::apply(sapply_fp_t fp, void *param)
|
|
{
|
|
return scondApply(body, fp, param) ||
|
|
(*fp)(this, param);
|
|
}
|
|
#endif
|
|
|
|
bool IfStatement::apply(sapply_fp_t fp, void *param)
|
|
{
|
|
return scondApply(ifbody, fp, param) ||
|
|
scondApply(elsebody, fp, param) ||
|
|
(*fp)(this, param);
|
|
}
|
|
|
|
bool ConditionalStatement::apply(sapply_fp_t fp, void *param)
|
|
{
|
|
return scondApply(ifbody, fp, param) ||
|
|
scondApply(elsebody, fp, param) ||
|
|
(*fp)(this, param);
|
|
}
|
|
|
|
bool PragmaStatement::apply(sapply_fp_t fp, void *param)
|
|
{
|
|
return scondApply(body, fp, param) ||
|
|
(*fp)(this, param);
|
|
}
|
|
|
|
bool SwitchStatement::apply(sapply_fp_t fp, void *param)
|
|
{
|
|
return scondApply(body, fp, param) ||
|
|
(*fp)(this, param);
|
|
}
|
|
|
|
bool CaseStatement::apply(sapply_fp_t fp, void *param)
|
|
{
|
|
return scondApply(statement, fp, param) ||
|
|
(*fp)(this, param);
|
|
}
|
|
|
|
#if DMDV2
|
|
bool CaseRangeStatement::apply(sapply_fp_t fp, void *param)
|
|
{
|
|
return scondApply(statement, fp, param) ||
|
|
(*fp)(this, param);
|
|
}
|
|
#endif
|
|
|
|
bool DefaultStatement::apply(sapply_fp_t fp, void *param)
|
|
{
|
|
return scondApply(statement, fp, param) ||
|
|
(*fp)(this, param);
|
|
}
|
|
|
|
bool SynchronizedStatement::apply(sapply_fp_t fp, void *param)
|
|
{
|
|
return scondApply(body, fp, param) ||
|
|
(*fp)(this, param);
|
|
}
|
|
|
|
bool WithStatement::apply(sapply_fp_t fp, void *param)
|
|
{
|
|
return scondApply(body, fp, param) ||
|
|
(*fp)(this, param);
|
|
}
|
|
|
|
bool TryCatchStatement::apply(sapply_fp_t fp, void *param)
|
|
{
|
|
bool r = scondApply(body, fp, param);
|
|
if (r)
|
|
return r;
|
|
|
|
for (size_t i = 0; i < catches->dim; i++)
|
|
{ Catch *c = (*catches)[i];
|
|
|
|
bool r = scondApply(c->handler, fp, param);
|
|
if (r)
|
|
return r;
|
|
}
|
|
return (*fp)(this, param);
|
|
}
|
|
|
|
bool TryFinallyStatement::apply(sapply_fp_t fp, void *param)
|
|
{
|
|
return scondApply(body, fp, param) ||
|
|
scondApply(finalbody, fp, param) ||
|
|
(*fp)(this, param);
|
|
}
|
|
|
|
bool OnScopeStatement::apply(sapply_fp_t fp, void *param)
|
|
{
|
|
return scondApply(statement, fp, param) ||
|
|
(*fp)(this, param);
|
|
}
|
|
|
|
bool DebugStatement::apply(sapply_fp_t fp, void *param)
|
|
{
|
|
return scondApply(statement, fp, param) ||
|
|
(*fp)(this, param);
|
|
}
|
|
|
|
bool LabelStatement::apply(sapply_fp_t fp, void *param)
|
|
{
|
|
return scondApply(statement, fp, param) ||
|
|
(*fp)(this, param);
|
|
}
|
|
|