# HG changeset patch # User Anders Halager # Date 1216942808 -7200 # Node ID 4e703658eca009c6b352b67cb1264b7146942685 # Parent 59cd211a1bd3231c1dd422acd236db2eefa9ec21# Parent 29324df1d64966ee17a2f94c46e79a544fa54adf merge diff -r 29324df1d649 -r 4e703658eca0 ast/Exp.d --- 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; } diff -r 29324df1d649 -r 4e703658eca0 gen/CodeGen.d --- 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)) diff -r 29324df1d649 -r 4e703658eca0 sema/DType.d --- 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) { diff -r 29324df1d649 -r 4e703658eca0 sema/TypeCheck.d --- 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 {