Mercurial > projects > dang
annotate ast/Stmt.d @ 46:90fb4fdfefdd new_gen
While is back
author | Anders Halager <halager@gmail.com> |
---|---|
date | Wed, 23 Apr 2008 17:01:24 +0200 |
parents | 9bc660cbdbec |
children | 4ae365eff712 |
rev | line source |
---|---|
1 | 1 module ast.Stmt; |
2 | |
36
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
3 import Array = tango.core.Array, |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
4 Integer = tango.text.convert.Integer; |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
5 |
1 | 6 import ast.Exp, |
7 ast.Decl; | |
8 | |
36
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
9 import sema.SymbolTable, |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
10 misc.Error; |
1 | 11 |
12 enum StmtType | |
13 { | |
14 Stmt, | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
36
diff
changeset
|
15 Compound, |
1 | 16 Decl, |
17 Exp, | |
18 Return, | |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
19 If, |
11
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
20 While, |
36
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
21 Switch, |
1 | 22 } |
23 | |
24 class Stmt | |
25 { | |
26 this(StmtType stmtType = StmtType.Stmt) | |
27 { | |
28 this.stmtType = stmtType; | |
29 } | |
30 | |
31 StmtType stmtType; | |
32 Scope env; | |
33 } | |
34 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
36
diff
changeset
|
35 class CompoundStatement : Stmt |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
36
diff
changeset
|
36 { |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
36
diff
changeset
|
37 this(Stmt[] stmts) |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
36
diff
changeset
|
38 { |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
36
diff
changeset
|
39 super(StmtType.Compound); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
36
diff
changeset
|
40 this.statements = stmts; |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
36
diff
changeset
|
41 } |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
36
diff
changeset
|
42 |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
36
diff
changeset
|
43 Stmt[] statements; |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
36
diff
changeset
|
44 } |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
36
diff
changeset
|
45 |
1 | 46 class ReturnStmt : Stmt |
47 { | |
48 this() | |
49 { | |
50 super(StmtType.Return); | |
51 } | |
52 | |
53 public Exp exp; | |
54 } | |
55 | |
56 class DeclStmt : Stmt | |
57 { | |
58 this(Decl decl) | |
59 { | |
60 super(StmtType.Decl); | |
61 this.decl = decl; | |
62 } | |
63 | |
64 public Decl decl; | |
65 } | |
66 | |
67 class ExpStmt : Stmt | |
68 { | |
69 this(Exp exp) | |
70 { | |
71 super(StmtType.Exp); | |
72 this.exp = exp; | |
73 } | |
74 | |
75 public Exp exp; | |
76 } | |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
77 |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
78 class IfStmt : Stmt |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
79 { |
45 | 80 this(Exp cond, Stmt then, Stmt el = null) |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
81 { |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
82 super(StmtType.If); |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
83 this.cond = cond; |
11
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
84 this.then_body = then; |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
85 this.else_body = el; |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
86 } |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
87 |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
88 Exp cond; |
45 | 89 Stmt then_body; |
90 Stmt else_body; | |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
91 } |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
92 |
11
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
93 class WhileStmt : Stmt |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
94 { |
46 | 95 this(Exp cond, Stmt stmts) |
11
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
96 { |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
97 super(StmtType.While); |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
98 this.cond = cond; |
46 | 99 this.whileBody = stmts; |
11
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
100 } |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
101 |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
102 Exp cond; |
46 | 103 Stmt whileBody; |
11
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
104 } |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
105 |
36
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
106 class SwitchStmt : Stmt |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
107 { |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
108 this(Exp target) |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
109 { |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
110 super(StmtType.Switch); |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
111 cond = target; |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
112 } |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
113 |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
114 void addCase(IntegerLit[] values, Stmt[] stmts) |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
115 { |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
116 long[] new_values; |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
117 foreach (lit; values) |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
118 new_values ~= Integer.parse(lit.token.get); |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
119 cases ~= Case(values, stmts, new_values); |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
120 |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
121 // Make sure there is no two cases with the same value |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
122 // Does it belong here? |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
123 new_values = new_values.dup; |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
124 Array.sort(new_values); |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
125 long[] all_values = Array.unionOf(old_values, new_values); |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
126 if (all_values.length != old_values.length + new_values.length) |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
127 { |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
128 // overlap! |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
129 auto e = new Error( |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
130 "Can't have multiple cases with the same value." |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
131 " Values appearing in multiple cases: %0"); |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
132 e.loc(values[0].token.location); |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
133 |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
134 all_values = Array.intersectionOf(old_values, new_values); |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
135 char[][] vals; |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
136 foreach (val; all_values) |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
137 vals ~= Integer.toString(val); |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
138 e.arg(vals); |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
139 /* |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
140 foreach (c; cases) |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
141 foreach (i, v; c.values_converted) |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
142 if (Array.bsearch(all_values, v)) |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
143 e.tok(c.values[i].token); |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
144 */ |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
145 throw e; |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
146 } |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
147 old_values = all_values; |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
148 } |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
149 |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
150 void setDefault(Stmt[] stmts) |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
151 { |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
152 if (defaultBlock.length != 0) |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
153 throw new Error("Switch statements can't have multiple defaults"); |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
154 defaultBlock = stmts; |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
155 if (cases.length > 0) |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
156 cases[$ - 1].followedByDefault = true; |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
157 } |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
158 |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
159 Exp cond; |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
160 Case[] cases; |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
161 Stmt[] defaultBlock; |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
162 |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
163 struct Case |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
164 { |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
165 IntegerLit[] values; |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
166 Stmt[] stmts; |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
167 long[] values_converted; |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
168 bool followedByDefault = false; |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
169 } |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
170 |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
171 private long[] old_values; |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
172 } |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
173 |