2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved
4 * written by Walter Bright
5 * http://www.digitalmars.com
6 * Distributed under the Boost Software License, Version 1.0.
7 * http://www.boost.org/LICENSE_1_0.txt
8 * https://github.com/D-Programming-Language/dmd/blob/master/src/apply.c
15 #include "expression.h"
20 /**************************************
21 * An Expression tree walker that will visit each Expression e in the tree,
22 * in depth-first evaluation order, and call fp(e,param) on it.
23 * fp() signals whether the walking continues with its return value:
27 * It's a bit slower than using virtual functions, but more encapsulated and less brittle.
28 * Creating an iterator for this would be much more complex.
31 class PostorderExpressionVisitor
: public StoppableVisitor
35 PostorderExpressionVisitor(StoppableVisitor
*v
) : v(v
) {}
37 bool doCond(Expression
*e
)
43 bool doCond(Expressions
*e
)
47 for (size_t i
= 0; i
< e
->dim
&& !stop
; i
++)
51 bool applyTo(Expression
*e
)
58 void visit(Expression
*e
)
65 //printf("NewExp::apply(): %s\n", toChars());
67 doCond(e
->thisexp
) || doCond(e
->newargs
) || doCond(e
->arguments
) || applyTo(e
);
70 void visit(NewAnonClassExp
*e
)
72 //printf("NewAnonClassExp::apply(): %s\n", toChars());
74 doCond(e
->thisexp
) || doCond(e
->newargs
) || doCond(e
->arguments
) || applyTo(e
);
77 void visit(TypeidExp
*e
)
79 doCond(isExpression(e
->obj
)) || applyTo(e
);
84 doCond(e
->e1
) || applyTo(e
);
89 doCond(e
->e1
) || doCond(e
->e2
) || applyTo(e
);
92 void visit(AssertExp
*e
)
94 //printf("CallExp::apply(apply_fp_t fp, void *param): %s\n", toChars());
95 doCond(e
->e1
) || doCond(e
->msg
) || applyTo(e
);
98 void visit(CallExp
*e
)
100 //printf("CallExp::apply(apply_fp_t fp, void *param): %s\n", toChars());
101 doCond(e
->e1
) || doCond(e
->arguments
) || applyTo(e
);
104 void visit(ArrayExp
*e
)
106 //printf("ArrayExp::apply(apply_fp_t fp, void *param): %s\n", toChars());
107 doCond(e
->e1
) || doCond(e
->arguments
) || applyTo(e
);
110 void visit(SliceExp
*e
)
112 doCond(e
->e1
) || doCond(e
->lwr
) || doCond(e
->upr
) || applyTo(e
);
115 void visit(ArrayLiteralExp
*e
)
117 doCond(e
->basis
) || doCond(e
->elements
) || applyTo(e
);
120 void visit(AssocArrayLiteralExp
*e
)
122 doCond(e
->keys
) || doCond(e
->values
) || applyTo(e
);
125 void visit(StructLiteralExp
*e
)
127 if (e
->stageflags
& stageApply
) return;
128 int old
= e
->stageflags
;
129 e
->stageflags
|= stageApply
;
130 doCond(e
->elements
) || applyTo(e
);
134 void visit(TupleExp
*e
)
136 doCond(e
->e0
) || doCond(e
->exps
) || applyTo(e
);
139 void visit(CondExp
*e
)
141 doCond(e
->econd
) || doCond(e
->e1
) || doCond(e
->e2
) || applyTo(e
);
145 bool walkPostorder(Expression
*e
, StoppableVisitor
*v
)
147 PostorderExpressionVisitor
pv(v
);