compiler/PPCConfiguration.st
author Jan Vrany <jan.vrany@fit.cvut.cz>
Fri, 04 Sep 2015 14:06:56 +0100
changeset 535 a8feb0f47574
parent 534 a949c4fe44df
child 536 548996aca274
permissions -rw-r--r--
PPCConfiguration refactoring: [7/10]: allow to configure passes ...run during compilation by setting a collection of passes to run. Got rid of PPCPluggableConfiguration and PPCConfiguration subclasses. Removed a bunch of options used to suppress certain passes.

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

"{ NameSpace: Smalltalk }"

Object subclass:#PPCConfiguration
	instanceVariableNames:'context ir history passes'
	classVariableNames:''
	poolDictionaries:''
	category:'PetitCompiler-Core'
!

!PPCConfiguration class methodsFor:'as yet unclassified'!

default
    ^ self universal
!

new
    ^ self basicNew
        initialize;
        yourself
!

tokenizing
    | options |

    options := PPCCompilationOptions default.
    options tokenize: true.
    ^ PPCConfiguration new
        options: options;
        yourself

    "Modified: / 04-09-2015 / 16:21:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

universal
    | options |

    options := PPCCompilationOptions default.
    options tokenize: false.
    ^ PPCConfiguration new
        options: options;
        yourself

    "Modified: / 04-09-2015 / 16:21:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!PPCConfiguration methodsFor:'accessing'!

context
    ^ context
!

defaultArguments
    ^ PPCCompilationOptions default

    "Modified: / 24-08-2015 / 23:39:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

input: aPPParser
    ir := aPPParser asCompilerTree.    
    self remember: (self copyTree: ir) as: #input

    "Modified (format): / 29-08-2015 / 07:18:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

ir
    ^ ir
!

ir: whatever
    ir := whatever
!

options
    ^ context options

    "Modified: / 26-08-2015 / 19:48:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

options: aPPCCompilationOptions
    context options: aPPCCompilationOptions

    "Created: / 26-08-2015 / 19:56:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

passes
    ^ passes
!

passes:aCollection
    passes := aCollection asOrderedCollection

    "Modified: / 04-09-2015 / 14:14:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!PPCConfiguration methodsFor:'accessing - defaults'!

defaultPassesForTokenizingParser
    ^  {
        PPCTokenDetector .
        PPCCacheFirstFollowPass .
        PPCLL1Visitor .
        PPCTokenizingVisitor .
        PPCMergingVisitor .
        PPCSpecializingVisitor .
        PPCInliningVisitor .
        PPCMergingVisitor .
        PPCCheckingVisitor .
        PPCCacheFirstFollowPass .
        PPCTokenizingCodeGenerator .
        PPCFSAVisitor .
        PPCTokenCodeGenerator .
        PPCScannerCodeGenerator .    
    } asOrderedCollection.

    "Created: / 04-09-2015 / 15:56:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

defaultPassesForUniversalParser
    ^ {
        PPCTokenDetector.
        PPCCacheFirstFollowPass. 
        PPCSpecializingVisitor .
        PPCRecognizerComponentDetector .
        PPCSpecializingVisitor .
        PPCInliningVisitor .
        PPCMergingVisitor .
        PPCCheckingVisitor .
        PPCUniversalCodeGenerator
    } asOrderedCollection.

    "Created: / 04-09-2015 / 15:56:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!PPCConfiguration methodsFor:'compiling'!

buildClass: clazz
    |  builder |
    builder := PPCClassBuilder new.
    
    builder compiledClassName: clazz name.
    builder compiledSuperclass: clazz superclass.
    builder methodDictionary: clazz methodDictionary.
    builder constants: clazz constants.

    ^ builder compileClass.	
!

compile: whatever
    | time |
    self input: whatever.
    
    time := [ self invokePhases ] timeToRun.
    ((Smalltalk respondsTo:#isSmalltalkX) and:[Smalltalk isSmalltalkX]) ifFalse:[ 
        "Assume Pharo"
        time := time asMilliSeconds.
    ].
    self reportTime: time.
    
    ^ ir

    "Modified: / 17-08-2015 / 13:06:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

generateParser
    | parserClass parserSuper rootMethod |

    context options generate ifFalse:[
        ^ self
    ].
    context parserClass methodDictionary isEmpty ifTrue:[ 
        ^ self
    ].

    parserSuper := context options parserSuperclass.
    parserSuper isNil ifTrue:[ 
        parserSuper := context options tokenize 
                        ifTrue:[ PPTokenizingCompiledParser ]
                        ifFalse:[ PPCompiledParser ]   
    ].
    rootMethod := context parserClass propertyAt:#rootMethod.
    context parserClass name:context options parserName.
    context parserClass superclass: parserSuper.
    parserClass := self buildClass:context parserClass.
    parserClass startSymbol:rootMethod methodName.
    self remember:parserClass as:#parser.
    ir := parserClass new

    "Modified: / 25-08-2015 / 00:05:49 / Jan Vrany"
    "Modified: / 04-09-2015 / 16:07:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

generateScanner
    | scanner |

    context options generate ifFalse:[
        ^ self
    ].
    context scannerClass methodDictionary isEmpty ifTrue:[ 
        ^ self
    ].

    context scannerClass name:context options scannerName.
    context scannerClass superclass:context options scannerSuperclass.
    scanner := (self buildClass:context scannerClass).
    context parserClass addConstant:scanner as:#scannerClass.
    ir := scanner.
    self remember:scanner as:#scanner

    "Modified: / 25-08-2015 / 00:06:49 / Jan Vrany"
    "Modified: / 04-09-2015 / 15:33:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

invokePhases
    self initializePassesIfNotAlready.

    self runPasses: passes.

    self generateScanner.
    self generateParser.

    "Modified: / 04-09-2015 / 16:22:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!PPCConfiguration methodsFor:'debugging'!

copy: somethingTransformable
    self deprecated: 'copy on your own, or whatever, but dont use me'.
    ^ somethingTransformable transform: [ :e | e copy ]
!

copyTree: somethingTransformable
    ^ somethingTransformable transform: [ :e | e copy ]
!

remember: key
    self deprecated: 'use remember:as:'.
    
    self options debug ifTrue: [ 
        history add: key -> (self copy: ir).
    ]
!

remember: value as: key
    context options debug ifTrue: [ 
        history add: key -> value.
    ]

    "Modified: / 28-08-2015 / 14:14:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!PPCConfiguration methodsFor:'initialization'!

initialize
    history := OrderedCollection new.
    context := PPCCompilationContext new.

    "Modified: / 04-09-2015 / 15:56:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

initializePassesIfNotAlready
    passes isNil ifTrue:[ 
        context options tokenize ifTrue:[ 
            passes := self defaultPassesForTokenizingParser
        ] ifFalse:[ 
            passes := self defaultPassesForUniversalParser
        ].
    ].

    "Created: / 04-09-2015 / 16:02:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!PPCConfiguration methodsFor:'reporting'!

reportTime: timeInMs
    context options profile ifTrue: [ 
        Transcript show: 'Time to compile: ', timeInMs asString, ' ms'; cr.
    ]

    "Modified: / 26-08-2015 / 16:35:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!PPCConfiguration methodsFor:'running'!

removePass: pass
    | index |

    self initializePassesIfNotAlready.
    [ 
        index := passes indexOf: pass.
        index ~~ 0
    ] whileTrue:[ 
        passes removeAtIndex: index
    ].

    "Created: / 04-09-2015 / 11:24:45 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 04-09-2015 / 16:02:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

runPass: pass
    | p |

    p := pass asPPCPass.
    ir := p run: ir in: context.
    self remember:(self copyTree:ir) as:p class name

    "Created: / 26-08-2015 / 22:35:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 29-08-2015 / 07:16:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

runPasses: aCollection
    aCollection do:[:each | self runPass: each  ]

    "Created: / 04-09-2015 / 11:23:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !