From 93654e5246f1b9ecf3e55ea04e9cc0b7e5c9825a Mon Sep 17 00:00:00 2001 From: Thomas Leonard Date: Sun, 7 Sep 2008 17:01:23 +0100 Subject: [PATCH] Passes arguments to Main constructor Each argument is created by calling _externals.ARG() in the generated main() function. --- dmd/idgen.c | 1 + dmd/module.c | 84 +++++++++++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 65 insertions(+), 20 deletions(-) diff --git a/dmd/idgen.c b/dmd/idgen.c index 7d882b4..6a0ce7e 100644 --- a/dmd/idgen.c +++ b/dmd/idgen.c @@ -211,6 +211,7 @@ struct Msgtable msgtable[] = { "aaKeys", "_aaKeys" }, { "aaValues", "_aaValues" }, { "aaRehash", "_aaRehash" }, + { "_externals" }, { "args" }, // For pragma's diff --git a/dmd/module.c b/dmd/module.c index 46728a9..449697f 100644 --- a/dmd/module.c +++ b/dmd/module.c @@ -649,34 +649,73 @@ void Module::parse() } FuncDeclaration *addMainFunction(Dsymbol *mainClass) { - ClassDeclaration *klass = mainClass->isClassDeclaration(); - if (klass == NULL) { - // Just ignore it then? - error("'Main' is not a class!"); - } + ClassDeclaration *klass = mainClass->isClassDeclaration(); + if (klass == NULL) { + // Just ignore it then? + error("'Main' is not a class!"); + } - // Create a main(string[] args) function - Arguments *arguments = new Arguments(); + // Create a main(string[] args) function + Arguments *arguments = new Arguments(); - Type *tstr = new TypeDArray(Type::tchar); - Type *targv = new TypeDArray(tstr); + Type *tstr = new TypeDArray(Type::tchar); + Type *targv = new TypeDArray(tstr); - Argument *a = new Argument(STCin, targv, Id::args, NULL); - arguments->push(a); + Argument *a = new Argument(STCin, targv, Id::args, NULL); + arguments->push(a); - Loc loc = mainClass->loc; + Loc loc = mainClass->loc; - TypeFunction *ta = new TypeFunction(arguments, new Type(Tvoid, NULL), 0, LINKc); - FuncDeclaration *f = new FuncDeclaration(mainClass->loc, 0, Id::main, STCundefined, ta); + TypeFunction *ta = new TypeFunction(arguments, new Type(Tvoid, NULL), 0, LINKc); + FuncDeclaration *f = new FuncDeclaration(mainClass->loc, 0, Id::main, STCundefined, ta); - // Inside main(), create a new Main + // Find the constructor + CtorDeclaration *ctor = NULL; + for (int i = 0; i < klass->members->dim; i++) { + Dsymbol *s; - f->endloc = mainClass->loc; - NewExp *e = new NewExp(loc, NULL, NULL, klass->getType(), NULL); - Statement *s = new ExpStatement(loc, e); - f->fbody = s; + s = (Dsymbol *)klass->members->data[i]; + CtorDeclaration *thisCtor = s->isCtorDeclaration(); + if (thisCtor) { + if (ctor) { + error(thisCtor->loc, "Multiple constructors for Main class!"); + return NULL; + } else { + ctor = thisCtor; + } + } + } - return f; + Expressions *args = new Expressions(); + + if (ctor == NULL) { + f->endloc = klass->loc; // Use default constructor + } else { + f->endloc = ctor->loc; + + Expressions *builderArgs = new Expressions(); + Expression *externals = new IdentifierExp(ctor->loc, Id::_externals); + // Collect all the objects we need for the constructor's arguments + for (int i = 0; i < ctor->arguments->dim; i++) { + Argument *arg = (Argument *) ctor->arguments->data[i]; + Expression *builder = new DotIdExp(ctor->loc, externals, arg->ident); + args->push(new CallExp(ctor->loc, builder, builderArgs)); + /* + error(ctor->loc, + "Don't know how to provide a '%s' to the Main constructor", + arg->ident->toChars()); + return NULL; + */ + } + } + + // Inside main(), create a new Main + + NewExp *e = new NewExp(loc, NULL, NULL, klass->getType(), args); + Statement *s = new ExpStatement(loc, e); + f->fbody = s; + + return f; } void Module::semantic() @@ -730,7 +769,12 @@ void Module::semantic() if (s->ident && s->ident == Id::Main) { Dsymbol *mainFn = addMainFunction(s); + if (!mainFn) + return; members->push(mainFn); + + Import *im = new Import(0, NULL, Id::_externals, NULL, true); + members->shift(im); break; } } -- 2.11.4.GIT