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