ParseNode.st
author Claus Gittinger <cg@exept.de>
Fri, 30 Apr 2010 12:01:39 +0200
changeset 2378 e41904c1091c
parent 2327 88c2ba0ae517
child 2382 5f84c8b618d0
permissions -rw-r--r--
automatically generated by browser

"
 COPYRIGHT (c) 1989 by Claus Gittinger
	      All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"
"{ Package: 'stx:libcomp' }"

Object subclass:#ParseNode
	instanceVariableNames:'type comments parenthized'
	classVariableNames:''
	poolDictionaries:''
	category:'System-Compiler-Support'
!

!ParseNode class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 1989 by Claus Gittinger
	      All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"
!

documentation
"
    node for parse-trees; abstract class
    This is a helper class for the compiler.

    [author:]
        Claus Gittinger
"
! !

!ParseNode class methodsFor:'instance creation'!

type:t
    ^ (self basicNew) type:t
! !

!ParseNode class methodsFor:'code generation helpers'!

codeLineNumber:nr on:aStream for:aCompiler
    "generate lineNumber information"

    "/ caveat: (currently) there is no separate lineNumber or symbol table;
    "/ the line numbers are coded right into the instruction stream.
    "/ This might change in the future.
    "/ (It is not a problem speed wise: the Jitter just skips them.)

    nr > 0 ifTrue:[
        nr <= 255 ifTrue:[
            aStream nextPut:#lineno.
            aStream nextPut:nr
        ] ifFalse:[
            nr <= 16rFFFF ifTrue:[
                aStream nextPut:#lineno16.
                aStream nextPut:((nr bitShift:-8) bitAnd:16rFF).
                aStream nextPut:(nr bitAnd:16rFF).
            ]
        ]
    ]

    "Created: 21.10.1996 / 14:42:27 / cg"
! !

!ParseNode methodsFor:'accessing'!

endPosition:aCharacterPosition
    "/ ignored here
!

lineNumber:dummy
    "set linenumber - ignored here"

    ^ self
!

parenthesized
    ^ parenthized ? false
!

parenthesized:aBoolean
    parenthized := aBoolean
!

parenthized
    "obsolete - typo in message name - use parenthesized"

    ^ parenthized ? false
!

parenthized:aBoolean
    "obsolete - typo in message name - use parenthesized:"

    parenthized := aBoolean
!

selectorPosition:aCharacterPosition
    "ignored here"

    "Created: 5.8.1997 / 16:32:17 / cg"
!

startPosition:aCharacterPosition
    "ignored here"
!

type
    "return the nodes type"

    ^ type
! !

!ParseNode methodsFor:'checks'!

plausibilityCheckIn:aParser
    ^ nil
! !

!ParseNode methodsFor:'code generation'!

codeForSideEffectOn:aStream inBlock:b for:aCompiler
    "generate code for this statement - value not needed"

    self codeOn:aStream inBlock:b for:aCompiler.
    aStream nextPut:#drop
!

codeForSimpleReturnOn:aStream inBlock:b lineNumber:lineNrOrNil for:aCompiler
    "generate code to return myself as a simple method return"

    self codeOn:aStream inBlock:b for:aCompiler.
    lineNrOrNil notNil ifTrue:[
        self codeLineNumber:lineNrOrNil on:aStream for:aCompiler
    ].
    aStream nextPut:#retTop.


!

codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
    "generate code for this statement - value is needed"

    self codeOn:aStream inBlock:b for:aCompiler.
!

codeLineNumber:nr on:aStream for:aCompiler
    "generate lineNumber information"

    self class codeLineNumber:nr on:aStream for:aCompiler
!

codeOn:aStream inBlock:codeBlock for:aCompiler
    ^ self subclassResponsibility
! !

!ParseNode methodsFor:'code generation helpers'!

emitPushGlobalWithLiteralIndex:litIndex on:aTokenCodeStream for:aCompiler
    litIndex <= 255 ifTrue:[
        aTokenCodeStream nextPut:#pushGlobalS; nextPut:litIndex
    ] ifFalse:[
        litIndex <= 16rFFFF ifTrue:[
            aTokenCodeStream nextPut:#pushGlobalL; nextPut:litIndex; nextPut:0
        ] ifFalse:[
            aTokenCodeStream nextPut:#pushGlobalVL; nextPut:0; nextPut:litIndex; nextPut:0; nextPut:0; nextPut:0
        ].
    ].
!

emitPushLiteral:value on:aTokenCodeStream for:aCompiler
    |index|

    index := aCompiler addLiteral:value.
    self emitPushLiteralIndex:index on:aTokenCodeStream for:aCompiler
!

emitPushLiteralIndex:index on:aTokenCodeStream for:aCompiler
    index <= 8 ifTrue:[
        aTokenCodeStream 
            nextPut:(#(pushLit1 pushLit2 pushLit3 pushLit4
                       pushLit5 pushLit6 pushLit7 pushLit8) at:index).
    ] ifFalse:[
        index <= 255 ifTrue:[
            aTokenCodeStream nextPut:#pushLitS; nextPut:index
        ] ifFalse:[
            index <= 16rFFFF ifTrue:[
                aTokenCodeStream nextPut:#pushLitL; nextPut:index; nextPut:0
            ] ifFalse:[
                aTokenCodeStream nextPut:#pushLitVL; nextPut:0; nextPut:index; nextPut:0; nextPut:0; nextPut:0
            ]
        ].
    ].
!

emitSendLiteralIndex:litIndex numArgs:nargs line:lineNr on:aStream
    (litIndex <= 255) ifTrue:[
        nargs <= 3 ifTrue:[
            aStream 
                nextPut:(#(send0 send1 send2 send3) at:(nargs+1)); nextPut:lineNr; 
                nextPut:litIndex.
            ^ self.
        ].
        aStream 
            nextPut:#send; nextPut:lineNr; 
            nextPut:litIndex; 
            nextPut:nargs.
        ^ self.
    ].

    (litIndex <= 16rFFFF) ifTrue:[
        aStream 
            nextPut:#sendL; nextPut:lineNr; 
            nextPut:litIndex; nextPut:0; 
            nextPut:nargs.
        ^ self.
    ].

    aStream 
        nextPut:#sendVL; nextPut:0; nextPut:lineNr; 
        nextPut:litIndex; nextPut:0; nextPut:0; nextPut:0; 
        nextPut:nargs.
!

emitStoreGlobalWithLiteralIndex:litIndex on:aTokenCodeStream for:aCompiler
    litIndex <= 255 ifTrue:[
        aTokenCodeStream nextPut:#storeGlobalS; nextPut:litIndex
    ] ifFalse:[
        litIndex <= 16rFFFF ifTrue:[
            aTokenCodeStream nextPut:#storeGlobalL; nextPut:litIndex; nextPut:0
        ] ifFalse:[
            aTokenCodeStream nextPut:#storeGlobalVL; nextPut:0; nextPut:litIndex; nextPut:0; nextPut:0; nextPut:0; nextPut:0
        ].
    ].
!

emitSuperSendLiteralIndex:litIndex classLiteralIndex:clsLitIndex numArgs:nargs line:lineNr on:aStream
    (litIndex <= 255 and:[clsLitIndex <= 255]) ifTrue:[
        aStream 
            nextPut:#superSend; nextPut:lineNr; 
            nextPut:litIndex; 
            nextPut:nargs; 
            nextPut:clsLitIndex.
    ] ifFalse:[
        (litIndex <= 16rFFFF and:[clsLitIndex <= 16rFFFF]) ifTrue:[
            aStream 
                nextPut:#superSendL; nextPut:lineNr; 
                nextPut:litIndex; nextPut:0; 
                nextPut:nargs; 
                nextPut:clsLitIndex; nextPut:0.
        ] ifFalse:[
            aStream 
                nextPut:#superSendVL; nextPut:0; nextPut:lineNr; 
                nextPut:litIndex; nextPut:0; nextPut:0; nextPut:0;
                nextPut:nargs; 
                nextPut:clsLitIndex; nextPut:0; nextPut:0; nextPut:0.
        ].
    ].
! !

!ParseNode methodsFor:'enumeration'!

messagesDo:aBlock
    ^ self
! !

!ParseNode methodsFor:'evaluation'!

evaluate
    ^ self evaluateIn:nil
!

evaluateForCascade
    ^ self evaluateForCascadeIn:nil
!

evaluateForCascadeIn:anEnvironment
    ^ self evaluateIn:anEnvironment
!

evaluateIn:anEnvironment
    self subclassResponsibility
! !

!ParseNode methodsFor:'printing & storing'!

printOn:aStream
    "append a user printed representation of the receiver to aStream.
     The format is suitable for a human - not meant to be read back."

    self printOn:aStream indent:0
!

printOn:aStream indent:indent
    "append a user printed representation of the receiver to aStream.
     The format is suitable for a human - not meant to be read back."

    self subclassResponsibility

    "Created: / 20-04-2005 / 14:21:46 / cg"
!

printOn:aStream indent:indent parenthized:parenthized
    parenthized ifTrue:[
        aStream nextPutAll:'('
    ].
    self printOn:aStream indent:indent.
    parenthized ifTrue:[
        aStream nextPutAll:')'
    ].

    "Created: / 20-04-2005 / 14:21:28 / cg"
! !

!ParseNode methodsFor:'private'!

type:t
    "set the nodes type"

    type := t
! !

!ParseNode methodsFor:'queries'!

canReuseAsArg:anotherNode
    ^ false

    "Created: 14.4.1996 / 00:43:08 / cg"
!

collectBlocksInto:aCollection
    ^ self

    "Created: 23.10.1996 / 15:45:00 / cg"
!

precedence
    ^ 9999
!

withConstantValueDo:aBlock
    "return true, if this evaluates to a constant value
     and evaluate aBlock with it"

    ^ false
! !

!ParseNode methodsFor:'testing'!

isAssignment
    "return true, if this is a node for an assignment"

    ^ false
!

isBinaryMessage
    "return true, if this is a node for a binary send"

    ^ false
!

isBlockNode
    "return true, if this is a node for a block"

    ^ false
!

isCascade
    ^ false

    "Created: / 16.7.1998 / 20:11:33 / cg"
!

isCascadeToSuper
    ^ false

    "Created: / 16.7.1998 / 19:51:07 / cg"
!

isConstant
    "return true, if this is a node for a constant"

    ^ false
!

isErrorNode
    ^ false
!

isGlobal
    "return true, if this is a node for a global variable"

    ^ false
!

isGlobalNamed:globalName
    "return true, if this is a node for a particular global variable"

    ^ false

    "Created: / 05-03-2007 / 15:13:23 / cg"
!

isGlobalVariable
    ^ false
!

isImmutable
    "not used with ST/X - 
     for JavaScript nodes return true here."

    ^ true
!

isInnerJavaScriptBlock
    ^ false
!

isMessage
    "return true, if this is a node for a message expression"

    ^ false
!

isMethodVariable
    ^ false
!

isNew
    "return true, if this is a new XXXX node"

    ^ false
!

isPostIncDec
    "for JavaScript"

    ^ false
!

isPreIncDec
    "for JavaScript"

    ^ false
!

isPrimary
    "return true, if this is a node for a primary (i.e. non-send)"

    ^ false
!

isReturnNode
    "return true, if this is a node for a return expression"

    ^ false
!

isSelf
    "return true, if this is a self-node"

    ^ false
!

isSuper
    "return true, if this is a super-node"

    ^ false
!

isThis
    "for JavaScript"

    ^ false
!

isUnaryMessage
    "return true, if this is a node for a unary send"

    ^ false
!

isVariable
    "return true, if this is a node for a variable"

    ^ false

    "Created: 14.4.1996 / 00:46:44 / cg"
! !

!ParseNode class methodsFor:'documentation'!

version
    ^ '$Header: /cvs/stx/stx/libcomp/ParseNode.st,v 1.51 2010-01-18 16:01:35 cg Exp $'
!

version_CVS
    ^ '$Header: /cvs/stx/stx/libcomp/ParseNode.st,v 1.51 2010-01-18 16:01:35 cg Exp $'
! !