Mercurial > projects > dang
annotate ast/Stmt.d @ 36:ce17bea8e9bd new_gen
Switch statements support
Can only switch on IntegerLit's but multiple values per case and the
default are supported.
An error is emitted if a value is used multiple times or if theres is more
than one default block
author | Anders Halager <halager@gmail.com> |
---|---|
date | Sun, 20 Apr 2008 22:39:07 +0200 |
parents | 642c6a998fd9 |
children | 495188f9078e |
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, | |
15 Decl, | |
16 Exp, | |
17 Return, | |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
18 If, |
11
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
19 While, |
36
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
20 Switch, |
1 | 21 } |
22 | |
23 class Stmt | |
24 { | |
25 this(StmtType stmtType = StmtType.Stmt) | |
26 { | |
27 this.stmtType = stmtType; | |
28 } | |
29 | |
30 StmtType stmtType; | |
31 Scope env; | |
32 } | |
33 | |
34 class ReturnStmt : Stmt | |
35 { | |
36 this() | |
37 { | |
38 super(StmtType.Return); | |
39 } | |
40 | |
41 public Exp exp; | |
42 } | |
43 | |
44 class DeclStmt : Stmt | |
45 { | |
46 this(Decl decl) | |
47 { | |
48 super(StmtType.Decl); | |
49 this.decl = decl; | |
50 } | |
51 | |
52 public Decl decl; | |
53 } | |
54 | |
55 class ExpStmt : Stmt | |
56 { | |
57 this(Exp exp) | |
58 { | |
59 super(StmtType.Exp); | |
60 this.exp = exp; | |
61 } | |
62 | |
63 public Exp exp; | |
64 } | |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
65 |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
66 class IfStmt : Stmt |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
67 { |
11
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
68 this(Exp cond, Stmt[] then, Stmt[] el = null) |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
69 { |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
70 super(StmtType.If); |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
71 this.cond = cond; |
11
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
72 this.then_body = then; |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
73 this.else_body = el; |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
74 } |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
75 |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
76 Exp cond; |
11
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
77 Stmt[] then_body; |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
78 Stmt[] else_body; |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
79 } |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
80 |
11
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
81 class WhileStmt : Stmt |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
82 { |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
83 this(Exp cond, Stmt[] stmts) |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
84 { |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
85 super(StmtType.While); |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
86 this.cond = cond; |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
87 this.stmts = stmts; |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
88 } |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
89 |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
90 Exp cond; |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
91 Stmt[] stmts; |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
92 } |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
93 |
36
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
94 class SwitchStmt : Stmt |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
95 { |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
96 this(Exp target) |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
97 { |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
98 super(StmtType.Switch); |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
99 cond = target; |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
100 } |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
101 |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
102 void addCase(IntegerLit[] values, Stmt[] stmts) |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
103 { |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
104 long[] new_values; |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
105 foreach (lit; values) |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
106 new_values ~= Integer.parse(lit.token.get); |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
107 cases ~= Case(values, stmts, new_values); |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
108 |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
109 // Make sure there is no two cases with the same value |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
110 // Does it belong here? |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
111 new_values = new_values.dup; |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
112 Array.sort(new_values); |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
113 long[] all_values = Array.unionOf(old_values, new_values); |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
114 if (all_values.length != old_values.length + new_values.length) |
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 // overlap! |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
117 auto e = new Error( |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
118 "Can't have multiple cases with the same value." |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
119 " Values appearing in multiple cases: %0"); |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
120 e.loc(values[0].token.location); |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
121 |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
122 all_values = Array.intersectionOf(old_values, new_values); |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
123 char[][] vals; |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
124 foreach (val; all_values) |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
125 vals ~= Integer.toString(val); |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
126 e.arg(vals); |
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 foreach (c; cases) |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
129 foreach (i, v; c.values_converted) |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
130 if (Array.bsearch(all_values, v)) |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
131 e.tok(c.values[i].token); |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
132 */ |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
133 throw e; |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
134 } |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
135 old_values = all_values; |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
136 } |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
137 |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
138 void setDefault(Stmt[] stmts) |
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 if (defaultBlock.length != 0) |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
141 throw new Error("Switch statements can't have multiple defaults"); |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
142 defaultBlock = stmts; |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
143 if (cases.length > 0) |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
144 cases[$ - 1].followedByDefault = true; |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
145 } |
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 Exp cond; |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
148 Case[] cases; |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
149 Stmt[] defaultBlock; |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
150 |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
151 struct Case |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
152 { |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
153 IntegerLit[] values; |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
154 Stmt[] stmts; |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
155 long[] values_converted; |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
156 bool followedByDefault = false; |
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 private long[] old_values; |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
160 } |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
161 |