Mercurial > projects > dil
comparison trunk/src/dil/ast/Visitor.d @ 769:5e3ef1b2011c
Added and improved documentation.
author | Aziz K?ksal <aziz.koeksal@gmail.com> |
---|---|
date | Sun, 17 Feb 2008 02:21:55 +0100 |
parents | e4b60543c5e8 |
children | cf2ad5df025c |
comparison
equal
deleted
inserted
replaced
768:d84349a60f5c | 769:5e3ef1b2011c |
---|---|
9 dil.ast.Expressions, | 9 dil.ast.Expressions, |
10 dil.ast.Statements, | 10 dil.ast.Statements, |
11 dil.ast.Types, | 11 dil.ast.Types, |
12 dil.ast.Parameters; | 12 dil.ast.Parameters; |
13 | 13 |
14 /++ | 14 /// Generate visit methods. |
15 Generate visit methods. | 15 /// |
16 E.g.: | 16 /// E.g.: |
17 Declaration visit(ClassDeclaration){return null;}; | 17 /// --- |
18 Expression visit(CommaExpression){return null;}; | 18 /// Declaration visit(ClassDeclaration){return null;}; |
19 +/ | 19 /// Expression visit(CommaExpression){return null;}; |
20 /// --- | |
20 char[] generateVisitMethods() | 21 char[] generateVisitMethods() |
21 { | 22 { |
22 char[] text; | 23 char[] text; |
23 foreach (className; classNames) | 24 foreach (className; classNames) |
24 text ~= "returnType!(\""~className~"\") visit("~className~" node){return node;}\n"; | 25 text ~= "returnType!(\""~className~"\") visit("~className~" node){return node;}\n"; |
42 alias TypeNode returnType; | 43 alias TypeNode returnType; |
43 else | 44 else |
44 alias Node returnType; | 45 alias Node returnType; |
45 } | 46 } |
46 | 47 |
47 /++ | 48 /// Generate functions which do the second dispatch. |
48 Generate functions which do the second dispatch.$(BR) | 49 /// |
49 E.g.:$(BR) | 50 /// E.g.: |
50 $(D_CODE | 51 /// --- |
51 Expression visitCommaExpression(Visitor visitor, CommaExpression c) | 52 /// Expression visitCommaExpression(Visitor visitor, CommaExpression c) |
52 { visitor.visit(c); }) | 53 /// { visitor.visit(c); /* Second dispatch. */ } |
53 | 54 /// --- |
54 The equivalent in the traditional visitor pattern would be:$(BR) | 55 /// The equivalent in the traditional visitor pattern would be: |
55 $(D_CODE | 56 /// --- |
56 class CommaExpression : Expression | 57 /// class CommaExpression : Expression |
57 { | 58 /// { |
58 void accept(Visitor visitor) | 59 /// void accept(Visitor visitor) |
59 { visitor.visit(this); } | 60 /// { visitor.visit(this); } |
60 }) | 61 /// } |
61 +/ | 62 /// --- |
62 char[] generateDispatchFunctions() | 63 char[] generateDispatchFunctions() |
63 { | 64 { |
64 char[] text; | 65 char[] text; |
65 foreach (className; classNames) | 66 foreach (className; classNames) |
66 text ~= "returnType!(\""~className~"\") visit"~className~"(Visitor visitor, "~className~" c)\n" | 67 text ~= "returnType!(\""~className~"\") visit"~className~"(Visitor visitor, "~className~" c)\n" |
68 return text; | 69 return text; |
69 } | 70 } |
70 // pragma(msg, generateDispatchFunctions()); | 71 // pragma(msg, generateDispatchFunctions()); |
71 | 72 |
72 /++ | 73 /++ |
73 The vtable holds a list of function pointers to the dispatch functions. | 74 Generates an array of function pointers. |
75 | |
76 --- | |
77 [ | |
78 cast(void*)&visitCommaExpression, | |
79 // etc. | |
80 ] | |
81 --- | |
74 +/ | 82 +/ |
75 char[] generateVTable() | 83 char[] generateVTable() |
76 { | 84 { |
77 char[] text = "["; | 85 char[] text = "["; |
78 foreach (className; classNames) | 86 foreach (className; classNames) |
79 text ~= "cast(void*)&visit"~className~",\n"; | 87 text ~= "cast(void*)&visit"~className~",\n"; |
80 return text[0..$-2]~"]"; // slice away last ",\n" | 88 return text[0..$-2]~"]"; // slice away last ",\n" |
81 } | 89 } |
82 // pragma(msg, generateVTable()); | 90 // pragma(msg, generateVTable()); |
83 | 91 |
84 /// The visitor pattern. | 92 /// Implements a variation of the visitor pattern. |
93 /// | |
94 /// Inherited by classes that need to traverse a D syntax tree | |
95 /// and do computations, transformations and other things on it. | |
85 abstract class Visitor | 96 abstract class Visitor |
86 { | 97 { |
87 mixin(generateVisitMethods()); | 98 mixin(generateVisitMethods()); |
88 | 99 |
89 static | 100 static |
90 mixin(generateDispatchFunctions()); | 101 mixin(generateDispatchFunctions()); |
91 | 102 |
92 /// The dispatch table. | 103 /// The table holding function pointers to the second dispatch functions. |
93 static const void*[] dispatch_vtable = mixin(generateVTable()); | 104 static const void*[] dispatch_vtable = mixin(generateVTable()); |
94 static assert(dispatch_vtable.length == classNames.length, "vtable length doesn't match number of classes"); | 105 static assert(dispatch_vtable.length == classNames.length, "vtable length doesn't match number of classes"); |
95 | 106 |
96 // Returns the dispatch function for n. | 107 /// Looks up the second dispatch function for n and returns that. |
97 Node function(Visitor, Node) getDispatchFunction()(Node n) | 108 Node function(Visitor, Node) getDispatchFunction()(Node n) |
98 { | 109 { |
99 return cast(Node function(Visitor, Node))dispatch_vtable[n.kind]; | 110 return cast(Node function(Visitor, Node))dispatch_vtable[n.kind]; |
100 } | 111 } |
101 | 112 |
113 /// The main and first dispatch function. | |
102 Node dispatch(Node n) | 114 Node dispatch(Node n) |
103 { // Do first dispatch. Second dispatch is done in the called function. | 115 { // Second dispatch is done in the called function. |
104 return getDispatchFunction(n)(this, n); | 116 return getDispatchFunction(n)(this, n); |
105 } | 117 } |
106 | 118 |
107 final: | 119 final: |
108 Declaration visit(Declaration n) | 120 Declaration visit(Declaration n) |