compiler/PPCCompiler.st
changeset 453 bd5107faf4d6
parent 445 eb33780df2f9
parent 452 9f4558b3be66
child 454 a9cd5ea7cc36
equal deleted inserted replaced
451:989570319d14 453:bd5107faf4d6
     1 "{ Package: 'stx:goodies/petitparser/compiler' }"
     1 "{ Package: 'stx:goodies/petitparser/compiler' }"
     2 
     2 
     3 "{ NameSpace: Smalltalk }"
     3 "{ NameSpace: Smalltalk }"
     4 
     4 
     5 Object subclass:#PPCCompiler
     5 Object subclass:#PPCCompiler
     6 	instanceVariableNames:'compilerStack compiledParser cache currentMethod ids rootNode
     6 	instanceVariableNames:'compilerStack compiledParser cache currentMethod ids constants
     7 		constants compiledParserName returnVariable arguments'
     7 		compiledParserName compiledParserSuperclass returnVariable
       
     8 		arguments'
     8 	classVariableNames:''
     9 	classVariableNames:''
     9 	poolDictionaries:''
    10 	poolDictionaries:''
    10 	category:'PetitCompiler-Core'
    11 	category:'PetitCompiler-Core'
    11 !
    12 !
    12 
    13 
    34 ! !
    35 ! !
    35 
    36 
    36 !PPCCompiler methodsFor:'accessing'!
    37 !PPCCompiler methodsFor:'accessing'!
    37 
    38 
    38 arguments: args
    39 arguments: args
    39 	arguments := args
    40     arguments := args
    40 !
    41 !
    41 
    42 
    42 compiledParser
    43 compiledParser
    43 	^ compiledParser 
    44     ^ compiledParser 
       
    45 !
       
    46 
       
    47 compiledParserSuperclass
       
    48     ^ compiledParserSuperclass ifNil: [ PPCompiledParser ]
    44 !
    49 !
    45 
    50 
    46 currentNonInlineMethod
    51 currentNonInlineMethod
    47 	^ compilerStack 
    52     ^ compilerStack 
    48 	    detect:[:m | m isInline not ] 
    53         detect:[:m | m isInline not ] 
    49 	    ifNone:[ self error: 'No non-inlined method']
    54         ifNone:[ self error: 'No non-inlined method']
    50 
    55 
    51     "Created: / 23-04-2015 / 17:33:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    56     "Created: / 23-04-2015 / 17:33:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    52 !
    57 !
    53 
    58 
    54 currentReturnVariable
    59 currentReturnVariable
    55 	^ currentMethod returnVariable 
    60     ^ currentMethod returnVariable 
    56 !
    61 !
    57 
    62 
    58 ids
    63 ids
    59 	^ ids
    64     ^ ids
    60 !
       
    61 
       
    62 rootNode
       
    63 	^ rootNode
       
    64 ! !
    65 ! !
    65 
    66 
    66 !PPCCompiler methodsFor:'cleaning'!
    67 !PPCCompiler methodsFor:'cleaning'!
    67 
    68 
    68 clean: class
    69 clean: class
    69 "	Transcript crShow: 'Cleaning time: ',
    70 "	Transcript crShow: 'Cleaning time: ',
    70 	[	
    71     [	
    71 "		self cleanGeneratedMethods: class.
    72 "		self cleanGeneratedMethods: class.
    72 		self cleanInstVars: class.
    73         self cleanInstVars: class.
    73 		self cleanConstants: class.
    74         self cleanConstants: class.
    74 "	] timeToRun asMilliSeconds asString, 'ms'."
    75 "	] timeToRun asMilliSeconds asString, 'ms'."
    75 !
    76 !
    76 
    77 
    77 cleanConstants: class
    78 cleanConstants: class
    78 	class constants removeAll.
    79     class constants removeAll.
    79 !
    80 !
    80 
    81 
    81 cleanGeneratedMethods: class
    82 cleanGeneratedMethods: class
    82 	((Smalltalk respondsTo:#isSmalltalkX) and:[ Smalltalk isSmalltalkX ]) ifTrue:[
    83     ((Smalltalk respondsTo:#isSmalltalkX) and:[ Smalltalk isSmalltalkX ]) ifTrue:[
    83 		class methodsDo: [ :mthd |
    84         class methodsDo: [ :mthd |
    84 			mthd category = #generated ifTrue:[
    85             mthd category = #generated ifTrue:[
    85 				class removeSelector: mthd selector.
    86                 class removeSelector: mthd selector.
    86 			]
    87             ]
    87 		]
    88         ]
    88 	] ifFalse: [ 
    89     ] ifFalse: [ 
    89 		(class allSelectorsInProtocol: #generated) do: [ :selector | 
    90         (class allSelectorsInProtocol: #generated) do: [ :selector | 
    90 			class removeSelectorSilently: selector ].
    91             class removeSelectorSilently: selector ].
    91 	]
    92     ]
    92 !
    93 !
    93 
    94 
    94 cleanInstVars: class
    95 cleanInstVars: class
    95 	class class instanceVariableNames: ''.
    96     class class instanceVariableNames: ''.
    96 !
    97 !
    97 
    98 
    98 cleanParsers: class
    99 cleanParsers: class
    99 	class parsers removeAll.
   100     class parsers removeAll.
   100 ! !
   101 ! !
   101 
   102 
   102 !PPCCompiler methodsFor:'code generation'!
   103 !PPCCompiler methodsFor:'code generation'!
   103 
   104 
   104 add: string
   105 add: string
   105 	currentMethod add: string.
   106     currentMethod add: string.
   106 !
   107 !
   107 
   108 
   108 addComment: string
   109 addComment: string
   109 	currentMethod add: '"', string, '"'.
   110     currentMethod add: '"', string, '"'.
   110 !
   111 !
   111 
   112 
   112 addConstant: value as: name
   113 addConstant: value as: name
   113 	constants at: name put: value
   114     constants at: name put: value
   114 !
   115 !
   115 
   116 
   116 addOnLine: string
   117 addOnLine: string
   117 	currentMethod addOnLine: string.
   118     currentMethod addOnLine: string.
   118 !
   119 !
   119 
   120 
   120 addVariable: name
   121 addVariable: name
   121     ^ self currentNonInlineMethod addVariable: name
   122     ^ self currentNonInlineMethod addVariable: name
   122 
   123 
   123     "Modified: / 23-04-2015 / 17:34:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   124     "Modified: / 23-04-2015 / 17:34:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   124 !
   125 !
   125 
   126 
   126 call: anotherMethod
   127 call: anotherMethod
   127 	currentMethod add: anotherMethod call.
   128     currentMethod add: anotherMethod call.
   128 !
   129 !
   129 
   130 
   130 callOnLine: anotherMethod
   131 callOnLine: anotherMethod
   131 	currentMethod addOnLine: anotherMethod call.
   132     currentMethod addOnLine: anotherMethod call.
   132 !
   133 !
   133 
   134 
   134 dedent
   135 dedent
   135 	currentMethod dedent
   136     currentMethod dedent
   136 !
   137 !
   137 
   138 
   138 indent
   139 indent
   139 	currentMethod indent
   140     currentMethod indent
   140 !
   141 !
   141 
   142 
   142 nl
   143 nl
   143 	currentMethod nl
   144     currentMethod nl
   144 !
   145 !
   145 
   146 
   146 smartRemember: parser
   147 smartRemember: parser to: variableName 
   147 	self flag: 'deprecated'.
   148     parser isContextFree ifTrue: [ 
   148 	^ self smartRemember: parser to: #memento 
   149         self 	codeAssign: 'context lwRemember.' 
   149 !
   150                 to: variableName.
   150 
   151     ] ifFalse: [ 
   151 smartRemember: parser to: variableName
   152         self  codeAssign: 'context remember.'
   152 	parser isContextFree ifTrue: [ 
   153                 to: variableName.
   153 		^ variableName, ' := context lwRemember.'.
   154     ]
   154 	].
       
   155 	^ variableName, ':= context remember.'
       
   156 !
       
   157 
       
   158 smartRestore: parser
       
   159 	self flag: 'deprecated'.
       
   160 	^ self smartRestore: parser from: #memento 
       
   161 !
   155 !
   162 
   156 
   163 smartRestore: parser from: mementoName
   157 smartRestore: parser from: mementoName
   164 	parser isContextFree ifTrue: [ 
   158     parser isContextFree ifTrue: [ 
   165 		^ 'context lwRestore: ', mementoName, '.'.
   159         self add: 'context lwRestore: ', mementoName, '.'.
   166 	].
   160     ] ifFalse: [ 
   167 	^ 'context restore: ', mementoName, '.'.
   161         self add: 'context restore: ', mementoName, '.'.
       
   162     ]
   168 ! !
   163 ! !
   169 
   164 
   170 !PPCCompiler methodsFor:'code generation - coding'!
   165 !PPCCompiler methodsFor:'code generation - coding'!
   171 
   166 
   172 codeAssign: code to: variable
   167 codeAssign: code to: variable
   173 	self assert: variable isNil not.
   168     self assert: variable isNil not.
   174 	
   169     
   175 	"TODO JK: Hack alert, whatever is magic constant!!"
   170     "TODO JK: Hack alert, whatever is magic constant!!"
   176 	(variable == #whatever) ifFalse: [ 
   171     (variable == #whatever) ifFalse: [ 
   177 		"Do not assign, if somebody does not care!!"
   172         "Do not assign, if somebody does not care!!"
   178 		self add: variable ,' := ', code.
   173         self add: variable ,' := ', code.
   179  	] ifTrue: [ 
   174  	] ifTrue: [ 
   180 		"In case code hava a side effect"
   175         "In case code hava a side effect"
   181  		self add: code	
   176  		self add: code	
   182 	]
   177     ]
   183 !
   178 !
   184 
   179 
   185 codeClearError
   180 codeClearError
   186 	self add: 'self clearError.'.
   181     self add: 'self clearError.'.
   187 !
   182 !
   188 
   183 
   189 codeError: errorMessage
   184 codeError: errorMessage
   190 	self add: 'self error: ''', errorMessage, '''.'
   185     self add: 'self error: ''', errorMessage, '''.'
   191 !
   186 !
   192 
   187 
   193 codeHalt
   188 codeHalt
   194 	self add: 'self halt. '
   189     self add: 'self halt. '
       
   190 !
       
   191 
       
   192 codeHaltIfShiftPressed
       
   193     arguments debug ifTrue: [ 
       
   194         self add: 'Halt ifShiftPressed.'
       
   195     ]
       
   196 !
       
   197 
       
   198 codeNextToken
       
   199     self add: 'self nextToken.'
       
   200 
       
   201     "Created: / 23-04-2015 / 18:01:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   202     "Modified: / 23-04-2015 / 20:51:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   195 !
   203 !
   196 
   204 
   197 codeReturn
   205 codeReturn
   198    currentMethod isInline ifTrue: [
   206    currentMethod isInline ifTrue: [
   199 		"If inlined, the return variable already holds the value"
   207 		"If inlined, the return variable already holds the value"
   204     "Created: / 23-04-2015 / 18:01:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   212     "Created: / 23-04-2015 / 18:01:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   205     "Modified: / 23-04-2015 / 20:51:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   213     "Modified: / 23-04-2015 / 20:51:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   206 !
   214 !
   207 
   215 
   208 codeReturn: code
   216 codeReturn: code
   209 	" - returns whatever is in code OR
   217     " - returns whatever is in code OR
   210 	  - assigns whatever is in code into the returnVariable"
   218       - assigns whatever is in code into the returnVariable"
   211    currentMethod isInline ifTrue:[ 
   219    currentMethod isInline ifTrue:[ 
   212 		self codeAssign: code to: currentMethod returnVariable. 
   220         self codeAssign: code to: currentMethod returnVariable. 
   213    ] ifFalse: [ 
   221    ] ifFalse: [ 
   214 		self add: '^ ', code 		
   222         self add: '^ ', code 		
   215 	]
   223     ]
   216 
   224 
   217     "Created: / 23-04-2015 / 18:01:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   225     "Created: / 23-04-2015 / 18:01:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   218     "Modified: / 23-04-2015 / 20:51:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   226     "Modified: / 23-04-2015 / 20:51:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   219 !
   227 !
   220 
   228 
   221 codeStoreValueOf: aBlock intoVariable: aString
   229 codeStoreValueOf: aBlock intoVariable: aString
   222 	| tmpVarirable method |
   230     | tmpVarirable method |
   223 	self assert: aBlock isBlock.
   231     self assert: aBlock isBlock.
   224 	self assert: aString isNil not.
   232     self assert: aString isNil not.
   225 	
   233     
   226 	tmpVarirable := returnVariable.
   234     tmpVarirable := returnVariable.
   227 	returnVariable := aString.
   235     returnVariable := aString.
   228 	method := [  
   236     method := [  
   229 		aBlock value 
   237         aBlock value 
   230 	] ensure: [ 
   238     ] ensure: [ 
   231 		returnVariable := tmpVarirable 
   239         returnVariable := tmpVarirable 
   232 	].
   240     ].
   233 	
   241     
   234 	method isInline ifTrue: [ 
   242     method isInline ifTrue: [ 
   235 		self callOnLine: method 
   243         self callOnLine: method 
   236 	] ifFalse: [ 
   244     ] ifFalse: [ 
   237 		self codeAssign: (method call) to: aString.
   245         self codeAssign: (method call) to: aString.
   238 	]	
   246     ]	
   239 	
   247     
   240 	"Created: / 23-04-2015 / 18:21:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   248     "Created: / 23-04-2015 / 18:21:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   249 !
       
   250 
       
   251 codeTranscriptShow: text
       
   252     (arguments profile) ifTrue: [ 
       
   253         self add: 'Transcript show: ', text storeString, '; cr.'.
       
   254     ]
   241 ! !
   255 ! !
   242 
   256 
   243 !PPCCompiler methodsFor:'code generation - ids'!
   257 !PPCCompiler methodsFor:'code generation - ids'!
   244 
   258 
       
   259 asSelector: string
       
   260     "e.g. '234znak 43 ) 2' asLegalSelector = #v234znak432"
       
   261     
       
   262     | toUse |
       
   263  	toUse := string select: [:char | char isAlphaNumeric or: [ char = $_ ] ].
       
   264     (toUse isEmpty or: [ toUse first isLetter not ])
       
   265         ifTrue: [ toUse := 'v', toUse ].
       
   266     ^ toUse uncapitalized asSymbol.
       
   267 !
       
   268 
   245 idFor: object
   269 idFor: object
   246 	self assert: (object isKindOf: PPCNode).
   270     self assert: (object isKindOf: PPCNode).
   247 	^ self idFor: object prefixed: object prefix suffixed: object suffix effect: #none
   271     ^ self idFor: object prefixed: object prefix suffixed: object suffix effect: #none
   248 !
   272 !
   249 
   273 
   250 idFor: object prefixed: prefix
   274 idFor: object prefixed: prefix
   251 	^ self idFor: object prefixed: prefix effect: #none
   275     ^ self idFor: object prefixed: prefix effect: #none
   252 !
   276 !
   253 
   277 
   254 idFor: object prefixed: prefix effect: effect
   278 idFor: object prefixed: prefix effect: effect
   255 	^ self idFor: object prefixed: prefix suffixed: '' effect: effect.
   279     ^ self idFor: object prefixed: prefix suffixed: '' effect: effect.
   256 !
   280 !
   257 
   281 
   258 idFor: object prefixed: prefix suffixed: suffix effect: effect
   282 idFor: object prefixed: prefix suffixed: suffix effect: effect
   259         | name id |
   283     | name id |
   260         ^ ids at: object ifAbsentPut: [ 
   284     ^ ids at: object ifAbsentPut: [ 
   261                 ((object isKindOf: PPCNode) and: [object name isNotNil]) ifTrue: [ 
   285         ((object isKindOf: PPCNode) and: [object name isNotNil]) ifTrue: [ 
   262                         "Do not use prefix, if there is a name"
   286             "Do not use prefix, if there is a name"
   263                         name := object name.
   287             name := self asSelector: object name.
   264                         "Selector sanitizing inlined here as Smalltalk/X does not
   288             id := (name, suffix) asSymbol.
   265                          support asLegalSelector"
   289             
   266                         name := name select: [:char | char isAlphaNumeric].
   290             "Make sure, that the generated ID is uniqe!!"
   267                         (name isEmpty or: [ name first isLetter not ])
   291             (ids includes: id) ifTrue: [ 
   268                             ifTrue: [ name := 'v', name ].
   292                 (id, '_', ids size asString) asSymbol 
   269                         id := (name, suffix) asSymbol.
   293             ] ifFalse: [ 
   270                         
   294                 id
   271                         "Make sure, that the generated ID is uniqe!!"
   295             ]
   272                         (ids includes: id) ifTrue: [ 
   296         ] ifFalse: [ 
   273                                 (id, '_', ids size asString) asSymbol 
   297             (prefix, '_', (ids size asString), suffix) asSymbol
   274                         ] ifFalse: [ 
       
   275                                 id
       
   276                         ]
       
   277                 ] ifFalse: [ 
       
   278                         (prefix, '_', (ids size asString), suffix) asSymbol
       
   279                 ]
       
   280         ]
   298         ]
   281 
   299     ]
   282     "Modified: / 01-05-2015 / 14:38:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   300 !
       
   301 
       
   302 idFor: object suffixed: suffix
       
   303     self assert: (object isKindOf: PPCNode) description: 'Shold use PPCNode for ids'.
       
   304     ^ self idFor: object prefixed: object prefix suffixed: suffix effect: #none
   283 ! !
   305 ! !
   284 
   306 
   285 !PPCCompiler methodsFor:'code generation - support'!
   307 !PPCCompiler methodsFor:'code generation - support'!
   286 
   308 
   287 cache: id as: value
   309 cache: id as: value
   288 	cache at: id put: value.
   310     cache at: id put: value.
   289 !
   311 !
   290 
   312 
   291 cachedValue: id
   313 cachedValue: id
   292 	^ cache at: id ifAbsent: [ nil ]
   314     ^ cache at: id ifAbsent: [ nil ]
   293 !
   315 !
   294 
   316 
   295 checkCache: id
   317 checkCache: id
   296 	| method  |
   318     | method  |
   297 	"Check if method is hand written"
   319     "Check if method is hand written"
   298 	method := compiledParser ifNotNil: [ compiledParser compiledMethodAt: id ifAbsent: [ nil ] ].
   320     method := compiledParser ifNotNil: [ compiledParser compiledMethodAt: id ifAbsent: [ nil ] ].
   299 	method ifNotNil: [ ^ PPCCompiledMethod new id: id; yourself ].
   321     method ifNotNil: [ ^ PPCCompiledMethod new id: id; yourself ].
   300 	
   322     
   301 	^ self cachedValue: id
   323     ^ self cachedValue: id
   302 !
   324 !
   303 
   325 
   304 pop
   326 pop
   305 	| retval |
   327     | retval |
   306 	retval := compilerStack pop.
   328     retval := compilerStack pop.
   307 	currentMethod := compilerStack isEmpty 
   329     currentMethod := compilerStack isEmpty 
   308 		ifTrue: [ nil ]
   330         ifTrue: [ nil ]
   309 		ifFalse: [ compilerStack top ].
   331         ifFalse: [ compilerStack top ].
   310 	^ retval
   332     ^ retval
   311 
   333 
   312     "Modified: / 21-11-2014 / 12:27:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   334     "Modified: / 21-11-2014 / 12:27:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   313 !
   335 !
   314 
   336 
   315 push
   337 push
   316         compilerStack push: currentMethod.
   338     compilerStack push: currentMethod.
   317         (compilerStack size > 500 )ifTrue: [ self error: 'unless it is very complex grammar, there is an error somewhere' ]
   339     (compilerStack size > 500 )ifTrue: [ self error: 'unless it is very complex grammar, there is an error somewhere' ]
   318 
   340 
   319     "Modified: / 21-11-2014 / 12:27:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   341     "Modified: / 21-11-2014 / 12:27:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   320 !
   342 !
   321 
   343 
   322 startInline: id
   344 startInline: id
   323 	(cache includesKey: id) ifTrue: [ self error: 'OOOUPS!!' ].
   345     | indentationLevel |
   324 
   346     (cache includesKey: id) ifTrue: [ self error: 'OOOUPS!!' ].
   325 	currentMethod := PPCInlinedMethod new.
   347     indentationLevel := currentMethod indentationLevel.
   326 	currentMethod id: id.   
   348     
   327 	currentMethod profile: arguments profile.
   349     currentMethod := PPCInlinedMethod new.
   328 	currentMethod returnVariable: returnVariable.
   350     currentMethod id: id.   
   329 	self push.
   351     currentMethod profile: arguments profile.
       
   352     currentMethod returnVariable: returnVariable.
       
   353     currentMethod indentationLevel: indentationLevel.
       
   354     self push.
   330 
   355 
   331     "Modified: / 23-04-2015 / 18:28:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   356     "Modified: / 23-04-2015 / 18:28:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   332 !
   357 !
   333 
   358 
   334 startMethod: id
   359 startMethod: id
   335 	(cache includesKey: id) ifTrue: [ self error: 'OOOUPS!!' ].
   360     (cache includesKey: id) ifTrue: [ self error: 'OOOUPS!!' ].
   336 
   361 
   337 	currentMethod := PPCMethod new.
   362     currentMethod := PPCMethod new.
   338 	currentMethod id: id.
   363     currentMethod id: id.
   339 	currentMethod profile: arguments profile.    
   364     currentMethod profile: arguments profile.    
   340 	self push.      
   365     self push.      
   341                 
   366                 
   342 	self cache: id as: currentMethod.
   367     self cache: id as: currentMethod.
   343 
   368 
   344     "Modified: / 23-04-2015 / 18:36:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   369     "Modified: / 23-04-2015 / 18:36:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   345 !
   370 !
   346 
   371 
   347 stopInline
   372 stopInline
   348 
   373 
   349 	^ self pop.
   374     ^ self pop.
   350 
   375 
   351     "Modified: / 23-04-2015 / 18:28:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   376     "Modified: / 23-04-2015 / 18:28:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   352 !
   377 !
   353 
   378 
   354 stopMethod
   379 stopMethod
   355         self cache: currentMethod methodName as: currentMethod.
   380     self cache: currentMethod methodName as: currentMethod.
   356         
   381     
   357         arguments profile ifTrue: [ Transcript show: currentMethod code; cr. ].
   382     arguments profile ifTrue: [ Transcript show: currentMethod code; cr. ].
   358         ^ self pop.
   383     ^ self pop.
   359 
   384 
   360     "Modified: / 01-05-2015 / 14:18:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   385     "Modified: / 01-05-2015 / 14:18:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   361 !
   386 !
   362 
   387 
   363 top
   388 top
   364 	^ compilerStack top
   389     ^ compilerStack top
   365 ! !
   390 ! !
   366 
   391 
   367 !PPCCompiler methodsFor:'code generation - variables'!
   392 !PPCCompiler methodsFor:'code generation - variables'!
   368 
   393 
   369 allocateReturnVariable
   394 allocateReturnVariable
   385 ! !
   410 ! !
   386 
   411 
   387 !PPCCompiler methodsFor:'compiling'!
   412 !PPCCompiler methodsFor:'compiling'!
   388 
   413 
   389 compileParser
   414 compileParser
   390 	self installVariables.
   415     self installVariables.
   391 	self installMethods.
   416     self installMethods.
   392 	self installClassConstants.
   417     self installClassConstants.
   393 
   418 
   394 	^ compiledParser
   419     ^ compiledParser
   395 !
   420 !
   396 
   421 
   397 copy: parser
   422 copy: parser
   398 	^ parser transform: [ :p | p copy ].
   423     ^ parser transform: [ :p | p copy ].
   399 !
   424 !
   400 
   425 
   401 installClassConstants
   426 installClassConstants
   402 	constants keysAndValuesDo: [ :key :value |
   427     constants keysAndValuesDo: [ :key :value |
   403 		compiledParser constants at: key put: value
   428         compiledParser constants at: key put: value
   404 	]
   429     ]
   405 !
   430 !
   406 
   431 
   407 installMethods
   432 installMethods
   408 	cache keysAndValuesDo: [ :key :method |
   433     cache keysAndValuesDo: [ :key :method |
   409 		compiledParser compileSilently: method code classified: 'generated'.
   434         compiledParser compileSilently: method code classified: 'generated'.
   410 	]
   435     ]
   411 !
   436 !
   412 
   437 
   413 installVariables
   438 installVariables
   414 	| varString |
   439     | varString |
   415 	varString := constants keys inject: '' into: [:r :e | r, ' ', e  ].
   440     varString := constants keys inject: '' into: [:r :e | r, ' ', e  ].
   416 
   441 
   417 	PPCompiledParser 
   442     (self compiledParserSuperclass) 
   418 		subclass: compiledParserName  
   443         subclass: compiledParserName  
   419 		instanceVariableNames: varString 
   444         instanceVariableNames: varString 
   420 		classVariableNames: '' 
   445         classVariableNames: '' 
   421 		poolDictionaries: '' 
   446         poolDictionaries: '' 
   422 		category: 'PetitCompiler-Generated'.
   447         category: 'PetitCompiler-Generated'.
   423 
   448 
   424 	compiledParser := Smalltalk at: compiledParserName.
   449     compiledParser := Smalltalk at: compiledParserName.
   425 !
       
   426 
       
   427 precomputeFirstSets: root
       
   428 	| firstSets |
       
   429 	firstSets := root firstSets.
       
   430 	
       
   431 	root allNodesDo: [ :node |
       
   432 		node firstSet: (firstSets at: node).
       
   433 	]
       
   434 	
       
   435 !
       
   436 
       
   437 precomputeFollowSets: root
       
   438 	| followSets |
       
   439 	followSets := root followSets.
       
   440 	
       
   441 	root allNodesDo: [ :node |
       
   442 		node followSet: (followSets at: node).
       
   443 	]
       
   444 	
       
   445 !
       
   446 
       
   447 precomputeFollowSetsWithTokens: root
       
   448 	| followSets |
       
   449 	followSets := root followSetsSuchThat: [:e | e isTerminal or: [ e isKindOf: PPCTrimmingTokenNode ]].
       
   450 	
       
   451 	root allNodesDo: [ :node |
       
   452 		node followSetWithTokens: (followSets at: node).
       
   453 	]
       
   454 	
       
   455 !
       
   456 
       
   457 toCompilerTree: parser
       
   458 	^ parser asCompilerTree
       
   459 ! !
   450 ! !
   460 
   451 
   461 !PPCCompiler methodsFor:'initialization'!
   452 !PPCCompiler methodsFor:'initialization'!
   462 
   453 
   463 initializeForCompiledClassName: aString
   454 initializeForCompiledClassName: aString
   464 	
   455     
   465 	self initialize.
   456     self initialize.
   466 	compilerStack := Stack new.
   457     compilerStack := Stack new.
   467 	cache := IdentityDictionary new.
   458     cache := IdentityDictionary new.
   468 	constants := IdentityDictionary new.
   459     constants := IdentityDictionary new.
   469 	ids := IdentityDictionary new.
   460     ids := IdentityDictionary new.
   470 	
   461     
   471 
   462 
   472 	compiledParserName := aString asSymbol.
   463     compiledParserName := aString asSymbol.
   473 	
   464     
   474 	((Smalltalk respondsTo:#isSmalltalkX) and:[ Smalltalk isSmalltalkX ]) ifTrue:[
   465     ((Smalltalk respondsTo:#isSmalltalkX) and:[ Smalltalk isSmalltalkX ]) ifTrue:[
   475 		| rPackageOrganizer |
   466         | rPackageOrganizer |
   476 		rPackageOrganizer := Smalltalk at: #RPackageOrganizer.
   467         rPackageOrganizer := Smalltalk at: #RPackageOrganizer.
   477 		rPackageOrganizer notNil ifTrue:[
   468         rPackageOrganizer notNil ifTrue:[
   478 			rPackageOrganizer default registerPackageNamed: 'PetitCompiler-Generated'.
   469             rPackageOrganizer default registerPackageNamed: 'PetitCompiler-Generated'.
   479 		].
   470         ].
   480 	] ifFalse: [ 
   471     ] ifFalse: [ 
   481 		RPackageOrganizer default registerPackageNamed: 'PetitCompiler-Generated'.
   472         RPackageOrganizer default registerPackageNamed: 'PetitCompiler-Generated'.
   482 	].
   473     ].
   483 
   474 
   484 	Smalltalk at: compiledParserName ifPresent: [ :class |
   475     Smalltalk at: compiledParserName ifPresent: [ :class |
   485 		compiledParser := class.
   476         compiledParser := class.
   486 		self clean: compiledParser.
   477         self clean: compiledParser.
   487 	].
   478     ].
       
   479 
       
   480 
       
   481     Transcript cr; show: 'intialized for: ', aString; cr.
   488 ! !
   482 ! !
   489 
   483 
   490 !PPCCompiler class methodsFor:'documentation'!
   484 !PPCCompiler class methodsFor:'documentation'!
   491 
   485 
   492 version_HG
   486 version_HG