Mercurial > projects > dil
changeset 791:5fe89bb8cbdd
Implemented syntax tree copying.
author | Aziz K?ksal <aziz.koeksal@gmail.com> |
---|---|
date | Tue, 26 Feb 2008 20:13:41 +0100 |
parents | a83a07f6233d |
children | 05dfe88dd3bb |
files | trunk/src/dil/ast/Declaration.d trunk/src/dil/ast/Declarations.d trunk/src/dil/ast/DefaultVisitor.d trunk/src/dil/ast/Expression.d trunk/src/dil/ast/Expressions.d trunk/src/dil/ast/Node.d trunk/src/dil/ast/NodeCopier.d trunk/src/dil/ast/Parameters.d trunk/src/dil/ast/Statement.d trunk/src/dil/ast/Statements.d trunk/src/dil/ast/Type.d trunk/src/dil/ast/Types.d trunk/src/dil/semantic/Interpreter.d |
diffstat | 13 files changed, 550 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- a/trunk/src/dil/ast/Declaration.d Mon Feb 25 03:37:20 2008 +0100 +++ b/trunk/src/dil/ast/Declaration.d Tue Feb 26 20:13:41 2008 +0100 @@ -40,4 +40,5 @@ this.prot = prot; } + override abstract Declaration copy(); }
--- a/trunk/src/dil/ast/Declarations.d Mon Feb 25 03:37:20 2008 +0100 +++ b/trunk/src/dil/ast/Declarations.d Tue Feb 26 20:13:41 2008 +0100 @@ -6,10 +6,11 @@ public import dil.ast.Declaration; import dil.ast.Node; -import dil.ast.Expressions; +import dil.ast.Expression; import dil.ast.Types; import dil.ast.Statements; import dil.ast.Parameters; +import dil.ast.NodeCopier; import dil.lexer.IdTable; import dil.semantic.Symbols; import dil.Enums; @@ -37,6 +38,13 @@ { return cast(Declaration[])this.children; } + + void decls(Declaration[] decls) + { + this.children = decls; + } + + mixin(copyMethod); } /// Single semicolon. @@ -46,19 +54,19 @@ { mixin(set_kind); } + mixin(copyMethod); } -/++ - Illegal declarations encompass all tokens that don't - start a DeclarationDefinition. - See_Also: dil.lexer.Token.isDeclDefStartToken() -+/ +/// Illegal declarations encompass all tokens that don't +/// start a DeclarationDefinition. +/// See_Also: dil.lexer.Token.isDeclDefStartToken() class IllegalDeclaration : Declaration { this() { mixin(set_kind); } + mixin(copyMethod); } /// FQN = fully qualified name @@ -102,6 +110,8 @@ pname = pname[0..$-1]; // Remove last separator return pname; } + + mixin(copyMethod); } class ImportDeclaration : Declaration @@ -136,6 +146,8 @@ } return FQNs; } + + mixin(copyMethod); } class AliasDeclaration : Declaration @@ -147,6 +159,7 @@ addChild(decl); this.decl = decl; } + mixin(copyMethod); } class TypedefDeclaration : Declaration @@ -158,6 +171,7 @@ addChild(decl); this.decl = decl; } + mixin(copyMethod); } class EnumDeclaration : Declaration @@ -178,6 +192,8 @@ } Enum symbol; + + mixin(copyMethod); } class EnumMemberDeclaration : Declaration @@ -194,6 +210,8 @@ } EnumMember symbol; + + mixin(copyMethod); } class TemplateDeclaration : Declaration @@ -214,6 +232,8 @@ } Template symbol; /// The template symbol for this declaration. + + mixin(copyMethod); } abstract class AggregateDeclaration : Declaration @@ -228,6 +248,7 @@ // this.tparams = tparams; this.decls = decls; } + mixin(copyMethod); } class ClassDeclaration : AggregateDeclaration @@ -245,6 +266,8 @@ } Class symbol; /// The class symbol for this declaration. + + mixin(copyMethod); } class InterfaceDeclaration : AggregateDeclaration @@ -264,6 +287,8 @@ alias dil.semantic.Symbols.Interface Interface; Interface symbol; /// The interface symbol for this declaration. + + mixin(copyMethod); } class StructDeclaration : AggregateDeclaration @@ -283,6 +308,8 @@ } Struct symbol; /// The struct symbol for this declaration. + + mixin(copyMethod); } class UnionDeclaration : AggregateDeclaration @@ -296,6 +323,8 @@ } Union symbol; /// The union symbol for this declaration. + + mixin(copyMethod); } class ConstructorDeclaration : Declaration @@ -312,6 +341,7 @@ this.params = params; this.funcBody = funcBody; } + mixin(copyMethod); } class StaticConstructorDeclaration : Declaration @@ -325,6 +355,7 @@ this.funcBody = funcBody; } + mixin(copyMethod); } class DestructorDeclaration : Declaration @@ -338,6 +369,7 @@ this.funcBody = funcBody; } + mixin(copyMethod); } class StaticDestructorDeclaration : Declaration @@ -351,6 +383,7 @@ this.funcBody = funcBody; } + mixin(copyMethod); } class FunctionDeclaration : Declaration @@ -388,6 +421,8 @@ // ^ params.begin.prevNWS return params.begin.prevNWS.kind == TOK.RParen; } + + mixin(copyMethod); } /// VariablesDeclaration := Type? Identifier ("=" Init)? ("," Identifier ("=" Init)?)* ";" @@ -420,6 +455,8 @@ } Variable[] variables; + + mixin(copyMethod); } class InvariantDeclaration : Declaration @@ -433,6 +470,7 @@ this.funcBody = funcBody; } + mixin(copyMethod); } class UnittestDeclaration : Declaration @@ -446,6 +484,7 @@ this.funcBody = funcBody; } + mixin(copyMethod); } abstract class ConditionalCompilationDeclaration : Declaration @@ -487,6 +526,7 @@ super(spec, cond, decls, elseDecls); mixin(set_kind); } + mixin(copyMethod); } class VersionDeclaration : ConditionalCompilationDeclaration @@ -496,6 +536,7 @@ super(spec, cond, decls, elseDecls); mixin(set_kind); } + mixin(copyMethod); } class StaticIfDeclaration : Declaration @@ -514,6 +555,7 @@ this.ifDecls = ifDecls; this.elseDecls = elseDecls; } + mixin(copyMethod); } class StaticAssertDeclaration : Declaration @@ -529,6 +571,7 @@ this.condition = condition; this.message = message; } + mixin(copyMethod); } class NewDeclaration : Declaration @@ -545,6 +588,7 @@ this.params = params; this.funcBody = funcBody; } + mixin(copyMethod); } class DeleteDeclaration : Declaration @@ -561,6 +605,7 @@ this.params = params; this.funcBody = funcBody; } + mixin(copyMethod); } abstract class AttributeDeclaration : Declaration @@ -583,6 +628,7 @@ mixin(set_kind); this.prot = prot; } + mixin(copyMethod); } class StorageClassDeclaration : AttributeDeclaration @@ -595,6 +641,7 @@ this.storageClass = storageClass; } + mixin(copyMethod); } class LinkageDeclaration : AttributeDeclaration @@ -607,6 +654,7 @@ this.linkageType = linkageType; } + mixin(copyMethod); } class AlignDeclaration : AttributeDeclaration @@ -618,6 +666,7 @@ mixin(set_kind); this.size = size; } + mixin(copyMethod); } class PragmaDeclaration : AttributeDeclaration @@ -633,6 +682,7 @@ this.ident = ident; this.args = args; } + mixin(copyMethod); } class MixinDeclaration : Declaration @@ -665,4 +715,6 @@ { return argument !is null; } + + mixin(copyMethod); }
--- a/trunk/src/dil/ast/DefaultVisitor.d Mon Feb 25 03:37:20 2008 +0100 +++ b/trunk/src/dil/ast/DefaultVisitor.d Tue Feb 26 20:13:41 2008 +0100 @@ -109,7 +109,7 @@ static if (is(E == IllegalExpression)) {} else - static if (is(E : CondExpression)) + static if (is(E == CondExpression)) visitE(e.condition), visitE(e.lhs), visitE(e.rhs); else static if (is(E : BinaryExpression)) @@ -192,8 +192,8 @@ { alias T S; static if (is(S == CompoundStatement)) - foreach (node; s.children) - visitS(cast(Statement)cast(void*)node); + foreach (stmnt; s.stmnts) + visitS(stmnt); //IllegalStatement has no subnodes. static if (is(S == FuncBodyStatement)) s.funcBody && visitS(s.funcBody), @@ -265,7 +265,8 @@ static if (is(S == AsmStatement)) foreach (op; s.operands) visitE(op); - //AsmAlignStatement has no subnodes. + //AsmAlignStatement, + //IllegalAsmStatement have no subnodes. static if (is(S == PragmaStatement)) { foreach (arg; s.args) @@ -342,7 +343,7 @@ //TemplateTupleParameter has no subnodes. } else - assert(0, "Missing default visit method for: "~t.classinfo.name); + static assert(0, "Missing default visit method for: "~typeof(t).stringof); return t; }
--- a/trunk/src/dil/ast/Expression.d Mon Feb 25 03:37:20 2008 +0100 +++ b/trunk/src/dil/ast/Expression.d Tue Feb 26 20:13:41 2008 +0100 @@ -17,4 +17,6 @@ { super(NodeCategory.Expression); } + + override abstract Expression copy(); }
--- a/trunk/src/dil/ast/Expressions.d Mon Feb 25 03:37:20 2008 +0100 +++ b/trunk/src/dil/ast/Expressions.d Tue Feb 26 20:13:41 2008 +0100 @@ -10,6 +10,7 @@ import dil.ast.Declarations; import dil.ast.Statements; import dil.ast.Parameters; +import dil.ast.NodeCopier; import dil.lexer.Identifier; import dil.semantic.Types; import common; @@ -20,6 +21,7 @@ { mixin(set_kind); } + mixin(copyMethod); } abstract class BinaryExpression : Expression @@ -34,6 +36,7 @@ this.rhs = rhs; this.tok = tok; } + mixin(copyMethod); } class CondExpression : BinaryExpression @@ -46,6 +49,7 @@ mixin(set_kind); this.condition = condition; } + mixin(copyMethod); } class CommaExpression : BinaryExpression @@ -355,6 +359,7 @@ addChild(e); this.e = e; } + mixin(copyMethod); } class AddressExpression : UnaryExpression @@ -478,6 +483,7 @@ this.type = type; this.ctorArgs = ctorArgs; } + mixin(copyMethod); } class NewAnonClassExpression : /*Unary*/Expression @@ -500,6 +506,7 @@ this.ctorArgs = ctorArgs; this.decls = decls; } + mixin(copyMethod); } class DeleteExpression : UnaryExpression @@ -521,6 +528,7 @@ mixin(set_kind); this.type = type; } + mixin(copyMethod); } class IndexExpression : UnaryExpression @@ -533,6 +541,7 @@ addChildren(args); this.args = args; } + mixin(copyMethod); } class SliceExpression : UnaryExpression @@ -549,6 +558,7 @@ this.left = left; this.right = right; } + mixin(copyMethod); } /// Module scope operator: '.' (IdentifierExpression|TemplateInstanceExpression) @@ -576,6 +586,7 @@ mixin(set_kind); this.identifier = identifier; } + mixin(copyMethod); } class SpecialTokenExpression : Expression @@ -588,6 +599,8 @@ } Expression value; /// The expression created in the semantic phase. + + mixin(copyMethod); } class TemplateInstanceExpression : Expression @@ -601,6 +614,7 @@ this.ident = ident; this.targs = targs; } + mixin(copyMethod); } class ThisExpression : Expression @@ -609,6 +623,7 @@ { mixin(set_kind); } + mixin(copyMethod); } class SuperExpression : Expression @@ -617,6 +632,7 @@ { mixin(set_kind); } + mixin(copyMethod); } class NullExpression : Expression @@ -631,6 +647,8 @@ this(); this.type = type; } + + mixin(copyMethod); } class DollarExpression : Expression @@ -639,6 +657,7 @@ { mixin(set_kind); } + mixin(copyMethod); } class BoolExpression : Expression @@ -655,6 +674,8 @@ } Expression value; /// IntExpression of type int. + + mixin(copyMethod); } class IntExpression : Expression @@ -686,6 +707,8 @@ } this(token.ulong_, type); } + + mixin(copyMethod); } class RealExpression : Expression @@ -721,22 +744,23 @@ } this(token.real_, type); } + + mixin(copyMethod); } -/++ - This expression holds a complex number. - It is only created in the semantic phase. -+/ + +/// This expression holds a complex number. +/// It is only created in the semantic phase. class ComplexExpression : Expression { creal number; - this(creal number, Type type) { mixin(set_kind); this.number = number; this.type = type; } + mixin(copyMethod); } class CharExpression : Expression @@ -747,6 +771,7 @@ mixin(set_kind); this.character = character; } + mixin(copyMethod); } class StringExpression : Expression @@ -783,6 +808,8 @@ // TODO: convert to char[] if charType !is Types.Char. return cast(char[])str[0..$-1]; } + + mixin(copyMethod); } class ArrayLiteralExpression : Expression @@ -794,6 +821,7 @@ addOptChildren(values); this.values = values; } + mixin(copyMethod); } class AArrayLiteralExpression : Expression @@ -808,6 +836,7 @@ this.keys = keys; this.values = values; } + mixin(copyMethod); } class AssertExpression : Expression @@ -821,6 +850,7 @@ this.expr = expr; this.msg = msg; } + mixin(copyMethod); } class MixinExpression : Expression @@ -832,6 +862,7 @@ addChild(expr); this.expr = expr; } + mixin(copyMethod); } class ImportExpression : Expression @@ -843,6 +874,7 @@ addChild(expr); this.expr = expr; } + mixin(copyMethod); } class TypeofExpression : Expression @@ -854,6 +886,7 @@ addChild(type); this.type = type; } + mixin(copyMethod); } class TypeDotIdExpression : Expression @@ -867,6 +900,7 @@ this.type = type; this.ident = ident; } + mixin(copyMethod); } class TypeidExpression : Expression @@ -878,6 +912,7 @@ addChild(type); this.type = type; } + mixin(copyMethod); } class IsExpression : Expression @@ -902,6 +937,7 @@ this.specType = specType; this.tparams = tparams; } + mixin(copyMethod); } class FunctionLiteralExpression : Expression @@ -931,6 +967,8 @@ this.funcBody = funcBody; this(); } + + mixin(copyMethod); } /// ParenthesisExpression := "(" Expression ")" @@ -943,6 +981,7 @@ addChild(next); this.next = next; } + mixin(copyMethod); } // version(D2) @@ -958,6 +997,7 @@ this.ident = ident; this.targs = targs; } + mixin(copyMethod); } // } @@ -967,6 +1007,7 @@ { mixin(set_kind); } + mixin(copyMethod); } class ArrayInitExpression : Expression @@ -985,6 +1026,7 @@ this.keys = keys; this.values = values; } + mixin(copyMethod); } class StructInitExpression : Expression @@ -998,6 +1040,7 @@ this.idents = idents; this.values = values; } + mixin(copyMethod); } class AsmTypeExpression : UnaryExpression @@ -1037,6 +1080,7 @@ addChild(e2); this.e2 = e2; } + mixin(copyMethod); } class AsmBracketExpression : Expression @@ -1048,6 +1092,7 @@ addChild(e); this.e = e; } + mixin(copyMethod); } class AsmLocalSizeExpression : Expression @@ -1056,6 +1101,7 @@ { mixin(set_kind); } + mixin(copyMethod); } class AsmRegisterExpression : Expression @@ -1068,4 +1114,5 @@ this.register = register; this.number = number; } + mixin(copyMethod); }
--- a/trunk/src/dil/ast/Node.d Mon Feb 25 03:37:20 2008 +0100 +++ b/trunk/src/dil/ast/Node.d Tue Feb 26 20:13:41 2008 +0100 @@ -77,6 +77,20 @@ { return cast(Class)cast(void*)this; } + + /// Returns a deep copy of this node. + abstract Node copy(); + + /// Returns a shallow copy of this object. + final Node dup() + { + // Find out the size of this object. + alias typeof(this.classinfo.init[0]) byte_t; + size_t size = this.classinfo.init.length; + // Copy this object's data. + byte_t[] data = (cast(byte_t*)this)[0..size].dup; + return cast(Node)data.ptr; + } } /// This string is mixed into the constructor of a class that inherits
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/trunk/src/dil/ast/NodeCopier.d Tue Feb 26 20:13:41 2008 +0100 @@ -0,0 +1,324 @@ +/++ + Author: Aziz Köksal + License: GPL3 ++/ +module dil.ast.NodeCopier; + +import common; + +/// Mixed into the body of a class that inherits from Node. +const string copyMethod = ` + override typeof(this) copy() + { + mixin copyNode!(typeof(this)); + return copyNode(this); + }`; + +/// A helper function that generates code for copying subnodes. +string doCopy_(string obj, string[] members) +{ + char[] result; + foreach (member; members) + { + if (member.length > 2 && member[$-2..$] == "[]") // Array copy. + { + member = member[0..$-2]; + // obj.member = obj.member.dup; + // foreach (ref m_; obj.member) + // m_ = m_.copy(); + result ~= obj~"."~member~" = "~obj~"."~member~".dup;" + "foreach (ref m_; "~obj~"."~member~")" + "m_ = m_.copy();"; + } + else if (member[$-1] == '?') // Optional member copy. + { + member = member[0..$-1]; + // obj.member && (obj.member = obj.member.copy()); + result ~= obj~"."~member~" && ("~obj~"."~member~" = "~obj~"."~member~".copy());"; + } + else // Non-optional member copy. + // obj.member = obj.member.copy(); + result ~= obj~"."~member~" = "~obj~"."~member~".copy();"; + } + return result; +} + +string doCopy(string[] members) +{ + return doCopy_("x", members); +} + +string doCopy(string member) +{ + return doCopy_("x", [member]); +} + +// pragma(msg, doCopy("decls?")); + +/// Returns a deep copy of node. +T copyNode(T)(T node) +{ + assert(node !is null); + + // Firstly do a shallow copy. + T x = cast(T)cast(void*)node.dup; + + // Now copy the subnodes. + static if (is(Declaration) && is(T : Declaration)) + { + alias T D; + static if (is(D == CompoundDeclaration)) + mixin(doCopy("decls[]")); + //EmptyDeclaration, + //IllegalDeclaration, + //ModuleDeclaration have no subnodes. + static if (is(D == AliasDeclaration) || + is(D == TypedefDeclaration)) + mixin(doCopy("decl")); + static if (is(D == EnumDeclaration)) + mixin(doCopy(["baseType?", "members[]"])); + static if (is(D == EnumMemberDeclaration)) + mixin(doCopy("value")); + static if (is(D == ClassDeclaration) || is( D == InterfaceDeclaration)) + mixin(doCopy(["bases[]", "decls"])); + static if (is(D == StructDeclaration) || is(D == UnionDeclaration)) + mixin(doCopy("decls")); + static if (is(D == ConstructorDeclaration)) + mixin(doCopy(["params", "funcBody"])); + static if (is(D == StaticConstructorDeclaration) || + is(D == DestructorDeclaration) || + is(D == StaticDestructorDeclaration) || + is(D == InvariantDeclaration) || + is(D == UnittestDeclaration)) + mixin(doCopy("funcBody")); + static if (is(D == FunctionDeclaration)) + mixin(doCopy(["returnType", "params", "funcBody"])); + static if (is(D == VariablesDeclaration)) + { + mixin(doCopy("typeNode?")); + x.inits = x.inits.dup; + foreach(ref init; x.inits) + init && (init = init.copy()); + } + static if (is(D == DebugDeclaration) || is(D == VersionDeclaration)) + mixin(doCopy(["decls?","elseDecls?"])); + static if (is(D == StaticIfDeclaration)) + mixin(doCopy(["condition","ifDecls", "elseDecls?"])); + static if (is(D == StaticAssertDeclaration)) + mixin(doCopy(["condition","message?"])); + static if (is(D == TemplateDeclaration)) + mixin(doCopy(["tparams","decls"])); + static if (is(D == NewDeclaration) || is(D == DeleteDeclaration)) + mixin(doCopy(["params","funcBody"])); + static if (is(D == ProtectionDeclaration) || + is(D == StorageClassDeclaration) || + is(D == LinkageDeclaration) || + is(D == AlignDeclaration)) + mixin(doCopy("decls")); + static if (is(D == PragmaDeclaration)) + mixin(doCopy(["args[]","decls"])); + static if (is(D == MixinDeclaration)) + mixin(doCopy(["templateExpr?","argument?"])); + } + else + static if (is(Expression) && is(T : Expression)) + { + alias T E; + static if (is(E == IllegalExpression)) + {} + else + static if (is(E == CondExpression)) + mixin(doCopy(["condition", "lhs", "rhs"])); + else + static if (is(E : BinaryExpression)) + mixin(doCopy(["lhs", "rhs"])); + else + static if (is(E : UnaryExpression)) + { + static if (is(E == CastExpression)) + mixin(doCopy("type")); + mixin(doCopy("e")); // Copy member in base class UnaryExpression. + static if (is(E == IndexExpression)) + mixin(doCopy("args[]")); + static if (is(E == SliceExpression)) + mixin(doCopy(["left?", "right?"])); + static if (is(E == AsmPostBracketExpression)) + mixin(doCopy("e2")); + } + else + { + static if (is(E == NewExpression)) + mixin(doCopy(["newArgs[]", "type", "ctorArgs[]"])); + static if (is(E == NewAnonClassExpression)) + mixin(doCopy(["newArgs[]", "bases[]", "ctorArgs[]", "decls"])); + static if (is(E == AsmBracketExpression)) + mixin(doCopy("e")); + static if (is(E == TemplateInstanceExpression)) + mixin(doCopy("targs?")); + static if (is(E == ArrayLiteralExpression)) + mixin(doCopy("values[]")); + static if (is(E == AArrayLiteralExpression)) + mixin(doCopy(["keys[]", "values[]"])); + static if (is(E == AssertExpression)) + mixin(doCopy(["expr", "msg?"])); + static if (is(E == MixinExpression) || + is(E == ImportExpression)) + mixin(doCopy("expr")); + static if (is(E == TypeofExpression) || + is(E == TypeDotIdExpression) || + is(E == TypeidExpression)) + mixin(doCopy("type")); + static if (is(E == IsExpression)) + mixin(doCopy(["type", "specType?", "tparams?"])); + static if (is(E == FunctionLiteralExpression)) + mixin(doCopy(["returnType?", "params?", "funcBody"])); + static if (is(E == ParenExpression)) + mixin(doCopy("next")); + static if (is(E == TraitsExpression)) + mixin(doCopy("targs")); + // VoidInitializer has no subnodes. + static if (is(E == ArrayInitExpression)) + { + mixin(doCopy("values[]")); + x.keys = x.keys.dup; + foreach(ref key; x.keys) + key && (key = key.copy()); + } + static if (is(E == StructInitExpression)) + mixin(doCopy("values[]")); + static if (is(E == StringExpression)) + x.str = x.str.dup; + } + } + else + static if (is(Statement) && is(T : Statement)) + { + alias T S; + static if (is(S == CompoundStatement)) + mixin(doCopy("stmnts[]")); + //IllegalStatement, + //EmptyStatement have no subnodes. + static if (is(S == FuncBodyStatement)) + mixin(doCopy(["funcBody?", "inBody?", "outBody?"])); + static if (is(S == ScopeStatement) || is(S == LabeledStatement)) + mixin(doCopy("s")); + static if (is(S == ExpressionStatement)) + mixin(doCopy("e")); + static if (is(S == DeclarationStatement)) + mixin(doCopy("decl")); + static if (is(S == IfStatement)) + { + if (x.variable) + mixin(doCopy("variable")); + else + mixin(doCopy("condition")); + mixin(doCopy(["ifBody", "elseBody?"])); + } + static if (is(S == WhileStatement)) + mixin(doCopy(["condition", "whileBody"])); + static if (is(S == DoWhileStatement)) + mixin(doCopy(["doBody", "condition"])); + static if (is(S == ForStatement)) + mixin(doCopy(["init?", "condition?", "increment?", "forBody"])); + static if (is(S == ForeachStatement)) + mixin(doCopy(["params", "aggregate", "forBody"])); + static if (is(S == ForeachRangeStatement)) + mixin(doCopy(["params", "lower", "upper", "forBody"])); + static if (is(S == SwitchStatement)) + mixin(doCopy(["condition", "switchBody"])); + static if (is(S == CaseStatement)) + mixin(doCopy(["values[]", "caseBody"])); + static if (is(S == DefaultStatement)) + mixin(doCopy("defaultBody")); + //ContinueStatement, + //BreakStatement have no subnodes. + static if (is(S == ReturnStatement)) + mixin(doCopy("e?")); + static if (is(S == GotoStatement)) + mixin(doCopy("caseExpr?")); + static if (is(S == WithStatement)) + mixin(doCopy(["e", "withBody"])); + static if (is(S == SynchronizedStatement)) + mixin(doCopy(["e?", "syncBody"])); + static if (is(S == TryStatement)) + mixin(doCopy(["tryBody", "catchBodies[]", "finallyBody?"])); + static if (is(S == CatchStatement)) + mixin(doCopy(["param?", "catchBody"])); + static if (is(S == FinallyStatement)) + mixin(doCopy("finallyBody")); + static if (is(S == ScopeGuardStatement)) + mixin(doCopy("scopeBody")); + static if (is(S == ThrowStatement)) + mixin(doCopy("e")); + static if (is(S == VolatileStatement)) + mixin(doCopy("volatileBody?")); + static if (is(S == AsmBlockStatement)) + mixin(doCopy("statements")); + static if (is(S == AsmStatement)) + mixin(doCopy("operands[]")); + //AsmAlignStatement, + //IllegalAsmStatement have no subnodes. + static if (is(S == PragmaStatement)) + mixin(doCopy(["args[]", "pragmaBody"])); + static if (is(S == MixinStatement)) + mixin(doCopy("templateExpr")); + static if (is(S == StaticIfStatement)) + mixin(doCopy(["condition", "ifBody", "elseBody?"])); + static if (is(S == StaticAssertStatement)) + mixin(doCopy(["condition", "message?"])); + static if (is(S == DebugStatement) || is(S == VersionStatement)) + mixin(doCopy(["mainBody", "elseBody?"])); + } + else + static if (is(TypeNode) && is(T : TypeNode)) + { + //IllegalType, + //IntegralType, + //IdentifierType have no subnodes. + static if (is(T == QualifiedType)) + mixin(doCopy(["lhs", "rhs"])); + static if (is(T == TypeofType)) + mixin(doCopy("e")); + static if (is(T == TemplateInstanceType)) + mixin(doCopy("targs?")); + static if (is(T == PointerType)) + mixin(doCopy("next")); + static if (is(T == ArrayType)) + mixin(doCopy(["next", "assocType?", "e1?", "e2?"])); + static if (is(T == FunctionType) || is(T == DelegateType)) + mixin(doCopy(["returnType", "params"])); + static if (is(T == CFuncPointerType)) + mixin(doCopy(["next", "params?"])); + static if (is(T == ModuleScopeType) || + is(T == BaseClassType) || + is(T == ConstType) || + is(T == InvariantType)) + mixin(doCopy("next")); + } + else + static if (is(Parameter) && is(T == Parameter)) + { + mixin(doCopy(["type?", "defValue?"])); + } + else + static if (is(Parameter) && is(T == Parameters) || + is(TemplateParameter) && is(T == TemplateParameters) || + is(TemplateArguments) && is(T == TemplateArguments)) + { + mixin(doCopy("children[]")); + } + else + static if (is(TemplateParameter) && is(T : TemplateParameter)) + { + static if (is(N == TemplateAliasParameter) || + is(N == TemplateTypeParameter) || + is(N == TemplateThisParameter)) + mixin(doCopy(["specType", "defType"])); + static if (is(N == TemplateValueParameter)) + mixin(doCopy(["valueType", "specValue?", "defValue?"])); + //TemplateTupleParameter has no subnodes. + } + else + static assert(0, "copying of "~typeof(x).stringof~" is not handled"); + return x; +}
--- a/trunk/src/dil/ast/Parameters.d Mon Feb 25 03:37:20 2008 +0100 +++ b/trunk/src/dil/ast/Parameters.d Tue Feb 26 20:13:41 2008 +0100 @@ -7,6 +7,7 @@ import dil.ast.Node; import dil.ast.Type; import dil.ast.Expression; +import dil.ast.NodeCopier; import dil.lexer.Identifier; import dil.Enums; @@ -52,6 +53,8 @@ { return !!(stc & StorageClass.Variadic); } + + mixin(copyMethod); } /// Array of parameters. @@ -78,6 +81,8 @@ size_t length() { return children.length; } + + mixin(copyMethod); } /*~~~~~~~~~~~~~~~~~~~~~~ @@ -93,6 +98,7 @@ super(NodeCategory.Other); this.ident = ident; } + override abstract TemplateParameter copy(); } /// E.g.: (alias T) @@ -109,6 +115,7 @@ this.specType = specType; this.defType = defType; } + mixin(copyMethod); } /// E.g.: (T t) @@ -125,6 +132,7 @@ this.specType = specType; this.defType = defType; } + mixin(copyMethod); } // version(D2) @@ -143,6 +151,7 @@ this.specType = specType; this.defType = defType; } + mixin(copyMethod); } // } @@ -163,6 +172,7 @@ this.specValue = specValue; this.defValue = defValue; } + mixin(copyMethod); } /// E.g.: (T...) @@ -174,6 +184,7 @@ mixin(set_kind); this.ident = ident; } + mixin(copyMethod); } /// Array of template parameters. @@ -194,6 +205,8 @@ { return cast(TemplateParameter[])children; } + + mixin(copyMethod); } /// Array of template arguments. @@ -209,4 +222,6 @@ { addChild(argument); } + + mixin(copyMethod); }
--- a/trunk/src/dil/ast/Statement.d Mon Feb 25 03:37:20 2008 +0100 +++ b/trunk/src/dil/ast/Statement.d Tue Feb 26 20:13:41 2008 +0100 @@ -13,4 +13,6 @@ { super(NodeCategory.Statement); } + + override abstract Statement copy(); }
--- a/trunk/src/dil/ast/Statements.d Mon Feb 25 03:37:20 2008 +0100 +++ b/trunk/src/dil/ast/Statements.d Tue Feb 26 20:13:41 2008 +0100 @@ -6,10 +6,11 @@ public import dil.ast.Statement; import dil.ast.Node; -import dil.ast.Expressions; -import dil.ast.Declarations; -import dil.ast.Types; +import dil.ast.Expression; +import dil.ast.Declaration; +import dil.ast.Type; import dil.ast.Parameters; +import dil.ast.NodeCopier; import dil.lexer.IdTable; class CompoundStatement : Statement @@ -23,6 +24,18 @@ { addChild(s); } + + Statement[] stmnts() + { + return cast(Statement[])this.children; + } + + void stmnts(Statement[] stmnts) + { + this.children = stmnts; + } + + mixin(copyMethod); } class IllegalStatement : Statement @@ -31,6 +44,7 @@ { mixin(set_kind); } + mixin(copyMethod); } class EmptyStatement : Statement @@ -39,6 +53,7 @@ { mixin(set_kind); } + mixin(copyMethod); } class FuncBodyStatement : Statement @@ -61,6 +76,8 @@ { return funcBody is null; } + + mixin(copyMethod); } class ScopeStatement : Statement @@ -72,6 +89,7 @@ addChild(s); this.s = s; } + mixin(copyMethod); } class LabeledStatement : Statement @@ -85,6 +103,7 @@ this.label = label; this.s = s; } + mixin(copyMethod); } class ExpressionStatement : Statement @@ -96,6 +115,7 @@ addChild(e); this.e = e; } + mixin(copyMethod); } class DeclarationStatement : Statement @@ -107,6 +127,7 @@ addChild(decl); this.decl = decl; } + mixin(copyMethod); } class IfStatement : Statement @@ -130,6 +151,7 @@ this.ifBody = ifBody; this.elseBody = elseBody; } + mixin(copyMethod); } class WhileStatement : Statement @@ -145,6 +167,7 @@ this.condition = condition; this.whileBody = whileBody; } + mixin(copyMethod); } class DoWhileStatement : Statement @@ -160,6 +183,7 @@ this.condition = condition; this.doBody = doBody; } + mixin(copyMethod); } class ForStatement : Statement @@ -181,6 +205,7 @@ this.increment = increment; this.forBody = forBody; } + mixin(copyMethod); } class ForeachStatement : Statement @@ -200,6 +225,7 @@ this.aggregate = aggregate; this.forBody = forBody; } + mixin(copyMethod); } // version(D2) @@ -222,6 +248,7 @@ this.upper = upper; this.forBody = forBody; } + mixin(copyMethod); } // } @@ -239,6 +266,7 @@ this.condition = condition; this.switchBody = switchBody; } + mixin(copyMethod); } class CaseStatement : Statement @@ -255,6 +283,7 @@ this.values = values; this.caseBody = caseBody; } + mixin(copyMethod); } class DefaultStatement : Statement @@ -267,6 +296,7 @@ this.defaultBody = defaultBody; } + mixin(copyMethod); } class ContinueStatement : Statement @@ -277,6 +307,7 @@ mixin(set_kind); this.ident = ident; } + mixin(copyMethod); } class BreakStatement : Statement @@ -287,6 +318,7 @@ mixin(set_kind); this.ident = ident; } + mixin(copyMethod); } class ReturnStatement : Statement @@ -298,6 +330,7 @@ addOptChild(e); this.e = e; } + mixin(copyMethod); } class GotoStatement : Statement @@ -311,6 +344,7 @@ this.ident = ident; this.caseExpr = caseExpr; } + mixin(copyMethod); } class WithStatement : Statement @@ -326,6 +360,7 @@ this.e = e; this.withBody = withBody; } + mixin(copyMethod); } class SynchronizedStatement : Statement @@ -341,6 +376,7 @@ this.e = e; this.syncBody = syncBody; } + mixin(copyMethod); } class TryStatement : Statement @@ -359,6 +395,7 @@ this.catchBodies = catchBodies; this.finallyBody = finallyBody; } + mixin(copyMethod); } class CatchStatement : Statement @@ -373,6 +410,7 @@ this.param = param; this.catchBody = catchBody; } + mixin(copyMethod); } class FinallyStatement : Statement @@ -384,6 +422,7 @@ addChild(finallyBody); this.finallyBody = finallyBody; } + mixin(copyMethod); } class ScopeGuardStatement : Statement @@ -397,6 +436,7 @@ this.condition = condition; this.scopeBody = scopeBody; } + mixin(copyMethod); } class ThrowStatement : Statement @@ -408,6 +448,7 @@ addChild(e); this.e = e; } + mixin(copyMethod); } class VolatileStatement : Statement @@ -419,6 +460,7 @@ addOptChild(volatileBody); this.volatileBody = volatileBody; } + mixin(copyMethod); } class AsmBlockStatement : Statement @@ -430,6 +472,7 @@ addChild(statements); this.statements = statements; } + mixin(copyMethod); } class AsmStatement : Statement @@ -443,6 +486,7 @@ this.ident = ident; this.operands = operands; } + mixin(copyMethod); } class AsmAlignStatement : Statement @@ -453,6 +497,7 @@ mixin(set_kind); this.number = number; } + mixin(copyMethod); } class IllegalAsmStatement : IllegalStatement @@ -461,6 +506,7 @@ { mixin(set_kind); } + mixin(copyMethod); } class PragmaStatement : Statement @@ -478,6 +524,7 @@ this.args = args; this.pragmaBody = pragmaBody; } + mixin(copyMethod); } class MixinStatement : Statement @@ -491,6 +538,7 @@ this.templateExpr = templateExpr; this.mixinIdent = mixinIdent; } + mixin(copyMethod); } class StaticIfStatement : Statement @@ -507,6 +555,7 @@ this.ifBody = ifBody; this.elseBody = elseBody; } + mixin(copyMethod); } class StaticAssertStatement : Statement @@ -520,6 +569,7 @@ this.condition = condition; this.message = message; } + mixin(copyMethod); } abstract class ConditionalCompilationStatement : Statement @@ -543,6 +593,7 @@ super(cond, debugBody, elseBody); mixin(set_kind); } + mixin(copyMethod); } class VersionStatement : ConditionalCompilationStatement @@ -552,4 +603,5 @@ super(cond, versionBody, elseBody); mixin(set_kind); } + mixin(copyMethod); }
--- a/trunk/src/dil/ast/Type.d Mon Feb 25 03:37:20 2008 +0100 +++ b/trunk/src/dil/ast/Type.d Tue Feb 26 20:13:41 2008 +0100 @@ -33,4 +33,6 @@ type = type.next; return type; } + + override abstract TypeNode copy(); }
--- a/trunk/src/dil/ast/Types.d Mon Feb 25 03:37:20 2008 +0100 +++ b/trunk/src/dil/ast/Types.d Tue Feb 26 20:13:41 2008 +0100 @@ -8,6 +8,7 @@ import dil.ast.Node; import dil.ast.Expression; import dil.ast.Parameters; +import dil.ast.NodeCopier; import dil.lexer.Identifier; import dil.semantic.Types; import dil.Enums; @@ -19,6 +20,7 @@ { mixin(set_kind); } + mixin(copyMethod); } /// char, int, float etc. @@ -30,6 +32,7 @@ mixin(set_kind); this.tok = tok; } + mixin(copyMethod); } /// Identifier @@ -41,6 +44,7 @@ mixin(set_kind); this.ident = ident; } + mixin(copyMethod); } /// Type "." Type @@ -55,6 +59,7 @@ addChild(rhs); this.rhs = rhs; } + mixin(copyMethod); } /// "." Type @@ -65,6 +70,7 @@ super(next); mixin(set_kind); } + mixin(copyMethod); } /// "typeof" "(" Expression ")" or$(BR) @@ -89,6 +95,8 @@ { return e is null; } + + mixin(copyMethod); } /// Identifier "!" "(" TemplateParameters? ")" @@ -103,6 +111,7 @@ this.ident = ident; this.targs = targs; } + mixin(copyMethod); } /// Type * @@ -113,6 +122,7 @@ super(next); mixin(set_kind); } + mixin(copyMethod); } /// Dynamic array: T[] or$(BR) @@ -165,6 +175,8 @@ { return assocType !is null; } + + mixin(copyMethod); } /// ReturnType "function" "(" Parameters? ")" @@ -179,6 +191,7 @@ addChild(params); this.params = params; } + mixin(copyMethod); } /// ReturnType "delegate" "(" Parameters? ")" @@ -193,6 +206,7 @@ addChild(params); this.params = params; } + mixin(copyMethod); } /// Type "(" BasicType2 Identifier ")" "(" Parameters? ")" @@ -205,6 +219,7 @@ mixin(set_kind); addOptChild(params); } + mixin(copyMethod); } /// "class" Identifier : BaseClasses @@ -217,6 +232,7 @@ mixin(set_kind); this.prot = prot; } + mixin(copyMethod); } // version(D2) @@ -230,6 +246,7 @@ super(next); mixin(set_kind); } + mixin(copyMethod); } /// "invariant" "(" Type ")" @@ -241,5 +258,6 @@ super(next); mixin(set_kind); } + mixin(copyMethod); } // } // version(D2)
--- a/trunk/src/dil/semantic/Interpreter.d Mon Feb 25 03:37:20 2008 +0100 +++ b/trunk/src/dil/semantic/Interpreter.d Tue Feb 26 20:13:41 2008 +0100 @@ -25,6 +25,7 @@ static class Result : Expression { + override Result copy(){return null;} } static const Result NAR; /// Not a Result. Similar to NAN in floating point arithmetics.