diff sema/TypeCheck.d @ 181:59cd211a1bd3

Better support for function pointers
author Anders Halager <halager@gmail.com>
date Fri, 25 Jul 2008 01:39:01 +0200
parents 2a1a635bd531
children 8ea749b7da91
line wrap: on
line diff
--- a/sema/TypeCheck.d	Fri Jul 25 01:21:07 2008 +0200
+++ b/sema/TypeCheck.d	Fri Jul 25 01:39:01 2008 +0200
@@ -113,106 +113,118 @@
 
             Exp[] newArgs;
 
-            Symbol[] methods = internalVisitMemberRef(iden);           
-
-            if (!methods.length)
+            DFunction function_type;
+            if (iden.type.isFunction())
             {
-                messages.report(NoMethodByName, iden.loc);
-                return;
-            }
+                Symbol[] methods = internalVisitMemberRef(iden);           
 
-            Symbol sel = getBestMatch(exp.args, methods);
+                if (!methods.length)
+                {
+                    messages.report(NoMethodByName, iden.loc);
+                    return;
+                }
 
-            if (sel)
-            {
-                foreach (i, arg; exp.args)
+                Symbol sel = getBestMatch(exp.args, methods);
+                exp.callSym = sel;
+                if (sel)
+                    function_type = sel.type.asFunction();
+                else
                 {
-                    auto argType = sel.type.asFunction.params[i];
-                    auto expType = arg.type;
-                    if (argType.isSame(expType))
+                    messages.report(NoMachingMethod, exp.loc);
+                    foreach ( i, s ; methods )
                     {
-                        if (!expType.hasImplicitConversionTo(argType))
-                            messages.report(InvalidImplicitCast, exp.loc)
-                                .arg(expType.toString)
-                                .arg(argType.toString);
-
-                        auto castExp = new CastExp(
-                                SLoc.Invalid,
-                                new Identifier(argType.name),
-                                arg);
-                        castExp.env = iden.env;
-                        newArgs ~= castExp;
+                        messages.report(CandidateNr, 
+                                (cast(FuncDecl)s.decl).identifier.loc)
+                            .arg(Integer.toString(i+1));
                     }
-                    else
-                        newArgs ~= arg;
-                }
-                exp.args = newArgs;
-                exp.callSym = sel;
-            }
-            else
-            {
-                messages.report(NoMachingMethod, exp.loc);
-                foreach ( i, s ; methods )
-                {
-                    messages.report(CandidateNr, 
-                            (cast(FuncDecl)s.decl).identifier.loc)
-                        .arg(Integer.toString(i+1));
                 }
             }
+            else if (iden.type.isCallable)
+                function_type = iden.type.asCallable();
+            else assert(0, "Should not happen");
+
+            foreach (i, arg; exp.args)
+            {
+                auto argType = function_type.params[i];
+                auto expType = arg.type;
+                if (argType.isSame(expType))
+                {
+                    if (!expType.hasImplicitConversionTo(argType))
+                        messages.report(InvalidImplicitCast, exp.loc)
+                            .arg(expType.toString)
+                            .arg(argType.toString);
+
+                    auto castExp = new CastExp(
+                            SLoc.Invalid,
+                            new Identifier(argType.name),
+                            arg);
+                    castExp.env = iden.env;
+                    newArgs ~= castExp;
+                }
+                else
+                    newArgs ~= arg;
+            }
+            exp.args = newArgs;
         }
         else if (auto iden = cast(Identifier)exp.exp)
         {
             Exp[] newArgs;
 
-            Symbol[] methods;
-            
-            foreach (decl ; iden.env.find(iden.get))
-                methods ~= decl.sym;
-
-            if (!methods.length)
+            DFunction function_type;
+            if (iden.type.isFunction())
             {
-                messages.report(NoMethodByName, iden.loc);
-                return;
-            }
+                Symbol[] methods;
 
-            Symbol sel = getBestMatch(exp.args, methods);
+                foreach (decl ; iden.env.find(iden.get))
+                    methods ~= decl.sym;
 
-            if (sel)
-            {
-                foreach (i, arg; exp.args)
+                if (!methods.length)
                 {
-                    auto argType = sel.type.asFunction.params[i];
-                    auto expType = arg.type;
-                    if (argType.byteSize != expType.byteSize)
+                    messages.report(NoMethodByName, iden.loc);
+                    return;
+                }
+
+                Symbol sel = getBestMatch(exp.args, methods);
+                exp.callSym = sel;
+                if (sel)
+                    function_type = sel.type.asFunction();
+                else
+                {
+                    messages.report(NoMachingMethod, exp.loc);
+                    foreach ( i, s ; methods )
                     {
-                        if (!expType.hasImplicitConversionTo(argType))
-                            messages.report(InvalidImplicitCast, exp.loc)
-                                .arg(expType.toString)
-                                .arg(argType.toString);
-
-                        auto castExp = new CastExp(
-                                SLoc.Invalid,
-                                new Identifier(argType.name),
-                                arg);
-                        castExp.env = iden.env;
-                        newArgs ~= castExp;
+                        messages.report(CandidateNr, 
+                                (cast(FuncDecl)s.decl).identifier.loc)
+                            .arg(Integer.toString(i+1));
                     }
-                    else
-                        newArgs ~= arg;
-                }
-                exp.args = newArgs;
-                exp.callSym = sel;
-            }
-            else
-            {
-                messages.report(NoMachingMethod, exp.loc);
-                foreach ( i, s ; methods )
-                {
-                    messages.report(CandidateNr, 
-                            (cast(FuncDecl)s.decl).identifier.loc)
-                        .arg(Integer.toString(i+1));
                 }
             }
+            else if (iden.type.isCallable)
+                function_type = iden.type.asCallable();
+            else assert(0, "Should not happen");
+
+            foreach (i, arg; exp.args)
+            {
+                auto argType = function_type.params[i];
+                auto expType = arg.type;
+                if (argType.isSame(expType))
+                {
+                    if (!expType.hasImplicitConversionTo(argType))
+                        messages.report(InvalidImplicitCast, exp.loc)
+                            .arg(expType.toString)
+                            .arg(argType.toString);
+
+                    auto castExp = new CastExp(
+                            SLoc.Invalid,
+                            new Identifier(argType.name),
+                            arg);
+                    castExp.env = iden.env;
+                    newArgs ~= castExp;
+                }
+                else
+                    newArgs ~= arg;
+            }
+            exp.args = newArgs;
         }
         else
         {