From acae4bab4f3fd840ef4e536c8ebb6d6ed18785ff Mon Sep 17 00:00:00 2001 From: Walter Bright Date: Thu, 28 Mar 2013 23:56:51 -0700 Subject: [PATCH] add apply() for statements --- src/posix.mak | 7 +- src/sapply.c | 220 ++++++++++++++++++++++++++++++++++++++++++++++++ src/statement.h | 27 ++++++ src/win32.mak | 5 +- 4 files changed, 255 insertions(+), 4 deletions(-) create mode 100644 src/sapply.c diff --git a/src/posix.mak b/src/posix.mak index 9d63a67308d4..77cb121af5ce 100644 --- a/src/posix.mak +++ b/src/posix.mak @@ -91,7 +91,7 @@ DMD_OBJS = \ hdrgen.o delegatize.o aa.o ti_achar.o toir.o interpret.o traits.o \ builtin.o ctfeexpr.o clone.o aliasthis.o \ man.o arrayop.o port.o response.o async.o json.o speller.o aav.o unittests.o \ - imphint.o argtypes.o ti_pvoid.o apply.o sideeffect.o \ + imphint.o argtypes.o ti_pvoid.o apply.o sapply.o sideeffect.o \ intrange.o canthrow.o target.o \ pdata.o cv8.o backconfig.o \ $(TARGET_OBJS) @@ -120,7 +120,7 @@ SRC = win32.mak posix.mak \ builtin.c clone.c lib.h libomf.c libelf.c libmach.c arrayop.c \ libmscoff.c scanelf.c scanmach.c \ aliasthis.h aliasthis.c json.h json.c unittests.c imphint.c \ - argtypes.c apply.c sideeffect.c \ + argtypes.c apply.c sapply.c sideeffect.c \ intrange.h intrange.c canthrow.c target.c target.h \ scanmscoff.c scanomf.c ctfe.h ctfeexpr.c \ $C/cdef.h $C/cc.h $C/oper.h $C/ty.h $C/optabgen.c \ @@ -550,6 +550,9 @@ root.o: $(ROOT)/root.c rtlsym.o: $C/rtlsym.c $C/rtlsym.h $(CC) -c $(MFLAGS) $< +sapply.o: sapply.c + $(CC) -c $(CFLAGS) $< + s2ir.o: s2ir.c $C/rtlsym.h statement.h $(CC) -c $(MFLAGS) -I$(ROOT) $< diff --git a/src/sapply.c b/src/sapply.c new file mode 100644 index 000000000000..e03303ee1040 --- /dev/null +++ b/src/sapply.c @@ -0,0 +1,220 @@ + +// 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 +#include + +#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 (*fp_t)(Statement *, void *); + +bool Statement::apply(fp_t fp, void *param) +{ + return (*fp)(this, param); +} + +/****************************** + * Perform apply() on an t if not null + */ +template +bool condApply(T* t, fp_t fp, void* param) +{ + return t ? t->apply(fp, param) : 0; +} + + + +bool PeelStatement::apply(fp_t fp, void *param) +{ + return s->apply(fp, param) || + (*fp)(this, param); +} + +bool CompoundStatement::apply(fp_t fp, void *param) +{ + for (size_t i = 0; i < statements->dim; i++) + { Statement *s = (*statements)[i]; + + bool r = condApply(s, fp, param); + if (r) + return r; + } + return (*fp)(this, param); +} + +bool UnrolledLoopStatement::apply(fp_t fp, void *param) +{ + for (size_t i = 0; i < statements->dim; i++) + { Statement *s = (*statements)[i]; + + bool r = condApply(s, fp, param); + if (r) + return r; + } + return (*fp)(this, param); +} + +bool ScopeStatement::apply(fp_t fp, void *param) +{ + return condApply(statement, fp, param) || + (*fp)(this, param); +} + +bool WhileStatement::apply(fp_t fp, void *param) +{ + return condApply(body, fp, param) || + (*fp)(this, param); +} + +bool DoStatement::apply(fp_t fp, void *param) +{ + return condApply(body, fp, param) || + (*fp)(this, param); +} + +bool ForStatement::apply(fp_t fp, void *param) +{ + return condApply(init, fp, param) || + condApply(body, fp, param) || + (*fp)(this, param); +} + +bool ForeachStatement::apply(fp_t fp, void *param) +{ + return condApply(body, fp, param) || + (*fp)(this, param); +} + +#if DMDV2 +bool ForeachRangeStatement::apply(fp_t fp, void *param) +{ + return condApply(body, fp, param) || + (*fp)(this, param); +} +#endif + +bool IfStatement::apply(fp_t fp, void *param) +{ + return condApply(ifbody, fp, param) || + condApply(elsebody, fp, param) || + (*fp)(this, param); +} + +bool ConditionalStatement::apply(fp_t fp, void *param) +{ + return condApply(ifbody, fp, param) || + condApply(elsebody, fp, param) || + (*fp)(this, param); +} + +bool PragmaStatement::apply(fp_t fp, void *param) +{ + return condApply(body, fp, param) || + (*fp)(this, param); +} + +bool SwitchStatement::apply(fp_t fp, void *param) +{ + return condApply(body, fp, param) || + (*fp)(this, param); +} + +bool CaseStatement::apply(fp_t fp, void *param) +{ + return condApply(statement, fp, param) || + (*fp)(this, param); +} + +#if DMDV2 +bool CaseRangeStatement::apply(fp_t fp, void *param) +{ + return condApply(statement, fp, param) || + (*fp)(this, param); +} +#endif + +bool DefaultStatement::apply(fp_t fp, void *param) +{ + return condApply(statement, fp, param) || + (*fp)(this, param); +} + +bool SynchronizedStatement::apply(fp_t fp, void *param) +{ + return condApply(body, fp, param) || + (*fp)(this, param); +} + +bool WithStatement::apply(fp_t fp, void *param) +{ + return condApply(body, fp, param) || + (*fp)(this, param); +} + +bool TryCatchStatement::apply(fp_t fp, void *param) +{ + bool r = condApply(body, fp, param); + if (r) + return r; + + for (size_t i = 0; i < catches->dim; i++) + { Catch *c = (*catches)[i]; + + bool r = condApply(c->handler, fp, param); + if (r) + return r; + } + return (*fp)(this, param); +} + +bool TryFinallyStatement::apply(fp_t fp, void *param) +{ + return condApply(body, fp, param) || + condApply(finalbody, fp, param) || + (*fp)(this, param); +} + +bool OnScopeStatement::apply(fp_t fp, void *param) +{ + return condApply(statement, fp, param) || + (*fp)(this, param); +} + +bool VolatileStatement::apply(fp_t fp, void *param) +{ + return condApply(statement, fp, param) || + (*fp)(this, param); +} + +bool DebugStatement::apply(fp_t fp, void *param) +{ + return condApply(statement, fp, param) || + (*fp)(this, param); +} + +bool LabelStatement::apply(fp_t fp, void *param) +{ + return condApply(statement, fp, param) || + (*fp)(this, param); +} + diff --git a/src/statement.h b/src/statement.h index 407382f60c42..214a3478ada2 100644 --- a/src/statement.h +++ b/src/statement.h @@ -53,6 +53,8 @@ struct InterState; enum TOK; +typedef bool (*sapply_fp_t)(Statement *, void *); + // Back end struct IRState; struct Blockx; @@ -108,6 +110,7 @@ struct Statement : Object virtual Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally); virtual Statements *flatten(Scope *sc); virtual Expression *interpret(InterState *istate); + virtual bool apply(sapply_fp_t fp, void *param); virtual Statement *last(); virtual int inlineCost(InlineCostState *ics); @@ -134,6 +137,7 @@ struct PeelStatement : Statement PeelStatement(Statement *s); Statement *semantic(Scope *sc); + bool apply(sapply_fp_t fp, void *param); }; struct ExpStatement : Statement @@ -201,6 +205,7 @@ struct CompoundStatement : Statement Statements *flatten(Scope *sc); ReturnStatement *isReturnStatement(); Expression *interpret(InterState *istate); + bool apply(sapply_fp_t fp, void *param); Statement *last(); int inlineCost(InlineCostState *ics); @@ -236,6 +241,7 @@ struct UnrolledLoopStatement : Statement int blockExit(bool mustNotThrow); int comeFrom(); Expression *interpret(InterState *istate); + bool apply(sapply_fp_t fp, void *param); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); int inlineCost(InlineCostState *ics); @@ -262,6 +268,7 @@ struct ScopeStatement : Statement int comeFrom(); int isEmpty(); Expression *interpret(InterState *istate); + bool apply(sapply_fp_t fp, void *param); int inlineCost(InlineCostState *ics); Expression *doInline(InlineDoState *ids); @@ -285,6 +292,7 @@ struct WhileStatement : Statement int blockExit(bool mustNotThrow); int comeFrom(); Expression *interpret(InterState *istate); + bool apply(sapply_fp_t fp, void *param); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); Statement *inlineScan(InlineScanState *iss); @@ -306,6 +314,7 @@ struct DoStatement : Statement int blockExit(bool mustNotThrow); int comeFrom(); Expression *interpret(InterState *istate); + bool apply(sapply_fp_t fp, void *param); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); Statement *inlineScan(InlineScanState *iss); @@ -338,6 +347,7 @@ struct ForStatement : Statement int blockExit(bool mustNotThrow); int comeFrom(); Expression *interpret(InterState *istate); + bool apply(sapply_fp_t fp, void *param); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); int inlineCost(InlineCostState *ics); @@ -374,6 +384,7 @@ struct ForeachStatement : Statement int blockExit(bool mustNotThrow); int comeFrom(); Expression *interpret(InterState *istate); + bool apply(sapply_fp_t fp, void *param); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); Statement *inlineScan(InlineScanState *iss); @@ -402,6 +413,7 @@ struct ForeachRangeStatement : Statement int blockExit(bool mustNotThrow); int comeFrom(); Expression *interpret(InterState *istate); + bool apply(sapply_fp_t fp, void *param); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); Statement *inlineScan(InlineScanState *iss); @@ -423,6 +435,7 @@ struct IfStatement : Statement Statement *syntaxCopy(); Statement *semantic(Scope *sc); Expression *interpret(InterState *istate); + bool apply(sapply_fp_t fp, void *param); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); bool usesEH(); int blockExit(bool mustNotThrow); @@ -448,6 +461,7 @@ struct ConditionalStatement : Statement Statements *flatten(Scope *sc); bool usesEH(); int blockExit(bool mustNotThrow); + bool apply(sapply_fp_t fp, void *param); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); }; @@ -463,6 +477,7 @@ struct PragmaStatement : Statement Statement *semantic(Scope *sc); bool usesEH(); int blockExit(bool mustNotThrow); + bool apply(sapply_fp_t fp, void *param); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); @@ -501,6 +516,7 @@ struct SwitchStatement : Statement bool usesEH(); int blockExit(bool mustNotThrow); Expression *interpret(InterState *istate); + bool apply(sapply_fp_t fp, void *param); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); Statement *inlineScan(InlineScanState *iss); @@ -524,6 +540,7 @@ struct CaseStatement : Statement int blockExit(bool mustNotThrow); int comeFrom(); Expression *interpret(InterState *istate); + bool apply(sapply_fp_t fp, void *param); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); CaseStatement *isCaseStatement() { return this; } @@ -543,6 +560,7 @@ struct CaseRangeStatement : Statement CaseRangeStatement(Loc loc, Expression *first, Expression *last, Statement *s); Statement *syntaxCopy(); Statement *semantic(Scope *sc); + bool apply(sapply_fp_t fp, void *param); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); }; @@ -562,6 +580,7 @@ struct DefaultStatement : Statement int blockExit(bool mustNotThrow); int comeFrom(); Expression *interpret(InterState *istate); + bool apply(sapply_fp_t fp, void *param); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); DefaultStatement *isDefaultStatement() { return this; } @@ -670,6 +689,7 @@ struct SynchronizedStatement : Statement bool hasContinue(); bool usesEH(); int blockExit(bool mustNotThrow); + bool apply(sapply_fp_t fp, void *param); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); Statement *inlineScan(InlineScanState *iss); @@ -693,6 +713,7 @@ struct WithStatement : Statement bool usesEH(); int blockExit(bool mustNotThrow); Expression *interpret(InterState *istate); + bool apply(sapply_fp_t fp, void *param); Statement *inlineScan(InlineScanState *iss); @@ -711,6 +732,7 @@ struct TryCatchStatement : Statement bool usesEH(); int blockExit(bool mustNotThrow); Expression *interpret(InterState *istate); + bool apply(sapply_fp_t fp, void *param); Statement *inlineScan(InlineScanState *iss); @@ -749,6 +771,7 @@ struct TryFinallyStatement : Statement bool usesEH(); int blockExit(bool mustNotThrow); Expression *interpret(InterState *istate); + bool apply(sapply_fp_t fp, void *param); Statement *inlineScan(InlineScanState *iss); @@ -768,6 +791,7 @@ struct OnScopeStatement : Statement bool usesEH(); Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally); Expression *interpret(InterState *istate); + bool apply(sapply_fp_t fp, void *param); void toIR(IRState *irs); }; @@ -799,6 +823,7 @@ struct VolatileStatement : Statement Statement *semantic(Scope *sc); Statements *flatten(Scope *sc); int blockExit(bool mustNotThrow); + bool apply(sapply_fp_t fp, void *param); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); Statement *inlineScan(InlineScanState *iss); @@ -814,6 +839,7 @@ struct DebugStatement : Statement Statement *syntaxCopy(); Statement *semantic(Scope *sc); Statements *flatten(Scope *sc); + bool apply(sapply_fp_t fp, void *param); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); }; @@ -850,6 +876,7 @@ struct LabelStatement : Statement int blockExit(bool mustNotThrow); int comeFrom(); Expression *interpret(InterState *istate); + bool apply(sapply_fp_t fp, void *param); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); Statement *inlineScan(InlineScanState *iss); diff --git a/src/win32.mak b/src/win32.mak index 19c492180d84..be3ae0f97023 100644 --- a/src/win32.mak +++ b/src/win32.mak @@ -160,7 +160,7 @@ OBJ1= mars.obj enum.obj struct.obj dsymbol.obj import.obj id.obj \ builtin.obj clone.obj libomf.obj scanomf.obj arrayop.obj irstate.obj \ glue.obj msc.obj tk.obj s2ir.obj todt.obj e2ir.obj tocsym.obj \ eh.obj toobj.obj toctype.obj tocvdebug.obj toir.obj \ - json.obj unittests.obj imphint.obj argtypes.obj apply.obj \ + json.obj unittests.obj imphint.obj argtypes.obj apply.obj sapply.obj \ sideeffect.obj libmscoff.obj scanmscoff.obj \ intrange.obj canthrow.obj target.obj @@ -204,7 +204,7 @@ SRCS= mars.c enum.c struct.c dsymbol.c import.c idgen.c impcnvgen.c utf.h \ delegatize.c toir.h toir.c interpret.c ctfeexpr.c traits.c builtin.c \ clone.c lib.h libomf.c scanomf.c libelf.c scanelf.c libmach.c scanmach.c arrayop.c \ aliasthis.h aliasthis.c json.h json.c unittests.c imphint.c argtypes.c \ - apply.c sideeffect.c libmscoff.c scanmscoff.c ctfe.h \ + apply.c sapply.c sideeffect.c libmscoff.c scanmscoff.c ctfe.h \ intrange.h intrange.c canthrow.c target.c target.h @@ -711,6 +711,7 @@ mangle.obj : $(TOTALH) dsymbol.h declaration.h mangle.c opover.obj : $(TOTALH) expression.h opover.c optimize.obj : $(TOTALH) expression.h optimize.c parse.obj : $(TOTALH) attrib.h lexer.h parse.h parse.c +sapply.obj : $(TOTALH) sapply.c scanomf.obj : $(TOTALH) lib.h scanomf.c scope.obj : $(TOTALH) scope.h scope.c sideeffect.obj : $(TOTALH) sideeffect.c