diff dmd/interpret/Util.d @ 63:cab4c37afb89

A bunch of implementations
author korDen
date Mon, 23 Aug 2010 16:52:24 +0400
parents
children 7e0d548de9e6
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd/interpret/Util.d	Mon Aug 23 16:52:24 2010 +0400
@@ -0,0 +1,213 @@
+module dmd.interpret.Util;
+
+import dmd.StructDeclaration;
+import dmd.Expression;
+import dmd.InterState;
+import dmd.ArrayTypes;
+import dmd.GlobalExpressions;
+import dmd.TOK;
+import dmd.AssocArrayLiteralExp;
+import dmd.IntegerExp;
+import dmd.Type;
+import dmd.Declaration;
+import dmd.Loc;
+import dmd.ArrayLiteralExp;
+import dmd.TypeAArray;
+import dmd.TypeSArray;
+import dmd.STC;
+import dmd.SymbolDeclaration;
+import dmd.StructLiteralExp;
+import dmd.VarDeclaration;
+import dmd.Util;
+
+Expression interpret_aaLen(InterState istate, Expressions arguments)
+{
+    if (!arguments || arguments.dim != 1)
+		return null;
+    Expression earg = cast(Expression)arguments.data[0];
+    earg = earg.interpret(istate);
+    if (earg is EXP_CANT_INTERPRET)
+		return null;
+    if (earg.op != TOKassocarrayliteral)
+		return null;
+    AssocArrayLiteralExp aae = cast(AssocArrayLiteralExp)earg;
+    Expression e = new IntegerExp(aae.loc, aae.keys.dim, Type.tsize_t);
+    return e;
+}
+
+Expression interpret_aaKeys(InterState istate, Expressions arguments)
+{
+version (LOG) {
+    printf("interpret_aaKeys()\n");
+}
+    if (!arguments || arguments.dim != 2)
+		return null;
+    Expression earg = cast(Expression)arguments.data[0];
+    earg = earg.interpret(istate);
+    if (earg is EXP_CANT_INTERPRET)
+		return null;
+    if (earg.op != TOKassocarrayliteral)
+		return null;
+    AssocArrayLiteralExp aae = cast(AssocArrayLiteralExp)earg;
+    Expression e = new ArrayLiteralExp(aae.loc, aae.keys);
+    Type elemType = (cast(TypeAArray)aae.type).index;
+    e.type = new TypeSArray(elemType, new IntegerExp(arguments ? arguments.dim : 0));
+    return e;
+}
+
+Expression interpret_aaValues(InterState istate, Expressions arguments)
+{
+    //printf("interpret_aaValues()\n");
+    if (!arguments || arguments.dim != 3)
+		return null;
+    Expression earg = cast(Expression)arguments.data[0];
+    earg = earg.interpret(istate);
+    if (earg is EXP_CANT_INTERPRET)
+		return null;
+    if (earg.op != TOKassocarrayliteral)
+		return null;
+    AssocArrayLiteralExp aae = cast(AssocArrayLiteralExp)earg;
+    Expression e = new ArrayLiteralExp(aae.loc, aae.values);
+    Type elemType = (cast(TypeAArray)aae.type).next;
+    e.type = new TypeSArray(elemType, new IntegerExp(arguments ? arguments.dim : 0));
+    //printf("result is %s\n", e.toChars());
+    return e;
+}
+
+Expression getVarExp(Loc loc, InterState istate, Declaration d)
+{
+    Expression e = EXP_CANT_INTERPRET;
+    VarDeclaration v = d.isVarDeclaration();
+    SymbolDeclaration s = d.isSymbolDeclaration();
+    if (v)
+    {
+///version (DMDV2) {
+		if ((v.isConst() || v.isInvariant() || v.storage_class & STCmanifest) && v.init && !v.value)
+///} else {
+///	if (v.isConst() && v.init)
+///}
+		{   
+			e = v.init.toExpression();
+			if (e && !e.type)
+				e.type = v.type;
+		}
+		else
+		{   
+			e = v.value;
+			if (v.isDataseg())
+			{	
+				error(loc, "static variable %s cannot be read at compile time", v.toChars());
+				e = EXP_CANT_INTERPRET;
+			}
+			else if (!e)
+				error(loc, "variable %s is used before initialization", v.toChars());
+			else if (e !is EXP_CANT_INTERPRET)
+				e = e.interpret(istate);
+		}
+		if (!e)
+			e = EXP_CANT_INTERPRET;
+    }
+    else if (s)
+    {
+		if (s.dsym.toInitializer() == s.sym)
+		{   
+			Expressions exps = new Expressions();
+			e = new StructLiteralExp(Loc(0), s.dsym, exps);
+			e = e.semantic(null);
+		}
+    }
+    return e;
+}
+
+/* Helper functions for BinExp.interpretAssignCommon
+ */
+
+/***************************************
+ * Duplicate the elements array, then set field 'indexToChange' = newelem.
+ */
+Expressions changeOneElement(Expressions oldelems, size_t indexToChange, void* newelem)
+{
+    Expressions expsx = new Expressions();
+    expsx.setDim(oldelems.dim);
+    for (size_t j = 0; j < expsx.dim; j++)
+    {
+		if (j == indexToChange)
+			expsx.data[j] = newelem;
+		else
+			expsx.data[j] = oldelems.data[j];
+    }
+    return expsx;
+}
+
+/***************************************
+ * Returns oldelems[0..insertpoint] ~ newelems ~ oldelems[insertpoint..$]
+ */
+Expressions spliceElements(Expressions oldelems, Expressions newelems, size_t insertpoint)
+{
+    Expressions expsx = new Expressions();
+    expsx.setDim(oldelems.dim);
+    for (size_t j = 0; j < expsx.dim; j++)
+    {
+		if (j >= insertpoint && j < insertpoint + newelems.dim)
+			expsx.data[j] = newelems.data[j - insertpoint];
+		else
+			expsx.data[j] = oldelems.data[j];
+    }
+    return expsx;
+}
+
+/******************************
+ * Create an array literal consisting of 'elem' duplicated 'dim' times.
+ */
+ArrayLiteralExp createBlockDuplicatedArrayLiteral(Type type, Expression elem, size_t dim)
+{
+    Expressions elements = new Expressions();
+    elements.setDim(dim);
+    for (size_t i = 0; i < dim; i++) {
+		elements.data[i] = cast(void*)elem;
+	}
+	
+    ArrayLiteralExp ae = new ArrayLiteralExp(Loc(0), elements);
+    ae.type = type;
+    return ae;
+}
+
+
+/********************************
+ * Necessary because defaultInit() for a struct is a VarExp, not a StructLiteralExp.
+ */
+StructLiteralExp createDefaultInitStructLiteral(Loc loc, StructDeclaration sym)
+{
+    Expressions structelems = new Expressions();
+    structelems.setDim(sym.fields.dim);
+    for (size_t j = 0; j < structelems.dim; j++)
+    {
+		structelems.data[j] = cast(void*)(cast(VarDeclaration)(sym.fields.data[j])).type.defaultInit(Loc(0));
+    }
+    StructLiteralExp structinit = new StructLiteralExp(loc, sym, structelems);
+    // Why doesn't the StructLiteralExp constructor do this, when
+    // sym.type != null ?
+    structinit.type = sym.type;
+    return structinit;
+}
+
+/********************************
+ *  Add v to the istate list, unless it already exists there.
+ */
+void addVarToInterstate(InterState istate, VarDeclaration v)
+{
+    if (!v.isParameter())
+    {
+		for (size_t i = 0; 1; i++)
+		{
+			if (i == istate.vars.dim)
+			{   
+				istate.vars.push(cast(void*)v);
+				//printf("\tadding %s to istate\n", v.toChars());
+				break;
+			}
+			if (v == cast(VarDeclaration)istate.vars.data[i])
+				break;
+		}
+    }
+}
\ No newline at end of file