ParseNodeVisitor.st
branchjv
changeset 4723 524785227024
parent 3968 4e4f134b6e26
parent 4542 6ebb1ee3f2e6
--- a/ParseNodeVisitor.st	Sat Aug 08 22:49:53 2020 +0100
+++ b/ParseNodeVisitor.st	Tue Aug 25 12:20:06 2020 +0100
@@ -14,7 +14,7 @@
 "{ NameSpace: Smalltalk }"
 
 Object subclass:#ParseNodeVisitor
-	instanceVariableNames:''
+	instanceVariableNames:'pluggableActionsPerNodeType'
 	classVariableNames:''
 	poolDictionaries:''
 	category:'System-Compiler-Support'
@@ -43,23 +43,40 @@
 "    
 ! !
 
+!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 
+    |action stmt lastResult|
 
-    | stmt |
+    action := pluggableActionsPerNodeType at:(anObject class) ifAbsent:[nil].
+    action notNil ifTrue:[ 
+        (action value:anObject) ifFalse:[^ self].
+    ].
 
-    ^anObject isStatementNode 
-        ifTrue:[
-            stmt := anObject.
-            [ stmt isNil ] whileFalse:[
-                stmt acceptVisitor:self.
-                stmt := stmt nextStatement.
-            ]
-        ] 
-        ifFalse:[
-            anObject acceptVisitor: self.
-        ]
+    anObject isStatementNode ifTrue:[
+        stmt := anObject.
+        [ stmt isNil ] whileFalse:[
+            lastResult := stmt acceptVisitor:self.
+            stmt := stmt nextStatement.
+        ].
+        ^ lastResult
+    ] ifFalse:[
+        ^ anObject acceptVisitor: self.
+    ]
 
     "Modified: / 25-07-2011 / 22:33:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
@@ -164,6 +181,19 @@
     "/ to be redefined in subclasses
 ! !
 
+!ParseNodeVisitor methodsFor:'visiting - javaScript'!
+
+doesNotUnderstand:aMessage
+    "catch to prevent stupid error reports from Explainer in end-user app (expecco)"
+
+    Smalltalk isStandAloneApp ifTrue:[^ self].
+    "/ ((aMessage selector startsWith:'visit') 
+    "/ and:[ aMessage selector endsWith:'Node:' ]) ifTrue:[
+    "/     ^ self.
+    "/ ].
+    ^ super doesNotUnderstand:aMessage.
+! !
+
 !ParseNodeVisitor class methodsFor:'documentation'!
 
 version