switched to GPLv3 ONLY, because i don't trust FSF anymore
[gaemu.git] / gaem / anal / withloop.d
blob0f730d13ac6bfc471ba06e9e3fcf0573911f67e3
1 /* GML analyzer
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, version 3 of the License ONLY.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 module gaem.anal.withloop is aliced;
19 import gaem.parser;
20 import gaem.anal.utils;
23 // ////////////////////////////////////////////////////////////////////////// //
24 void analWith (NodeFunc fn) {
26 void anal (Node nn) {
27 if (nn is null) return;
28 if (cast(NodeStatement)nn) {
29 selectNode!(void)(nn,
30 (NodeVarDecl n) {},
31 (NodeBlock n) { foreach (Node st; n.stats) anal(st); },
32 (NodeStatementEmpty n) {},
33 (NodeStatementAss n) { anal(n.el); anal(n.er); },
34 (NodeStatementExpr n) { anal(n.e); },
35 (NodeReturn n) { anal(n.e); },
36 (NodeWith n) {
37 anal(n.e);
38 if (auto blk = cast(NodeBlock)n.ebody) {
39 if (blk.stats.length == 0) {
40 message(fn, n.loc, ": ???");
41 } else if (blk.stats.length == 1) {
42 if (cast(NodeStatementExpr)blk.stats[0] || cast(NodeReturn)blk.stats[0]) {
43 message(fn, n.loc, ": possible excessive '{}' in 'with'");
44 return;
46 if (cast(NodeStatementEmpty)blk.stats[0]) {
47 message(fn, n.loc, ": empty statement in empty block in 'with'");
48 return;
50 if (cast(NodeStatementBreak)blk.stats[0]) {
51 message(fn, n.loc, ": single 'break' in 'with', noop");
52 return;
54 if (cast(NodeStatementContinue)blk.stats[0]) {
55 message(fn, n.loc, ": single 'continue' in 'with', noop");
56 return;
60 anal(n.ebody);
62 (NodeIf n) { anal(n.ec); anal(n.et); anal(n.ef); },
63 (NodeStatementBreak n) {},
64 (NodeStatementContinue n) {},
65 (NodeFor n) { anal(n.einit); anal(n.econd); anal(n.enext); anal(n.ebody); },
66 (NodeWhile n) { anal(n.econd); anal(n.ebody); },
67 (NodeDoUntil n) { anal(n.econd); anal(n.ebody); },
68 (NodeRepeat n) { anal(n.ecount); anal(n.ebody); },
69 (NodeSwitch n) {
70 anal(n.e);
71 foreach (ref ci; n.cases) { anal(ci.e); anal(ci.st); }
73 () { assert(0, "unimplemented node: "~typeid(nn).name); },
75 } else {
76 selectNode!(void)(nn,
77 (NodeLiteral n) {},
78 (NodeUnary n) { anal(n.e); },
79 (NodeStatementAss n) { anal(n.el); anal(n.er); },
80 (NodeBinary n) { anal(n.el); anal(n.er); },
81 (NodeFCall n) {
82 anal(n.fe);
83 foreach (immutable idx, Node a; n.args) anal(a);
85 (NodeId n) {},
86 (NodeDot n) { anal(n.e); },
87 (NodeIndex n) {
88 anal(n.ei0);
89 anal(n.ei1);
90 anal(n.e);
92 (NodeFunc n) { anal(n.ebody); },
93 () { assert(0, "unimplemented node: "~typeid(nn).name); },
98 anal(fn);