changeset 670:d8c32113afde

Added command 'translate'. Added Undefined to enum NodeCategory. Fixed ctor of QualifiedType. Improved GermanTranslator.
author Aziz K?ksal <aziz.koeksal@gmail.com>
date Thu, 17 Jan 2008 22:28:04 +0100
parents 1e3c5967ef12
children f1325a4506de
files trunk/src/dil/ast/NodesEnum.d trunk/src/dil/ast/Types.d trunk/src/dil/semantic/Pass1.d trunk/src/dil/translator/German.d trunk/src/main.d
diffstat 5 files changed, 186 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/trunk/src/dil/ast/NodesEnum.d	Thu Jan 17 19:45:28 2008 +0100
+++ b/trunk/src/dil/ast/NodesEnum.d	Thu Jan 17 22:28:04 2008 +0100
@@ -6,6 +6,7 @@
 
 enum NodeCategory : ushort
 {
+  Undefined,
   Declaration,
   Statement,
   Expression,
--- a/trunk/src/dil/ast/Types.d	Thu Jan 17 19:45:28 2008 +0100
+++ b/trunk/src/dil/ast/Types.d	Thu Jan 17 22:28:04 2008 +0100
@@ -11,6 +11,7 @@
 import dil.Enums;
 import dil.semantic.Types;
 
+// Scheduled for deletion.
 enum TID
 {
   Void    = TOK.Void,
@@ -54,6 +55,7 @@
   Invariant, // D2
 }
 
+/// The base class of all type nodes.
 abstract class TypeNode : Node
 {
   TID tid;
@@ -74,6 +76,7 @@
   }
 }
 
+/// Illegal type.
 class UndefinedType : TypeNode
 {
   this()
@@ -113,7 +116,9 @@
   this(TypeNode left, TypeNode right)
   {
     super(TID.Qualified, left);
+    mixin(set_kind);
     addChild(right);
+    this.right = right;
   }
 }
 
@@ -127,6 +132,7 @@
   }
 }
 
+/// "typeof" "(" Expression ")
 class TypeofType : TypeNode
 {
   Expression e;
@@ -137,6 +143,7 @@
     this.e = e;
   }
 
+  /// D2.0: "typeof" "(" "return" ")"
   this()
   {
     super(TID.Typeof);
@@ -149,6 +156,7 @@
   }
 }
 
+/// Identifier "!" "(" TemplateParameters? ")"
 class TemplateInstanceType : TypeNode
 {
   Identifier* ident;
@@ -163,6 +171,7 @@
   }
 }
 
+/// Type *
 class PointerType : TypeNode
 {
   this(TypeNode t)
@@ -236,6 +245,7 @@
   }
 }
 
+/// Type "(" BasicType2 Identifier ")" "(" Parameters? ")"
 class CFuncPointerType : TypeNode
 {
   Parameters params;
@@ -247,7 +257,7 @@
   }
 }
 
-/// "class" Identifier : BaseClass
+/// "class" Identifier : BaseClasses
 class BaseClassType : TypeNode
 {
   Protection prot;
@@ -261,6 +271,7 @@
 
 // version(D2)
 // {
+/// "const" "(" Type ")"
 class ConstType : TypeNode
 {
   this(TypeNode t)
@@ -271,6 +282,7 @@
   }
 }
 
+/// "invariant" "(" Type ")"
 class InvariantType : TypeNode
 {
   this(TypeNode t)
--- a/trunk/src/dil/semantic/Pass1.d	Thu Jan 17 19:45:28 2008 +0100
+++ b/trunk/src/dil/semantic/Pass1.d	Thu Jan 17 22:28:04 2008 +0100
@@ -66,7 +66,7 @@
   {
     foreach (node; d.children)
     {
-      assert(node.category == NodeCategory.Declaration);
+      assert(node.category == NodeCategory.Declaration, Format("{}", node));
       visitD(cast(Declaration)cast(void*)node);
     }
     return d;
--- a/trunk/src/dil/translator/German.d	Thu Jan 17 19:45:28 2008 +0100
+++ b/trunk/src/dil/translator/German.d	Thu Jan 17 22:28:04 2008 +0100
@@ -91,22 +91,39 @@
   }
 
   alias Enter!(ClassDeclaration) EnteredClass;
+  alias Enter!(InterfaceDeclaration) EnteredInterface;
+  alias Enter!(StructDeclaration) EnteredStruct;
+  alias Enter!(UnionDeclaration) EnteredUnion;
   alias Enter!(FunctionDeclaration) EnteredFunction;
   alias Enter!(ConstructorDeclaration) EnteredConstructor;
 
+  void printLoc(Node node)
+  {
+    auto loc = node.begin.getLocation();
+    put(indent).formatln("@({},{})",/+ loc.filePath,+/ loc.lineNum, loc.colNum);
+  }
 
 override:
   D visit(ModuleDeclaration n)
   {
-    put.format("Das Modul '{}'", n.moduleName.str);
+    printLoc(n);
+    put.format("Dies ist das Modul '{}'", n.moduleName.str);
     if (n.packages.length)
       put.format(" im Paket '{}'", n.getPackageName('.'));
     put(".").newline;
     return n;
   }
 
+  D visit(ImportDeclaration n)
+  {
+    printLoc(n);
+    put("Importiert Symbole aus einem anderen Modul bzw. Module.").newline;
+    return n;
+  }
+
   D visit(ClassDeclaration n)
   {
+    printLoc(n);
     scope E = new EnteredClass(n);
     put(indent).formatln("'{}' is eine Klasse mit den Eigenschaften:", n.name.str);
     scope I = new Indent();
@@ -114,11 +131,42 @@
     return n;
   }
 
+  D visit(InterfaceDeclaration n)
+  {
+    printLoc(n);
+    scope E = new EnteredInterface(n);
+    put(indent).formatln("'{}' is ein Interface mit den Eigenschaften:", n.name.str);
+    scope I = new Indent();
+    n.decls && visitD(n.decls);
+    return n;
+  }
+
+  D visit(StructDeclaration n)
+  {
+    printLoc(n);
+    scope E = new EnteredStruct(n);
+    put(indent).formatln("'{}' is eine Datenstruktur mit den Eigenschaften:", n.name.str);
+    scope I = new Indent();
+    n.decls && visitD(n.decls);
+    return n;
+  }
+
+  D visit(UnionDeclaration n)
+  {
+    printLoc(n);
+    scope E = new EnteredUnion(n);
+    put(indent).formatln("'{}' is eine Datenunion mit den Eigenschaften:", n.name.str);
+    scope I = new Indent();
+    n.decls && visitD(n.decls);
+    return n;
+  }
+
   D visit(VariableDeclaration n)
   {
+    printLoc(n);
     char[] was;
     if (inAggregate)
-      was = "MemberVariable";
+      was = "Membervariable";
     else if (inFunc)
       was = "lokale Variable";
     else
@@ -137,78 +185,114 @@
 
   D visit(FunctionDeclaration n)
   {
+    printLoc(n);
+    char[] was;
+    if (inAggregate)
+      was = "Methode";
+    else if(inFunc)
+      was = "geschachtelte Funktion";
+    else
+      was = "Funktion";
     scope E = new EnteredFunction(n);
-    char[] was = inAggregate ? "Methode" : "Funktion";
     put(indent).format("'{}' ist eine {} ", n.name.str, was);
-    if (n.params.length)
-      put("mit den Argumenten"), visitN(n.params);
+    if (n.params.length == 1)
+      put("mit dem Argument "), visitN(n.params);
+    else if (n.params.length > 1)
+      put("mit den Argumenten "), visitN(n.params);
     else
       put("ohne Argumente");
-    put.newline;
+    put(".").newline;
     scope I = new Indent();
     return n;
   }
 
   D visit(ConstructorDeclaration n)
   {
+    printLoc(n);
     scope E = new EnteredConstructor(n);
     put(indent)("Ein Konstruktor ");
     if (n.params.length == 1)
-      put("mit dem Argument "),put((visitN(n.params), "."));
+      put("mit dem Argument "), visitN(n.params);
     else if (n.params.length > 1)
-      put("mit den Argumenten "),put((visitN(n.params), "."));
+      put("mit den Argumenten "), visitN(n.params);
     else
-      put("ohne Argumente.");
-    put.newline;
+      put("ohne Argumente");
+    put(".").newline;
     return n;
   }
 
   D visit(StaticConstructorDeclaration n)
   {
-    put(indent)("Statischer Konstruktor.").newline;
+    printLoc(n);
+    put(indent)("Ein statischer Konstruktor.").newline;
     return n;
   }
 
   D visit(DestructorDeclaration n)
   {
-    put(indent)("Destruktor.").newline;
+    printLoc(n);
+    put(indent)("Ein Destruktor.").newline;
     return n;
   }
 
   D visit(StaticDestructorDeclaration n)
   {
-    put(indent)("Statischer Destruktor.").newline;
+    printLoc(n);
+    put(indent)("Ein statischer Destruktor.").newline;
     return n;
   }
 
   D visit(InvariantDeclaration n)
   {
+    printLoc(n);
     put(indent)("Eine Unveränderliche.").newline;
     return n;
   }
 
   D visit(UnittestDeclaration n)
   {
-    put(".").newline;
+    printLoc(n);
+    put(indent)("Ein Komponententest.").newline;
     return n;
   }
 
   Node visit(Parameter n)
   {
     put.format("'{}' des Typs \"", n.name ? n.name.str : "unbenannt");
-    visitN(n.type);
+    n.type && visitN(n.type);
     put(\");
     return n;
   }
 
+  Node visit(Parameters n)
+  {
+    if (n.length > 1)
+    {
+      visitN(n.children[0]);
+      foreach (node; n.children[1..$])
+        put(", "), visitN(node);
+    }
+    else
+      super.visit(n);
+    return n;
+  }
+
   TypeNode visit(ArrayType n)
   {
     if (n.assocType)
-      visitT(n.assocType);
+      put("assoziatives Array von ");
+//       visitT(n.assocType);
     else if (n.e)
-      visitE(n.e), n.e2 && visitE(n.e2);
+    {
+      if (n.e2)
+        put("gescheibtes Array von ");
+      else
+        put("statisches Array von ");
+//       visitE(n.e), n.e2 && visitE(n.e2);
+    }
     else
-      put("dynamisches Array von "), visitT(n.next);
+      put("dynamisches Array von ");
+    visitT(n.next);
     return n;
   }
 
@@ -218,6 +302,20 @@
     return n;
   }
 
+  TypeNode visit(QualifiedType n)
+  {
+    visitT(n.left);
+    put(".");
+    visitT(n.right);
+    return n;
+  }
+
+  TypeNode visit(IdentifierType n)
+  {
+    put(n.ident.str);
+    return n;
+  }
+
   TypeNode visit(IntegralType n)
   {
     put(n.begin.srcText);
--- a/trunk/src/main.d	Thu Jan 17 19:45:28 2008 +0100
+++ b/trunk/src/main.d	Thu Jan 17 22:28:04 2008 +0100
@@ -12,15 +12,16 @@
        dil.ast.Expressions,
        dil.ast.Node,
        dil.ast.Visitor;
+import dil.semantic.Module;
+import dil.semantic.Symbols;
 import dil.semantic.Pass1;
+import dil.translator.German;
 import dil.Messages;
 import dil.Settings;
 import dil.SettingsLoader;
 import dil.CompilerInfo;
-import dil.semantic.Module;
 import dil.Information;
 import dil.File;
-import dil.semantic.Symbols;
 
 import cmd.Generate;
 import cmd.Statistics;
@@ -55,6 +56,7 @@
       mod.parse();
       if (mod.hasErrors)
         continue;
+
       // Start semantic analysis.
       auto pass1 = new SemanticPass1(mod);
       pass1.start();
@@ -74,20 +76,7 @@
       printSymbolTable(mod);
     }
 
-    foreach (info; infoMan.info)
-    {
-      char[] errorFormat;
-      if (info.classinfo is LexerError.classinfo)
-        errorFormat = GlobalSettings.lexerErrorFormat;
-      else if (info.classinfo is ParserError.classinfo)
-        errorFormat = GlobalSettings.parserErrorFormat;
-      else if (info.classinfo is SemanticError.classinfo)
-        errorFormat = GlobalSettings.semanticErrorFormat;
-      else
-        continue;
-      auto err = cast(Problem)info;
-      Stderr.formatln(errorFormat, err.filePath, err.loc, err.col, err.getMsg);
-    }
+    printErrors(infoMan);
     break;
   case "gen", "generate":
     char[] fileName;
@@ -198,6 +187,25 @@
       Stdout(token.srcText)(separator);
     }
     break;
+  case "trans", "translate":
+    if (args.length < 3)
+      return printHelp("trans");
+
+    if (args[2] != "German")
+      return Stdout.formatln("Error: unrecognized target language \"{}\"", args[2]);
+
+    auto infoMan = new InfoManager();
+    auto filePath = args[3];
+    auto mod = new Module(filePath, infoMan);
+    // Parse the file.
+    mod.parse();
+    if (!mod.hasErrors)
+    { // Translate
+      auto german = new GermanTranslator(Stdout, "  ");
+      german.translate(mod.root);
+    }
+    printErrors(infoMan);
+    break;
   case "profile":
     if (args.length < 3)
       break;
@@ -235,7 +243,8 @@
   "  help (?)\n"
   "  importgraph (igraph)\n"
   "  statistics (stats)\n"
-  "  tokenize (tok)\n";
+  "  tokenize (tok)\n"
+  "  translate (trans)\n";
 
 bool strbeg(char[] str, char[] begin)
 {
@@ -247,6 +256,24 @@
   return false;
 }
 
+void printErrors(InfoManager infoMan)
+{
+  foreach (info; infoMan.info)
+  {
+    char[] errorFormat;
+    if (info.classinfo is LexerError.classinfo)
+      errorFormat = GlobalSettings.lexerErrorFormat;
+    else if (info.classinfo is ParserError.classinfo)
+      errorFormat = GlobalSettings.parserErrorFormat;
+    else if (info.classinfo is SemanticError.classinfo)
+      errorFormat = GlobalSettings.semanticErrorFormat;
+    else
+      continue;
+    auto err = cast(Problem)info;
+    Stderr.formatln(errorFormat, err.filePath, err.loc, err.col, err.getMsg);
+  }
+}
+
 char[] helpMain()
 {
   return FormatMsg(MID.HelpMain, VERSION, COMMANDS, COMPILED_WITH, COMPILED_VERSION, COMPILED_DATE);
@@ -302,6 +329,17 @@
 Example:
   dil stat src/dil/Parser.d src/dil/Lexer.d";
     break;
+  case "trans", "translate":
+    msg = `Translate a D source file to another language.
+Usage:
+  dil translate Language file.d
+
+  Languages that are supported:
+    *) German
+
+Example:
+  dil trans German src/main.d`;
+    break;
   default:
     msg = helpMain();
   }