ParseNodeVisitor.st
author Claus Gittinger <cg@exept.de>
Fri, 06 Sep 2019 09:54:50 +0200
changeset 4542 6ebb1ee3f2e6
parent 4516 e9cf1489f95b
child 4723 524785227024
permissions -rw-r--r--
#REFACTORING by exept class: ParseNodeVisitor class definition added: #actionForNodeClass:put: changed: #visit:

"{ Encoding: utf8 }"

"{ Package: 'stx:libcomp' }"

"{ NameSpace: Smalltalk }"

Object subclass:#ParseNodeVisitor
	instanceVariableNames:'pluggableActionsPerNodeType'
	classVariableNames:''
	poolDictionaries:''
	category:'System-Compiler-Support'
!

!ParseNodeVisitor class methodsFor:'documentation'!

documentation
"
    a whitebox expandable abstract parsenode visitor.
    Subclasses should redefine those acceptXXX methods, in which they are interested.
"    
! !

!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|

    action := pluggableActionsPerNodeType at:(anObject class) ifAbsent:[nil].
    action notNil ifTrue:[ 
        (action value:anObject) ifFalse:[^ 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>"
!

visitAssignmentNode:anObject 

    self visit: anObject variable.
    self visit: anObject expression.

    "Modified: / 25-07-2011 / 22:30:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

visitBinaryNode:anObject 

    ^self visitMessageNode: anObject

    "Modified: / 25-07-2011 / 22:30:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

visitBlockNode:anObject 

    anObject statements ifNotNil:[
        self visit: anObject statements
    ].

    "Modified: / 25-07-2011 / 22:45:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

visitCascadeNode:anObject 

    self visitMessageNode: anObject.

    "Modified: / 25-07-2011 / 22:37:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

visitConstantNode:anObject

    "Modified: / 25-07-2011 / 22:41:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

visitECompletionConstantNode:anObject 
    "dispatched back from the visited eCompletionConstantNode-object (visitor pattern)"

    "fall back to general object-case - please change as required"

    ^ self visitObject:anObject
!

visitMessageNode:anObject 

    self visit: anObject receiver.
    anObject arguments do:[:arg|
        self visit: arg.
    ]

    "Modified: / 25-07-2011 / 22:37:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

visitObject:anObject 
    "dispatched back from the visited objects (visitor pattern)"

    "general fallBack - please change as required"

    self halt:'not yet implemented'
!

visitParseErrorNode:anObject

    "Modified: / 25-07-2011 / 22:38:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

visitPrimitiveNode:anObject

    "Modified: / 25-07-2011 / 22:38:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

visitReturnNode:anObject 
    self visit: anObject expression.
!

visitSelfNode:anObject 
    "/ to be redefined in subclasses
!

visitStatementNode:anObject 
    |expr|

    (expr := anObject expression) notNil ifTrue:[
        self visit: expr.
    ]
!

visitSuperNode:anObject 
    "/ to be redefined in subclasses
!

visitUnaryNode:anObject 
    ^self visitMessageNode: anObject
!

visitVariableNode:anObject 
    "/ 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
    ^ '$Header$'
!

version_CVS
    ^ '$Header$'
! !