]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/d/dmd/sapply.c
Add D front-end, libphobos library, and D2 testsuite.
[thirdparty/gcc.git] / gcc / d / dmd / sapply.c
1
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/sapply.c
9 */
10
11 #include <stdio.h>
12 #include <assert.h>
13
14 #include "mars.h"
15 #include "statement.h"
16 #include "visitor.h"
17
18
19 /**************************************
20 * A Statement tree walker that will visit each Statement s in the tree,
21 * in depth-first evaluation order, and call fp(s,param) on it.
22 * fp() signals whether the walking continues with its return value:
23 * Returns:
24 * 0 continue
25 * 1 done
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.
28 */
29
30 class PostorderStatementVisitor : public StoppableVisitor
31 {
32 public:
33 StoppableVisitor *v;
34 PostorderStatementVisitor(StoppableVisitor *v) : v(v) {}
35
36 bool doCond(Statement *s)
37 {
38 if (!stop && s)
39 s->accept(this);
40 return stop;
41 }
42 bool applyTo(Statement *s)
43 {
44 s->accept(v);
45 stop = v->stop;
46 return true;
47 }
48
49 void visit(Statement *s)
50 {
51 applyTo(s);
52 }
53 void visit(PeelStatement *s)
54 {
55 doCond(s->s) || applyTo(s);
56 }
57 void visit(CompoundStatement *s)
58 {
59 for (size_t i = 0; i < s->statements->dim; i++)
60 if (doCond((*s->statements)[i]))
61 return;
62 applyTo(s);
63 }
64 void visit(UnrolledLoopStatement *s)
65 {
66 for (size_t i = 0; i < s->statements->dim; i++)
67 if (doCond((*s->statements)[i]))
68 return;
69 applyTo(s);
70 }
71 void visit(ScopeStatement *s)
72 {
73 doCond(s->statement) || applyTo(s);
74 }
75 void visit(WhileStatement *s)
76 {
77 doCond(s->_body) || applyTo(s);
78 }
79 void visit(DoStatement *s)
80 {
81 doCond(s->_body) || applyTo(s);
82 }
83 void visit(ForStatement *s)
84 {
85 doCond(s->_init) || doCond(s->_body) || applyTo(s);
86 }
87 void visit(ForeachStatement *s)
88 {
89 doCond(s->_body) || applyTo(s);
90 }
91 void visit(ForeachRangeStatement *s)
92 {
93 doCond(s->_body) || applyTo(s);
94 }
95 void visit(IfStatement *s)
96 {
97 doCond(s->ifbody) || doCond(s->elsebody) || applyTo(s);
98 }
99 void visit(PragmaStatement *s)
100 {
101 doCond(s->_body) || applyTo(s);
102 }
103 void visit(SwitchStatement *s)
104 {
105 doCond(s->_body) || applyTo(s);
106 }
107 void visit(CaseStatement *s)
108 {
109 doCond(s->statement) || applyTo(s);
110 }
111 void visit(DefaultStatement *s)
112 {
113 doCond(s->statement) || applyTo(s);
114 }
115 void visit(SynchronizedStatement *s)
116 {
117 doCond(s->_body) || applyTo(s);
118 }
119 void visit(WithStatement *s)
120 {
121 doCond(s->_body) || applyTo(s);
122 }
123 void visit(TryCatchStatement *s)
124 {
125 if (doCond(s->_body))
126 return;
127
128 for (size_t i = 0; i < s->catches->dim; i++)
129 if (doCond((*s->catches)[i]->handler))
130 return;
131 applyTo(s);
132 }
133 void visit(TryFinallyStatement *s)
134 {
135 doCond(s->_body) || doCond(s->finalbody) || applyTo(s);
136 }
137 void visit(OnScopeStatement *s)
138 {
139 doCond(s->statement) || applyTo(s);
140 }
141 void visit(DebugStatement *s)
142 {
143 doCond(s->statement) || applyTo(s);
144 }
145 void visit(LabelStatement *s)
146 {
147 doCond(s->statement) || applyTo(s);
148 }
149 };
150
151 bool walkPostorder(Statement *s, StoppableVisitor *v)
152 {
153 PostorderStatementVisitor pv(v);
154 s->accept(&pv);
155 return v->stop;
156 }