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