annotate trunk/src/dil/ast/Visitor.d @ 754:c7a5499faa77

Improved DDoc related code.
author Aziz K?ksal <aziz.koeksal@gmail.com>
date Wed, 13 Feb 2008 17:10:55 +0100
parents ca7607226caa
children e4b60543c5e8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
635
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
1 /++
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
2 Author: Aziz Köksal
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
3 License: GPL3
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
4 +/
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
5 module dil.ast.Visitor;
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
6
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
7 import dil.ast.Node;
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
8 import dil.ast.Declarations,
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
9 dil.ast.Expressions,
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
10 dil.ast.Statements,
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
11 dil.ast.Types,
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
12 dil.ast.Parameters;
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
13
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
14 /++
649
3ebe76ad680e Using SemanticPass1 in main.d do start semantic analysis.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 648
diff changeset
15 Generate visit methods.
635
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
16 E.g.:
649
3ebe76ad680e Using SemanticPass1 in main.d do start semantic analysis.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 648
diff changeset
17 Declaration visit(ClassDeclaration){return null;};
3ebe76ad680e Using SemanticPass1 in main.d do start semantic analysis.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 648
diff changeset
18 Expression visit(CommaExpression){return null;};
635
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
19 +/
649
3ebe76ad680e Using SemanticPass1 in main.d do start semantic analysis.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 648
diff changeset
20 char[] generateVisitMethods()
635
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
21 {
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
22 char[] text;
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
23 foreach (className; classNames)
667
1ac758cd952a Fixed a few things in DefaultVisitor.d and Pass1.d
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 655
diff changeset
24 text ~= "returnType!(\""~className~"\") visit("~className~" node){return node;}\n";
635
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
25 return text;
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
26 }
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
27 // pragma(msg, generateAbstractVisitMethods());
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
28
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
29 /// Gets the appropriate return type for the provided class.
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
30 template returnType(char[] className)
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
31 {
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
32 static if (is(typeof(mixin(className)) : Declaration))
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
33 alias Declaration returnType;
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
34 else
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
35 static if (is(typeof(mixin(className)) : Statement))
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
36 alias Statement returnType;
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
37 else
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
38 static if (is(typeof(mixin(className)) : Expression))
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
39 alias Expression returnType;
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
40 else
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
41 static if (is(typeof(mixin(className)) : TypeNode))
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
42 alias TypeNode returnType;
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
43 else
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
44 alias Node returnType;
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
45 }
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
46
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
47 /++
731
ca7607226caa Added new module cmd.DDoc.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 667
diff changeset
48 Generate functions which do the second dispatch.$(BR)
ca7607226caa Added new module cmd.DDoc.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 667
diff changeset
49 E.g.:$(BR)
ca7607226caa Added new module cmd.DDoc.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 667
diff changeset
50 $(D_CODE
ca7607226caa Added new module cmd.DDoc.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 667
diff changeset
51 Expression visitCommaExpression(Visitor visitor, CommaExpression c)
ca7607226caa Added new module cmd.DDoc.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 667
diff changeset
52 { visitor.visit(c); })
635
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
53
731
ca7607226caa Added new module cmd.DDoc.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 667
diff changeset
54 The equivalent in the traditional visitor pattern would be:$(BR)
ca7607226caa Added new module cmd.DDoc.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 667
diff changeset
55 $(D_CODE
ca7607226caa Added new module cmd.DDoc.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 667
diff changeset
56 class CommaExpression : Expression
ca7607226caa Added new module cmd.DDoc.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 667
diff changeset
57 {
ca7607226caa Added new module cmd.DDoc.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 667
diff changeset
58 void accept(Visitor visitor)
ca7607226caa Added new module cmd.DDoc.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 667
diff changeset
59 { visitor.visit(this); }
ca7607226caa Added new module cmd.DDoc.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 667
diff changeset
60 })
635
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
61 +/
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
62 char[] generateDispatchFunctions()
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
63 {
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
64 char[] text;
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
65 foreach (className; classNames)
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
66 text ~= "returnType!(\""~className~"\") visit"~className~"(Visitor visitor, "~className~" c)\n"
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
67 "{ return visitor.visit(c); }\n";
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
68 return text;
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
69 }
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
70 // pragma(msg, generateDispatchFunctions());
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
71
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
72 /++
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
73 The vtable holds a list of function pointers to the dispatch functions.
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
74 +/
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
75 char[] generateVTable()
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
76 {
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
77 char[] text = "[";
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
78 foreach (className; classNames)
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
79 text ~= "cast(void*)&visit"~className~",\n";
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
80 return text[0..$-2]~"]"; // slice away last ",\n"
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
81 }
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
82 // pragma(msg, generateVTable());
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
83
731
ca7607226caa Added new module cmd.DDoc.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 667
diff changeset
84 /// The visitor pattern.
635
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
85 abstract class Visitor
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
86 {
649
3ebe76ad680e Using SemanticPass1 in main.d do start semantic analysis.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 648
diff changeset
87 mixin(generateVisitMethods());
635
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
88
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
89 static
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
90 mixin(generateDispatchFunctions());
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
91
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
92 /// The dispatch table.
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
93 static const void*[] dispatch_vtable = mixin(generateVTable());
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
94 static assert(dispatch_vtable.length == classNames.length, "vtable length doesn't match number of classes");
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
95
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
96 // Returns the dispatch function for n.
754
c7a5499faa77 Improved DDoc related code.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 731
diff changeset
97 final T function(Visitor,T) getDispatchFunction(T)(T n)
635
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
98 {
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
99 return cast(T function(Visitor,T))dispatch_vtable[n.kind];
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
100 }
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
101
648
4ae7b13aaac8 Moved some semantic() methods to SemanticPass1.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 641
diff changeset
102 Declaration visit(Declaration n)
4ae7b13aaac8 Moved some semantic() methods to SemanticPass1.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 641
diff changeset
103 { return visitD(n); }
4ae7b13aaac8 Moved some semantic() methods to SemanticPass1.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 641
diff changeset
104 Statement visit(Statement n)
4ae7b13aaac8 Moved some semantic() methods to SemanticPass1.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 641
diff changeset
105 { return visitS(n); }
4ae7b13aaac8 Moved some semantic() methods to SemanticPass1.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 641
diff changeset
106 Expression visit(Expression n)
4ae7b13aaac8 Moved some semantic() methods to SemanticPass1.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 641
diff changeset
107 { return visitE(n); }
4ae7b13aaac8 Moved some semantic() methods to SemanticPass1.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 641
diff changeset
108 TypeNode visit(TypeNode n)
4ae7b13aaac8 Moved some semantic() methods to SemanticPass1.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 641
diff changeset
109 { return visitT(n); }
4ae7b13aaac8 Moved some semantic() methods to SemanticPass1.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 641
diff changeset
110 Node visit(Node n)
4ae7b13aaac8 Moved some semantic() methods to SemanticPass1.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 641
diff changeset
111 { return visitN(n); }
4ae7b13aaac8 Moved some semantic() methods to SemanticPass1.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents: 641
diff changeset
112
635
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
113 Declaration visitD(Declaration n)
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
114 {
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
115 // Do first dispatch. Second dispatch is done in the called function.
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
116 return getDispatchFunction(n)(this, n);
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
117 }
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
118
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
119 Statement visitS(Statement n)
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
120 {
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
121 return getDispatchFunction(n)(this, n);
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
122 }
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
123
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
124 Expression visitE(Expression n)
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
125 {
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
126 return getDispatchFunction(n)(this, n);
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
127 }
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
128
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
129 TypeNode visitT(TypeNode n)
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
130 {
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
131 return getDispatchFunction(n)(this, n);
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
132 }
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
133
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
134 Node visitN(Node n)
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
135 {
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
136 return getDispatchFunction(n)(this, n);
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
137 }
b2fc028d8b55 Added class Visitor.
Aziz K?ksal <aziz.koeksal@gmail.com>
parents:
diff changeset
138 }