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