compiler/PPCCompiler.st
changeset 438 20598d7ce9fa
parent 428 b879012e366e
child 443 2c87ed364404
child 452 9f4558b3be66
equal deleted inserted replaced
437:54b3bc9e3987 438:20598d7ce9fa
     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 inlining debug profile
     6 	instanceVariableNames:'compilerStack compiledParser cache currentMethod ids rootNode
     7 		currentMethod guards ids tokenMode rootNode'
     7 		constants compiledParserName returnVariable arguments'
     8 	classVariableNames:''
     8 	classVariableNames:''
     9 	poolDictionaries:''
     9 	poolDictionaries:''
    10 	category:'PetitCompiler-Core'
    10 	category:'PetitCompiler-Core'
    11 !
    11 !
    12 
    12 
    14 !PPCCompiler class methodsFor:'instance creation'!
    14 !PPCCompiler class methodsFor:'instance creation'!
    15 
    15 
    16 new
    16 new
    17     "return an initialized instance"
    17     "return an initialized instance"
    18 
    18 
    19     ^ self basicNew initialize.
    19     ^ self basicNew initializeForCompiledClassName: 'PPGeneratedParser'
       
    20 !
       
    21 
       
    22 newForCompiledClassName: aString
       
    23     "return an initialized instance"
       
    24 	self halt: 'deprecated'.
       
    25     ^ self basicNew initializeForCompiledClassName: aString
       
    26 !
       
    27 
       
    28 on: aPPCArguments
       
    29     "return an initialized instance"
       
    30 
       
    31     ^ self basicNew
       
    32 		arguments: aPPCArguments;
       
    33 		initializeForCompiledClassName: aPPCArguments name
    20 ! !
    34 ! !
    21 
    35 
    22 !PPCCompiler methodsFor:'accessing'!
    36 !PPCCompiler methodsFor:'accessing'!
    23 
    37 
    24 inlining
    38 arguments: args
    25 	^ inlining
    39 	arguments := args
    26 !
    40 !
    27 
    41 
    28 inlining: value
    42 compiledParser
    29 	inlining := value
    43 	^ compiledParser 
    30 !
    44 !
    31 
    45 
    32 parameters: associations
    46 currentNonInlineMethod
    33 	| key value |
    47 	^ compilerStack 
    34 	associations do: [ :ass |
    48 	    detect:[:m | m isInline not ] 
    35 		key := ass key.
    49 	    ifNone:[ self error: 'No non-inlined method']
    36 		value := ass value.
    50 
    37 		
    51     "Created: / 23-04-2015 / 17:33:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    38 		(key = #profile) ifTrue: [ profile := value ].
    52 !
    39 		(key = #inline) ifTrue: [ inlining := value ].
    53 
    40 		(key = #guards) ifTrue: [ guards := value ].
    54 currentReturnVariable
    41 	]
    55 	^ currentMethod returnVariable 
    42 !
    56 !
    43 
    57 
    44 profile
    58 ids
    45 	^ profile
    59 	^ ids
    46 !
       
    47 
       
    48 profile: aBoolean
       
    49 	profile := aBoolean 
       
    50 !
    60 !
    51 
    61 
    52 rootNode
    62 rootNode
    53 	^ rootNode
    63 	^ rootNode
    54 ! !
    64 ! !
    58 clean: class
    68 clean: class
    59 "	Transcript crShow: 'Cleaning time: ',
    69 "	Transcript crShow: 'Cleaning time: ',
    60 	[	
    70 	[	
    61 "		self cleanGeneratedMethods: class.
    71 "		self cleanGeneratedMethods: class.
    62 		self cleanInstVars: class.
    72 		self cleanInstVars: class.
    63 		self cleanParsers: class.
       
    64 		self cleanConstants: class.
    73 		self cleanConstants: class.
    65 "	] timeToRun asMilliSeconds asString, 'ms'."
    74 "	] timeToRun asMilliSeconds asString, 'ms'."
    66 !
    75 !
    67 
    76 
    68 cleanConstants: class
    77 cleanConstants: class
    99 addComment: string
   108 addComment: string
   100 	currentMethod add: '"', string, '"'.
   109 	currentMethod add: '"', string, '"'.
   101 !
   110 !
   102 
   111 
   103 addConstant: value as: name
   112 addConstant: value as: name
   104 	compiledParser addConstant: value as: name.
   113 	constants at: name put: value
   105 !
   114 !
   106 
   115 
   107 addOnLine: string
   116 addOnLine: string
   108 	currentMethod addOnLine: string.
   117 	currentMethod addOnLine: string.
   109 !
   118 !
   110 
   119 
   111 addVariable: name
   120 addVariable: name
   112 	currentMethod addVariable: name.
   121     ^ self currentNonInlineMethod addVariable: name
       
   122 
       
   123     "Modified: / 23-04-2015 / 17:34:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   113 !
   124 !
   114 
   125 
   115 call: anotherMethod
   126 call: anotherMethod
   116 	currentMethod add: anotherMethod call.
   127 	currentMethod add: anotherMethod call.
   117 !
   128 !
   131 nl
   142 nl
   132 	currentMethod nl
   143 	currentMethod nl
   133 !
   144 !
   134 
   145 
   135 smartRemember: parser
   146 smartRemember: parser
       
   147 	self flag: 'deprecated'.
   136 	^ self smartRemember: parser to: #memento 
   148 	^ self smartRemember: parser to: #memento 
   137 !
   149 !
   138 
   150 
   139 smartRemember: parser to: variableName
   151 smartRemember: parser to: variableName
   140 	parser isContextFree ifTrue: [ 
   152 	parser isContextFree ifTrue: [ 
   142 	].
   154 	].
   143 	^ variableName, ':= context remember.'
   155 	^ variableName, ':= context remember.'
   144 !
   156 !
   145 
   157 
   146 smartRestore: parser
   158 smartRestore: parser
       
   159 	self flag: 'deprecated'.
   147 	^ self smartRestore: parser from: #memento 
   160 	^ self smartRestore: parser from: #memento 
   148 !
   161 !
   149 
   162 
   150 smartRestore: parser from: mementoName
   163 smartRestore: parser from: mementoName
   151 	parser isContextFree ifTrue: [ 
   164 	parser isContextFree ifTrue: [ 
   152 		^ 'context lwRestore: ', mementoName, '.'.
   165 		^ 'context lwRestore: ', mementoName, '.'.
   153 	].
   166 	].
   154 	^ 'context restore: ', mementoName, '.'.
   167 	^ 'context restore: ', mementoName, '.'.
   155 ! !
   168 ! !
   156 
   169 
       
   170 !PPCCompiler methodsFor:'code generation - coding'!
       
   171 
       
   172 codeAssign: code to: variable
       
   173 	self assert: variable isNil not.
       
   174 	
       
   175 	"TODO JK: Hack alert, whatever is magic constant!!"
       
   176 	(variable == #whatever) ifFalse: [ 
       
   177 		"Do not assign, if somebody does not care!!"
       
   178 		self add: variable ,' := ', code.
       
   179  	] ifTrue: [ 
       
   180 		"In case code hava a side effect"
       
   181  		self add: code	
       
   182 	]
       
   183 !
       
   184 
       
   185 codeClearError
       
   186 	self add: 'self clearError.'.
       
   187 !
       
   188 
       
   189 codeError: errorMessage
       
   190 	self add: 'self error: ''', errorMessage, '''.'
       
   191 !
       
   192 
       
   193 codeHalt
       
   194 	self add: 'self halt. '
       
   195 !
       
   196 
       
   197 codeReturn
       
   198    currentMethod isInline ifTrue: [
       
   199 		"If inlined, the return variable already holds the value"
       
   200 	] ifFalse: [
       
   201 		self add: '^ ', currentMethod returnVariable  
       
   202    ].
       
   203 
       
   204     "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>"
       
   206 !
       
   207 
       
   208 codeReturn: code
       
   209 	" - returns whatever is in code OR
       
   210 	  - assigns whatever is in code into the returnVariable"
       
   211    currentMethod isInline ifTrue:[ 
       
   212 		self codeAssign: code to: currentMethod returnVariable. 
       
   213    ] ifFalse: [ 
       
   214 		self add: '^ ', code 		
       
   215 	]
       
   216 
       
   217     "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>"
       
   219 !
       
   220 
       
   221 codeStoreValueOf: aBlock intoVariable: aString
       
   222 	| tmpVarirable method |
       
   223 	self assert: aBlock isBlock.
       
   224 	self assert: aString isNil not.
       
   225 	
       
   226 	tmpVarirable := returnVariable.
       
   227 	returnVariable := aString.
       
   228 	method := [  
       
   229 		aBlock value 
       
   230 	] ensure: [ 
       
   231 		returnVariable := tmpVarirable 
       
   232 	].
       
   233 	
       
   234 	method isInline ifTrue: [ 
       
   235 		self callOnLine: method 
       
   236 	] ifFalse: [ 
       
   237 		self codeAssign: (method call) to: aString.
       
   238 	]	
       
   239 	
       
   240 	"Created: / 23-04-2015 / 18:21:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   241 ! !
       
   242 
   157 !PPCCompiler methodsFor:'code generation - ids'!
   243 !PPCCompiler methodsFor:'code generation - ids'!
       
   244 
       
   245 idFor: object
       
   246 	self assert: (object isKindOf: PPCNode).
       
   247 	^ self idFor: object prefixed: object prefix suffixed: object suffix effect: #none
       
   248 !
   158 
   249 
   159 idFor: object prefixed: prefix
   250 idFor: object prefixed: prefix
   160 	^ self idFor: object prefixed: prefix effect: #none
   251 	^ self idFor: object prefixed: prefix effect: #none
   161 !
   252 !
   162 
   253 
   163 idFor: object prefixed: prefix effect: effect
   254 idFor: object prefixed: prefix effect: effect
   164 	^ self idFor: object prefixed: prefix suffixed: '' effect: effect.
   255 	^ self idFor: object prefixed: prefix suffixed: '' effect: effect.
   165 !
   256 !
   166 
   257 
   167 idFor: object prefixed: prefix suffixed: suffix effect: effect
   258 idFor: object prefixed: prefix suffixed: suffix effect: effect
   168 	| body id |
   259 	| name id |
   169 	
       
   170 	"Halt if: [ (object isKindOf: PPCNode) and: [object name = #smalltalk_ws ] ]."
       
   171 	
       
   172 "	((object isKindOf: PPCNode) and: [object name = #smalltalk_ws ])  ifTrue: [ Transcript crShow: 'st_ws' ].
       
   173 "	
       
   174 	^ ids at: object ifAbsentPut: [ 
   260 	^ ids at: object ifAbsentPut: [ 
   175 		((object isKindOf: PPCNode) and: [object name isNotNil]) ifTrue: [ 
   261 		((object isKindOf: PPCNode) and: [object name isNotNil]) ifTrue: [ 
   176 			"Halt if: [ object name = #smalltalk_ws ]."
   262 			"Do not use prefix, if there is a name"
   177 "			(object name = #smalltalk_ws) ifTrue: [Transcript crShow: 'NEW st_ws'].
   263 			name := object name asLegalSelector.
   178 "			
   264 			id := (name, suffix) asSymbol.
   179 			id := (object name, suffix) asSymbol.
   265 			
   180 			"Make sure, that the generated ID is uniqe!!"
   266 			"Make sure, that the generated ID is uniqe!!"
   181 			((ids values select: [ :e | e = id ]) isEmpty) ifTrue: [ id ]
   267 			(ids includes: id) ifTrue: [ 
   182 			ifFalse: [ 
   268 				(id, '_', ids size asString) asSymbol 
   183 				body := ids size asString.
   269 			] ifFalse: [ 
   184 				(id, '_', body) asSymbol 
   270 				id
   185 			]
   271 			]
   186 		] ifFalse: [ 
   272 		] ifFalse: [ 
   187 			body := ids size asString.
   273 			(prefix, '_', (ids size asString), suffix) asSymbol
   188 			(prefix asString, '_', body, suffix) asSymbol
       
   189 		]
   274 		]
   190 	]
   275 	]
   191 ! !
   276 ! !
   192 
   277 
   193 !PPCCompiler methodsFor:'code generation - support'!
   278 !PPCCompiler methodsFor:'code generation - support'!
   201 !
   286 !
   202 
   287 
   203 checkCache: id
   288 checkCache: id
   204 	| method  |
   289 	| method  |
   205 	"Check if method is hand written"
   290 	"Check if method is hand written"
   206 	method := compiledParser compiledMethodAt: id ifAbsent: [ nil ].
   291 	method := compiledParser ifNotNil: [ compiledParser compiledMethodAt: id ifAbsent: [ nil ] ].
   207 	method ifNotNil: [ ^ PPCCompiledMethod new id: id; yourself ].
   292 	method ifNotNil: [ ^ PPCCompiledMethod new id: id; yourself ].
   208 	
   293 	
   209 	^ self cachedValue: id
   294 	^ self cachedValue: id
   210 !
   295 !
   211 
   296 
   212 pop
   297 pop
   213         | retval |
   298 	| retval |
   214         retval := compilerStack pop.
   299 	retval := compilerStack pop.
   215         compilerStack isEmpty ifFalse: [ currentMethod := compilerStack top ].
   300 	currentMethod := compilerStack isEmpty 
   216         ^ retval
   301 		ifTrue: [ nil ]
       
   302 		ifFalse: [ compilerStack top ].
       
   303 	^ retval
   217 
   304 
   218     "Modified: / 21-11-2014 / 12:27:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   305     "Modified: / 21-11-2014 / 12:27:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   219 !
   306 !
   220 
   307 
   221 push
   308 push
   224 
   311 
   225     "Modified: / 21-11-2014 / 12:27:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   312     "Modified: / 21-11-2014 / 12:27:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   226 !
   313 !
   227 
   314 
   228 startInline: id
   315 startInline: id
   229 	| sender |	
   316 	(cache includesKey: id) ifTrue: [ self error: 'OOOUPS!!' ].
   230 	
   317 
   231 	currentMethod := PPCInlinedMethod new.
   318 	currentMethod := PPCInlinedMethod new.
   232 	currentMethod id: id.	
   319 	currentMethod id: id.   
   233 	currentMethod profile: self profile.
   320 	currentMethod profile: arguments profile.
       
   321 	currentMethod returnVariable: returnVariable.
   234 	self push.
   322 	self push.
   235 	
   323 
   236 	
   324     "Modified: / 23-04-2015 / 18:28:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   237 	sender := thisContext sender receiver.
       
   238 	self addComment: 'START inlining by ', sender asString.
       
   239 !
   325 !
   240 
   326 
   241 startMethod: id
   327 startMethod: id
   242 	|  sender |
       
   243 	(cache includesKey: id) ifTrue: [ self error: 'OOOUPS!!' ].
   328 	(cache includesKey: id) ifTrue: [ self error: 'OOOUPS!!' ].
   244 	
   329 
   245 	currentMethod := PPCMethod new.
   330 	currentMethod := PPCMethod new.
   246 	currentMethod id: id.
   331 	currentMethod id: id.
   247 	currentMethod profile: self profile.	
   332 	currentMethod profile: arguments profile.    
   248 	self push.	
   333 	self push.      
   249 		
   334                 
   250 	self cache: id as: currentMethod.
   335 	self cache: id as: currentMethod.
   251 	
   336 
   252 	sender := thisContext sender receiver.
   337     "Modified: / 23-04-2015 / 18:36:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   253 	self addComment: 'START of method generated by ', sender asString.
       
   254 !
   338 !
   255 
   339 
   256 stopInline
   340 stopInline
   257 	| sender |
   341 
   258 	sender := thisContext sender receiver.
       
   259 	self addComment: 'STOP inlining by ', sender asString.
       
   260 	^ self pop.
   342 	^ self pop.
       
   343 
       
   344     "Modified: / 23-04-2015 / 18:28:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   261 !
   345 !
   262 
   346 
   263 stopMethod
   347 stopMethod
   264 	| sender |
       
   265 	sender := thisContext sender receiver.
       
   266 	self addComment: 'END of method generated by ', sender asString.
       
   267 
       
   268 	self cache: currentMethod methodName as: currentMethod.
   348 	self cache: currentMethod methodName as: currentMethod.
       
   349 	
       
   350 	arguments profile ifTrue: [ Transcript crShow: currentMethod code ].
   269 	^ self pop.
   351 	^ self pop.
       
   352 
       
   353     "Modified: / 23-04-2015 / 18:36:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   270 !
   354 !
   271 
   355 
   272 top
   356 top
   273 	^ compilerStack top
   357 	^ compilerStack top
   274 ! !
   358 ! !
   275 
   359 
       
   360 !PPCCompiler methodsFor:'code generation - variables'!
       
   361 
       
   362 allocateReturnVariable
       
   363     "Return a new variable to store parsed value"
       
   364 
       
   365    ^ currentMethod allocateReturnVariable 
       
   366 
       
   367     "Created: / 23-04-2015 / 17:58:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   368     "Modified (comment): / 23-04-2015 / 21:12:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   369 !
       
   370 
       
   371 allocateTemporaryVariableNamed: preferredName 
       
   372     "Allocate a new variable with (preferably) given name.
       
   373      Returns a real variable name that should be used."
       
   374     
       
   375     ^ self currentNonInlineMethod allocateTemporaryVariableNamed: preferredName
       
   376 
       
   377     "Created: / 23-04-2015 / 17:33:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   378 ! !
       
   379 
   276 !PPCCompiler methodsFor:'compiling'!
   380 !PPCCompiler methodsFor:'compiling'!
   277 
   381 
   278 compile: aPPParser as: name
   382 compileParser
   279 	^ self compile: aPPParser as: name params: #()
   383 	self installVariables.
   280 !
   384 	self installMethods.
   281 
   385 	self installClassConstants.
   282 compile: aPPParser as: name params: params
   386 
   283 	| parser |
   387 	^ compiledParser
   284 	parser := self copy: aPPParser.
   388 !
   285 	parser := self toCompilerTree: parser.
   389 
   286 	parser := self optimize: parser params: params.
   390 copy: parser
   287 	parser := self compileTree: parser as: name parser: aPPParser params: params.
   391 	^ parser transform: [ :p | p copy ].
   288 	^ parser
   392 !
   289 	
   393 
   290 !
   394 installClassConstants
   291 
   395 	constants keysAndValuesDo: [ :key :value |
   292 compileTree: compilerTree as: name parser: parser params: params
   396 		compiledParser constants at: key put: value
   293 	|  |
   397 	]
   294 	params do: [ :p | 
   398 !
   295 		(p key = #guards) ifTrue: [ self guards: p value ].
   399 
   296 	].	
   400 installMethods
   297 
   401 	cache keysAndValuesDo: [ :key :method |
   298 
   402 		compiledParser compileSilently: method code classified: 'generated'.
       
   403 	]
       
   404 !
       
   405 
       
   406 installVariables
       
   407 	| varString |
       
   408 	varString := constants keys inject: '' into: [:r :e | r, ' ', e  ].
       
   409 
       
   410 	PPCompiledParser 
       
   411 		subclass: compiledParserName  
       
   412 		instanceVariableNames: varString 
       
   413 		classVariableNames: '' 
       
   414 		poolDictionaries: '' 
       
   415 		category: 'PetitCompiler-Generated'.
       
   416 
       
   417 	compiledParser := Smalltalk at: compiledParserName.
       
   418 !
       
   419 
       
   420 precomputeFirstSets: root
       
   421 	| firstSets |
       
   422 	firstSets := root firstSets.
       
   423 	
       
   424 	root allNodesDo: [ :node |
       
   425 		node firstSet: (firstSets at: node).
       
   426 	]
       
   427 	
       
   428 !
       
   429 
       
   430 precomputeFollowSets: root
       
   431 	| followSets |
       
   432 	followSets := root followSets.
       
   433 	
       
   434 	root allNodesDo: [ :node |
       
   435 		node followSet: (followSets at: node).
       
   436 	]
       
   437 	
       
   438 !
       
   439 
       
   440 precomputeFollowSetsWithTokens: root
       
   441 	| followSets |
       
   442 	followSets := root followSetsSuchThat: [:e | e isTerminal or: [ e isKindOf: PPCTrimmingTokenNode ]].
       
   443 	
       
   444 	root allNodesDo: [ :node |
       
   445 		node followSetWithTokens: (followSets at: node).
       
   446 	]
       
   447 	
       
   448 !
       
   449 
       
   450 toCompilerTree: parser
       
   451 	^ parser asCompilerTree
       
   452 ! !
       
   453 
       
   454 !PPCCompiler methodsFor:'initialization'!
       
   455 
       
   456 initializeForCompiledClassName: aString
       
   457 	
       
   458 	self initialize.
       
   459 	compilerStack := Stack new.
       
   460 	cache := IdentityDictionary new.
       
   461 	constants := IdentityDictionary new.
       
   462 	ids := IdentityDictionary new.
       
   463 	
       
   464 
       
   465 	compiledParserName := aString asSymbol.
       
   466 	
   299 	((Smalltalk respondsTo:#isSmalltalkX) and:[ Smalltalk isSmalltalkX ]) ifTrue:[
   467 	((Smalltalk respondsTo:#isSmalltalkX) and:[ Smalltalk isSmalltalkX ]) ifTrue:[
   300 		| rPackageOrganizer |
   468 		| rPackageOrganizer |
   301 		rPackageOrganizer := Smalltalk at: #RPackageOrganizer.
   469 		rPackageOrganizer := Smalltalk at: #RPackageOrganizer.
   302 		rPackageOrganizer notNil ifTrue:[
   470 		rPackageOrganizer notNil ifTrue:[
   303 			rPackageOrganizer default registerPackageNamed: 'PetitCompiler-Generated'.
   471 			rPackageOrganizer default registerPackageNamed: 'PetitCompiler-Generated'.
   304 		].
   472 		].
   305 
       
   306       compiledParser := (Smalltalk at: name ifAbsent: [ nil ]).
       
   307       compiledParser ifNil: [ 
       
   308                 PPCompiledParser subclass: name
       
   309                    instanceVariableNames:''
       
   310                    classVariableNames:''
       
   311                    poolDictionaries:''
       
   312                    category:'PetitCompiler-Generated'.                
       
   313                 compiledParser := Smalltalk at: name.
       
   314       ] ifNotNil: [ 
       
   315                 self clean: compiledParser 
       
   316       ].      		
       
   317 	] ifFalse: [ 
   473 	] ifFalse: [ 
   318 		RPackageOrganizer default registerPackageNamed: 'PetitCompiler-Generated'.
   474 		RPackageOrganizer default registerPackageNamed: 'PetitCompiler-Generated'.
   319 		compiledParser := (Smalltalk at: name ifAbsent: [ nil ]).
       
   320 		compiledParser ifNil: [ 
       
   321 							PPCompiledParser subclass: name.
       
   322 							compiledParser := Smalltalk at: name.
       
   323 							compiledParser category: 'PetitCompiler-Generated'							
       
   324 							] ifNotNil: [ 
       
   325 								self clean: compiledParser 
       
   326 							].	
       
   327 	].
   475 	].
   328 	compiledParser constants removeAll.
   476 
   329 	
   477 	Smalltalk at: compiledParserName ifPresent: [ :class |
   330 	rootNode := compilerTree.
   478 		compiledParser := class.
   331 	self precomputeFirstSets: rootNode.
   479 		self clean: compiledParser.
   332 	self precomputeFollowSets: rootNode.
   480 	].
   333 	self precomputeFollowSetsWithTokens: rootNode.
       
   334 	
       
   335 	self startMethod: #start.
       
   336 	self add: '^ '.
       
   337 	self callOnLine: (compilerTree compileWith: self).
       
   338 	self stopMethod.
       
   339 
       
   340 	self installVariablesAndMethods.
       
   341 
       
   342 	compiledParser referringParser: parser.
       
   343 	^ compiledParser
       
   344 !
       
   345 
       
   346 copy: parser
       
   347 	^ parser transform: [ :p | p copy ].
       
   348 !
       
   349 
       
   350 installMethods: class
       
   351 	cache keysAndValuesDo: [ :key :method |
       
   352 		class compileSilently: method code classified: 'generated'.
       
   353 	]
       
   354 !
       
   355 
       
   356 installMethodsAndVariables: class
       
   357 	self installVariables: class.
       
   358 	self installMethods: class.	
       
   359 	
       
   360 !
       
   361 
       
   362 installVariables: class
       
   363 	| string |
       
   364 	string := class constants keys inject: '' into: [:r :e | r, ' ', e  ].
       
   365 	PPCompiledParser subclass: class name instanceVariableNames: string classVariableNames: '' poolDictionaries: '' category: 'PetitCompiler-Generated'.
       
   366 !
       
   367 
       
   368 installVariablesAndMethods
       
   369     "Updates the class and compile generated code"
       
   370 
       
   371     | compiledParserClassName |
       
   372 
       
   373     compiledParserClassName := compiledParser name.
       
   374     self installVariables: compiledParser.
       
   375     "Now we have to refetch the class again. The reason is, that
       
   376     in (at least) Smalltalk/X modyfing a layout of a class results
       
   377     in creating a new class rather than updating an old one and migrating
       
   378     instances. Therefore, to install methods in in correct class, we have
       
   379     to refetch new version from system dictionary. On Pharo it should not harm."
       
   380     compiledParser := Smalltalk at: compiledParserClassName.
       
   381 
       
   382     self installMethods: compiledParser.
       
   383 !
       
   384 
       
   385 optimize: parser params: params
       
   386 	| retval |
       
   387 	retval := parser optimizeTree: params.
       
   388 	retval checkTree.
       
   389 	^ retval
       
   390 !
       
   391 
       
   392 precomputeFirstSets: root
       
   393 	| firstSets |
       
   394 	firstSets := root firstSets.
       
   395 	
       
   396 	root allNodesDo: [ :node |
       
   397 		node firstSet: (firstSets at: node).
       
   398 	]
       
   399 	
       
   400 !
       
   401 
       
   402 precomputeFollowSets: root
       
   403 	| followSets |
       
   404 	followSets := root followSets.
       
   405 	
       
   406 	root allNodesDo: [ :node |
       
   407 		node followSet: (followSets at: node).
       
   408 	]
       
   409 	
       
   410 !
       
   411 
       
   412 precomputeFollowSetsWithTokens: root
       
   413 	| followSets |
       
   414 	followSets := root followSetsSuchThat: [:e | e isTerminal or: [ e isKindOf: PPCTrimmingTokenNode ]].
       
   415 	
       
   416 	root allNodesDo: [ :node |
       
   417 		node followSetWithTokens: (followSets at: node).
       
   418 	]
       
   419 	
       
   420 !
       
   421 
       
   422 toCompilerTree: parser
       
   423 	^ parser asCompilerTree
       
   424 ! !
       
   425 
       
   426 !PPCCompiler methodsFor:'guard'!
       
   427 
       
   428 guards
       
   429 	^ guards
       
   430 !
       
   431 
       
   432 guards: aBoolean
       
   433 	guards := aBoolean
       
   434 ! !
       
   435 
       
   436 !PPCCompiler methodsFor:'initialization'!
       
   437 
       
   438 initialize
       
   439 	super initialize.
       
   440 	compilerStack := Stack new.
       
   441 	cache := IdentityDictionary new.
       
   442 	ids := Dictionary new.
       
   443 	
       
   444 	tokenMode := false.
       
   445 	inlining := true.
       
   446 	profile := false.
       
   447 	guards := true.
       
   448 ! !
   481 ! !
   449 
   482 
   450 !PPCCompiler class methodsFor:'documentation'!
   483 !PPCCompiler class methodsFor:'documentation'!
   451 
   484 
   452 version_HG
   485 version_HG