Mercurial > projects > ddmd
annotate dmd/ArrayScopeSymbol.d @ 187:b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
author | Abscissa |
---|---|
date | Tue, 07 Jun 2011 23:37:34 -0400 |
parents | e3afd1303184 |
children |
rev | line source |
---|---|
0 | 1 module dmd.ArrayScopeSymbol; |
2 | |
114 | 3 import dmd.common; |
0 | 4 import dmd.ScopeDsymbol; |
5 import dmd.Expression; | |
6 import dmd.TypeTuple; | |
7 import dmd.TupleDeclaration; | |
8 import dmd.Scope; | |
9 import dmd.Dsymbol; | |
10 import dmd.Loc; | |
11 import dmd.TOK; | |
12 import dmd.Identifier; | |
13 import dmd.Id; | |
14 import dmd.TY; | |
15 import dmd.TupleExp; | |
16 import dmd.StringExp; | |
17 import dmd.WANT; | |
18 import dmd.TypeExp; | |
19 import dmd.Type; | |
20 import dmd.SliceExp; | |
21 import dmd.IndexExp; | |
22 import dmd.IntegerExp; | |
23 import dmd.STC; | |
24 import dmd.ExpInitializer; | |
25 import dmd.VarDeclaration; | |
26 import dmd.ArrayLiteralExp; | |
27 import dmd.expression.Util; | |
28 | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
29 import dmd.DDMDExtensions; |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
30 |
0 | 31 class ArrayScopeSymbol : ScopeDsymbol |
32 { | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
33 mixin insertMemberExtension!(typeof(this)); |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
34 |
0 | 35 Expression exp; // IndexExp or SliceExp |
36 TypeTuple type; // for tuple[length] | |
37 TupleDeclaration td; // for tuples of objects | |
38 Scope sc; | |
39 | |
40 this(Scope sc, Expression e) | |
41 { | |
178 | 42 register(); |
0 | 43 super(); |
44 assert(e.op == TOKindex || e.op == TOKslice); | |
45 this.exp = e; | |
46 this.sc = sc; | |
47 } | |
48 | |
49 this(Scope sc, TypeTuple t) | |
50 { | |
178 | 51 register(); |
49 | 52 exp = null; |
53 type = t; | |
54 td = null; | |
55 this.sc = sc; | |
0 | 56 } |
57 | |
38 | 58 this(Scope sc, TupleDeclaration s) |
0 | 59 { |
178 | 60 register(); |
61 | |
38 | 62 exp = null; |
63 type = null; | |
64 td = s; | |
65 this.sc = sc; | |
0 | 66 } |
67 | |
72 | 68 override Dsymbol search(Loc loc, Identifier ident, int flags) |
0 | 69 { |
70 //printf("ArrayScopeSymbol.search('%s', flags = %d)\n", ident.toChars(), flags); | |
71 if (ident == Id.length || ident == Id.dollar) | |
72 { | |
73 VarDeclaration* pvar; | |
74 Expression ce; | |
75 | |
76 L1: | |
77 if (td) | |
78 { /* $ gives the number of elements in the tuple | |
79 */ | |
80 VarDeclaration v = new VarDeclaration(loc, Type.tsize_t, Id.dollar, null); | |
81 Expression e = new IntegerExp(Loc(0), td.objects.dim, Type.tsize_t); | |
82 v.init = new ExpInitializer(Loc(0), e); | |
83 v.storage_class |= STCstatic | STCconst; | |
84 v.semantic(sc); | |
85 return v; | |
86 } | |
87 | |
88 if (type) | |
89 { /* $ gives the number of type entries in the type tuple | |
90 */ | |
91 VarDeclaration v = new VarDeclaration(loc, Type.tsize_t, Id.dollar, null); | |
92 Expression e = new IntegerExp(Loc(0), type.arguments.dim, Type.tsize_t); | |
93 v.init = new ExpInitializer(Loc(0), e); | |
94 v.storage_class |= STCstatic | STCconst; | |
95 v.semantic(sc); | |
96 return v; | |
97 } | |
98 | |
99 if (exp.op == TOKindex) | |
100 { /* array[index] where index is some function of $ | |
101 */ | |
102 IndexExp ie = cast(IndexExp)exp; | |
103 | |
104 pvar = &ie.lengthVar; | |
105 ce = ie.e1; | |
106 } | |
107 else if (exp.op == TOKslice) | |
108 { /* array[lwr .. upr] where lwr or upr is some function of $ | |
109 */ | |
110 SliceExp se = cast(SliceExp)exp; | |
111 | |
112 pvar = &se.lengthVar; | |
113 ce = se.e1; | |
114 } | |
115 else | |
116 /* Didn't find $, look in enclosing scope(s). | |
117 */ | |
118 return null; | |
119 | |
120 /* If we are indexing into an array that is really a type | |
121 * tuple, rewrite this as an index into a type tuple and | |
122 * try again. | |
123 */ | |
124 if (ce.op == TOKtype) | |
125 { | |
126 Type t = (cast(TypeExp)ce).type; | |
127 if (t.ty == Ttuple) | |
128 { | |
129 type = cast(TypeTuple)t; | |
130 goto L1; | |
131 } | |
132 } | |
133 | |
134 /* *pvar is lazily initialized, so if we refer to $ | |
135 * multiple times, it gets set only once. | |
136 */ | |
137 if (!*pvar) // if not already initialized | |
138 { /* Create variable v and set it to the value of $, | |
139 * which will be a constant. | |
140 */ | |
141 VarDeclaration v = new VarDeclaration(loc, Type.tsize_t, Id.dollar, null); | |
142 | |
143 if (ce.op == TOKvar) | |
144 { // if ce is const, get its initializer | |
145 ce = fromConstInitializer(WANTvalue | WANTinterpret, ce); | |
146 } | |
147 | |
148 if (ce.op == TOKstring) | |
149 { /* It is for a string literal, so the | |
150 * length will be a const. | |
151 */ | |
152 Expression e = new IntegerExp(Loc(0), (cast(StringExp)ce).len, Type.tsize_t); | |
153 v.init = new ExpInitializer(Loc(0), e); | |
154 v.storage_class |= STCstatic | STCconst; | |
155 } | |
156 else if (ce.op == TOKarrayliteral) | |
157 { /* It is for an array literal, so the | |
158 * length will be a const. | |
159 */ | |
160 Expression e = new IntegerExp(Loc(0), (cast(ArrayLiteralExp)ce).elements.dim, Type.tsize_t); | |
161 v.init = new ExpInitializer(Loc(0), e); | |
162 v.storage_class |= STCstatic | STCconst; | |
163 } | |
164 else if (ce.op == TOKtuple) | |
165 { /* It is for an expression tuple, so the | |
166 * length will be a const. | |
167 */ | |
168 Expression e = new IntegerExp(Loc(0), (cast(TupleExp)ce).exps.dim, Type.tsize_t); | |
169 v.init = new ExpInitializer(Loc(0), e); | |
170 v.storage_class |= STCstatic | STCconst; | |
171 } | |
172 *pvar = v; | |
173 } | |
174 (*pvar).semantic(sc); | |
175 return (*pvar); | |
176 } | |
177 return null; | |
178 } | |
179 | |
72 | 180 override ArrayScopeSymbol isArrayScopeSymbol() { return this; } |
181 } |