import compiler.lang.d.ast.Node;
import compiler.lang.d.ast.Module;
import compiler.lang.d.ast.Condition;
import compiler.lang.d.ast.ConditionDeclaration;
template VisitFunc(T)
{
void visit(T node);
}
template VisitFunc(T, U...)
{
void visit(T node);
mixin visitFunc!(U);
}
template ApplyAllNodes(T)
{
mixin T!(Node, Module, Condition, ConditionDeclaration);
}
interface Visitor
{
public:
mixin ApplyAllNodes!(VisitFunc);
}
class DefaultVisitor : public Visitor
{
public:
mixin ApplyAllNodes!(VisitFunc);
}
--
Alexandre Bique (bique.a...@gmail.com)
Epita 2009 - GISTR - Yaka
Port. +336 19 42 85 26
Sinon tu devrais utiliser des fonctions templatees plutot que des templates :
void visit(T)(T Node)
Apres je n'ai pas teste donc c'est surement tres approximatif.
--
Arkanosis
L'objectif c'est de creer une interface avec une vtable complete. Je
ne sais pas si ca marche avec un template dans l'interface. Je
testerais plutard quand j'aurais le temps.
[... une rando roller est passee ...]
Ca y est j'ai la solution, il fallait utiliser les template alias !
http://www.digitalmars.com/d/1.0/template.html#TemplateAliasParameter
nm Visitor.o
U _D10ModuleInfo6__vtblZ
U _D6Object7__ClassZ
U _D6object6Object5opCmpMFC6ObjectZi
U _D6object6Object6toHashMFZk
U _D6object6Object8opEqualsMFC6ObjectZi
U _D6object6Object8toStringMFZAa
00000070 D _D7Visitor12__ModuleInfoZ
U _D7Visitor14DefaultVisitor48__T13ApplyAllNodesS267Visitor16DefaultVisitFuncZ110__T9VisitFuncTC4Node4NodeTC6Module6ModuleTC9Condition9ConditionTC20ConditionDeclaration20ConditionDeclarationZ26__T9VisitFuncTC4Node4NodeZ5visitMFC4Node4NodeZv
U _D7Visitor14DefaultVisitor48__T13ApplyAllNodesS267Visitor16DefaultVisitFuncZ110__T9VisitFuncTC4Node4NodeTC6Module6ModuleTC9Condition9ConditionTC20ConditionDeclaration20ConditionDeclarationZ98__T9VisitFuncTC6Module6ModuleTC9Condition9ConditionTC20ConditionDeclaration20ConditionDeclarationZ30__T9VisitFuncTC6Module6ModuleZ5visitMFC6Module6ModuleZv
U _D7Visitor14DefaultVisitor48__T13ApplyAllNodesS267Visitor16DefaultVisitFuncZ110__T9VisitFuncTC4Node4NodeTC6Module6ModuleTC9Condition9ConditionTC20ConditionDeclaration20ConditionDeclarationZ98__T9VisitFuncTC6Module6ModuleTC9Condition9ConditionTC20ConditionDeclaration20ConditionDeclarationZ82__T9VisitFuncTC9Condition9ConditionTC20ConditionDeclaration20ConditionDeclarationZ36__T9VisitFuncTC9Condition9ConditionZ5visitMFC9Condition9ConditionZv
U _D7Visitor14DefaultVisitor48__T13ApplyAllNodesS267Visitor16DefaultVisitFuncZ110__T9VisitFuncTC4Node4NodeTC6Module6ModuleTC9Condition9ConditionTC20ConditionDeclaration20ConditionDeclarationZ98__T9VisitFuncTC6Module6ModuleTC9Condition9ConditionTC20ConditionDeclaration20ConditionDeclarationZ82__T9VisitFuncTC9Condition9ConditionTC20ConditionDeclaration20ConditionDeclarationZ60__T9VisitFuncTC20ConditionDeclaration20ConditionDeclarationZ5visitMFC20ConditionDeclaration20ConditionDeclarationZv
00000058 R _D7Visitor14DefaultVisitor6__initZ
00000080 R _D7Visitor14DefaultVisitor6__vtblZ
00000000 D _D7Visitor14DefaultVisitor7__ClassZ
00000010 R _D7Visitor7Visitor11__InterfaceZ
00000000 T _D7Visitor7__arrayZ
00000000 T _D7Visitor8__assertFiZv
U _D9ClassInfo6__vtblZ
U _Dmodule_ref
00000000 t _TMP0
00000008 t _TMP1
00000010 t _TMP2
00000018 t _TMP3
000000b0 r _TMP4
U _d_array_bounds
U _d_assert
00000000 t gcc2_compiled.
Franchement vous etes daccord pour dire que ces symboles sont n'importe quoi ?
U _D10ModuleInfo6__vtblZ
U _D11TypeInfo_Aa6__initZ
U _D6Object7__ClassZ
U _D6object6Object5opCmpMFC6ObjectZi
U _D6object6Object6toHashMFZk
U _D6object6Object8opEqualsMFC6ObjectZi
U _D6object6Object8toStringMFZAa
00000000 W _D7Visitor106__T16DefaultVisitFuncTC6Module6ModuleTC9Condition9ConditionTC20ConditionDeclaration20ConditionDeclarationZ16DefaultVisitFuncFZAa
00000000 W _D7Visitor110__T9VisitFuncTC4Node4NodeTC6Module6ModuleTC9Condition9ConditionTC20ConditionDeclaration20ConditionDeclarationZ9VisitFuncFZAa
00000000 W _D7Visitor118__T16DefaultVisitFuncTC4Node4NodeTC6Module6ModuleTC9Condition9ConditionTC20ConditionDeclaration20ConditionDeclarationZ16DefaultVisitFuncFZAa
00000070 D _D7Visitor12__ModuleInfoZ
00000000 T _D7Visitor14DefaultVisitor5visitMFC20ConditionDeclaration20ConditionDeclarationZv
00000000 T _D7Visitor14DefaultVisitor5visitMFC4Node4NodeZv
00000000 T _D7Visitor14DefaultVisitor5visitMFC6Module6ModuleZv
00000000 T _D7Visitor14DefaultVisitor5visitMFC9Condition9ConditionZv
00000058 R _D7Visitor14DefaultVisitor6__initZ
00000080 R _D7Visitor14DefaultVisitor6__vtblZ
00000000 D _D7Visitor14DefaultVisitor7__ClassZ
00000000 W _D7Visitor26__T9VisitFuncTC4Node4NodeZ9VisitFuncFZAa
00000000 W _D7Visitor30__T9VisitFuncTC6Module6ModuleZ9VisitFuncFZAa
00000000 W _D7Visitor34__T16DefaultVisitFuncTC4Node4NodeZ16DefaultVisitFuncFZAa
00000000 W _D7Visitor36__T9VisitFuncTC9Condition9ConditionZ9VisitFuncFZAa
00000000 W _D7Visitor38__T16DefaultVisitFuncTC6Module6ModuleZ16DefaultVisitFuncFZAa
00000000 W _D7Visitor40__T13ApplyAllNodesS187Visitor9VisitFuncZ13ApplyAllNodesFZAa
00000000 W _D7Visitor44__T16DefaultVisitFuncTC9Condition9ConditionZ16DefaultVisitFuncFZAa
00000000 W _D7Visitor48__T13ApplyAllNodesS267Visitor16DefaultVisitFuncZ13ApplyAllNodesFZAa
00000000 W _D7Visitor60__T9VisitFuncTC20ConditionDeclaration20ConditionDeclarationZ9VisitFuncFZAa
00000000 W _D7Visitor68__T16DefaultVisitFuncTC20ConditionDeclaration20ConditionDeclarationZ16DefaultVisitFuncFZAa
00000010 R _D7Visitor7Visitor11__InterfaceZ
00000000 T _D7Visitor7__arrayZ
00000000 W _D7Visitor82__T9VisitFuncTC9Condition9ConditionTC20ConditionDeclaration20ConditionDeclarationZ9VisitFuncFZAa
00000000 T _D7Visitor8__assertFiZv
00000000 W _D7Visitor90__T16DefaultVisitFuncTC9Condition9ConditionTC20ConditionDeclaration20ConditionDeclarationZ16DefaultVisitFuncFZAa
00000000 W _D7Visitor98__T9VisitFuncTC6Module6ModuleTC9Condition9ConditionTC20ConditionDeclaration20ConditionDeclarationZ9VisitFuncFZAa
U _D9ClassInfo6__vtblZ
U _D9invariant12_d_invariantFC6ObjectZv
U _Dmodule_ref
0000000c t _TMP0
00000014 t _TMP1
00000220 r _TMP10
00000278 r _TMP11
00000290 r _TMP12
0000001c t _TMP2
00000024 t _TMP3
000000c0 r _TMP4
000000e8 r _TMP5
00000110 r _TMP6
00000140 r _TMP7
00000188 r _TMP8
000001d0 r _TMP9
U _d_array_bounds
U _d_arraycatT
U _d_assert
00000000 t gcc2_compiled.
La solution est un peu gore :p :
import compiler.lang.d.ast.Node;
import compiler.lang.d.ast.Module;
import compiler.lang.d.ast.Condition;
import compiler.lang.d.ast.ConditionDeclaration;
template VisitFunc(T)
{
char[] VisitFunc()
{
return "void visit(" ~ T.stringof ~ " node);";
}
}
template VisitFunc(T, U...)
{
char[] VisitFunc()
{
return VisitFunc!(T)() ~ VisitFunc!(U)();
}
}
template DefaultVisitFunc(T)
{
char[] DefaultVisitFunc()
{
return
"void visit(" ~ T.stringof ~ " node)" ~
" in { assert (node !is null); }" ~
"body {}";
}
}
template DefaultVisitFunc(T, U...)
{
char[] DefaultVisitFunc()
{
return DefaultVisitFunc!(T)() ~ DefaultVisitFunc!(U)();
}
}
template ApplyAllNodes(alias T)
{
char[] ApplyAllNodes()
{
return T!(Node, Module, Condition, ConditionDeclaration)();
}
}
interface Visitor
{
public:
mixin(ApplyAllNodes!(VisitFunc)());
}
class DefaultVisitor : public Visitor
{
public:
mixin(ApplyAllNodes!(DefaultVisitFunc)());
Je préfère largement la première version ; là tu modifie ce qui est
bien pour compenser un problème qui est ailleurs.
--
Arkanosis
echo _D7Visitor14DefaultVisitor48__T13ApplyAllNodesS267Visitor16DefaultVisitFuncZ110__T9VisitFuncTC4Node4NodeTC6Module6ModuleTC9Condition9ConditionTC20ConditionDeclaration20ConditionDeclarationZ98__T9VisitFuncTC6Module6ModuleTC9Condition9ConditionTC20ConditionDeclaration20ConditionDeclarationZ30__T9VisitFuncTC6Module6ModuleZ5visitMFC6Module6ModuleZv
| wc -c
347
echo _D7Visitor14DefaultVisitor48__T13ApplyAllNodesS267Visitor16DefaultVisitFuncZ110__T9VisitFuncTC4Node4NodeTC6Module6ModuleTC9Condition9ConditionTC20ConditionDeclaration20ConditionDeclarationZ98__T9VisitFuncTC6Module6ModuleTC9Condition9ConditionTC20ConditionDeclaration20ConditionDeclarationZ82__T9VisitFuncTC9Condition9ConditionTC20ConditionDeclaration20ConditionDeclarationZ36__T9VisitFuncTC9Condition9ConditionZ5visitMFC9Condition9ConditionZv
| wc -c
443
Avec la solution precedente, la taille des symbole etait une suite
arithmetique, ce qui pose un gros probleme si la raison de ta suite
est de ~100 et que tu as ~60 noeuds, le dernier symbole fera ~ 6000
caracteres.
Imagines un cas similaire ou tu as 300 noeuds, dans un packages style
com.microsoft.research.language.roumain_hihi.ast.MyRootNode; (on
aurais pu faire un package plus long). La raison depend du nom
canonique de la classe par laquelle tu template, 300 * 100 = 30 000.
Cette methode est super gore :-)
Sérieusement, t'aurais vraiment envie de coder en D si on te montrait
des mixins pareils ?
--
Arkanosis
> Sérieusement, t'aurais vraiment envie de coder en D si on te montrait
> des mixins pareils ?
Regarde ca : http://trac-hg.assembla.com/dcompiler/browser/compiler/lang/d/ast/Visitor.d?rev=27
nm Visitor.o
U _D10ModuleInfo6__vtblZ
U _D11TypeInfo_Aa6__initZ
U _D6Object7__ClassZ
U _D6object6Object5opCmpMFC6ObjectZi
U _D6object6Object6toHashMFZk
U _D6object6Object8opEqualsMFC6ObjectZi
U _D6object6Object8toStringMFZAa
00000080 D _D7Visitor12__ModuleInfoZ
00000000 T _D7Visitor14DefaultVisitor5visitMFC16VersionCondition16VersionConditionZv
00000000 T _D7Visitor14DefaultVisitor5visitMFC22ConditionalDeclaration22ConditionalDeclarationZv
00000000 T _D7Visitor14DefaultVisitor5visitMFC4Node4NodeZv
00000000 T _D7Visitor14DefaultVisitor5visitMFC6Module6ModuleZv
00000000 T _D7Visitor14DefaultVisitor5visitMFC7DeclDef7DeclDefZv
00000000 T _D7Visitor14DefaultVisitor5visitMFC7Visitor7VisitorZv
00000000 T _D7Visitor14DefaultVisitor5visitMFC9Condition9ConditionZv
00000058 R _D7Visitor14DefaultVisitor6__initZ
00000080 R _D7Visitor14DefaultVisitor6__vtblZ
00000000 D _D7Visitor14DefaultVisitor7__ClassZ
00000000 W _D7Visitor188__T9VisitFuncTC22ConditionalDeclaration22ConditionalDeclarationTC9Condition9ConditionTC7DeclDef7DeclDefTC6Module6ModuleTC4Node4NodeTC16VersionCondition16VersionConditionTC7Visitor7VisitorZ9VisitFuncFZAa
00000000 W _D7Visitor196__T16DefaultVisitFuncTC22ConditionalDeclaration22ConditionalDeclarationTC9Condition9ConditionTC7DeclDef7DeclDefTC6Module6ModuleTC4Node4NodeTC16VersionCondition16VersionConditionTC7Visitor7VisitorZ16DefaultVisitFuncFZAa
00000000 W _D7Visitor40__T13ApplyAllNodesS187Visitor9VisitFuncZ13ApplyAllNodesFZAa
00000000 W _D7Visitor48__T13ApplyAllNodesS267Visitor16DefaultVisitFuncZ13ApplyAllNodesFZAa
00000010 R _D7Visitor7Visitor11__InterfaceZ
00000000 T _D7Visitor7__arrayZ
00000000 T _D7Visitor8__assertFiZv
U _D9ClassInfo6__vtblZ
U _D9invariant12_d_invariantFC6ObjectZv
U _Dmodule_ref
0000000c t _TMP0
00000014 t _TMP1
00000168 r _TMP10
00000190 r _TMP11
000001c8 r _TMP12
000001f8 r _TMP13
00000260 r _TMP14
000002c0 r _TMP15
00000320 r _TMP16
00000378 r _TMP17
000003d0 r _TMP18
00000438 r _TMP19
0000001c t _TMP2
00000498 r _TMP20
000004b0 r _TMP21
00000024 t _TMP3
0000002c t _TMP4
00000034 t _TMP5
0000003c t _TMP6
000000e0 r _TMP7
00000110 r _TMP8
00000140 r _TMP9
U _d_array_bounds
U _d_arrayappendT
U _d_assert
00000000 t gcc2_compiled.
C'est plutot propre niveau symbole et une pointe de style avec le
foreach sur les types du template variadic plus ecriture de code a la
compilation => quel gros sexe !!! Les symboles en trop du template (il
y en a 4) peuvent-etre supprime a l'aide d'un strip car le code n'a
aucune dependance envers eux une fois compile (sauf si le ModuleInfo
garde une reference....)
--
Arkanosis
On Sat, Apr 26, 2008 at 11:24 PM, Arkanosis <arka...@gmail.com> wrote:
Ca va etre pratique pour generer un visiteur de tests qui verifie que
tous les noeuds ont bien la methode visit d'implementer :-)