Mercurial > projects > ddmd
diff dmd/expression/Slice.d @ 0:10317f0c89a5
Initial commit
author | korDen |
---|---|
date | Sat, 24 Oct 2009 08:42:06 +0400 |
parents | |
children | 7427ded8caf7 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dmd/expression/Slice.d Sat Oct 24 08:42:06 2009 +0400 @@ -0,0 +1,79 @@ +module dmd.expression.Slice; + +import dmd.Expression; +import dmd.Type; +import dmd.Loc; +import dmd.TOK; +import dmd.StringExp; +import dmd.GlobalExpressions; +import dmd.ArrayLiteralExp; +import dmd.ArrayTypes; + +import core.stdc.stdlib; +import core.stdc.string; + +import std.contracts; + +/* Also return EXP_CANT_INTERPRET if this fails + */ +Expression Slice(Type type, Expression e1, Expression lwr, Expression upr) +{ + Expression e = EXP_CANT_INTERPRET; + Loc loc = e1.loc; + +version (LOG) { + printf("Slice()\n"); + if (lwr) + { + printf("\te1 = %s\n", e1.toChars()); + printf("\tlwr = %s\n", lwr.toChars()); + printf("\tupr = %s\n", upr.toChars()); + } +} + if (e1.op == TOKstring && lwr.op == TOKint64 && upr.op == TOKint64) + { + StringExp es1 = cast(StringExp)e1; + ulong ilwr = lwr.toInteger(); + ulong iupr = upr.toInteger(); + + if (iupr > es1.len || ilwr > iupr) + e1.error("string slice [%ju .. %ju] is out of bounds", ilwr, iupr); + else + { + size_t len = cast(size_t)(iupr - ilwr); + int sz = es1.sz; + + char* s = cast(char*)malloc((len + 1) * sz); + memcpy(s, cast(ubyte*)es1.string_ + ilwr * sz, len * sz); + memset(s + len * sz, 0, sz); + + StringExp es = new StringExp(loc, assumeUnique(s[0..len]), es1.postfix); + es.sz = cast(ubyte)sz; + es.committed = 1; + es.type = type; + e = es; + } + } + else if (e1.op == TOKarrayliteral && + lwr.op == TOKint64 && upr.op == TOKint64 && + !e1.checkSideEffect(2)) + { + ArrayLiteralExp es1 = cast(ArrayLiteralExp)e1; + ulong ilwr = lwr.toInteger(); + ulong iupr = upr.toInteger(); + + if (iupr > es1.elements.dim || ilwr > iupr) + e1.error("array slice [%ju .. %ju] is out of bounds", ilwr, iupr); + else + { + Expressions elements = new Expressions(); + elements.setDim(cast(uint)(iupr - ilwr)); + memcpy(elements.data, + es1.elements.data + ilwr, + cast(uint)(iupr - ilwr) * (*es1.elements.data).sizeof); + e = new ArrayLiteralExp(e1.loc, elements); + e.type = type; + } + } + return e; +} \ No newline at end of file