compiler/PPCTokenCodeGenerator.st
author Jan Vrany <jan.vrany@fit.cvut.cz>
Thu, 21 May 2015 14:12:22 +0100
changeset 464 f6d77fee9811
parent 459 4751c407bb40
child 465 f729f6cd3c76
child 502 1e45d3c96ec5
permissions -rw-r--r--
Updated to PetitCompiler-JanKurs.118, PetitCompiler-Tests-JanKurs.46, PetitCompiler-Extras-Tests-JanKurs.11, and PetitCompiler-Benchmarks-JanKurs.11 Name: PetitCompiler-JanKurs.118 Author: JanKurs Time: 13-05-2015, 03:59:01.292 PM UUID: 4a8ccd94-3131-4cc7-9098-528f8e5ea0b5 Name: PetitCompiler-Tests-JanKurs.46 Author: JanKurs Time: 04-05-2015, 04:25:06.162 PM UUID: 9f4cf8b7-876e-4a13-9579-b833f016db66 Name: PetitCompiler-Extras-Tests-JanKurs.11 Author: JanKurs Time: 13-05-2015, 04:27:27.940 PM UUID: e9f30c31-fbd0-4e96-ad2a-868f88d20ea8 Name: PetitCompiler-Benchmarks-JanKurs.11 Author: JanKurs Time: 13-05-2015, 02:21:49.932 PM UUID: 6a23fd1e-a86f-46db-8221-cc41b778d32c

"{ Package: 'stx:goodies/petitparser/compiler' }"

"{ NameSpace: Smalltalk }"

PPCCodeGenerator subclass:#PPCTokenCodeGenerator
	instanceVariableNames:''
	classVariableNames:''
	poolDictionaries:''
	category:'PetitCompiler-Visitors'
!

!PPCTokenCodeGenerator methodsFor:'as yet unclassified'!

afterAccept: node retval: retval
    | return |
    return := super afterAccept: node retval: retval.
    return category: 'generated - tokens'.
    ^ return
!

fromTokenMode
    compiler rememberStrategy: (PPCCompilerTokenizingRememberStrategy on: compiler).
    compiler errorStrategy: (PPCCompilerTokenizingErrorStrategy on: compiler).
!

toTokenMode
    compiler rememberStrategy: (PPCCompilerTokenRememberStrategy on: compiler).	
    compiler errorStrategy: (PPCCompilerTokenErrorStrategy on: compiler).
! !

!PPCTokenCodeGenerator methodsFor:'visiting'!

visitOptionalNode: node
    compiler codeStoreValueOf: [ self visit: node child ] intoVariable: self retvalVar.
    compiler codeAssign: 'false.' to: 'error'.
    compiler codeReturn.
!

visitTokenNode: node
    | id startVar endVar  |
    "Tokens cannot be inlined, 
        - their result is true/false
        - the return value is always stored in currentTokenValue
        - the current token type is always stored in currentTokenType
    "
    self assert: node isMarkedForInline not.	
    
    startVar := compiler allocateTemporaryVariableNamed: 'start'.
    endVar := compiler allocateTemporaryVariableNamed: 'end'.

    id := compiler idFor: node.
    self toTokenMode.

    compiler add: 'currentTokenType isNil ifFalse: [ ^ currentTokenType == ', id storeString, '].'.	
    compiler profileTokenRead: id.
    
    node allNodes size > 2 ifTrue: [ 
        self addGuard: node ifTrue: nil  ifFalse: [ compiler addOnLine: '^ false' ].
    ].

    
    compiler codeAssign: 'context position + 1.' to: startVar.
    compiler codeStoreValueOf: [ self visit: node child ] intoVariable: #whatever.
    compiler add: 'error ifTrue: [ ^ error := false ].'.

    compiler codeAssign: 'context position.' to: endVar.

    compiler codeTranscriptShow: 'current token type: ', id storeString.
    compiler codeAssign: id storeString, '.' to: 'currentTokenType'.
    compiler codeAssign: node tokenClass asString, ' on: (context collection) 
                                                                start: ', startVar, '  
                                                                stop: ', endVar, '
                                                                value: nil.'
                to: 'currentTokenValue := ', self retvalVar.
    
        
    compiler codeClearError.
    compiler add: '^ true'.

    self fromTokenMode.
!

visitTrimmingTokenCharacterNode: node
    |  id     |

    "Tokens cannot be inlined, 
        - their result is true/false
        - the return value is always stored in currentTokenValue
        - the current token type is always stored in currentTokenType
    "
    self assert: node isMarkedForInline not.
    
    id := compiler idFor: node.
    self toTokenMode.
    
    compiler add: 'currentTokenType isNil ifFalse: [ ^ currentTokenType == ', id storeString, '].'.
    compiler profileTokenRead: id.

    self addGuard: node ifTrue: nil ifFalse: [ compiler addOnLine: ' ^ false' ].

    compiler add: 'context next.'.

    compiler codeTranscriptShow: 'current token type: ', id storeString.
    compiler codeAssign: id storeString, '.' to: 'currentTokenType'.
    compiler codeAssign: node tokenClass asString, ' on: (context collection) 
                                                            start: context position 
                                                            stop: context position
                                                            value: nil.'
               to: 'currentTokenValue := ', self retvalVar.
    
    compiler addComment: 'Consume Whitespace:'.
    compiler codeStoreValueOf: [ self visit: node whitespace ] intoVariable: #whatever.
    compiler nl.
    
    compiler add: '^ true'.

    self fromTokenMode.
!

visitTrimmingTokenNode: node
    |  id  startVar endVar  |

    "Tokens cannot be inlined, 
        - their result is true/false
        - the return value is always stored in currentTokenValue
        - the current token type is always stored in currentTokenType
    "
    self assert: node isMarkedForInline not.
    
    startVar := compiler allocateTemporaryVariableNamed: 'start'.
    endVar := compiler allocateTemporaryVariableNamed:  'end'.
    
    id := compiler idFor: node.
    self toTokenMode.
    
    compiler add: 'currentTokenType isNil ifFalse: [ ^ currentTokenType == ', id storeString, '].'.
    compiler profileTokenRead: id.
    
    node allNodes size > 2 ifTrue: [ 
        self addGuard: node ifTrue: nil  ifFalse: [ compiler addOnLine: '^ false' ].
    ].

    compiler codeAssign: 'context position + 1.' to: startVar.
    compiler codeStoreValueOf: [ self visit: node child ] intoVariable: #whatever.

    compiler add: 'error ifTrue: [ ^ error := false ].'.

        compiler codeAssign: 'context position.' to: endVar.
    
        compiler addComment: 'Consume Whitespace:'.
        compiler codeStoreValueOf: [ self visit: node whitespace ] intoVariable: #whatever.
        compiler nl.
    
    
        compiler codeTranscriptShow: 'current token type: ', id storeString.
        compiler codeAssign: id storeString, '.' to: 'currentTokenType'.
        compiler codeAssign: node tokenClass asString, ' on: (context collection) 
                                                                start: ', startVar, ' 
                                                                stop: ', endVar, '
                                                                value: nil.'
                   to: 'currentTokenValue := ', self retvalVar.

    compiler codeClearError.
    compiler add: '^ true'.

    self fromTokenMode.
! !