# HG changeset patch # User Anders Johnsen # Date 1216894008 -7200 # Node ID 7982eb63c0ebdf55490d37ee70441d726dc3c9bf # Parent 9cfa335175263838086a7cfbb67704fe71790289 Some changes to get function overloading to work. Also class inherit works now - to some extend. needs vtables and all the complex stuff of it. diff -r 9cfa33517526 -r 7982eb63c0eb ast/Exp.d --- a/ast/Exp.d Tue Jul 22 21:34:53 2008 +0200 +++ b/ast/Exp.d Thu Jul 24 12:06:48 2008 +0200 @@ -115,6 +115,7 @@ Exp exp; Exp[] args; + Symbol callSym; bool sret = false; override SourceRange sourceRange() @@ -389,16 +390,16 @@ if ( target.type.isStruct ) { - DStruct st = target.type.asStruct; - if (auto t = st.typeOf(child.name)) - myType = t; + Symbol st = target.getSymbol; + if (auto t = st.findMembers(child.name)) + myType = t[0].type; // else assert(0, "Referencing non-existant member"); } else if ( target.type.isClass ) { - DClass cl = target.type.asClass; - if (auto t = cl.typeOf(child.name)) - myType = t; + Symbol cl = target.getSymbol; + if (auto t = cl.findMembers(child.name)) + myType = t[0].type; // else assert(0, "Referencing non-existant member"); } else @@ -605,9 +606,9 @@ override Symbol getSymbol() { if (auto decl = env.find(this.get)) - return decl.sym; - else - return null; + if(decl.length) + return decl[$-1].sym; + return null; } override DType type() diff -r 9cfa33517526 -r 7982eb63c0eb basic/Messages.d --- a/basic/Messages.d Tue Jul 22 21:34:53 2008 +0200 +++ b/basic/Messages.d Thu Jul 24 12:06:48 2008 +0200 @@ -41,6 +41,8 @@ NoConstructor, NoMachingCon, CandidateNr, + NoMethodByName, + NoMachingMethod, // Strings InvalidStrPrefix, @@ -113,6 +115,8 @@ NoConstructor : E(Err, "No constructor avaible"), NoMachingCon : E(Err, "No maching constructor. Candidates are:"), CandidateNr : E(Err, "Candidate number %0"), + NoMethodByName : E(Err, "No method with that name"), + NoMachingMethod : E(Err, "No maching method. Candidates are:"), // - switch MultipleDefaults : E(Err, "Switch statements can't have multiple defaults"), diff -r 9cfa33517526 -r 7982eb63c0eb dang/compiler.d --- a/dang/compiler.d Tue Jul 22 21:34:53 2008 +0200 +++ b/dang/compiler.d Thu Jul 24 12:06:48 2008 +0200 @@ -29,6 +29,7 @@ sema.LiteralInterpreter, sema.ScopeCheck, sema.VC, + sema.ObjectOriented, sema.TypeCheck; import tango.stdc.posix.unistd; @@ -320,6 +321,11 @@ auto type_check = watch2.stop; watch2.start; + (new ObjectOriented(messages)).visit(modules); + messages.checkErrors; + auto object_check = watch2.stop; + + watch2.start; auto vc = new VC; vc.msg = messages; foreach (m; modules) diff -r 9cfa33517526 -r 7982eb63c0eb sema/ObjectOriented.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sema/ObjectOriented.d Thu Jul 24 12:06:48 2008 +0200 @@ -0,0 +1,64 @@ +module sema.ObjectOriented; + +import sema.Visitor, + sema.Symbol, + sema.DType; + +import tango.io.Stdout, + Array = tango.core.Array; + +import basic.SourceLocation, + basic.Message; + +class ObjectOriented : Visitor!(void) +{ + this(MessageHandler messages) + { + this.messages = messages; + } + + override void visit(Module[] m) + { + super.visit(m); + + ClassDecl[] visitBaseClass(ClassDecl current, ClassDecl[] visited) + { + visited ~= current; + foreach (d ; current.baseClasses) + if (d.type.isClass) + if(Array.find(visited, + (cast(ClassDecl)d.getSymbol.decl)) - visited.length) + assert(0,"Circulair base class"); + else + return visitBaseClass((cast(ClassDecl)d.getSymbol.decl), visited); + return visited; + } + + while (classes.length) + { + ClassDecl current = classes[$-1]; + ClassDecl[] visited; + visited = visitBaseClass(current, visited); + foreach (v; visited) + classes.length = Array.remove(classes, v); + } + } + + override void visitClassDecl(ClassDecl decl) + { + classes ~= decl; + } + + ClassDecl[] classNoBase; + ClassDecl[] classes; + MessageHandler messages; +} + +class FindClassNoBase : Visitor!(void) +{ + override void visitClassDecl(ClassDecl decl) + { + } + + ClassDecl[] classes; +} diff -r 9cfa33517526 -r 7982eb63c0eb sema/Scope.d --- a/sema/Scope.d Tue Jul 22 21:34:53 2008 +0200 +++ b/sema/Scope.d Thu Jul 24 12:06:48 2008 +0200 @@ -30,23 +30,23 @@ void put(char[] id, Decl d) { - symbols[id] = d; + symbols[id] ~= d; } - Decl find(char[] id) + Decl[] find(char[] id) { - if(id is null) + if(id is "") return null; else if (auto sym = id in symbols) + { return *sym; + } else if (enclosing !is null) { - auto res = enclosing.find(id); - if (res is null) - return mHandle.find(getImports, id); + auto res = enclosing.find(id) ~ mHandle.find(getImports, id); return res; } - return null; + return []; } ImportDecl[] getImports() @@ -110,7 +110,7 @@ DType[char[]] types; int currentStmtIndex = -1; private: - Decl[char[]] symbols; + Decl[][char[]] symbols; FuncDecl func; } @@ -138,7 +138,7 @@ return null; } - Decl find(ImportDecl[] imports, char[] id) + Decl[] find(ImportDecl[] imports, char[] id) { foreach(i ; imports) if(i.get in modules) @@ -147,7 +147,7 @@ if(t !is null) return t; } - return null; + return []; } char[][char[]] fileToModule; diff -r 9cfa33517526 -r 7982eb63c0eb sema/ScopeBuilder.d --- a/sema/ScopeBuilder.d Tue Jul 22 21:34:53 2008 +0200 +++ b/sema/ScopeBuilder.d Thu Jul 24 12:06:48 2008 +0200 @@ -64,7 +64,7 @@ DType t = typeOf(d.varType, d.env); d.sym = current.symbol.createAlias( d.identifier.get, - d.env.find(d.varType.get).sym, + d.env.find(d.varType.get)[0].sym, d); d.sym.type = t; } @@ -131,7 +131,7 @@ s.sym = current.symbol.createMember( s.identifier.get, st, - s.env.find(s.identifier.get)); + s.env.find(s.identifier.get)[0]); foreach (decl; s.decls) { @@ -158,7 +158,7 @@ s.sym = current.symbol.createMember( s.identifier.get, st, - s.env.find(s.identifier.get)); + s.env.find(s.identifier.get)[0]); foreach (decl; s.decls) { @@ -185,7 +185,7 @@ s.sym = current.symbol.createMember( s.identifier.get, st, - s.env.find(s.identifier.get)); + s.env.find(s.identifier.get)[0]); foreach (decl; s.decls) { diff -r 9cfa33517526 -r 7982eb63c0eb sema/ScopeCheck.d --- a/sema/ScopeCheck.d Tue Jul 22 21:34:53 2008 +0200 +++ b/sema/ScopeCheck.d Thu Jul 24 12:06:48 2008 +0200 @@ -39,7 +39,7 @@ if (d.env.parentFunction !is null) while( d.env.parentFunction.env !is env) { - if (d.env.enclosing.find(d.identifier.get).env == env) + if (d.env.enclosing.find(d.identifier.get)[0].env == env) messages.report(CannotRedeclare, d.identifier.loc) .arg(d.identifier.get); env = env.enclosing; @@ -74,40 +74,31 @@ private Symbol internalVisitMemberRef(MemberReference m) { + Symbol visitRef(MemberReference m, Identifier target, Symbol st) + { + auto child = m.child; + auto res = st.findMembers(child.get); + + if(!res.length) + messages.report(MissingMember, m.loc) + .arg(st.type.name) + .arg(target.get) + .arg(child.get); + else + internalCheckProtection(res[0], child); + + return res.length ? res[0] : null; + } switch(m.target.expType) { case ExpType.Identifier: - auto target = cast(Identifier)m.target; - auto child = m.child; - auto st = target.getSymbol; - auto res = st.findMembers(child.get); - - if(!res.length) - messages.report(MissingMember, m.loc) - .arg(st.type.name) - .arg(target.get) - .arg(child.get); - else - internalCheckProtection(res[0], child); - - return res.length ? res[0] : null; + return visitRef(m, cast(Identifier)m.target, + (cast(Identifier)m.target).getSymbol); case ExpType.MemberReference: Symbol s = internalVisitMemberRef(cast(MemberReference)m.target); if(!s) return null; - auto target = cast(Identifier)m.target; - auto child = m.child; - auto res = s.findMembers(child.get); - - if(!res.length) - messages.report(MissingMember, m.loc) - .arg(s.type.name) - .arg(target.get) - .arg(child.get); - else - internalCheckProtection(res[0], child); - - return res.length ? res[0] : null; + return visitRef(m, cast(Identifier)m.target, s); } } @@ -118,7 +109,7 @@ { if (exp.env.findType((cast(Identifier)exp).get) is null) internalCheckProtection( - exp.env.find((cast(Identifier)exp).get).sym, + exp.env.find((cast(Identifier)exp).get)[0].sym, cast(Identifier)exp); } diff -r 9cfa33517526 -r 7982eb63c0eb sema/Symbol.d --- a/sema/Symbol.d Tue Jul 22 21:34:53 2008 +0200 +++ b/sema/Symbol.d Thu Jul 24 12:06:48 2008 +0200 @@ -40,8 +40,7 @@ } /** - Try to find a contained symbol with the given name - returns null if not - found + Try to find a contained symbol with the given name **/ Symbol[] findMembers(char[] member) { @@ -49,6 +48,25 @@ foreach (possible; actual.contained) if (possible.name == member) res ~= possible; + + if (!res.length && actual.type.isClass) + { + foreach (base ; (cast(ClassDecl)actual.decl).baseClasses) + if (base.type.isClass) + res ~= base.getSymbol.findMembers(member); + } + return res; + } + + /** + Try to find a contained symbol with the given name, who's type is a DFunction + **/ + Symbol[] findFunctionMembers(char[] member) + { + Symbol[] res; + foreach (possible; actual.contained) + if (possible.name == member && possible.type.isFunction) + res ~= possible; return res; } @@ -103,6 +121,11 @@ // to that symbol Symbol parent; + char[] toString() + { + return getMangledFQN; + } + private: // Helper for getMangledFQN - gets the FQN without _D and the type char[] internalFQN() diff -r 9cfa33517526 -r 7982eb63c0eb sema/TypeCheck.d --- a/sema/TypeCheck.d Tue Jul 22 21:34:53 2008 +0200 +++ b/sema/TypeCheck.d Thu Jul 24 12:06:48 2008 +0200 @@ -88,31 +88,89 @@ { super.visitCallExp(exp); - Exp[] newArgs; - - foreach(i, arg; exp.args) + if (auto iden = cast(Identifier)exp.exp) { - auto argType = exp.exp.type.asFunction.params[i]; - auto expType = arg.type; - if(argType.byteSize != expType.byteSize) + Exp[] newArgs; + + Symbol[] methods; + + foreach (decl ; iden.env.find(iden.get)) + methods ~= decl.sym; + + if (!methods.length) + { + messages.report(NoMethodByName, iden.loc); + return; + } + + Symbol sel = getBestMatch(exp.args, methods); + + if (sel) { - if(!expType.hasImplicitConversionTo(argType)) - messages.report(InvalidImplicitCast, exp.loc) - .arg(expType.toString) - .arg(argType.toString); + foreach (i, arg; exp.args) + { + auto argType = sel.type.asFunction.params[i]; + auto expType = arg.type; + if (argType.byteSize != expType.byteSize) + { + 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 = exp.exp.env; - newArgs ~= castExp; + auto castExp = new CastExp( + SLoc.Invalid, + new Identifier(argType.name), + arg); + castExp.env = iden.env; + newArgs ~= castExp; + } + else + newArgs ~= arg; + } + exp.args = newArgs; + exp.callSym = sel; } else - newArgs ~= arg; + { + messages.report(NoMachingMethod, exp.loc); + foreach ( i, s ; methods ) + { + messages.report(CandidateNr, + (cast(FuncDecl)s.decl).identifier.loc) + .arg(Integer.toString(i+1)); + } + } + } + else + { + Exp[] newArgs; - exp.args = newArgs; + foreach(i, arg; exp.args) + { + auto argType = exp.exp.type.asFunction.params[i]; + auto expType = arg.type; + if(argType.byteSize != expType.byteSize) + { + 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 = exp.exp.env; + newArgs ~= castExp; + } + else + newArgs ~= arg; + } + + exp.args = newArgs; + } } override void visitNewExp(NewExp exp) @@ -121,7 +179,7 @@ Exp[] newArgs; - Symbol[] methods = exp.newType.getSymbol.findMembers("this"); + Symbol[] methods = exp.newType.getSymbol.findFunctionMembers("this"); if (!methods.length) { @@ -243,14 +301,13 @@ } private Symbol getBestMatch(Exp[] arg_list , Symbol[] available) + in + { + foreach (a ; available) + assert(a.type.isFunction, "A non-function found in available-list."); + } body { - Symbol[] _a; - foreach (a ; available) - if (a.type.isFunction) - _a ~= a; - available = _a; - assert(available.length, "No available methods in symbol-list."); Symbol[] possible; @@ -262,6 +319,7 @@ continue; bool per = true; + bool work = true; foreach (i, arg; arg_list) { @@ -271,23 +329,22 @@ { per = false; if( !expType.hasImplicitConversionTo(argType) ) + { + work = false; break; - } - - if (i == arg_list.length-1) - { - bool work = true; - foreach (a ; (cast(FuncDecl)s.decl).funcArgs[i+1..$]) - if (a.init is null) - work = false; - - if (work) - if (per) - return s; - else - possible ~= s; + } } } + + foreach (a ; (cast(FuncDecl)s.decl).funcArgs[arg_list.length..$]) + if (a.init is null) + work = false; + + if (work) + if (per) + return s; + else + possible ~= s; } if (possible.length) diff -r 9cfa33517526 -r 7982eb63c0eb tests/sema/class_1.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/sema/class_1.d Thu Jul 24 12:06:48 2008 +0200 @@ -0,0 +1,35 @@ + +class A +{ + this() + { + } + + int foo() + { + return 1; + } + + int boo() + { + return 0; + } +} + +class B : A +{ + this() + { + } + + int foo() + { + return 0; + } +} + +int main() +{ + B a = new B(); + return a.foo() + a.boo(); +} diff -r 9cfa33517526 -r 7982eb63c0eb tests/sema/function_overload_1.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/sema/function_overload_1.d Thu Jul 24 12:06:48 2008 +0200 @@ -0,0 +1,12 @@ + + +void main() +{ + int x = 5; + foo(x); + long y = 12; + foo(y); +} + +int foo(long x); +int foo(int x);