annotate dmd/expression/Slice.d @ 0:10317f0c89a5

Initial commit
author korDen
date Sat, 24 Oct 2009 08:42:06 +0400
parents
children 7427ded8caf7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1 module dmd.expression.Slice;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3 import dmd.Expression;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
4 import dmd.Type;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
5 import dmd.Loc;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
6 import dmd.TOK;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
7 import dmd.StringExp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
8 import dmd.GlobalExpressions;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
9 import dmd.ArrayLiteralExp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
10 import dmd.ArrayTypes;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
11
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
12 import core.stdc.stdlib;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
13 import core.stdc.string;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
14
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
15 import std.contracts;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
16
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
17 /* Also return EXP_CANT_INTERPRET if this fails
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
18 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
19 Expression Slice(Type type, Expression e1, Expression lwr, Expression upr)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
20 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
21 Expression e = EXP_CANT_INTERPRET;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
22 Loc loc = e1.loc;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
23
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
24 version (LOG) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
25 printf("Slice()\n");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
26 if (lwr)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
27 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
28 printf("\te1 = %s\n", e1.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
29 printf("\tlwr = %s\n", lwr.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
30 printf("\tupr = %s\n", upr.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
31 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
32 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
33 if (e1.op == TOKstring && lwr.op == TOKint64 && upr.op == TOKint64)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
34 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
35 StringExp es1 = cast(StringExp)e1;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
36 ulong ilwr = lwr.toInteger();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
37 ulong iupr = upr.toInteger();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
38
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
39 if (iupr > es1.len || ilwr > iupr)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
40 e1.error("string slice [%ju .. %ju] is out of bounds", ilwr, iupr);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
41 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
42 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
43 size_t len = cast(size_t)(iupr - ilwr);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
44 int sz = es1.sz;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
45
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
46 char* s = cast(char*)malloc((len + 1) * sz);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
47 memcpy(s, cast(ubyte*)es1.string_ + ilwr * sz, len * sz);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
48 memset(s + len * sz, 0, sz);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
49
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
50 StringExp es = new StringExp(loc, assumeUnique(s[0..len]), es1.postfix);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
51 es.sz = cast(ubyte)sz;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
52 es.committed = 1;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
53 es.type = type;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
54 e = es;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
55 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
56 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
57 else if (e1.op == TOKarrayliteral &&
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
58 lwr.op == TOKint64 && upr.op == TOKint64 &&
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
59 !e1.checkSideEffect(2))
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
60 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
61 ArrayLiteralExp es1 = cast(ArrayLiteralExp)e1;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
62 ulong ilwr = lwr.toInteger();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
63 ulong iupr = upr.toInteger();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
64
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
65 if (iupr > es1.elements.dim || ilwr > iupr)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
66 e1.error("array slice [%ju .. %ju] is out of bounds", ilwr, iupr);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
67 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
68 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
69 Expressions elements = new Expressions();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
70 elements.setDim(cast(uint)(iupr - ilwr));
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
71 memcpy(elements.data,
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
72 es1.elements.data + ilwr,
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
73 cast(uint)(iupr - ilwr) * (*es1.elements.data).sizeof);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
74 e = new ArrayLiteralExp(e1.loc, elements);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
75 e.type = type;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
76 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
77 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
78 return e;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
79 }