changeset 182:4e703658eca0

merge
author Anders Halager <halager@gmail.com>
date Fri, 25 Jul 2008 01:40:08 +0200
parents 59cd211a1bd3 (diff) 29324df1d649 (current diff)
children 8ea749b7da91
files
diffstat 4 files changed, 124 insertions(+), 88 deletions(-) [+]
line wrap: on
line diff
--- a/ast/Exp.d	Fri Jul 25 01:34:12 2008 +0200
+++ b/ast/Exp.d	Fri Jul 25 01:40:08 2008 +0200
@@ -104,7 +104,7 @@
 
     override DType type()
     {
-        DFunction f = cast(DFunction)exp.type();
+        DFunction f = exp.type.asCallable();
         assert(f !is null, "Can only call functions");
         return f.returnType;
     }
--- a/gen/CodeGen.d	Fri Jul 25 01:34:12 2008 +0200
+++ b/gen/CodeGen.d	Fri Jul 25 01:40:08 2008 +0200
@@ -218,7 +218,7 @@
                 auto id = varDecl.identifier;
                 Type t = llvm(id.type);
                 GlobalVariable g = m.addGlobal(t, id.get);
-                g.initializer = ConstantInt.GetS(t, 0);
+                g.initializer = Constant.GetNull(t);
                 table[varDecl.identifier.get] = g;
                 break;
 
@@ -342,6 +342,10 @@
                 auto derefExp = cast(DerefExp)exp;
                 auto target = genExpression(derefExp.exp);
                 return RValue(b.buildLoad(target.value, "deref"));
+            case ExpType.AddressOfExp:
+                auto addrExp = cast(AddressOfExp)exp;
+                auto target = genLValue(addrExp.exp);
+                return RValue(target.getAddress());
             case ExpType.AssignExp:
                 auto AE = cast(AssignExp)exp;
                 LValue dst = genLValue(AE.identifier);
@@ -372,11 +376,11 @@
                 // if delegate do a third thing
                 // if struct/class check for opCall
                 DType type = callExp.exp.type;
-                assert (type.isFunction(), "Can only call functions");
+                assert (type.isCallable(), "Can only call functions");
                 scope args = new Value[callExp.args.length];
                 foreach (i, arg; callExp.args)
                     args[i] = genExpression(arg).value;
-                DFunction ftype = type.asFunction();
+                DFunction ftype = type.asCallable();
                 Type llvm_ftype = llvm(ftype);
                 Value f = null;
                 if (callExp.callSym is null)
@@ -409,11 +413,19 @@
 
             case ExpType.Identifier:
                 auto id = cast(Identifier)exp;
-                if (id.type.isStruct()
-                        || id.type.isArray()
-                        || id.type.isStaticArray()
-                        || id.type.isClass())
+                auto type = id.type;
+                if (type.isStruct()
+                        || type.isArray()
+                        || type.isStaticArray()
+                        || type.isClass())
                     return RValue(table.find(id.get));
+                else if (type.isFunction())
+                {
+                    auto func_name = id.getSymbol().getMangledFQN();
+                    return RValue(m.getNamedFunction(func_name));
+                }
+                else if (type.isCallable())
+                    return RValue(genLValue(id).getAddress());
                 else
                     return RValue(b.buildLoad(table.find(id.get), id.get));
             case ExpType.MemberReference:
@@ -690,7 +702,10 @@
         {
             case ExpType.Identifier:
                 auto id = cast(Identifier)exp;
-                return LValue(table.find(id.get));
+                Value v = table.find(id.get);
+                if (v is null)
+                    v = m.getNamedFunction(id.getSymbol().getMangledFQN());
+                return LValue(v);
             case ExpType.Deref:
                 // LValue(*x): load(x)
                 // RValue(*x): load(load(x))
--- a/sema/DType.d	Fri Jul 25 01:34:12 2008 +0200
+++ b/sema/DType.d	Fri Jul 25 01:40:08 2008 +0200
@@ -61,6 +61,11 @@
     /// Return a DFunction if this is one, otherwise return null
     DFunction asFunction() { return null; }
 
+    /// Is this type a DFunction or a pointer to one
+    bool isCallable() { return false; }
+    /// Return a DFunction if this one is available
+    DFunction asCallable() { return null; }
+
     /// Returns true for integers, reals and complex numbers
     bool isArithmetic() { return false; }
 
@@ -607,6 +612,8 @@
 
     override bool isPointer() { return true; }
     override DPointer asPointer() { return this; }
+    bool isCallable() { return pointerOf.isFunction(); }
+    DFunction asCallable() { return pointerOf.asFunction(); }
 
     int byteSize() { return DType.Int.byteSize; }
 
@@ -655,6 +662,8 @@
 
     override bool isFunction() { return true; }
     override DFunction asFunction() { return this; }
+    bool isCallable() { return true; }
+    DFunction asCallable() { return this; }
 
     override bool hasImplicitConversionTo(DType that)
     {
--- a/sema/TypeCheck.d	Fri Jul 25 01:34:12 2008 +0200
+++ b/sema/TypeCheck.d	Fri Jul 25 01:40:08 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
         {