compiler/PPCCompiler.st
changeset 422 116d2b2af905
parent 421 7e08b31e0dae
child 428 b879012e366e
equal deleted inserted replaced
421:7e08b31e0dae 422:116d2b2af905
     1 "{ Package: 'stx:goodies/petitparser/compiler' }"
     1 "{ Package: 'stx:goodies/petitparser/compiler' }"
       
     2 
       
     3 "{ NameSpace: Smalltalk }"
     2 
     4 
     3 Object subclass:#PPCCompiler
     5 Object subclass:#PPCCompiler
     4 	instanceVariableNames:'compilerStack compiledParser cache inlining debug profile
     6 	instanceVariableNames:'compilerStack compiledParser cache inlining debug profile
     5 		currentMethod guards ids tokenMode rootNode'
     7 		currentMethod guards ids tokenMode rootNode'
     6 	classVariableNames:''
     8 	classVariableNames:''
    16 
    18 
    17     ^ self basicNew initialize.
    19     ^ self basicNew initialize.
    18 ! !
    20 ! !
    19 
    21 
    20 !PPCCompiler methodsFor:'accessing'!
    22 !PPCCompiler methodsFor:'accessing'!
    21 
       
    22 fastMode
       
    23 	^ tokenMode
       
    24 !
       
    25 
    23 
    26 inlining
    24 inlining
    27 	^ inlining
    25 	^ inlining
    28 !
    26 !
    29 
    27 
   112 
   110 
   113 addVariable: name
   111 addVariable: name
   114 	currentMethod addVariable: name.
   112 	currentMethod addVariable: name.
   115 !
   113 !
   116 
   114 
   117 allowInline
       
   118 	currentMethod allowInline
       
   119 !
       
   120 
       
   121 cache: id as: value
       
   122 	cache at: id put: value.
       
   123 !
       
   124 
       
   125 cachedValue: id
       
   126 	^ cache at: id ifAbsent: [ nil ]
       
   127 !
       
   128 
       
   129 call: anotherMethod
   115 call: anotherMethod
   130 	currentMethod add: anotherMethod call.
   116 	currentMethod add: anotherMethod call.
   131 !
   117 !
   132 
   118 
   133 callOnLine: anotherMethod
   119 callOnLine: anotherMethod
   164 smartRestore: parser from: mementoName
   150 smartRestore: parser from: mementoName
   165 	parser isContextFree ifTrue: [ 
   151 	parser isContextFree ifTrue: [ 
   166 		^ 'context lwRestore: ', mementoName, '.'.
   152 		^ 'context lwRestore: ', mementoName, '.'.
   167 	].
   153 	].
   168 	^ 'context restore: ', mementoName, '.'.
   154 	^ 'context restore: ', mementoName, '.'.
   169 !
       
   170 
       
   171 startTokenMode
       
   172 	tokenMode := true
       
   173 !
       
   174 
       
   175 stopTokenMode
       
   176 	tokenMode := false
       
   177 ! !
   155 ! !
   178 
   156 
   179 !PPCCompiler methodsFor:'code generation - ids'!
   157 !PPCCompiler methodsFor:'code generation - ids'!
   180 
   158 
   181 idFor: object prefixed: prefix
   159 idFor: object prefixed: prefix
   211 		]
   189 		]
   212 	]
   190 	]
   213 ! !
   191 ! !
   214 
   192 
   215 !PPCCompiler methodsFor:'code generation - support'!
   193 !PPCCompiler methodsFor:'code generation - support'!
       
   194 
       
   195 cache: id as: value
       
   196 	cache at: id put: value.
       
   197 !
       
   198 
       
   199 cachedValue: id
       
   200 	^ cache at: id ifAbsent: [ nil ]
       
   201 !
   216 
   202 
   217 checkCache: id
   203 checkCache: id
   218 	| method  |
   204 	| method  |
   219 	"Check if method is hand written"
   205 	"Check if method is hand written"
   220 	method := compiledParser compiledMethodAt: id ifAbsent: [ nil ].
   206 	method := compiledParser compiledMethodAt: id ifAbsent: [ nil ].
   431 	^ parser asCompilerTree
   417 	^ parser asCompilerTree
   432 ! !
   418 ! !
   433 
   419 
   434 !PPCCompiler methodsFor:'guard'!
   420 !PPCCompiler methodsFor:'guard'!
   435 
   421 
   436 addSequenceGuard: parser
       
   437 
       
   438 	| firsts  guardSet guardSetId |
       
   439 	(self guards not or: [(guardSet := self guardCharSet: parser) isNil]) ifTrue: [ ^ self].
       
   440 
       
   441 	firsts := (parser firstSetSuchThat: [ :e | (e isKindOf: PPTokenParser) or: [ e isTerminal ] ]).
       
   442 	
       
   443 	"If we start with PPTokenParser, we should invoke the whitespace parser"
       
   444 	(firsts allSatisfy: [ :e | e isKindOf: PPTokenParser ]) ifTrue: [  
       
   445 		guardSetId := (self idFor: guardSet prefixed: #guard).
       
   446 		self addConstant: guardSet as: guardSetId.
       
   447 		self add: 'wsParser parseOn: context.'.
       
   448 		self add: 'context atEnd ifTrue: [ ^ self error ].'.
       
   449 		self add: '(', guardSetId, ' value: context peek) ifFalse: [ ^ self error ].'.
       
   450 	].
       
   451 
       
   452 	(firsts allSatisfy: [ :e | e isTerminal ]) ifTrue: [  
       
   453 		guardSetId := (self idFor: guardSet prefixed: #guard).
       
   454 		self addConstant: guardSet as: guardSetId.
       
   455 		self add: 'context atEnd ifTrue: [ ^ self error ].'.
       
   456 		self add: '(', guardSetId, ' value: context peek) ifFalse: [ ^ self error ].'.
       
   457 	].
       
   458 !
       
   459 
       
   460 guardCharSet: parser
       
   461 	| fs charSet   |
       
   462 	"No Guards fro trimming parser so far"
       
   463 	(parser firstSetSuchThat: [ :e | e isKindOf: PPCTrimNode ]) isEmpty ifFalse: [ ^ nil ].
       
   464 
       
   465 	"Makes no sense to do guard for epsilon parse"
       
   466 	(parser acceptsEpsilon) ifTrue: [ ^ nil ].
       
   467 
       
   468 	fs := parser firstSet.
       
   469 	fs do: [ :p |
       
   470 		"If we can accept epsilon guard does not make sense"
       
   471 		p isNullable ifTrue: [ ^ nil ].
       
   472 	].
       
   473 	
       
   474 	charSet := PPCharSetPredicate on: [:char | fs anySatisfy: [:e | (e firstCharParser parse: char asString) isPetitFailure not ]].
       
   475 	^ charSet
       
   476 !
       
   477 
       
   478 guards
   422 guards
   479 	^ guards
   423 	^ guards
   480 !
   424 !
   481 
   425 
   482 guards: aBoolean
   426 guards: aBoolean