2 * coded by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
3 * Understanding is not required. Only obedience.
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 module gmlparser
.astools
is aliced
;
20 import gmlparser
.lexer
;
21 import gmlparser
.tokens
;
22 import gmlparser
.utils
;
26 // ////////////////////////////////////////////////////////////////////////// //
27 bool isEmpty (Node nn
) {
28 if (nn
is null) return true;
29 if (auto n
= cast(NodeFunc
)nn
) return isEmpty(n
.ebody
);
30 if (cast(NodeStatement
)nn
) {
31 if (cast(NodeStatementEmpty
)nn
) return true;
32 if (auto n
= cast(NodeBlock
)nn
) {
33 foreach (Node st
; n
.stats
) if (!isEmpty(st
)) return false;
41 // ////////////////////////////////////////////////////////////////////////// //
42 bool hasReturn (Node nn
) {
43 if (nn
is null) return false;
44 if (cast(NodeStatement
)nn
) {
45 return selectNode
!(bool)(nn
,
46 (NodeVarDecl n
) => false,
48 foreach (Node st
; n
.stats
) if (hasReturn(st
)) return true;
51 (NodeStatementEmpty n
) => false,
52 (NodeStatementExpr n
) => hasReturn(n
.e
),
53 (NodeReturn n
) => true,
54 (NodeWith n
) => (hasReturn(n
.e
) ||
hasReturn(n
.ebody
)),
55 (NodeWithObject n
) => (hasReturn(n
.e
) ||
hasReturn(n
.ebody
)),
56 (NodeIf n
) => (hasReturn(n
.ec
) ||
hasReturn(n
.et
) ||
hasReturn(n
.ef
)),
57 (NodeStatementBreak n
) => false,
58 (NodeStatementContinue n
) => false,
59 (NodeFor n
) => (hasReturn(n
.einit
) ||
hasReturn(n
.econd
) ||
hasReturn(n
.enext
) ||
hasReturn(n
.ebody
)),
60 (NodeWhile n
) => (hasReturn(n
.econd
) ||
hasReturn(n
.ebody
)),
61 (NodeDoUntil n
) => (hasReturn(n
.econd
) ||
hasReturn(n
.ebody
)),
62 (NodeRepeat n
) => (hasReturn(n
.ecount
) ||
hasReturn(n
.ebody
)),
64 if (hasReturn(n
.e
)) return true;
65 foreach (ref ci
; n
.cases
) if (hasReturn(ci
.e
) ||
hasReturn(ci
.st
)) return true;
68 () { assert(0, "unimplemented node: "~typeid(nn
).name
); },
71 return selectNode
!(bool)(nn
,
72 (NodeLiteral n
) => false,
73 (NodeUnary n
) => hasReturn(n
.e
),
74 (NodeBinary n
) => hasReturn(n
.el
) ||
hasReturn(n
.er
),
76 if (hasReturn(n
.fe
)) return true;
77 foreach (immutable idx
, Node a
; n
.args
) if (hasReturn(a
)) return true;
81 (NodeDot n
) => hasReturn(n
.e
),
82 (NodeIndex n
) => (hasReturn(n
.e
) ||
hasReturn(n
.ei0
) ||
hasReturn(n
.ei1
)),
83 (NodeFunc n
) => hasReturn(n
.ebody
),
84 () { assert(0, "unimplemented node: "~typeid(nn
).name
); },