Mercurial > projects > ddmd
comparison dmd/expression/Index.d @ 0:10317f0c89a5
Initial commit
author | korDen |
---|---|
date | Sat, 24 Oct 2009 08:42:06 +0400 |
parents | |
children | 39648eb578f6 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:10317f0c89a5 |
---|---|
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 } |