compiler/PPCCompiler.st
changeset 537 fb212e14d1f4
parent 536 548996aca274
child 538 16e8536f5cfb
equal deleted inserted replaced
536:548996aca274 537:fb212e14d1f4
       
     1 "{ Package: 'stx:goodies/petitparser/compiler' }"
       
     2 
       
     3 "{ NameSpace: Smalltalk }"
       
     4 
       
     5 Object subclass:#PPCCompiler
       
     6 	instanceVariableNames:'context ir history passes'
       
     7 	classVariableNames:''
       
     8 	poolDictionaries:''
       
     9 	category:'PetitCompiler-Core'
       
    10 !
       
    11 
       
    12 
       
    13 !PPCCompiler class methodsFor:'as yet unclassified'!
       
    14 
       
    15 default
       
    16     ^ self universal
       
    17 !
       
    18 
       
    19 new
       
    20     ^ self basicNew
       
    21         initialize;
       
    22         yourself
       
    23 !
       
    24 
       
    25 tokenizing
       
    26     | options |
       
    27 
       
    28     options := PPCCompilationOptions default.
       
    29     options tokenize:true.
       
    30     ^ (PPCCompiler new)
       
    31         options:options;
       
    32         yourself
       
    33 
       
    34     "Modified: / 04-09-2015 / 16:21:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
    35 !
       
    36 
       
    37 universal
       
    38     | options |
       
    39 
       
    40     options := PPCCompilationOptions default.
       
    41     options tokenize:false.
       
    42     ^ (PPCCompiler new)
       
    43         options:options;
       
    44         yourself
       
    45 
       
    46     "Modified: / 04-09-2015 / 16:21:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
    47 ! !
       
    48 
       
    49 !PPCCompiler methodsFor:'accessing'!
       
    50 
       
    51 context
       
    52     ^ context
       
    53 !
       
    54 
       
    55 options
       
    56     ^ context options
       
    57 
       
    58     "Modified: / 26-08-2015 / 19:48:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
    59 !
       
    60 
       
    61 options: aPPCCompilationOptions
       
    62     context options: aPPCCompilationOptions
       
    63 
       
    64     "Created: / 26-08-2015 / 19:56:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
    65 !
       
    66 
       
    67 passes
       
    68     ^ passes
       
    69 !
       
    70 
       
    71 passes:aCollection
       
    72     passes := aCollection asOrderedCollection
       
    73 
       
    74     "Modified: / 04-09-2015 / 14:14:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
    75 ! !
       
    76 
       
    77 !PPCCompiler methodsFor:'accessing - defaults'!
       
    78 
       
    79 defaultPassesForTokenizingParser
       
    80     ^  {
       
    81         PPCTokenDetector .
       
    82         PPCCacheFirstFollowPass .
       
    83         PPCLL1Visitor .
       
    84         PPCTokenizingVisitor .
       
    85         PPCMergingVisitor .
       
    86         PPCSpecializingVisitor .
       
    87         PPCInliningVisitor .
       
    88         PPCMergingVisitor .
       
    89         PPCCheckingVisitor .
       
    90         PPCCacheFirstFollowPass .
       
    91         PPCTokenizingCodeGenerator .
       
    92         PPCFSAVisitor .
       
    93         PPCTokenCodeGenerator .
       
    94         PPCScannerCodeGenerator .    
       
    95     } asOrderedCollection.
       
    96 
       
    97     "Created: / 04-09-2015 / 15:56:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
    98 !
       
    99 
       
   100 defaultPassesForUniversalParser
       
   101     ^ {
       
   102         PPCTokenDetector.
       
   103         PPCCacheFirstFollowPass. 
       
   104         PPCSpecializingVisitor .
       
   105         PPCRecognizerComponentDetector .
       
   106         PPCSpecializingVisitor .
       
   107         PPCInliningVisitor .
       
   108         PPCMergingVisitor .
       
   109         PPCCheckingVisitor .
       
   110         PPCUniversalCodeGenerator
       
   111     } asOrderedCollection.
       
   112 
       
   113     "Created: / 04-09-2015 / 15:56:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   114 ! !
       
   115 
       
   116 !PPCCompiler methodsFor:'adding / removing passes'!
       
   117 
       
   118 removePass: pass
       
   119     | index |
       
   120 
       
   121     self initializePassesIfNotAlready.
       
   122     [ 
       
   123         index := passes indexOf: pass.
       
   124         index ~~ 0
       
   125     ] whileTrue:[ 
       
   126         passes removeAtIndex: index
       
   127     ].
       
   128 
       
   129     "Created: / 04-09-2015 / 11:24:45 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   130     "Modified: / 04-09-2015 / 16:02:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   131 ! !
       
   132 
       
   133 !PPCCompiler methodsFor:'compiling'!
       
   134 
       
   135 compile: aPPParser
       
   136     | time |
       
   137     self input: aPPParser.
       
   138     
       
   139     time := [ self compile ] timeToRun.
       
   140     ((Smalltalk respondsTo:#isSmalltalkX) and:[Smalltalk isSmalltalkX]) ifFalse:[ 
       
   141         "Assume Pharo"
       
   142         time := time asMilliSeconds.
       
   143     ].
       
   144     self reportTime: time.
       
   145     
       
   146     ^ ir
       
   147 
       
   148     "Modified: / 17-08-2015 / 13:06:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   149 ! !
       
   150 
       
   151 !PPCCompiler methodsFor:'initialization'!
       
   152 
       
   153 initialize
       
   154     history := OrderedCollection new.
       
   155     context := PPCCompilationContext new.
       
   156 
       
   157     "Modified: / 04-09-2015 / 15:56:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   158 !
       
   159 
       
   160 initializePassesIfNotAlready
       
   161     passes isNil ifTrue:[ 
       
   162         context options tokenize ifTrue:[ 
       
   163             passes := self defaultPassesForTokenizingParser
       
   164         ] ifFalse:[ 
       
   165             passes := self defaultPassesForUniversalParser
       
   166         ].
       
   167     ].
       
   168 
       
   169     "Created: / 04-09-2015 / 16:02:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   170 ! !
       
   171 
       
   172 !PPCCompiler methodsFor:'private'!
       
   173 
       
   174 buildClass: clazz
       
   175     |  builder |
       
   176     builder := PPCClassBuilder new.
       
   177     
       
   178     builder compiledClassName: clazz name.
       
   179     builder compiledSuperclass: clazz superclass.
       
   180     builder methodDictionary: clazz methodDictionary.
       
   181     builder constants: clazz constants.
       
   182 
       
   183     ^ builder compileClass.	
       
   184 !
       
   185 
       
   186 compile
       
   187     self runPasses.
       
   188     self generateScanner.
       
   189     self generateParser.
       
   190 
       
   191     "Modified: / 07-09-2015 / 07:53:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   192 !
       
   193 
       
   194 copyTree: somethingTransformable
       
   195     ^ somethingTransformable transform: [ :e | e copy ]
       
   196 !
       
   197 
       
   198 generateParser
       
   199     | parserClass parserSuper rootMethod |
       
   200 
       
   201     context options generate ifFalse:[
       
   202         ^ self
       
   203     ].
       
   204     context parserClass methodDictionary isEmpty ifTrue:[ 
       
   205         ^ self
       
   206     ].
       
   207 
       
   208     parserSuper := context options parserSuperclass.
       
   209     parserSuper isNil ifTrue:[ 
       
   210         parserSuper := context options tokenize 
       
   211                         ifTrue:[ PPTokenizingCompiledParser ]
       
   212                         ifFalse:[ PPCompiledParser ]   
       
   213     ].
       
   214     rootMethod := context parserClass propertyAt:#rootMethod.
       
   215     context parserClass name:context options parserName.
       
   216     context parserClass superclass: parserSuper.
       
   217     parserClass := self buildClass:context parserClass.
       
   218     parserClass startSymbol:rootMethod methodName.
       
   219     self remember:parserClass as:#parser.
       
   220     ir := parserClass new
       
   221 
       
   222     "Modified: / 25-08-2015 / 00:05:49 / Jan Vrany"
       
   223     "Modified: / 04-09-2015 / 16:07:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   224 !
       
   225 
       
   226 generateScanner
       
   227     | scanner |
       
   228 
       
   229     context options generate ifFalse:[
       
   230         ^ self
       
   231     ].
       
   232     context scannerClass methodDictionary isEmpty ifTrue:[ 
       
   233         ^ self
       
   234     ].
       
   235 
       
   236     context scannerClass name:context options scannerName.
       
   237     context scannerClass superclass:context options scannerSuperclass.
       
   238     scanner := (self buildClass:context scannerClass).
       
   239     context parserClass addConstant:scanner as:#scannerClass.
       
   240     ir := scanner.
       
   241     self remember:scanner as:#scanner
       
   242 
       
   243     "Modified: / 25-08-2015 / 00:06:49 / Jan Vrany"
       
   244     "Modified: / 04-09-2015 / 15:33:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   245 !
       
   246 
       
   247 input: aPPParser
       
   248     ir := aPPParser asCompilerTree.    
       
   249     self remember: (self copyTree: ir) as: #input
       
   250 
       
   251     "Modified (format): / 29-08-2015 / 07:18:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   252 !
       
   253 
       
   254 ir
       
   255     ^ ir
       
   256 !
       
   257 
       
   258 ir: whatever
       
   259     ir := whatever
       
   260 !
       
   261 
       
   262 remember: value as: key
       
   263     context options debug ifTrue: [ 
       
   264         history add: key -> value.
       
   265     ]
       
   266 
       
   267     "Modified: / 28-08-2015 / 14:14:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   268 !
       
   269 
       
   270 reportTime: timeInMs
       
   271     context options profile ifTrue: [ 
       
   272         Transcript show: 'Time to compile: '; show: timeInMs asString; show: ' ms'; cr.
       
   273     ]
       
   274 
       
   275     "Modified: / 07-09-2015 / 07:55:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   276 !
       
   277 
       
   278 runPasses
       
   279     self initializePassesIfNotAlready.
       
   280     passes do:[:each | self runPass: each  ]
       
   281 
       
   282     "Created: / 07-09-2015 / 07:53:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   283 ! !
       
   284 
       
   285 !PPCCompiler methodsFor:'running'!
       
   286 
       
   287 runPass: pass
       
   288     | p |
       
   289 
       
   290     p := pass asPPCPass.
       
   291     ir := p run: ir in: context.
       
   292     self remember:(self copyTree:ir) as:p class name
       
   293 
       
   294     "Created: / 26-08-2015 / 22:35:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   295     "Modified: / 29-08-2015 / 07:16:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   296 ! !
       
   297 
       
   298 !PPCCompiler class methodsFor:'documentation'!
       
   299 
       
   300 version_HG
       
   301 
       
   302     ^ '$Changeset: <not expanded> $'
       
   303 ! !
       
   304