Mercurial > projects > ddmd
diff dmd/expression/Util.d @ 130:60bb0fe4563e
dmdfe 2.037 first main iteration
author | Eldar Insafutdinov <e.insafutdinov@gmail.com> |
---|---|
date | Thu, 09 Sep 2010 22:51:44 +0100 |
parents | 010eb8f0e18d |
children | af1bebfd96a4 |
line wrap: on
line diff
--- a/dmd/expression/Util.d Sun Sep 05 15:32:22 2010 +0400 +++ b/dmd/expression/Util.d Thu Sep 09 22:51:44 2010 +0100 @@ -24,7 +24,8 @@ import dmd.IndexExp; import dmd.AssignExp; import dmd.CommaExp; -import dmd.Argument; +import dmd.CondExp; +import dmd.Parameter; import dmd.DefaultInitExp; import dmd.Identifier; import dmd.Dsymbol; @@ -64,6 +65,7 @@ import dmd.TypeAArray; import dmd.Id; import dmd.PtrExp; +import dmd.ErrorExp; import std.stdio : writef; @@ -188,17 +190,30 @@ struct Param2 { Match* m; +version(DMDV2) { Expression ethis; + int property; // 0: unintialized + // 1: seen @property + // 2: not @property +} Expressions arguments; - int fp2(void*, FuncDeclaration f) - { + int fp2(void* param, FuncDeclaration f) + { + auto p = cast(Param2*)param; MATCH match; if (f != m.lastf) // skip duplicates { m.anyf = f; TypeFunction tf = cast(TypeFunction)f.type; + + int property = (tf.isproperty) ? 1 : 2; + if (p.property == 0) + p.property = property; + else if (p.property != property) + error(f.loc, "cannot overload both property and non-property functions"); + match = tf.callMatch(f.needThis() ? ethis : null, arguments); //printf("test: match = %d\n", match); if (match != MATCH.MATCHnomatch) @@ -216,6 +231,7 @@ else if (f.overrides(m.lastf)) goto LfIsBetter; +version(DMDV2) { /* Try to disambiguate using template-style partial ordering rules. * In essence, if f() and g() are ambiguous, if f() can call g(), * but g() cannot call f(), then pick f(). @@ -230,6 +246,7 @@ if (c1 < c2) goto LlastIsBetter; } +} Lambiguous: m.nextf = f; @@ -264,9 +281,10 @@ } version (DMDV2) { - /* Allow covariant matches, if it's just a const conversion - * of the return type - */ + /* Allow covariant matches, as long as the return type + * is just a const conversion. + * This allows things like pure functions to match with an impure function type. + */ if (t.ty == Tfunction) { TypeFunction tf = cast(TypeFunction)f.type; @@ -287,6 +305,7 @@ Param2 p; p.m = m; p.ethis = ethis; + p.property = 0; p.arguments = arguments; overloadApply(fstart, &p.fp2, &p); } @@ -328,11 +347,108 @@ } } +Expressions arrayExpressionToCommonType(Scope sc, Expressions exps, Type *pt) +{ +//version(DMDV1) { +// /* The first element sets the type +// */ +// Type *t0 = NULL; +// for (size_t i = 0; i < exps->dim; i++) +// { Expression *e = (Expression *)exps->data[i]; +// +// if (!e->type) +// { error("%s has no value", e->toChars()); +// e = new ErrorExp(); +// } +// e = resolveProperties(sc, e); +// +// if (!t0) +// t0 = e->type; +// else +// e = e->implicitCastTo(sc, t0); +// exps->data[i] = (void *)e; +// } +// +// if (!t0) +// t0 = Type::tvoid; +// if (pt) +// *pt = t0; +// +// // Eventually, we want to make this copy-on-write +// return exps; +//} +version(DMDV2) { + /* The type is determined by applying ?: to each pair. + */ + /* Still have a problem with: + * ubyte[][] = [ cast(ubyte[])"hello", [1]]; + * which works if the array literal is initialized top down with the ubyte[][] + * type, but fails with this function doing bottom up typing. + */ + //printf("arrayExpressionToCommonType()\n"); + scope integerexp = new IntegerExp(0); + scope condexp = new CondExp(Loc(0), integerexp, null, null); + + Type t0; + Expression e0; + int j0; + foreach (size_t i, Expression e; exps) + { + e = resolveProperties(sc, e); + if (!e.type) + { error("%s has no value", e.toChars()); + e = new ErrorExp(); + } + + if (t0) + { + if (t0 != e.type) + { + /* This applies ?: to merge the types. It's backwards; + * ?: should call this function to merge types. + */ + condexp.type = null; + condexp.e1 = e0; + condexp.e2 = e; + condexp.semantic(sc); + exps[j0] = condexp.e1; + e = condexp.e2; + j0 = i; + e0 = e; + t0 = e0.type; + } + } + else + { + j0 = i; + e0 = e; + t0 = e.type; + } + exps[i] = e; + } + + if (t0) + { + foreach (ref Expression e; exps) + { + e = e.implicitCastTo(sc, t0); + } + } + else + t0 = Type.tvoid; // [] is typed as void[] + if (pt) + *pt = t0; + + // Eventually, we want to make this copy-on-write + return exps; +} +} + /**************************************** * Preprocess arguments to function. */ -void preFunctionArguments(Loc loc, Scope sc, Expressions exps) +void preFunctionParameters(Loc loc, Scope sc, Expressions exps) { if (exps) { @@ -480,14 +596,14 @@ * 5. call copy constructor for struct value arguments */ -void functionArguments(Loc loc, Scope sc, TypeFunction tf, Expressions arguments) +void functionParameters(Loc loc, Scope sc, TypeFunction tf, Expressions arguments) { uint n; - //printf("functionArguments()\n"); + //printf("functionParameters()\n"); assert(arguments); size_t nargs = arguments ? arguments.dim : 0; - size_t nparams = Argument.dim(tf.parameters); + size_t nparams = Parameter.dim(tf.parameters); if (nargs > nparams && tf.varargs == 0) error(loc, "expected %zu arguments, not %zu for non-variadic function type %s", nparams, nargs, tf.toChars()); @@ -508,7 +624,7 @@ if (i < nparams) { - auto p = Argument.getNth(tf.parameters, i); + auto p = Parameter.getNth(tf.parameters, i); if (!arg) { @@ -518,21 +634,13 @@ goto L2; error(loc, "expected %d function arguments, not %d", nparams, nargs); - break; + return; } arg = p.defaultArg; -version (DMDV2) { - if (arg.op == TOK.TOKdefault) - { - DefaultInitExp de = cast(DefaultInitExp)arg; - arg = de.resolve(loc, sc); - } - else - { - arg = arg.copy(); - } -} else { arg = arg.copy(); +version (DMDV2) +{ + arg = arg.resolveLoc(loc, sc); // __FILE__ and __LINE__ } arguments.push(arg); nargs++; @@ -544,7 +652,10 @@ if (arg.implicitConvTo(p.type)) { if (nargs != nparams) + { error(loc, "expected %zu function arguments, not %zu", nparams, nargs); + return; + } goto L1; } L2: @@ -778,6 +889,7 @@ // If D linkage and variadic, add _arguments[] as first argument if (tf.linkage == LINK.LINKd && tf.varargs == 1) { + assert(arguments.dim >= nparams); auto e = createTypeInfoArray(sc, &arguments[nparams], arguments.dim - nparams); arguments.insert(0, e); } @@ -954,11 +1066,11 @@ /* Create the TypeTuple corresponding to the types of args[] */ - Arguments args = new Arguments; + auto args = new Parameters; args.setDim(dim); for (size_t i = 0; i < dim; i++) { - Argument arg = new Argument(STCin, exps[i].type, null, null); + auto arg = new Parameter(STCin, exps[i].type, null, null); args[i] = arg; } TypeTuple tup = new TypeTuple(args); @@ -1274,7 +1386,7 @@ * them from the aggregate type. */ -void inferApplyArgTypes(TOK op, Arguments arguments, Expression aggr) +void inferApplyArgTypes(TOK op, Parameters arguments, Expression aggr) { if (!arguments || !arguments.dim) return; @@ -1286,14 +1398,14 @@ if (u == arguments.dim) return; - Argument arg = arguments[u]; + auto arg = arguments[u]; if (!arg.type) break; } AggregateDeclaration ad; - Argument arg = arguments[0]; + auto arg = arguments[0]; Type taggr = aggr.type; if (!taggr) return; @@ -1315,7 +1427,7 @@ case TY.Taarray: { - TypeAArray taa = cast(TypeAArray)tab; + auto taa = cast(TypeAArray)tab; if (arguments.dim == 2) { @@ -1414,7 +1526,7 @@ int fp3(void*, FuncDeclaration f) { - TypeFunction tf = cast(TypeFunction)f.type; + auto tf = cast(TypeFunction)f.type; if (inferApplyArgTypesY(tf, arguments) == 1) return 0; @@ -1424,10 +1536,10 @@ return 0; } - Arguments arguments; + Parameters arguments; } -void inferApplyArgTypesX(FuncDeclaration fstart, Arguments arguments) +void inferApplyArgTypesX(FuncDeclaration fstart, Parameters arguments) { Param3 p3; p3.arguments = arguments; @@ -1441,15 +1553,15 @@ * 1 no match for this function */ -int inferApplyArgTypesY(TypeFunction tf, Arguments arguments) +int inferApplyArgTypesY(TypeFunction tf, Parameters arguments) { size_t nparams; - Argument p; + Parameter p; - if (Argument.dim(tf.parameters) != 1) + if (Parameter.dim(tf.parameters) != 1) goto Lnomatch; - p = Argument.getNth(tf.parameters, 0); + p = Parameter.getNth(tf.parameters, 0); if (p.type.ty != TY.Tdelegate) goto Lnomatch; @@ -1459,7 +1571,7 @@ /* We now have tf, the type of the delegate. Match it against * the arguments, filling in missing argument types. */ - nparams = Argument.dim(tf.parameters); + nparams = Parameter.dim(tf.parameters); if (nparams == 0 || tf.varargs) goto Lnomatch; // not enough parameters if (arguments.dim != nparams) @@ -1467,8 +1579,8 @@ for (size_t u = 0; u < nparams; u++) { - Argument arg = arguments[u]; - Argument param = Argument.getNth(tf.parameters, u); + auto arg = arguments[u]; + auto param = Parameter.getNth(tf.parameters, u); if (arg.type) { if (!arg.type.equals(param.type)) @@ -1620,4 +1732,4 @@ * so be sure and ignore them. */ memcmp(&x1, &x2, REALSIZE - REALPAD) == 0; -} \ No newline at end of file +}