Mercurial > projects > ddmd
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