--- a/ParseNodeVisitor.st Tue Sep 03 16:16:22 2019 +0200
+++ b/ParseNodeVisitor.st Fri Sep 06 09:54:50 2019 +0200
@@ -1,9 +1,11 @@
+"{ Encoding: utf8 }"
+
"{ Package: 'stx:libcomp' }"
"{ NameSpace: Smalltalk }"
Object subclass:#ParseNodeVisitor
- instanceVariableNames:''
+ instanceVariableNames:'pluggableActionsPerNodeType'
classVariableNames:''
poolDictionaries:''
category:'System-Compiler-Support'
@@ -18,10 +20,29 @@
"
! !
+!ParseNodeVisitor methodsFor:'pluggable setup'!
+
+actionForNodeClass:aNodeClass put:aBlock
+ "setup so that for nodes of type aNodeClass, aBlock is invoked.
+ If the block returns true, subnodes (eg. right side of assignments, etc.)
+ will be enumerated as well.
+ Otherwise, no subnodes are visited."
+
+ pluggableActionsPerNodeType isNil ifTrue:[
+ pluggableActionsPerNodeType := Dictionary new.
+ ].
+ pluggableActionsPerNodeType at:aNodeClass put:aBlock
+! !
+
!ParseNodeVisitor methodsFor:'visiting'!
visit:anObject
- | stmt lastResult |
+ |action stmt lastResult|
+
+ action := pluggableActionsPerNodeType at:(anObject class) ifAbsent:[nil].
+ action notNil ifTrue:[
+ (action value:anObject) ifFalse:[^ self].
+ ].
anObject isStatementNode ifTrue:[
stmt := anObject.