changeset 489:a7291d3ee9d7

Refactored classes that inherit from Node. Added methods addChild(), addOptChild(), addChildren(), addOptChildren() to class Node. Refactored subclasses to use the new methods instead of appending directly to the array Node.children. Moved enums StorageClass and Protection to new module dil.Enums. Added members stc, prot, isStatic() and isPulic() to Declaration.
author Aziz K?ksal <aziz.koeksal@gmail.com>
date Mon, 03 Dec 2007 22:44:27 +0100
parents cfb3805768b6
children 47be6bfe39cd
files trunk/src/dil/Declarations.d trunk/src/dil/Enums.d trunk/src/dil/Expressions.d trunk/src/dil/Lexer.d trunk/src/dil/Parser.d trunk/src/dil/Statements.d trunk/src/dil/SyntaxTree.d trunk/src/dil/Types.d
diffstat 8 files changed, 309 insertions(+), 349 deletions(-) [+]
line wrap: on
line diff
--- a/trunk/src/dil/Declarations.d	Sat Dec 01 21:42:24 2007 +0100
+++ b/trunk/src/dil/Declarations.d	Mon Dec 03 22:44:27 2007 +0100
@@ -8,46 +8,55 @@
 import dil.Types;
 import dil.Statements;
 import dil.Token;
+import dil.Enums;
 import dil.Scope;
 
 abstract class Declaration : Node
 {
   bool hasBody;
-  this(bool hasBody)
+  this()
   {
     super(NodeCategory.Declaration);
-    this.hasBody = hasBody;
   }
 
+  // Members relevant to semantic phase.
+  StorageClass stc;
+  Protection prot;
+
   void semantic(Scope sc)
   {
 //     foreach (node; this.children)
 //       if (node.category == NodeCategory.Declaration)
 //         (cast(Declaration)cast(void*)node).semantic(sc);
   }
+
+  final bool isStatic()
+  {
+    return !!(stc & StorageClass.Static);
+  }
+
+  final bool isPublic()
+  {
+    return !!(prot & Protection.Public);
+  }
 }
 
 class Declarations : Declaration
 {
   this()
   {
-    super(true);
+    hasBody = true;
     mixin(set_kind);
   }
 
   void opCatAssign(Declaration d)
   {
-    this.children ~= d;
-  }
-
-  void opCatAssign(Declaration[] decls)
-  {
-    this.children ~= decls;
+    addChild(d);
   }
 
   void opCatAssign(Declarations ds)
   {
-    this.children ~= ds.children;
+    addChildren(ds.children);
   }
 }
 
@@ -55,7 +64,6 @@
 {
   this()
   {
-    super(false);
     mixin(set_kind);
   }
 }
@@ -65,7 +73,6 @@
   Token* token;
   this(Token* token)
   {
-    super(false);
     mixin(set_kind);
     this.token = token;
   }
@@ -80,7 +87,6 @@
   Token*[] packages;
   this(ModuleFQN moduleFQN)
   {
-    super(false);
     mixin(set_kind);
     assert(moduleFQN.length != 0);
     this.moduleName = moduleFQN[$-1];
@@ -121,17 +127,16 @@
   Token*[] moduleAliases;
   Token*[] bindNames;
   Token*[] bindAliases;
-  bool isStatic_;
 
   this(ModuleFQN[] moduleFQNs, Token*[] moduleAliases, Token*[] bindNames, Token*[] bindAliases, bool isStatic)
   {
-    super(false);
     mixin(set_kind);
     this.moduleFQNs = moduleFQNs;
     this.moduleAliases = moduleAliases;
     this.bindNames = bindNames;
     this.bindAliases = bindAliases;
-    this.isStatic_ = isStatic;
+    if (isStatic)
+      this.stc |= StorageClass.Static;
   }
 
   char[][] getModuleFQNs(char separator)
@@ -147,17 +152,6 @@
     }
     return FQNs;
   }
-
-  bool isStatic()
-  {
-    return isStatic_;
-  }
-
-  bool isPublic()
-  {
-    // TODO:
-    return false;
-  }
 }
 
 class AliasDeclaration : Declaration
@@ -165,9 +159,8 @@
   Declaration decl;
   this(Declaration decl)
   {
-    super(false);
     mixin(set_kind);
-    this.children = [decl];
+    addChild(decl);
     this.decl = decl;
   }
 }
@@ -177,9 +170,8 @@
   Declaration decl;
   this(Declaration decl)
   {
-    super(false);
     mixin(set_kind);
-    this.children = [decl];
+    addChild(decl);
     this.decl = decl;
   }
 }
@@ -191,12 +183,10 @@
   EnumMember[] members;
   this(Token* name, Type baseType, EnumMember[] members, bool hasBody)
   {
-    super(hasBody);
+    super.hasBody = hasBody;
     mixin(set_kind);
-    if (baseType)
-      this.children = [baseType];
-    if (members.length)
-        this.children ~= members;
+    addOptChild(baseType);
+    addOptChildren(members);
 
     this.name = name;
     this.baseType = baseType;
@@ -212,8 +202,7 @@
   {
     super(NodeCategory.Other);
     mixin(set_kind);
-    if (value)
-      this.children = [value];
+    addOptChild(value);
 
     this.name = name;
     this.value = value;
@@ -228,14 +217,11 @@
   Declarations decls;
   this(Token* name, TemplateParameters tparams, BaseClass[] bases, Declarations decls, bool hasBody)
   {
-    super(hasBody);
+    super.hasBody = hasBody;
     mixin(set_kind);
-    if (tparams)
-      this.children = [tparams];
-    if (bases.length)
-      this.children ~= bases;
-    if (decls)
-      this.children ~= decls;
+    addOptChild(tparams);
+    addOptChildren(bases);
+    addOptChild(decls);
 
     this.name = name;
     this.tparams = tparams;
@@ -252,14 +238,11 @@
   Declarations decls;
   this(Token* name, TemplateParameters tparams, BaseClass[] bases, Declarations decls, bool hasBody)
   {
-    super(hasBody);
+    super.hasBody = hasBody;
     mixin(set_kind);
-    if (tparams)
-      this.children = [tparams];
-    if (bases.length)
-      this.children ~= bases;
-    if (decls)
-      this.children ~= decls;
+    addOptChild(tparams);
+    addOptChildren(bases);
+    addOptChild(decls);
 
     this.name = name;
     this.tparams = tparams;
@@ -275,12 +258,10 @@
   Declarations decls;
   this(Token* name, TemplateParameters tparams, Declarations decls, bool hasBody)
   {
-    super(hasBody);
+    super.hasBody = hasBody;
     mixin(set_kind);
-    if (tparams)
-      this.children = [tparams];
-    if (decls)
-      this.children ~= decls;
+    addOptChild(tparams);
+    addOptChild(decls);
 
     this.name = name;
     this.tparams = tparams;
@@ -295,12 +276,10 @@
   Declarations decls;
   this(Token* name, TemplateParameters tparams, Declarations decls, bool hasBody)
   {
-    super(hasBody);
+    super.hasBody = hasBody;
     mixin(set_kind);
-    if (tparams)
-      this.children = [tparams];
-    if (decls)
-      this.children ~= decls;
+    addOptChild(tparams);
+    addOptChild(decls);
 
     this.name = name;
     this.tparams = tparams;
@@ -314,10 +293,10 @@
   FunctionBody funcBody;
   this(Parameters parameters, FunctionBody funcBody)
   {
-    super(true);
+    super.hasBody = true;
     mixin(set_kind);
-    assert(parameters !is null && funcBody !is null);
-    this.children = [cast(Node)parameters, funcBody];
+    addChild(parameters);
+    addChild(funcBody);
 
     this.parameters = parameters;
     this.funcBody = funcBody;
@@ -329,10 +308,9 @@
   FunctionBody funcBody;
   this(FunctionBody funcBody)
   {
-    super(true);
+    super.hasBody = true;
     mixin(set_kind);
-    assert(funcBody !is null);
-    this.children = [funcBody];
+    addChild(funcBody);
 
     this.funcBody = funcBody;
   }
@@ -343,9 +321,9 @@
   FunctionBody funcBody;
   this(FunctionBody funcBody)
   {
-    super(true);
+    super.hasBody = true;
     mixin(set_kind);
-    this.children = [funcBody];
+    addChild(funcBody);
 
     this.funcBody = funcBody;
   }
@@ -356,9 +334,9 @@
   FunctionBody funcBody;
   this(FunctionBody funcBody)
   {
-    super(true);
+    super.hasBody = true;
     mixin(set_kind);
-    this.children = [funcBody];
+    addChild(funcBody);
 
     this.funcBody = funcBody;
   }
@@ -373,13 +351,12 @@
   FunctionBody funcBody;
   this(Type returnType, Token* funcName, TemplateParameters tparams, Parameters params, FunctionBody funcBody)
   {
-    assert(returnType !is null);
-    super(funcBody.funcBody !is null);
+    super.hasBody = funcBody.funcBody !is null;
     mixin(set_kind);
-    this.children = [returnType];
-    if (tparams)
-      this.children ~= tparams;
-    this.children ~= [cast(Node)params, funcBody];
+    addChild(returnType);
+    addOptChild(tparams);
+    addChild(params);
+    addChild(funcBody);
 
     this.returnType = returnType;
     this.funcName = funcName;
@@ -396,13 +373,10 @@
   Expression[] values;
   this(Type type, Token*[] idents, Expression[] values)
   {
-    super(false);
     mixin(set_kind);
-    if (type)
-      this.children = [type];
+    addOptChild(type);
     foreach(value; values)
-      if (value)
-        this.children ~= value;
+      addOptChild(value);
 
     this.type = type;
     this.idents = idents;
@@ -415,10 +389,9 @@
   FunctionBody funcBody;
   this(FunctionBody funcBody)
   {
-    super(true);
+    super.hasBody = true;
     mixin(set_kind);
-    assert(funcBody !is null);
-    this.children = [funcBody];
+    addChild(funcBody);
 
     this.funcBody = funcBody;
   }
@@ -429,10 +402,9 @@
   FunctionBody funcBody;
   this(FunctionBody funcBody)
   {
-    super(true);
+    super.hasBody = true;
     mixin(set_kind);
-    assert(funcBody !is null);
-    this.children = [funcBody];
+    addChild(funcBody);
 
     this.funcBody = funcBody;
   }
@@ -446,12 +418,10 @@
 
   this(Token* spec, Token* cond, Declaration decls, Declaration elseDecls)
   {
-    super(true /+decls.length != 0+/);
+    super.hasBody = decls !is null;
     mixin(set_kind);
-    if (decls)
-      this.children = [decls];
-    if (elseDecls)
-      this.children ~= elseDecls;
+    addOptChild(decls);
+    addOptChild(elseDecls);
 
     this.spec = spec;
     this.cond = cond;
@@ -468,12 +438,10 @@
 
   this(Token* spec, Token* cond, Declaration decls, Declaration elseDecls)
   {
-    super(true /+decls.length != 0+/);
+    super.hasBody = decls !is null;
     mixin(set_kind);
-    if (decls)
-      this.children = [decls];
-    if (elseDecls)
-      this.children ~= elseDecls;
+    addOptChild(decls);
+    addOptChild(elseDecls);
 
     this.spec = spec;
     this.cond = cond;
@@ -488,14 +456,11 @@
   Declaration ifDecls, elseDecls;
   this(Expression condition, Declaration ifDecls, Declaration elseDecls)
   {
-    super(true);
+    super.hasBody = true;
     mixin(set_kind);
-    assert(condition !is null);
-    this.children = [condition];
-    if (ifDecls)
-      this.children ~= ifDecls;
-    if (elseDecls)
-      this.children ~= elseDecls;
+    addChild(condition);
+    addOptChild(ifDecls);
+    addOptChild(elseDecls);
 
     this.condition = condition;
     this.ifDecls = ifDecls;
@@ -508,12 +473,11 @@
   Expression condition, message;
   this(Expression condition, Expression message)
   {
-    super(true);
+    super.hasBody = true;
     mixin(set_kind);
-    assert(condition !is null);
-    this.children = [condition];
-    if (message)
-      this.children ~= message;
+    addChild(condition);
+    addOptChild(message);
+
     this.condition = condition;
     this.message = message;
   }
@@ -526,12 +490,10 @@
   Declarations decls;
   this(Token* name, TemplateParameters tparams, Declarations decls)
   {
-    super(true);
+    super.hasBody = true;
     mixin(set_kind);
-    if (tparams)
-      this.children = [tparams];
-    assert(decls !is null);
-    this.children ~= decls;
+    addOptChild(tparams);
+    addChild(decls);
 
     this.name = name;
     this.tparams = tparams;
@@ -545,10 +507,10 @@
   FunctionBody funcBody;
   this(Parameters parameters, FunctionBody funcBody)
   {
-    super(true);
+    super.hasBody = true;
     mixin(set_kind);
-    assert(parameters !is null && funcBody !is null);
-    this.children = [cast(Node)parameters, funcBody];
+    addChild(parameters);
+    addChild(funcBody);
 
     this.parameters = parameters;
     this.funcBody = funcBody;
@@ -561,10 +523,10 @@
   FunctionBody funcBody;
   this(Parameters parameters, FunctionBody funcBody)
   {
-    super(true);
+    super.hasBody = true;
     mixin(set_kind);
-    assert(parameters !is null && funcBody !is null);
-    this.children = [cast(Node)parameters, funcBody];
+    addChild(parameters);
+    addChild(funcBody);
 
     this.parameters = parameters;
     this.funcBody = funcBody;
@@ -577,10 +539,9 @@
   Declaration decls;
   this(TOK attribute, Declaration decls)
   {
-    super(true);
+    super.hasBody = true;
     mixin(set_kind);
-    assert(decls !is null);
-    this.children ~= decls;
+    addChild(decls);
 
     this.attribute = attribute;
     this.decls = decls;
@@ -594,8 +555,8 @@
   {
     super(TOK.Extern, decls);
     mixin(set_kind);
-    if (linkage)
-      this.children ~= linkage;
+    addOptChild(linkage);
+
     this.linkage = linkage;
   }
 }
@@ -617,8 +578,7 @@
   Expression[] args;
   this(Token* ident, Expression[] args, Declaration decls)
   {
-    if (args.length)
-      this.children ~= args; // Add args before calling super().
+    addOptChildren(args); // Add args before calling super().
     super(TOK.Pragma, decls);
     mixin(set_kind);
 
@@ -632,21 +592,21 @@
   Expression[] templateIdents;
   Token* mixinIdent;
   Expression argument; // mixin ( AssignExpression )
+
   this(Expression[] templateIdents, Token* mixinIdent)
   {
-    super(false);
     mixin(set_kind);
-    assert(templateIdents.length != 0);
-    this.children = templateIdents;
+    addChildren(templateIdents);
+
     this.templateIdents = templateIdents;
     this.mixinIdent = mixinIdent;
   }
+
   this(Expression argument)
   {
-    super(false);
     mixin(set_kind);
-    assert(argument !is null);
-    this.children = [argument];
+    addChild(argument);
+
     this.argument = argument;
   }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/trunk/src/dil/Enums.d	Mon Dec 03 22:44:27 2007 +0100
@@ -0,0 +1,36 @@
+/++
+  Author: Aziz Köksal
+  License: GPL3
++/
+module dil.Enums;
+
+enum StorageClass
+{
+  None         = 0,
+  Abstract     = 1,
+  Auto         = 1<<2,
+  Const        = 1<<3,
+  Deprecated   = 1<<4,
+  Extern       = 1<<5,
+  Final        = 1<<6,
+  Invariant    = 1<<7,
+  Override     = 1<<8,
+  Scope        = 1<<9,
+  Static       = 1<<10,
+  Synchronized = 1<<11,
+  In           = 1<<12,
+  Out          = 1<<13,
+  Ref          = 1<<14,
+  Lazy         = 1<<15,
+  Variadic     = 1<<16,
+}
+
+enum Protection
+{
+  None,
+  Private   = 1,
+  Protected = 1<<1,
+  Package   = 1<<2,
+  Public    = 1<<3,
+  Export    = 1<<4
+}
--- a/trunk/src/dil/Expressions.d	Sat Dec 01 21:42:24 2007 +0100
+++ b/trunk/src/dil/Expressions.d	Mon Dec 03 22:44:27 2007 +0100
@@ -31,7 +31,7 @@
   Token* tok;
   this(Expression left, Expression right, Token* tok)
   {
-    this.children = [left, right];
+    addChildren([left, right]);
     this.left = left;
     this.right = right;
     this.tok = tok;
@@ -45,7 +45,7 @@
   {
     super(left, right, tok);
     mixin(set_kind);
-    this.children ~= [condition];
+    addChild(condition);
     this.condition = condition;
   }
 }
@@ -339,7 +339,7 @@
   Expression e;
   this(Expression e)
   {
-    this.children ~= e;
+    addChild(e);
     this.e = e;
   }
 }
@@ -455,7 +455,7 @@
   {
     super(e);
     mixin(set_kind);
-    this.children ~= [dotList];
+    addChild(dotList);
     this.dotList = dotList;
   }
 }
@@ -467,7 +467,7 @@
   {
     super(e);
     mixin(set_kind);
-    this.children ~= args;
+    addOptChildren(args);
     this.args = args;
   }
 }
@@ -481,11 +481,9 @@
   {
     /*super(e);*/
     mixin(set_kind);
-    if (newArgs.length)
-      this.children ~= newArgs;
-    this.children ~= type;
-    if (ctorArgs.length)
-      this.children ~= ctorArgs;
+    addOptChildren(newArgs);
+    addChild(type);
+    addOptChildren(ctorArgs);
     this.newArgs = newArgs;
     this.type = type;
     this.ctorArgs = ctorArgs;
@@ -502,13 +500,10 @@
   {
     /*super(e);*/
     mixin(set_kind);
-    if (newArgs.length)
-      this.children ~= newArgs;
-    if (bases.length)
-      this.children ~= bases;
-    if (ctorArgs.length)
-      this.children ~= ctorArgs;
-    this.children ~= decls;
+    addOptChildren(newArgs);
+    addOptChildren(bases);
+    addOptChildren(ctorArgs);
+    addChild(decls);
 
     this.newArgs = newArgs;
     this.bases = bases;
@@ -531,7 +526,7 @@
   Type type;
   this(Expression e, Type type)
   {
-    this.children = [type];
+    addChild(type); // Add type before super().
     super(e);
     mixin(set_kind);
     this.type = type;
@@ -545,7 +540,7 @@
   {
     super(e);
     mixin(set_kind);
-    this.children ~= args;
+    addChildren(args);
     this.args = args;
   }
 }
@@ -557,10 +552,9 @@
   {
     super(e);
     mixin(set_kind);
+    assert(left ? (right !is null) : right is null);
     if (left)
-      this.children ~= left;
-    if (right)
-      this.children ~= right;
+      addChildren([left, right]);
 
     this.left = left;
     this.right = right;
@@ -619,7 +613,7 @@
   this(Expression[] items)
   {
     mixin(set_kind);
-    this.children = items;
+    addChildren(items);
     this.items = items;
   }
 }
@@ -631,8 +625,7 @@
   this(Token* ident, TemplateArguments targs)
   {
     mixin(set_kind);
-    if (targs)
-      this.children = [targs];
+    addOptChild(targs);
     this.ident = ident;
     this.targs = targs;
   }
@@ -738,7 +731,7 @@
   this(Expression[] values)
   {
     mixin(set_kind);
-    this.children = values;
+    addOptChildren(values);
     this.values = values;
   }
 }
@@ -751,7 +744,7 @@
     assert(keys.length == values.length);
     mixin(set_kind);
     foreach (i, key; keys)
-      this.children ~= [key, values[i]];
+      addChildren([key, values[i]]);
     this.keys = keys;
     this.values = values;
   }
@@ -763,9 +756,8 @@
   this(Expression expr, Expression msg)
   {
     mixin(set_kind);
-    this.children = [expr];
-    if (msg)
-      this.children ~= msg;
+    addChild(expr);
+    addOptChild(msg);
     this.expr = expr;
     this.msg = msg;
   }
@@ -777,7 +769,7 @@
   this(Expression expr)
   {
     mixin(set_kind);
-    this.children = [expr];
+    addChild(expr);
     this.expr = expr;
   }
 }
@@ -788,7 +780,7 @@
   this(Expression expr)
   {
     mixin(set_kind);
-    this.children = [expr];
+    addChild(expr);
     this.expr = expr;
   }
 }
@@ -799,7 +791,7 @@
   this(Type type)
   {
     mixin(set_kind);
-    this.children = [type];
+    addChild(type);
     this.type = type;
   }
 }
@@ -811,7 +803,7 @@
   this(Type type, Token* ident)
   {
     mixin(set_kind);
-    this.children = [type];
+    addChild(type);
     this.type = type;
     this.ident = ident;
   }
@@ -823,7 +815,7 @@
   this(Type type)
   {
     mixin(set_kind);
-    this.children = [type];
+    addChild(type);
     this.type = type;
   }
 }
@@ -838,11 +830,10 @@
   this(Type type, Token* ident, Token* opTok, Token* specTok, Type specType, typeof(tparams) tparams)
   {
     mixin(set_kind);
-    this.children = [type];
-    if (specType)
-      this.children ~= specType;
-    if (tparams)
-      this.children ~= tparams;
+    addChild(type);
+    addOptChild(specType);
+  version(D2)
+    addOptChild(tparams);
     this.type = type;
     this.ident = ident;
     this.opTok = opTok;
@@ -861,11 +852,9 @@
   this()
   {
     mixin(set_kind);
-    if (returnType)
-      this.children ~= returnType;
-    if (parameters)
-      this.children ~= parameters;
-    this.children ~= funcBody;
+    addOptChild(returnType);
+    addOptChild(parameters);
+    addChild(funcBody);
   }
 
   this(Type returnType, Parameters parameters, FunctionBody funcBody)
@@ -892,8 +881,7 @@
   this(typeof(ident) ident, typeof(targs) targs)
   {
     mixin(set_kind);
-    if (targs)
-      this.children = [targs];
+    addOptChild(targs);
     this.ident = ident;
     this.targs = targs;
   }
@@ -918,10 +906,8 @@
     mixin(set_kind);
     foreach (i, key; keys)
     {
-      if (key)
-        this.children ~= key;
-      if (values[i])
-        this.children ~= values[i];
+      addOptChild(key); // The key is optional in ArrayInitializers.
+      addChild(values[i]);
     }
     this.keys = keys;
     this.values = values;
@@ -935,7 +921,7 @@
   this(Token*[] idents, Expression[] values)
   {
     mixin(set_kind);
-    this.children = values;
+    addOptChildren(values);
     this.idents = idents;
     this.values = values;
   }
@@ -983,7 +969,7 @@
   this(Expression e)
   {
     mixin(set_kind);
-    this.children = [e];
+    addChild(e);
     this.e = e;
   }
 }
--- a/trunk/src/dil/Lexer.d	Sat Dec 01 21:42:24 2007 +0100
+++ b/trunk/src/dil/Lexer.d	Mon Dec 03 22:44:27 2007 +0100
@@ -311,7 +311,7 @@
     This is the old scan method.
     TODO: profile old and new to see which one is faster.
   +/
-  public void scan_(out Token t)
+  public void scan(out Token t)
   in
   {
     assert(text.ptr <= p && p < end);
@@ -771,7 +771,7 @@
     const char[] case_L3 = case_!(str, tok, "Lcommon");
   }
 
-  public void scan(out Token t)
+  public void scan_(out Token t)
   in
   {
     assert(text.ptr <= p && p < end);
--- a/trunk/src/dil/Parser.d	Sat Dec 01 21:42:24 2007 +0100
+++ b/trunk/src/dil/Parser.d	Mon Dec 03 22:44:27 2007 +0100
@@ -12,6 +12,7 @@
 import dil.Statements;
 import dil.Expressions;
 import dil.Types;
+import dil.Enums;
 import common;
 
 private alias TOK T;
@@ -86,7 +87,7 @@
     auto decls = new Declarations;
     if (token.type == T.Module)
       decls ~= parseModuleDeclaration();
-    decls ~= parseDeclarationDefinitions();
+    decls.addOptChildren(parseDeclarationDefinitions());
     set(decls, begin);
     return decls;
   }
@@ -2212,15 +2213,9 @@
   Statement parseCaseStatement()
   {
     assert(token.type == T.Case);
-    // T.Case skipped in do-while.
-    Expression[] values;
-    do
-    {
-      nT();
-      values ~= parseAssignExpression();
-    } while (token.type == T.Comma)
+    nT();
+    auto values = parseExpressionList();
     require(T.Colon);
-
     auto caseBody = parseCaseOrDefaultBody();
     return new CaseStatement(values, caseBody);
   }
@@ -3342,6 +3337,7 @@
       case T.LBracket:
         // parse Slice- and IndexExpression
         nT();
+        // [] is a SliceExpression
         if (token.type == T.RBracket)
         {
           e = new SliceExpression(e, null, null);
@@ -3350,6 +3346,7 @@
 
         Expression[] es = [parseAssignExpression()];
 
+        // [ AssignExpression .. AssignExpression ]
         if (token.type == T.Slice)
         {
           nT();
@@ -3358,6 +3355,7 @@
           goto Lset;
         }
 
+        // [ ExpressionList ]
         if (token.type == T.Comma)
         {
            nT();
@@ -3371,7 +3369,7 @@
         return e;
       }
       nT();
-    Lset:
+    Lset: // Jumped here to skip nT().
       set(e, begin);
     }
     assert(0);
@@ -3699,9 +3697,7 @@
       auto id = requireId();
       TemplateArguments args;
       if (token.type == T.Comma)
-      {
         args = parseTemplateArguments2();
-      }
       else
         require(T.RParen);
       e = new TraitsExpression(id, args);
--- a/trunk/src/dil/Statements.d	Sat Dec 01 21:42:24 2007 +0100
+++ b/trunk/src/dil/Statements.d	Mon Dec 03 22:44:27 2007 +0100
@@ -26,7 +26,7 @@
 
   void opCatAssign(Statement s)
   {
-    this.children ~= s;
+    addChild(s);
   }
 }
 
@@ -60,12 +60,9 @@
 
   void finishConstruction()
   {
-    if (funcBody)
-      this.children ~= funcBody;
-    if (inBody)
-      this.children ~= inBody;
-    if (outBody)
-      this.children ~= outBody;
+    addOptChild(funcBody);
+    addOptChild(inBody);
+    addOptChild(outBody);
   }
 }
 
@@ -75,7 +72,7 @@
   this(Statement s)
   {
     mixin(set_kind);
-    this.children = [s];
+    addChild(s);
     this.s = s;
   }
 }
@@ -87,7 +84,7 @@
   this(Token* label, Statement s)
   {
     mixin(set_kind);
-    this.children = [s];
+    addChild(s);
     this.label = label;
     this.s = s;
   }
@@ -99,7 +96,7 @@
   this(Expression expression)
   {
     mixin(set_kind);
-    this.children = [expression];
+    addChild(expression);
     this.expression = expression;
   }
 }
@@ -110,7 +107,7 @@
   this(Declaration declaration)
   {
     mixin(set_kind);
-    this.children = [declaration];
+    addChild(declaration);
     this.declaration = declaration;
   }
 }
@@ -125,12 +122,12 @@
   {
     mixin(set_kind);
     if (variable)
-      this.children ~= variable;
+      addChild(variable);
     else
-      this.children ~= condition;
-    this.children ~= ifBody;
-    if (elseBody)
-      this.children ~= elseBody;
+      addChild(condition);
+    addChild(ifBody);
+    addOptChild(elseBody);
+
     this.variable = variable;
     this.condition = condition;
     this.ifBody = ifBody;
@@ -145,7 +142,9 @@
   this(Expression condition, Statement whileBody)
   {
     mixin(set_kind);
-    this.children = [cast(Node)condition, whileBody];
+    addChild(condition);
+    addChild(whileBody);
+
     this.condition = condition;
     this.whileBody = whileBody;
   }
@@ -158,7 +157,9 @@
   this(Expression condition, Statement doBody)
   {
     mixin(set_kind);
-    this.children = [cast(Node)condition, doBody];
+    addChild(condition);
+    addChild(doBody);
+
     this.condition = condition;
     this.doBody = doBody;
   }
@@ -173,13 +174,11 @@
   this(Statement init, Expression condition, Expression increment, Statement forBody)
   {
     mixin(set_kind);
-    if (init)
-      this.children ~= init;
-    if (condition)
-      this.children ~= condition;
-    if (increment)
-      this.children ~= increment;
-    this.children ~= forBody;
+    addOptChild(init);
+    addOptChild(condition);
+    addOptChild(increment);
+    addChild(forBody);
+
     this.init = init;
     this.condition = condition;
     this.increment = increment;
@@ -197,7 +196,8 @@
   this(TOK tok, Parameters params, Expression aggregate, Statement forBody)
   {
     mixin(set_kind);
-    this.children = [cast(Node)params, aggregate, forBody];
+    addChildren([cast(Node)params, aggregate, forBody]);
+
     this.tok = tok;
     this.params = params;
     this.aggregate = aggregate;
@@ -217,7 +217,8 @@
   this(TOK tok, Parameters params, Expression lower, Expression upper, Statement forBody)
   {
     mixin(set_kind);
-    this.children = [cast(Node)params, lower, upper, forBody];
+    addChildren([cast(Node)params, lower, upper, forBody]);
+
     this.tok = tok;
     this.params = params;
     this.lower = lower;
@@ -235,7 +236,9 @@
   this(Expression condition, Statement switchBody)
   {
     mixin(set_kind);
-    this.children = [cast(Node)condition, switchBody];
+    addChild(condition);
+    addChild(switchBody);
+
     this.condition = condition;
     this.switchBody = switchBody;
   }
@@ -249,7 +252,9 @@
   this(Expression[] values, Statement caseBody)
   {
     mixin(set_kind);
-    this.children = cast(Node[])values ~ [caseBody];
+    addChildren(values);
+    addChild(caseBody);
+
     this.values = values;
     this.caseBody = caseBody;
   }
@@ -261,7 +266,8 @@
   this(Statement defaultBody)
   {
     mixin(set_kind);
-    this.children = [defaultBody];
+    addChild(defaultBody);
+
     this.defaultBody = defaultBody;
   }
 }
@@ -292,8 +298,7 @@
   this(Expression expr)
   {
     mixin(set_kind);
-    if (expr)
-      this.children = [expr];
+    addOptChild(expr);
     this.expr = expr;
   }
 }
@@ -305,8 +310,7 @@
   this(Token* ident, Expression caseExpr)
   {
     mixin(set_kind);
-    if (caseExpr)
-      this.children = [caseExpr];
+    addOptChild(caseExpr);
     this.ident = ident;
     this.caseExpr = caseExpr;
   }
@@ -319,8 +323,9 @@
   this(Expression expr, Statement withBody)
   {
     mixin(set_kind);
-    assert(expr !is null && withBody !is null);
-    this.children = [cast(Node)expr, withBody];
+    addChild(expr);
+    addChild(withBody);
+
     this.expr = expr;
     this.withBody = withBody;
   }
@@ -333,10 +338,9 @@
   this(Expression expr, Statement syncBody)
   {
     mixin(set_kind);
-    if (expr)
-      this.children ~= expr;
-    assert(syncBody !is null);
-    this.children ~= syncBody;
+    addOptChild(expr);
+    addChild(syncBody);
+
     this.expr = expr;
     this.syncBody = syncBody;
   }
@@ -350,12 +354,10 @@
   this(Statement tryBody, CatchBody[] catchBodies, FinallyBody finallyBody)
   {
     mixin(set_kind);
-    assert(tryBody !is null);
-    this.children = [tryBody];
-    if (catchBodies.length)
-      this.children ~= catchBodies;
-    if (finallyBody)
-      this.children ~= finallyBody;
+    addChild(tryBody);
+    addOptChildren(catchBodies);
+    addOptChild(finallyBody);
+
     this.tryBody = tryBody;
     this.catchBodies = catchBodies;
     this.finallyBody = finallyBody;
@@ -369,10 +371,8 @@
   this(Parameter param, Statement catchBody)
   {
     mixin(set_kind);
-    if (param)
-      this.children ~= param;
-    assert(catchBody !is null);
-    this.children ~= catchBody;
+    addOptChild(param);
+    addChild(catchBody);
     this.param = param;
     this.catchBody = catchBody;
   }
@@ -384,8 +384,7 @@
   this(Statement finallyBody)
   {
     mixin(set_kind);
-    assert(finallyBody !is null);
-    this.children = [finallyBody];
+    addChild(finallyBody);
     this.finallyBody = finallyBody;
   }
 }
@@ -397,8 +396,7 @@
   this(Token* condition, Statement scopeBody)
   {
     mixin(set_kind);
-    assert(scopeBody !is null);
-    this.children = [scopeBody];
+    addChild(scopeBody);
     this.condition = condition;
     this.scopeBody = scopeBody;
   }
@@ -410,7 +408,7 @@
   this(Expression expr)
   {
     mixin(set_kind);
-    this.children = [expr];
+    addChild(expr);
     this.expr = expr;
   }
 }
@@ -421,8 +419,7 @@
   this(Statement volatileBody)
   {
     mixin(set_kind);
-    if (volatileBody)
-      this.children = [volatileBody];
+    addOptChild(volatileBody);
     this.volatileBody = volatileBody;
   }
 }
@@ -433,7 +430,7 @@
   this(Statements statements)
   {
     mixin(set_kind);
-    this.children = [statements];
+    addChild(statements);
     this.statements = statements;
   }
 }
@@ -445,8 +442,7 @@
   this(Token* ident, Expression[] operands)
   {
     mixin(set_kind);
-    if (operands.length)
-      this.children = operands;
+    addOptChildren(operands);
     this.ident = ident;
     this.operands = operands;
   }
@@ -479,9 +475,9 @@
   this(Token* ident, Expression[] args, Statement pragmaBody)
   {
     mixin(set_kind);
-    if (args.length)
-      this.children = args;
-    this.children ~= pragmaBody;
+    addOptChildren(args);
+    addChild(pragmaBody);
+
     this.ident = ident;
     this.args = args;
     this.pragmaBody = pragmaBody;
@@ -495,7 +491,7 @@
   this(Expression[] templateIdents, Token* mixinIdent)
   {
     mixin(set_kind);
-    this.children = templateIdents;
+    addChildren(templateIdents);
     this.templateIdents = templateIdents;
     this.mixinIdent = mixinIdent;
   }
@@ -508,9 +504,9 @@
   this(Expression condition, Statement ifBody, Statement elseBody)
   {
     mixin(set_kind);
-    this.children = [cast(Node)condition, ifBody];
-    if (elseBody)
-      this.children ~= elseBody;
+    addChild(condition);
+    addChild(ifBody);
+    addOptChild(elseBody);
     this.condition = condition;
     this.ifBody = ifBody;
     this.elseBody = elseBody;
@@ -523,9 +519,8 @@
   this(Expression condition, Expression message)
   {
     mixin(set_kind);
-    this.children = [condition];
-    if (message)
-      this.children ~= message;
+    addChild(condition);
+    addOptChild(message);
     this.condition = condition;
     this.message = message;
   }
@@ -538,9 +533,8 @@
   this(Token* cond, Statement debugBody, Statement elseBody)
   {
     mixin(set_kind);
-    this.children = [debugBody];
-    if (elseBody)
-      this.children ~= elseBody;
+    addChild(debugBody);
+    addOptChild(elseBody);
     this.cond = cond;
     this.debugBody = debugBody;
     this.elseBody = elseBody;
@@ -554,9 +548,8 @@
   this(Token* cond, Statement versionBody, Statement elseBody)
   {
     mixin(set_kind);
-    this.children = [versionBody];
-    if (elseBody)
-      this.children ~= [elseBody];
+    addChild(versionBody);
+    addOptChild(elseBody);
     this.cond = cond;
     this.versionBody = versionBody;
     this.elseBody = elseBody;
@@ -570,8 +563,7 @@
   this(TOK tok, Statement statement)
   {
     mixin(set_kind);
-    assert(statement !is null);
-    this.children = [statement];
+    addChild(statement);
     this.tok = tok;
     this.statement = statement;
   }
@@ -584,8 +576,7 @@
   {
     super(TOK.Extern, statement);
     mixin(set_kind);
-    if (linkage)
-      this.children ~= linkage;
+    addOptChild(linkage);
     this.linkage = linkage;
   }
 }
--- a/trunk/src/dil/SyntaxTree.d	Sat Dec 01 21:42:24 2007 +0100
+++ b/trunk/src/dil/SyntaxTree.d	Mon Dec 03 22:44:27 2007 +0100
@@ -245,4 +245,32 @@
     this.begin = begin;
     this.end = end;
   }
+
+  void addChild(Node child)
+  {
+    assert(child !is null, "failed in " ~ this.classinfo.name);
+    this.children ~= child;
+  }
+
+  void addOptChild(Node child)
+  {
+    child is null || addChild(child);
+  }
+
+  void addChildren(Node[] children)
+  {
+    assert(children !is null && delegate{
+      foreach (child; children)
+        if (child is null)
+          return false;
+      return true; }(),
+      "failed in " ~ this.classinfo.name
+    );
+    this.children ~= children;
+  }
+
+  void addOptChildren(Node[] children)
+  {
+    children is null || addChildren(children);
+  }
 }
--- a/trunk/src/dil/Types.d	Sat Dec 01 21:42:24 2007 +0100
+++ b/trunk/src/dil/Types.d	Mon Dec 03 22:44:27 2007 +0100
@@ -6,6 +6,7 @@
 import dil.SyntaxTree;
 import dil.Token;
 import dil.Expressions;
+import dil.Enums;
 
 class Linkage : Node
 {
@@ -49,27 +50,6 @@
   }
 }
 
-enum StorageClass
-{
-  None         = 0,
-  Abstract     = 1,
-  Auto         = 1<<2,
-  Const        = 1<<3,
-  Deprecated   = 1<<4,
-  Extern       = 1<<5,
-  Final        = 1<<6,
-  Invariant    = 1<<7,
-  Override     = 1<<8,
-  Scope        = 1<<9,
-  Static       = 1<<10,
-  Synchronized = 1<<11,
-  In           = 1<<12,
-  Out          = 1<<13,
-  Ref          = 1<<14,
-  Lazy         = 1<<15,
-  Variadic     = 1<<16,
-}
-
 class Parameter : Node
 {
   StorageClass stc;
@@ -82,10 +62,9 @@
   {
     super(NodeCategory.Other);
     mixin(set_kind);
-    if (type) // type can be null when param in foreach statement
-      this.children = [type];
-    if (assignExpr)
-      this.children ~= assignExpr;
+    // type can be null when param in foreach statement
+    addOptChild(type);
+    addOptChild(assignExpr);
 
     StorageClass stc;
     if (stcTok !is null)
@@ -139,7 +118,7 @@
   }
 
   void opCatAssign(Parameter param)
-  { children ~= param; }
+  { addChild(param); }
 
   Parameter[] items()
   { return cast(Parameter[])children; }
@@ -148,17 +127,6 @@
   { return children.length; }
 }
 
-
-enum Protection
-{
-  None,
-  Private   = 1,
-  Protected = 1<<1,
-  Package   = 1<<2,
-  Public    = 1<<3,
-  Export    = 1<<4
-}
-
 class BaseClass : Node
 {
   Protection prot;
@@ -167,7 +135,7 @@
   {
     super(NodeCategory.Other);
     mixin(set_kind);
-    this.children = [type];
+    addChild(type);
     this.prot = prot;
     this.type = type;
   }
@@ -188,10 +156,8 @@
   this(Token* ident, Type specType, Type defType)
   {
     mixin(set_kind);
-    if (specType)
-      this.children ~= specType;
-    if (defType)
-      this.children ~= defType;
+    addOptChild(specType);
+    addOptChild(defType);
     this.ident = ident;
     this.specType = specType;
     this.defType = defType;
@@ -205,10 +171,8 @@
   this(Token* ident, Type specType, Type defType)
   {
     mixin(set_kind);
-    if (specType)
-      this.children ~= specType;
-    if (defType)
-      this.children ~= defType;
+    addOptChild(specType);
+    addOptChild(defType);
     this.ident = ident;
     this.specType = specType;
     this.defType = defType;
@@ -223,11 +187,9 @@
   this(Type valueType, Token* ident, Expression specValue, Expression defValue)
   {
     mixin(set_kind);
-    this.children ~= valueType;
-    if (specValue)
-      this.children ~= specValue;
-    if (defValue)
-      this.children ~= defValue;
+    addChild(valueType);
+    addOptChild(specValue);
+    addOptChild(defValue);
     this.valueType = valueType;
     this.ident = ident;
     this.specValue = specValue;
@@ -255,7 +217,7 @@
 
   void opCatAssign(TemplateParameter parameter)
   {
-    this.children ~= parameter;
+    addChild(parameter);
   }
 
   TemplateParameter[] items()
@@ -274,7 +236,7 @@
 
   void opCatAssign(Node argument)
   {
-    this.children ~= argument;
+    addChild(argument);
   }
 }
 
@@ -331,8 +293,7 @@
   this(TID tid, Type next)
   {
     super(NodeCategory.Type);
-    if (next)
-      this.children ~= next;
+    addOptChild(next);
     this.tid = tid;
     this.next = next;
   }
@@ -363,7 +324,7 @@
   {
     super(TID.DotList);
     mixin(set_kind);
-    this.children ~= dotList;
+    addChildren(dotList);
     this.dotList = dotList;
   }
 }
@@ -395,7 +356,7 @@
   {
     super(TID.Typeof);
     mixin(set_kind);
-    this.children ~= e;
+    addChild(e);
     this.e = e;
   }
 }
@@ -408,8 +369,7 @@
   {
     super(TID.TemplateInstance);
     mixin(set_kind);
-    if (targs)
-      this.children ~= targs;
+    addOptChild(targs);
     this.ident = ident;
     this.targs = targs;
   }
@@ -428,23 +388,25 @@
 {
   Expression e, e2;
   Type assocType;
+
   this(Type t)
   {
     super(TID.Array, t);
     mixin(set_kind);
   }
+
   this(Type t, Expression e, Expression e2)
   {
-    this.children = [e];
-    if (e2)
-      this.children ~= e2;
+    addChild(e);
+    addOptChild(e2);
     this.e = e;
     this.e2 = e2;
     this(t);
   }
+
   this(Type t, Type assocType)
   {
-    this.children = [assocType];
+    addChild(assocType);
     this.assocType = assocType;
     this(t);
   }
@@ -458,7 +420,8 @@
   {
     super(TID.Function);
     mixin(set_kind);
-    this.children = [cast(Node)returnType, parameters];
+    addChild(returnType);
+    addChild(parameters);
     this.returnType = returnType;
     this.parameters = parameters;
   }
@@ -472,7 +435,8 @@
   {
     super(TID.Delegate);
     mixin(set_kind);
-    this.children = [cast(Node)returnType, parameters];
+    addChild(returnType);
+    addChild(parameters);
     this.returnType = returnType;
     this.parameters = parameters;
   }
@@ -485,8 +449,7 @@
   {
     super(TID.CFuncPointer, type);
     mixin(set_kind);
-    if (params)
-      this.children ~= params;
+    addOptChild(params);
   }
 }