changeset 367:dda55fae37de

- ImportGraph.execute() can parse all modules depending on the imports of the root module. - Added function findModule(). - Renamed option includes to import_paths. - Fix in ctor of ModuleDeclaration: check for pname.length before removing last separator. - Fixed scanning binary numbers. - Added member modules and method getFQN() to class Module. - Fix in parseIfStatement(): AttributeStatement mustn't have a null parameter. - Parsing import_paths in GlobalSettings.load().
author aziz
date Fri, 31 Aug 2007 23:07:05 +0000
parents dcbd3bf9bf74
children 2adf808343d6
files trunk/src/cmd/ImportGraph.d trunk/src/config.d trunk/src/dil/Declarations.d trunk/src/dil/Lexer.d trunk/src/dil/Module.d trunk/src/dil/Parser.d trunk/src/dil/Settings.d
diffstat 7 files changed, 86 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/trunk/src/cmd/ImportGraph.d	Fri Aug 31 12:14:03 2007 +0000
+++ b/trunk/src/cmd/ImportGraph.d	Fri Aug 31 23:07:05 2007 +0000
@@ -9,18 +9,60 @@
 import dil.Parser, dil.Lexer;
 import dil.File;
 import dil.Module;
+import dil.Settings;
 import std.stdio : writefln;
+import std.path : getDirName, dirSep = sep;
+import std.file : exists;
+
+string findModule(string moduleFQN, string[] importPaths)
+{
+  string modulePath;
+  foreach (path; importPaths)
+  {
+    modulePath = path ~ (path[$-1] == dirSep[0] ? "" : dirSep) ~ moduleFQN ~ ".d";
+    if (exists(modulePath))
+      return modulePath;
+  }
+  return null;
+}
+
+void execute(string fileName, string[] importPaths)
+{
+  // Add directory of file and global directories to import paths.
+  importPaths ~= getDirName(fileName) ~ GlobalSettings.importPaths;
+
+  Module[string] loadedModules;
 
-void execute(string fileName, string[] includePaths)
-{
+  Module loadModule(string moduleFQN)
+  {
+    auto mod_ = moduleFQN in loadedModules;
+    if (mod_ !is null)
+      return *mod_;
+
+    auto modulePath = findModule(moduleFQN, importPaths);
+    if (modulePath is null)
+      writefln("Warning: Module %s.d couldn't be found.", moduleFQN);
+    else
+    {
+      auto mod = new Module(modulePath);
+      mod.parse();
+
+      loadedModules[moduleFQN] = mod;
+
+      auto moduleFQNs = mod.getImports();
+
+      foreach (moduleFQN_; moduleFQNs)
+        mod.modules ~= loadModule(moduleFQN_);
+      return mod;
+    }
+    return null;
+  }
+
   auto mod = new Module(fileName);
   mod.parse();
-  auto root = mod.root;
 
-  Module[] modules;
+  auto moduleFQNs = mod.getImports();
 
-  foreach (decl; root.children)
-  {
-
-  }
+  foreach (moduleFQN_; moduleFQNs)
+    mod.modules ~= loadModule(moduleFQN_);
 }
--- a/trunk/src/config.d	Fri Aug 31 12:14:03 2007 +0000
+++ b/trunk/src/config.d	Fri Aug 31 23:07:05 2007 +0000
@@ -1,2 +1,2 @@
 option langfile = "lang_en.d";
-option includes = [];
+option import_paths = [];
--- a/trunk/src/dil/Declarations.d	Fri Aug 31 12:14:03 2007 +0000
+++ b/trunk/src/dil/Declarations.d	Fri Aug 31 23:07:05 2007 +0000
@@ -87,7 +87,8 @@
     foreach (pckg; packages)
       if (pckg)
         pname ~= pckg.identifier ~ separator;
-    pname = pname[0..$-1]; // Remove last separator
+    if (pname.length)
+      pname = pname[0..$-1]; // Remove last separator
     return pname;
   }
 }
--- a/trunk/src/dil/Lexer.d	Fri Aug 31 12:14:03 2007 +0000
+++ b/trunk/src/dil/Lexer.d	Fri Aug 31 23:07:05 2007 +0000
@@ -1140,15 +1140,16 @@
         ++digits;
         ulong_ *= 2;
       }
-      if (*p == '1')
+      else if (*p == '1')
       {
         ++digits;
         ulong_ *= 2;
         ulong_ += *p - '0';
       }
-      if (*p == '_')
-        continue;
-      break;
+      else if (*p == '_')
+        continue; 
+      else
+        break;
     }
 
     if (digits == 0)
@@ -1156,7 +1157,8 @@
 
     if (digits > 64)
       error(MID.OverflowBinaryNumber);
-    assert((p[-1] == '0' || p[-1] == '1' || p[-1] == '_') && !(*p == '0' || *p == '1' || *p == '_'));
+    assert(p[-1] == '0' || p[-1] == '1' || p[-1] == '_', p[-1] ~ "");
+    assert( !(*p == '0' || *p == '1' || *p == '_') );
     goto Lfinalize;
 
   LscanOct:
--- a/trunk/src/dil/Module.d	Fri Aug 31 12:14:03 2007 +0000
+++ b/trunk/src/dil/Module.d	Fri Aug 31 23:07:05 2007 +0000
@@ -20,6 +20,8 @@
   ModuleDeclaration moduleDecl;
   private Parser parser;
 
+  Module[] modules;
+
   this(string fileName)
   {
     this.fileName = fileName;
@@ -60,4 +62,9 @@
       result ~= import_.getModuleFQNs(std.path.sep[0]);
     return result;
   }
+
+  string getFQN()
+  {
+    return packageName ~ std.path.sep ~ moduleName;
+  }
 }
--- a/trunk/src/dil/Parser.d	Fri Aug 31 12:14:03 2007 +0000
+++ b/trunk/src/dil/Parser.d	Fri Aug 31 23:07:05 2007 +0000
@@ -1905,13 +1905,11 @@
     // auto Identifier = Expression
     if (token.type == T.Auto)
     {
-      auto a = new AttributeStatement(token.type, null);
       nT();
       ident = requireId();
       require(T.Assign);
       auto init = parseExpression();
-      a.statement = new DeclarationStatement(new VariableDeclaration(null, [ident], [init]));
-      variable = a;
+      variable = new AttributeStatement(T.Auto, new DeclarationStatement(new VariableDeclaration(null, [ident], [init])));
     }
     else
     {
--- a/trunk/src/dil/Settings.d	Fri Aug 31 12:14:03 2007 +0000
+++ b/trunk/src/dil/Settings.d	Fri Aug 31 23:07:05 2007 +0000
@@ -47,6 +47,7 @@
 static:
   string language; /// Language of messages catalogue to load.
   string[] messages; /// Table of localized compiler messages.
+  string[] importPaths; /// Array of import paths to look for modules.
   void load()
   {
     auto fileName = "config.d"[];
@@ -63,18 +64,32 @@
     foreach (decl; root.children)
     {
       auto v = Cast!(VariableDeclaration)(decl);
-      if (v && v.idents[0].srcText == "langfile")
+      if (v is null)
+        continue;
+      auto vname = v.idents[0].srcText;
+      if (vname == "langfile")
       {
         auto e = v.values[0];
         if (!e)
           throw new Exception("langfile variable has no value set.");
         auto val = Cast!(StringLiteralsExpression)(e);
         if (val)
-        {
           // Set fileName to d-file with messages table.
           fileName = val.getString();
-          break;
+      }
+      else if (vname == "import_paths")
+      {
+        auto e = v.values[0];
+        if (e is null)
+          throw new Exception("import_paths variable has no variable set.");
+        if (auto array = Cast!(ArrayInitializer)(e))
+        {
+          foreach (value; array.values)
+            if (auto str = Cast!(StringLiteralsExpression)(value))
+              GlobalSettings.importPaths ~= str.getString();
         }
+        else
+          throw new Exception("import_paths variable is set to "~e.classinfo.name~" instead of an ArrayInitializer.");
       }
     }