2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2020 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
11 #include "root/dsystem.h"
14 #include "expression.h"
19 /**************************************
20 * An Expression tree walker that will visit each Expression e in the tree,
21 * in depth-first evaluation order, and call fp(e,param) on it.
22 * fp() signals whether the walking continues with its return value:
26 * It's a bit slower than using virtual functions, but more encapsulated and less brittle.
27 * Creating an iterator for this would be much more complex.
30 class PostorderExpressionVisitor
: public StoppableVisitor
34 PostorderExpressionVisitor(StoppableVisitor
*v
) : v(v
) {}
36 bool doCond(Expression
*e
)
42 bool doCond(Expressions
*e
)
46 for (size_t i
= 0; i
< e
->dim
&& !stop
; i
++)
50 bool applyTo(Expression
*e
)
57 void visit(Expression
*e
)
64 //printf("NewExp::apply(): %s\n", toChars());
66 doCond(e
->thisexp
) || doCond(e
->newargs
) || doCond(e
->arguments
) || applyTo(e
);
69 void visit(NewAnonClassExp
*e
)
71 //printf("NewAnonClassExp::apply(): %s\n", toChars());
73 doCond(e
->thisexp
) || doCond(e
->newargs
) || doCond(e
->arguments
) || applyTo(e
);
76 void visit(TypeidExp
*e
)
78 doCond(isExpression(e
->obj
)) || applyTo(e
);
83 doCond(e
->e1
) || applyTo(e
);
88 doCond(e
->e1
) || doCond(e
->e2
) || applyTo(e
);
91 void visit(AssertExp
*e
)
93 //printf("CallExp::apply(apply_fp_t fp, void *param): %s\n", toChars());
94 doCond(e
->e1
) || doCond(e
->msg
) || applyTo(e
);
97 void visit(CallExp
*e
)
99 //printf("CallExp::apply(apply_fp_t fp, void *param): %s\n", toChars());
100 doCond(e
->e1
) || doCond(e
->arguments
) || applyTo(e
);
103 void visit(ArrayExp
*e
)
105 //printf("ArrayExp::apply(apply_fp_t fp, void *param): %s\n", toChars());
106 doCond(e
->e1
) || doCond(e
->arguments
) || applyTo(e
);
109 void visit(SliceExp
*e
)
111 doCond(e
->e1
) || doCond(e
->lwr
) || doCond(e
->upr
) || applyTo(e
);
114 void visit(ArrayLiteralExp
*e
)
116 doCond(e
->basis
) || doCond(e
->elements
) || applyTo(e
);
119 void visit(AssocArrayLiteralExp
*e
)
121 doCond(e
->keys
) || doCond(e
->values
) || applyTo(e
);
124 void visit(StructLiteralExp
*e
)
126 if (e
->stageflags
& stageApply
) return;
127 int old
= e
->stageflags
;
128 e
->stageflags
|= stageApply
;
129 doCond(e
->elements
) || applyTo(e
);
133 void visit(TupleExp
*e
)
135 doCond(e
->e0
) || doCond(e
->exps
) || applyTo(e
);
138 void visit(CondExp
*e
)
140 doCond(e
->econd
) || doCond(e
->e1
) || doCond(e
->e2
) || applyTo(e
);
144 bool walkPostorder(Expression
*e
, StoppableVisitor
*v
)
146 PostorderExpressionVisitor
pv(v
);