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
+}