added missing opcodes to VM
[gaemu.git] / gaem / anal / withloop.d
blobcef338d94ad7c138d235d030540225a7d4605169
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, 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 gaem.anal.withloop is aliced;
20 import gaem.parser;
21 import gaem.anal.utils;
24 // ////////////////////////////////////////////////////////////////////////// //
25 void analWith (NodeFunc fn) {
27 void anal (Node nn) {
28 if (nn is null) return;
29 if (cast(NodeStatement)nn) {
30 selectNode!(void)(nn,
31 (NodeVarDecl n) {},
32 (NodeBlock n) { foreach (Node st; n.stats) anal(st); },
33 (NodeStatementEmpty n) {},
34 (NodeStatementAss n) { anal(n.el); anal(n.er); },
35 (NodeStatementExpr n) { anal(n.e); },
36 (NodeReturn n) { anal(n.e); },
37 (NodeWith n) {
38 anal(n.e);
39 if (auto blk = cast(NodeBlock)n.ebody) {
40 if (blk.stats.length == 0) {
41 message(fn, n.loc, ": ???");
42 } else if (blk.stats.length == 1) {
43 if (cast(NodeStatementExpr)blk.stats[0] || cast(NodeReturn)blk.stats[0]) {
44 message(fn, n.loc, ": possible excessive '{}' in 'with'");
45 return;
47 if (cast(NodeStatementEmpty)blk.stats[0]) {
48 message(fn, n.loc, ": empty statement in empty block in 'with'");
49 return;
51 if (cast(NodeStatementBreak)blk.stats[0]) {
52 message(fn, n.loc, ": single 'break' in 'with', noop");
53 return;
55 if (cast(NodeStatementContinue)blk.stats[0]) {
56 message(fn, n.loc, ": single 'continue' in 'with', noop");
57 return;
61 anal(n.ebody);
63 (NodeIf n) { anal(n.ec); anal(n.et); anal(n.ef); },
64 (NodeStatementBreak n) {},
65 (NodeStatementContinue n) {},
66 (NodeFor n) { anal(n.einit); anal(n.econd); anal(n.enext); anal(n.ebody); },
67 (NodeWhile n) { anal(n.econd); anal(n.ebody); },
68 (NodeDoUntil n) { anal(n.econd); anal(n.ebody); },
69 (NodeRepeat n) { anal(n.ecount); anal(n.ebody); },
70 (NodeSwitch n) {
71 anal(n.e);
72 foreach (ref ci; n.cases) { anal(ci.e); anal(ci.st); }
74 () { assert(0, "unimplemented node: "~typeid(nn).name); },
76 } else {
77 selectNode!(void)(nn,
78 (NodeLiteral n) {},
79 (NodeUnary n) { anal(n.e); },
80 (NodeStatementAss n) { anal(n.el); anal(n.er); },
81 (NodeBinary n) { anal(n.el); anal(n.er); },
82 (NodeFCall n) {
83 anal(n.fe);
84 foreach (immutable idx, Node a; n.args) anal(a);
86 (NodeId n) {},
87 (NodeDot n) { anal(n.e); },
88 (NodeIndex n) {
89 anal(n.ei0);
90 anal(n.ei1);
91 anal(n.e);
93 (NodeFunc n) { anal(n.ebody); },
94 () { assert(0, "unimplemented node: "~typeid(nn).name); },
99 anal(fn);