0
|
1 module dmd.expression.Index;
|
|
2
|
|
3 import dmd.Type;
|
|
4 import dmd.Loc;
|
|
5 import dmd.StringExp;
|
|
6 import dmd.TOK;
|
|
7 import dmd.Expression;
|
|
8 import dmd.GlobalExpressions;
|
|
9 import dmd.IntegerExp;
|
|
10 import dmd.TY;
|
|
11 import dmd.TypeSArray;
|
|
12 import dmd.ArrayLiteralExp;
|
|
13 import dmd.AssocArrayLiteralExp;
|
|
14
|
|
15 import dmd.expression.Equal;
|
|
16
|
|
17 /* Also return EXP_CANT_INTERPRET if this fails
|
|
18 */
|
|
19 Expression Index(Type type, Expression e1, Expression e2)
|
|
20 {
|
|
21 Expression e = EXP_CANT_INTERPRET;
|
|
22 Loc loc = e1.loc;
|
|
23
|
|
24 //printf("Index(e1 = %s, e2 = %s)\n", e1.toChars(), e2.toChars());
|
|
25 assert(e1.type);
|
|
26 if (e1.op == TOKstring && e2.op == TOKint64)
|
|
27 {
|
|
28 StringExp es1 = cast(StringExp)e1;
|
|
29 ulong i = e2.toInteger();
|
|
30
|
|
31 if (i >= es1.len)
|
|
32 e1.error("string index %ju is out of bounds [0 .. %zu]", i, es1.len);
|
|
33 else
|
|
34 {
|
|
35 uint value = es1.charAt(cast(uint)i);
|
|
36 e = new IntegerExp(loc, value, type);
|
|
37 }
|
|
38 }
|
|
39 else if (e1.type.toBasetype().ty == Tsarray && e2.op == TOKint64)
|
|
40 {
|
|
41 TypeSArray tsa = cast(TypeSArray)e1.type.toBasetype();
|
|
42 ulong length = tsa.dim.toInteger();
|
|
43 ulong i = e2.toInteger();
|
|
44
|
|
45 if (i >= length)
|
|
46 {
|
|
47 e2.error("array index %ju is out of bounds %s[0 .. %ju]", i, e1.toChars(), length);
|
|
48 }
|
|
49 else if (e1.op == TOKarrayliteral && !e1.checkSideEffect(2))
|
|
50 {
|
|
51 ArrayLiteralExp ale = cast(ArrayLiteralExp)e1;
|
|
52 e = cast(Expression)ale.elements.data[cast(uint)i];
|
|
53 e.type = type;
|
|
54 }
|
|
55 }
|
|
56 else if (e1.type.toBasetype().ty == Tarray && e2.op == TOKint64)
|
|
57 {
|
|
58 ulong i = e2.toInteger();
|
|
59
|
|
60 if (e1.op == TOKarrayliteral && !e1.checkSideEffect(2))
|
|
61 {
|
|
62 ArrayLiteralExp ale = cast(ArrayLiteralExp)e1;
|
|
63 if (i >= ale.elements.dim)
|
|
64 {
|
|
65 e2.error("array index %ju is out of bounds %s[0 .. %u]", i, e1.toChars(), ale.elements.dim);
|
|
66 }
|
|
67 else
|
|
68 {
|
|
69 e = cast(Expression)ale.elements.data[cast(uint)i];
|
|
70 e.type = type;
|
|
71 }
|
|
72 }
|
|
73 }
|
|
74 else if (e1.op == TOKassocarrayliteral && !e1.checkSideEffect(2))
|
|
75 {
|
|
76 AssocArrayLiteralExp ae = cast(AssocArrayLiteralExp)e1;
|
|
77 /* Search the keys backwards, in case there are duplicate keys
|
|
78 */
|
|
79 for (size_t i = ae.keys.dim; i;)
|
|
80 {
|
|
81 i--;
|
|
82 Expression ekey = cast(Expression)ae.keys.data[i];
|
|
83 Expression ex = Equal(TOKequal, Type.tbool, ekey, e2);
|
|
84 if (ex is EXP_CANT_INTERPRET)
|
|
85 return ex;
|
|
86 if (ex.isBool(true))
|
|
87 {
|
|
88 e = cast(Expression)ae.values.data[i];
|
|
89 e.type = type;
|
|
90 break;
|
|
91 }
|
|
92 }
|
|
93 }
|
|
94
|
|
95 return e;
|
|
96 } |