151 ! ! |
151 ! ! |
152 |
152 |
153 !PPCCodeGenerator methodsFor:'traversing - caching'! |
153 !PPCCodeGenerator methodsFor:'traversing - caching'! |
154 |
154 |
155 cache: node value: retval |
155 cache: node value: retval |
156 "this is compiler thing, not mine" |
156 "this is compiler thing, not mine" |
157 ! |
157 ! |
158 |
158 |
159 cachedDetected: node |
159 cachedDetected: node |
160 ^ compiler checkCache: (compiler idFor: node) |
160 ^ compiler checkCache: (compiler idFor: node) |
161 ! |
161 ! |
162 |
162 |
163 isCached: node |
163 isCached: node |
164 ^ (compiler checkCache: (compiler idFor: node)) isNil not |
164 ^ (compiler checkCache: (compiler idFor: node)) isNil not |
165 ! ! |
165 ! ! |
166 |
166 |
167 !PPCCodeGenerator methodsFor:'visiting'! |
167 !PPCCodeGenerator methodsFor:'visiting'! |
168 |
168 |
169 visitActionNode: node |
169 visitActionNode: node |
170 compiler addConstant: node block as: (compiler idFor: node). |
170 | blockId | |
|
171 |
|
172 blockId := 'block_', (compiler idFor: node). |
|
173 compiler addConstant: node block as: blockId. |
171 |
174 |
172 compiler addVariable: 'element'. |
175 compiler codeStoreValueOf: [ self visit: node child ] intoVariable: self retvalVar. |
173 compiler add: 'element := '. |
176 compiler add: 'error ifFalse: ['. |
174 compiler callOnLine: (self visit: node child). |
177 compiler codeReturn: blockId, ' value: ', self retvalVar. |
175 compiler add: 'error ifFalse: [ ^ ', (compiler idFor: node), ' value: element ].'. |
178 compiler add: '] ifTrue: ['. |
176 compiler add: '^ failure'. |
179 compiler codeReturn: 'failure'. |
|
180 compiler add: '].'. |
177 |
181 |
178 "Modified: / 23-04-2015 / 15:59:00 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
182 "Modified: / 23-04-2015 / 15:59:00 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
179 ! |
183 ! |
180 |
184 |
181 visitAndNode: node |
185 visitAndNode: node |
182 | mementoVar | |
186 | mementoVar | |
183 |
187 |
184 mementoVar := compiler allocateTemporaryVariableNamed: 'memento'. |
188 mementoVar := compiler allocateTemporaryVariableNamed: 'memento'. |
185 compiler add: (compiler smartRemember: node child to: mementoVar). |
189 compiler smartRemember: node child to: mementoVar. |
186 |
190 |
187 compiler codeStoreValueOf: [ self visit: node child ] intoVariable: self retvalVar. |
191 compiler codeStoreValueOf: [ self visit: node child ] intoVariable: self retvalVar. |
188 compiler add: (compiler smartRestore: node child from: mementoVar). |
192 compiler smartRestore: node child from: mementoVar. |
189 |
193 |
190 compiler codeReturn. |
194 compiler codeReturn. |
191 |
195 |
192 "Modified: / 23-04-2015 / 15:59:07 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
196 "Modified: / 23-04-2015 / 15:59:07 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
193 ! |
197 ! |
194 |
198 |
195 visitAnyNode: node |
199 visitAnyNode: node |
196 |
200 |
197 compiler codeReturn: 'context next ifNil: [ error := true. ].'. |
201 compiler codeReturn: 'context next ifNil: [ error := true. ].'. |
198 |
202 |
199 "Modified: / 23-04-2015 / 20:52:15 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
203 "Modified: / 23-04-2015 / 20:52:15 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
200 ! |
204 ! |
201 |
205 |
202 visitCharSetPredicateNode: node |
206 visitCharSetPredicateNode: node |
203 |
207 |
204 | classification classificationId | |
208 | classification classificationId | |
205 classification := node extendClassification: node predicate classification. |
209 classification := node extendClassification: node predicate classification. |
206 classificationId := compiler idFor: classification prefixed: #classification. |
210 classificationId := compiler idFor: classification prefixed: #classification. |
207 compiler addConstant: classification as: classificationId. |
211 compiler addConstant: classification as: classificationId. |
208 |
212 |
209 compiler addOnLine: '(', classificationId, ' at: context peek asInteger)'. |
213 compiler add: '(', classificationId, ' at: context peek asInteger)'. |
210 compiler indent. |
214 compiler indent. |
211 compiler add: 'ifFalse: [ self error: ''predicate not found'' ]'. |
215 compiler add: 'ifFalse: [ self error: ''predicate not found'' ]'. |
212 compiler add: 'ifTrue: [ '. |
216 compiler add: 'ifTrue: [ '. |
213 compiler codeReturn: 'context next'. |
217 compiler codeReturn: 'context next'. |
214 compiler add: '].'. |
218 compiler add: '].'. |
215 compiler dedent. |
219 compiler dedent. |
216 ! |
220 ! |
217 |
221 |
218 visitCharacterNode: node |
222 visitCharacterNode: node |
219 | chid | |
223 | chid | |
220 node character ppcPrintable ifTrue: [ |
224 node character ppcPrintable ifTrue: [ |
221 chid := node character storeString |
225 chid := node character storeString |
222 ] ifFalse: [ |
226 ] ifFalse: [ |
223 chid := compiler idFor: node character prefixed: #char. |
227 chid := compiler idFor: node character prefixed: #char. |
224 compiler addConstant: (Character value: node character asInteger) as: chid . |
228 compiler addConstant: (Character value: node character asInteger) as: chid . |
225 ]. |
229 ]. |
226 |
230 |
227 compiler add: '(context peek == ', chid, ')'. |
231 compiler add: '(context peek == ', chid, ')'. |
228 compiler indent. |
232 compiler indent. |
229 compiler add: 'ifFalse: [ self error: ''', node character asInteger asString, ' expected'' at: context position ] '. |
233 compiler add: 'ifFalse: [ self error: ''', node character asInteger asString, ' expected'' at: context position ] '. |
230 compiler add: 'ifTrue: [ '. |
234 compiler add: 'ifTrue: [ '. |
231 compiler codeReturn: 'context next'. |
235 compiler codeReturn: 'context next'. |
232 compiler add: '].'. |
236 compiler add: '].'. |
233 compiler dedent. |
237 compiler dedent. |
234 ! |
238 ! |
235 |
239 |
236 visitChild: child of: node |
240 visitChild: child of: node |
237 | | |
241 | | |
238 |
242 |
239 (self isOpen: child) ifTrue: [ |
243 (self isOpen: child) ifTrue: [ |
240 "already processing..." |
244 "already processing..." |
241 ^ nil |
245 ^ nil |
242 ]. |
246 ]. |
243 |
247 |
244 "TODO JK: this is is wrong,.. to tired now to fix this :(" |
248 "TODO JK: this is is wrong,.. to tired now to fix this :(" |
245 " (self isCached: child) ifTrue: [ |
249 " (self isCached: child) ifTrue: [ |
246 node replace: child with: (self cachedValue: child). |
250 node replace: child with: (self cachedValue: child). |
247 ^ nil |
251 ^ nil |
248 ]. |
252 ]. |
249 " |
253 " |
250 ^ self visit: child. |
254 ^ self visit: child. |
251 ! |
255 ! |
252 |
256 |
253 visitChoiceNode: node |
257 visitChoiceNode: node |
254 | firsts guard whitespaceConsumed | |
258 | firsts guard whitespaceConsumed elementVar | |
255 |
259 "The code is not ready for inlining" |
256 |
260 self assert: node isMarkedForInline not. |
257 whitespaceConsumed := false. |
261 |
258 firsts := (node firstSetSuchThat: [ :e | (e isKindOf: PPCTrimmingTokenNode) or: [ e isTerminal ] ]). |
262 whitespaceConsumed := false. |
|
263 firsts := node firstSetWithTokens. |
259 |
264 |
260 |
265 |
261 compiler addVariable: 'element'. |
266 elementVar := compiler allocateTemporaryVariableNamed: 'element'. |
262 "If we start with trimming token, we should invoke the whitespace parser" |
267 " |
263 (firsts allSatisfy: [ :e | e isKindOf: PPCTrimmingTokenNode ]) ifTrue: [ |
268 If we want to compile in guard and the choice starts with trimming token, |
264 self compileTokenWhitespace: firsts anyOne. |
269 we should invoke the whitespace parser |
265 whitespaceConsumed := true. |
270 " |
266 ]. |
271 (arguments guards and: [ firsts allSatisfy: [ :e | e isTrimmingTokenNode ] ]) ifTrue: [ |
|
272 self compileTokenWhitespace: firsts anyOne. |
|
273 whitespaceConsumed := true. |
|
274 ]. |
267 |
275 |
268 1 to: node children size do: [ :idx | |child allowGuard | |
276 1 to: node children size do: [ :idx | |child allowGuard | |
269 child := node children at: idx. |
277 child := node children at: idx. |
270 " allowGuard := ((child isKindOf: PPCTrimmingTokenNode) and: [ whitespaceConsumed not ]) not. |
278 allowGuard := whitespaceConsumed. |
271 " |
|
272 allowGuard := whitespaceConsumed. |
|
273 |
279 |
274 (allowGuard and: [arguments guards and: [ (guard := PPCGuard on: child) makesSense ]]) ifTrue: [ |
280 (allowGuard and: [arguments guards and: [ (guard := PPCGuard on: child) makesSense ]]) ifTrue: [ |
275 guard id: (compiler idFor: guard prefixed: #guard). |
281 guard id: (compiler idFor: guard prefixed: #guard). |
276 guard compileGuard: compiler. |
282 guard compileGuard: compiler. |
277 compiler add: ' ifTrue: [ '. |
283 compiler add: ' ifTrue: [ '. |
278 compiler indent. |
284 compiler indent. |
279 compiler add: 'self clearError.'. |
285 compiler add: 'self clearError.'. |
280 compiler codeStoreValueOf: [self visit: child] intoVariable: 'element'. |
286 compiler codeStoreValueOf: [self visit: child] intoVariable: elementVar. |
281 compiler add: 'error ifFalse: [ ^ element ].'. |
287 compiler add: 'error ifFalse: [ ^ element ].'. |
282 compiler dedent. |
288 compiler dedent. |
283 compiler add: ' ].'. |
289 compiler add: ' ].'. |
284 ] ifFalse: [ |
290 ] ifFalse: [ |
285 compiler add: 'self clearError.'. |
291 compiler add: 'self clearError.'. |
286 compiler codeStoreValueOf: [self visit: child] intoVariable: 'element'. |
292 compiler codeStoreValueOf: [self visit: child] intoVariable: elementVar. |
287 compiler add: 'error ifFalse: [ ^ element ].'. |
293 compiler add: 'error ifFalse: [ ^ element ].'. |
288 ] |
294 ] |
289 ]. |
295 ]. |
290 compiler add: '^ self error: ''no choice suitable'''. |
296 compiler add: '^ self error: ''no choice suitable'''. |
291 |
297 |
292 "Modified: / 23-04-2015 / 21:40:23 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
298 "Modified: / 23-04-2015 / 21:40:23 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
293 ! |
299 ! |
294 |
300 |
295 visitEndOfFileNode: node |
301 visitEndOfFileNode: node |
296 compiler codeReturn: 'context atEnd ifTrue: [ #EOF ] ifFalse: [ self error: ''EOF expected!!'' ].'. |
302 compiler codeReturn: 'context atEnd ifTrue: [ #EOF ] ifFalse: [ self error: ''EOF expected!!'' ].'. |
|
303 ! |
|
304 |
|
305 visitEndOfInputNode: node |
|
306 |
|
307 compiler codeStoreValueOf: [ self visit: node child ] intoVariable: self retvalVar. |
|
308 compiler add: 'context atEnd ifTrue: ['. |
|
309 compiler codeReturn. |
|
310 compiler add: '] ifFalse: ['. |
|
311 compiler codeError: 'End of input expected'. |
|
312 compiler add: ']'. |
297 ! |
313 ! |
298 |
314 |
299 visitForwardNode: node |
315 visitForwardNode: node |
300 |
316 |
301 compiler codeStoreValueOf: [ self visit: node child ] intoVariable: self retvalVar. |
317 compiler codeStoreValueOf: [ self visit: node child ] intoVariable: self retvalVar. |
302 compiler codeReturn. |
318 compiler codeReturn. |
303 ! |
319 ! |
304 |
320 |
305 visitLiteralNode: node |
321 visitLiteralNode: node |
306 | positionVar encodedLiteral | |
322 | positionVar encodedLiteral | |
307 encodedLiteral := node encodeQuotes: node literal. |
323 encodedLiteral := node encodeQuotes: node literal. |
308 positionVar := compiler allocateTemporaryVariableNamed: 'position'. |
324 positionVar := compiler allocateTemporaryVariableNamed: 'position'. |
309 |
325 |
310 compiler codeAssign: 'context position.' to: positionVar. |
326 compiler codeAssign: 'context position.' to: positionVar. |
311 compiler add: '((context next: ', node literal size asString, ') = #''', encodedLiteral, ''') ifTrue: ['. |
327 compiler add: '((context next: ', node literal size asString, ') = #''', encodedLiteral, ''') ifTrue: ['. |
312 compiler codeReturn: '#''', encodedLiteral, ''' '. |
328 compiler codeReturn: '#''', encodedLiteral, ''' '. |
313 compiler add: '] ifFalse: ['. |
329 compiler add: '] ifFalse: ['. |
314 compiler add: ' context position: ', positionVar, '.'. |
330 compiler add: ' context position: ', positionVar, '.'. |
315 compiler add: ' self error: ''', encodedLiteral, ' expected'' at: position'. |
331 compiler add: ' self error: ''', encodedLiteral, ' expected'' at: position'. |
316 compiler add: '].'. |
332 compiler add: '].'. |
317 ! |
333 ! |
318 |
334 |
319 visitMessagePredicateNode: node |
335 visitMessagePredicateNode: node |
320 compiler add: '(context peek ', node message, ') ifFalse: ['. |
336 compiler add: '(context peek ', node message, ') ifFalse: ['. |
321 compiler add: ' self error: ''predicate not found'''. |
337 compiler add: ' self error: ''predicate not found'''. |
322 compiler add: '] ifTrue: [ '. |
338 compiler add: '] ifTrue: [ '. |
323 compiler codeReturn: ' context next'. |
339 compiler codeReturn: ' context next'. |
324 compiler add: '].'. |
340 compiler add: '].'. |
325 |
341 |
326 "Modified: / 23-04-2015 / 18:39:03 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
342 "Modified: / 23-04-2015 / 18:39:03 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
327 ! |
343 ! |
328 |
344 |
329 visitNilNode: node |
345 visitNilNode: node |
330 |
346 |
331 compiler codeReturn: 'nil.'. |
347 compiler codeReturn: 'nil.'. |
332 ! |
348 ! |
333 |
349 |
334 visitNotCharSetPredicateNode: node |
350 visitNotCharSetPredicateNode: node |
335 | classificationId classification | |
351 | classificationId classification | |
336 classification := node extendClassification: node predicate classification. |
352 classification := node extendClassification: node predicate classification. |
337 classificationId := (compiler idFor: classification prefixed: #classification). |
353 classificationId := (compiler idFor: classification prefixed: #classification). |
338 compiler addConstant: classification as: classificationId. |
354 compiler addConstant: classification as: classificationId. |
339 |
355 |
340 compiler addOnLine: '(', classificationId, ' at: context peek asInteger)'. |
356 compiler addOnLine: '(', classificationId, ' at: context peek asInteger)'. |
341 compiler indent. |
357 compiler indent. |
342 compiler add: ' ifTrue: [ self error: '' predicate not expected'' ]'. |
358 compiler add: ' ifTrue: [ self error: '' predicate not expected'' ]'. |
343 compiler add: ' ifFalse: ['. |
359 compiler add: ' ifFalse: ['. |
344 compiler codeReturn: 'nil'. |
360 compiler codeReturn: 'nil'. |
345 compiler add: '].'. |
361 compiler add: '].'. |
346 compiler dedent. |
362 compiler dedent. |
347 ! |
363 ! |
348 |
364 |
349 visitNotLiteralNode: node |
365 visitNotLiteralNode: node |
350 | encodedLiteral size | |
366 | encodedLiteral size | |
351 encodedLiteral := node encodeQuotes: node literal. |
367 encodedLiteral := node encodeQuotes: node literal. |
352 size := node literal size asString. |
368 size := node literal size asString. |
353 |
369 |
354 compiler add: '((context peek: ', size, ') =#''', encodedLiteral, ''')'. |
370 compiler add: '((context peek: ', size, ') =#''', encodedLiteral, ''')'. |
355 compiler indent. |
371 compiler indent. |
356 compiler add: 'ifTrue: [ self error: ''', encodedLiteral, ' not expected'' ]'. |
372 compiler add: 'ifTrue: [ self error: ''', encodedLiteral, ' not expected'' ]'. |
357 compiler add: 'ifFalse: [ '. |
373 compiler add: 'ifFalse: [ '. |
358 compiler codeReturn: 'nil' . |
374 compiler codeReturn: 'nil' . |
359 compiler add: '].'. |
375 compiler add: '].'. |
360 compiler dedent. |
376 compiler dedent. |
361 ! |
377 ! |
362 |
378 |
363 visitNotMessagePredicateNode: node |
379 visitNotMessagePredicateNode: node |
364 compiler addOnLine: '(context peek ', node message, ')'. |
380 compiler addOnLine: '(context peek ', node message, ')'. |
365 compiler indent. |
381 compiler indent. |
366 compiler add: ' ifTrue: [ '. |
382 compiler add: ' ifTrue: [ '. |
367 compiler codeError: 'predicate not expected'. |
383 compiler codeError: 'predicate not expected'. |
368 compiler add: '] ifFalse: ['. |
384 compiler add: '] ifFalse: ['. |
369 compiler codeReturn: 'nil'. |
385 compiler codeReturn: 'nil'. |
370 compiler add: ' ].'. |
386 compiler add: ' ].'. |
371 compiler dedent. |
387 compiler dedent. |
372 ! |
388 ! |
373 |
389 |
374 visitNotNode: node |
390 visitNotNode: node |
375 |
391 | mementoVar | |
376 |
392 |
377 compiler addVariable: 'memento'. |
393 mementoVar := compiler allocateTemporaryVariableNamed: 'memento'. |
378 compiler add: (compiler smartRemember: node child). |
394 compiler smartRemember: node child to: mementoVar. |
379 |
395 |
380 compiler call: (self visit: node child). |
396 compiler codeStoreValueOf: [ self visit: node child ] intoVariable: #whatever. |
381 compiler add: (compiler smartRestore: node child). |
397 compiler smartRestore: node child from: mementoVar. |
382 |
398 |
383 compiler add: '^ error ifFalse: [ self error ] ifTrue: [ self clearError. nil ]'. |
399 compiler add: '^ error ifFalse: [ self error ] ifTrue: [ self clearError. nil ]'. |
384 ! |
400 ! |
385 |
401 |
386 visitOptionalNode: node |
402 visitOptionalNode: node |
387 compiler codeStoreValueOf: [ self visit: node child ] intoVariable: self retvalVar. |
403 compiler codeStoreValueOf: [ self visit: node child ] intoVariable: self retvalVar. |
388 compiler add: 'error ifTrue: [ '. |
404 compiler add: 'error ifTrue: [ '. |
389 compiler add: ' self clearError. '. |
405 compiler add: ' self clearError. '. |
390 compiler codeAssign: 'nil.' to: self retvalVar. |
406 compiler codeAssign: 'nil.' to: self retvalVar. |
391 compiler add: '].'. |
407 compiler add: '].'. |
392 compiler codeReturn. |
408 compiler codeReturn. |
393 ! |
409 ! |
394 |
410 |
395 visitPluggableNode: node |
411 visitPluggableNode: node |
396 | blockId | |
412 | blockId | |
397 blockId := compiler idFor: node block prefixed: #block. |
413 blockId := compiler idFor: node block prefixed: #block. |
398 |
414 |
399 compiler addConstant: node block as: blockId. |
415 compiler addConstant: node block as: blockId. |
400 compiler codeReturn: blockId, ' value: context.'. |
416 compiler codeReturn: blockId, ' value: context.'. |
401 ! |
417 ! |
402 |
418 |
403 visitPlusNode: node |
419 visitPlusNode: node |
404 | elementVar | |
420 | elementVar | |
405 |
421 |
406 elementVar := compiler allocateTemporaryVariableNamed: 'element'. |
422 elementVar := compiler allocateTemporaryVariableNamed: 'element'. |
407 |
423 |
408 compiler codeAssign: 'OrderedCollection new.' to: self retvalVar. |
424 compiler codeAssign: 'OrderedCollection new.' to: self retvalVar. |
409 compiler codeStoreValueOf: [ self visit: node child ] intoVariable: elementVar. |
425 compiler codeStoreValueOf: [ self visit: node child ] intoVariable: elementVar. |
410 |
426 |
411 compiler add: 'error ifTrue: [ self error: ''at least one occurence expected'' ] ifFalse: ['. |
427 compiler add: 'error ifTrue: [ self error: ''at least one occurence expected'' ] ifFalse: ['. |
412 compiler indent. |
428 compiler indent. |
413 compiler add: self retvalVar , ' add: ',elementVar , '.'. |
429 compiler add: self retvalVar , ' add: ',elementVar , '.'. |
414 |
430 |
415 compiler codeStoreValueOf: [ self visit: node child ] intoVariable: elementVar. |
431 compiler codeStoreValueOf: [ self visit: node child ] intoVariable: elementVar. |
416 compiler add: '[ error ] whileFalse: ['. |
432 compiler add: '[ error ] whileFalse: ['. |
417 compiler indent. |
433 compiler indent. |
418 compiler add: self retvalVar , ' add: ',elementVar , '.'. |
434 compiler add: self retvalVar , ' add: ',elementVar , '.'. |
419 compiler codeStoreValueOf: [ self visit: node child ] intoVariable: elementVar. |
435 compiler codeStoreValueOf: [ self visit: node child ] intoVariable: elementVar. |
420 compiler dedent. |
436 compiler dedent. |
421 compiler add: '].'. |
437 compiler add: '].'. |
422 compiler add: 'self clearError.'. |
438 compiler add: 'self clearError.'. |
423 compiler codeReturn: self retvalVar , ' asArray.'. |
439 compiler codeReturn: self retvalVar , ' asArray.'. |
424 compiler dedent. |
440 compiler dedent. |
425 compiler add: '].'. |
441 compiler add: '].'. |
426 |
442 |
427 "Modified (comment): / 23-04-2015 / 21:30:49 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
443 "Modified (comment): / 23-04-2015 / 21:30:49 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
428 ! |
444 ! |
429 |
445 |
430 visitPredicateNode: node |
446 visitPredicateNode: node |
431 | pid | |
447 | pid | |
432 pid := (compiler idFor: node predicate prefixed: #predicate). |
448 pid := (compiler idFor: node predicate prefixed: #predicate). |
433 |
449 |
434 compiler addConstant: node predicate as: pid. |
450 compiler addConstant: node predicate as: pid. |
435 |
451 |
436 compiler add: '(context atEnd not and: [ ', pid , ' value: context uncheckedPeek])'. |
452 compiler add: '(context atEnd not and: [ ', pid , ' value: context uncheckedPeek])'. |
437 compiler indent. |
453 compiler indent. |
438 compiler add: 'ifFalse: [ self error: ''predicate not found'' ]'. |
454 compiler add: 'ifFalse: [ self error: ''predicate not found'' ]'. |
439 compiler add: 'ifTrue: [ ', self retvalVar ,' := context next ].'. |
455 compiler add: 'ifTrue: [ ', self retvalVar ,' := context next ].'. |
440 compiler dedent. |
456 compiler dedent. |
441 compiler codeReturn. |
457 compiler codeReturn. |
442 |
458 |
443 "Modified: / 23-04-2015 / 21:48:11 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
459 "Modified: / 23-04-2015 / 21:48:11 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
444 ! |
460 ! |
445 |
461 |
|
462 visitRecognizingSequenceNode: node |
|
463 | mementoVar | |
|
464 |
|
465 mementoVar := compiler allocateTemporaryVariableNamed: 'memento'. |
|
466 compiler smartRemember: node to: mementoVar. |
|
467 |
|
468 " self addGuard: compiler." |
|
469 |
|
470 compiler codeStoreValueOf: [ self visit: (node children at: 1) ] intoVariable: #whatever. |
|
471 compiler add: 'error ifTrue: [ ^ failure ].'. |
|
472 |
|
473 2 to: (node children size) do: [ :idx | |child| |
|
474 child := node children at: idx. |
|
475 compiler codeStoreValueOf: [ self visit: child ] intoVariable: #whatever. |
|
476 compiler add: 'error ifTrue: [ '. |
|
477 compiler indent. |
|
478 compiler smartRestore: node from: mementoVar. |
|
479 compiler add: ' ^ failure .'. |
|
480 compiler dedent. |
|
481 compiler add: '].'. |
|
482 ]. |
|
483 ! |
|
484 |
446 visitSequenceNode: node |
485 visitSequenceNode: node |
447 |
486 |
448 | elementVar mementoVar | |
487 | elementVar mementoVar | |
449 |
488 |
450 elementVar := compiler allocateTemporaryVariableNamed: 'element'. |
489 elementVar := compiler allocateTemporaryVariableNamed: 'element'. |
451 mementoVar := compiler allocateTemporaryVariableNamed: 'memento'. |
490 mementoVar := compiler allocateTemporaryVariableNamed: 'memento'. |
452 |
491 |
453 compiler add: (compiler smartRemember: node to: mementoVar). |
492 compiler smartRemember: node to: mementoVar. |
454 compiler codeAssign: 'Array new: ', node children size asString, '.' to: self retvalVar. |
493 compiler codeAssign: 'Array new: ', node children size asString, '.' to: self retvalVar. |
455 self addGuard: node. |
494 self addGuard: node. |
456 |
495 |
457 1 to: (node children size) do: [ :idx | |child| |
496 1 to: (node children size) do: [ :idx | |child| |
458 child := node children at: idx. |
497 child := node children at: idx. |
459 compiler codeStoreValueOf: [ self visit: child ] intoVariable: elementVar. |
498 compiler codeStoreValueOf: [ self visit: child ] intoVariable: elementVar. |
460 |
499 |
461 compiler add: 'error ifTrue: [ ', (compiler smartRestore: node) ,' ^ failure ].'. |
500 compiler add: 'error ifTrue: [ '. |
462 compiler add: self retvalVar , ' at: ', idx asString, ' put: ',elementVar,'.'. |
501 compiler indent. |
463 ]. |
502 compiler smartRestore: node from: mementoVar. |
464 compiler codeReturn |
503 compiler add: '^ failure.'. |
|
504 compiler dedent. |
|
505 compiler add: '].'. |
|
506 compiler add: self retvalVar , ' at: ', idx asString, ' put: ',elementVar,'.'. |
|
507 ]. |
|
508 compiler codeReturn |
465 |
509 |
466 "Modified: / 23-04-2015 / 22:03:11 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
510 "Modified: / 23-04-2015 / 22:03:11 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
467 ! |
511 ! |
468 |
512 |
469 visitStarAnyNode: node |
513 visitStarAnyNode: node |
470 |
514 |
471 compiler addVariable: 'retval size'. |
515 compiler addVariable: 'retval size'. |
472 compiler add: 'size := context size - context position.'. |
516 compiler add: 'size := context size - context position.'. |
473 compiler add: 'retval := Array new: size.'. |
517 compiler add: 'retval := Array new: size.'. |
474 compiler add: '(1 to: size) do: [ :e | retval at: e put: context next ].'. |
518 compiler add: '(1 to: size) do: [ :e | retval at: e put: context next ].'. |
475 compiler add: '^ retval'. |
519 compiler add: '^ retval'. |
476 |
520 |
477 ! |
521 ! |
478 |
522 |
479 visitStarCharSetPredicateNode: node |
523 visitStarCharSetPredicateNode: node |
480 | classification classificationId | |
524 | classification classificationId | |
481 |
525 |
482 |
526 |
483 classification := node extendClassification: node predicate classification. |
527 classification := node extendClassification: node predicate classification. |
484 classificationId := compiler idFor: classification prefixed: #classification. |
528 classificationId := compiler idFor: classification prefixed: #classification. |
485 compiler addConstant: classification as: classificationId. |
529 compiler addConstant: classification as: classificationId. |
486 |
530 |
487 compiler codeAssign: 'OrderedCollection new.' to: self retvalVar. |
531 compiler codeAssign: 'OrderedCollection new.' to: self retvalVar. |
488 compiler add: '[ ', classificationId, ' at: context peek asInteger ] whileTrue: ['. |
532 compiler add: '[ ', classificationId, ' at: context peek asInteger ] whileTrue: ['. |
489 compiler indent. |
533 compiler indent. |
490 compiler add: self retvalVar, ' add: context next.'. |
534 compiler add: self retvalVar, ' add: context next.'. |
491 compiler dedent. |
535 compiler dedent. |
492 compiler add: '].'. |
536 compiler add: '].'. |
493 compiler codeReturn: 'retval asArray'. |
537 compiler codeReturn: 'retval asArray'. |
494 ! |
538 ! |
495 |
539 |
496 visitStarMessagePredicateNode: node |
540 visitStarMessagePredicateNode: node |
497 |
541 |
498 compiler codeAssign: 'OrderedCollection new.' to: self retvalVar. |
542 compiler codeAssign: 'OrderedCollection new.' to: self retvalVar. |
499 compiler add: '[ context peek ', node message, ' ] whileTrue: ['. |
543 compiler add: '[ context peek ', node message, ' ] whileTrue: ['. |
500 compiler indent. |
544 compiler indent. |
501 compiler add: self retvalVar, ' add: context next.'. |
545 compiler add: self retvalVar, ' add: context next.'. |
502 compiler dedent. |
546 compiler dedent. |
503 compiler add: '].'. |
547 compiler add: '].'. |
504 compiler codeReturn: 'retval asArray'. |
548 compiler codeReturn: 'retval asArray'. |
505 ! |
549 ! |
506 |
550 |
507 visitStarNode: node |
551 visitStarNode: node |
508 | elementVar | |
552 | elementVar | |
509 |
553 |
510 elementVar := compiler allocateTemporaryVariableNamed: 'element'. |
554 elementVar := compiler allocateTemporaryVariableNamed: 'element'. |
511 |
555 |
512 compiler codeAssign: 'OrderedCollection new.' to: self retvalVar. |
556 compiler codeAssign: 'OrderedCollection new.' to: self retvalVar. |
513 compiler codeStoreValueOf: [ self visit: node child ] intoVariable: elementVar. |
557 compiler codeStoreValueOf: [ self visit: node child ] intoVariable: elementVar. |
514 compiler add: '[ error ] whileFalse: ['. |
558 compiler add: '[ error ] whileFalse: ['. |
515 compiler indent. |
559 compiler indent. |
516 compiler add: self retvalVar, ' add: element.'. |
560 compiler add: self retvalVar, ' add: ', elementVar, '.'. |
517 compiler codeStoreValueOf: [ self visit: node child ] intoVariable: elementVar. |
561 compiler codeStoreValueOf: [ self visit: node child ] intoVariable: elementVar. |
518 compiler dedent. |
562 compiler dedent. |
519 compiler add: '].'. |
563 compiler add: '].'. |
520 compiler codeClearError. |
564 compiler codeClearError. |
521 compiler codeReturn: self retvalVar, ' asArray'. |
565 compiler codeReturn: self retvalVar, ' asArray.'. |
522 ! |
566 ! |
523 |
567 |
524 visitSymbolActionNode: node |
568 visitSymbolActionNode: node |
525 | elementVar | |
569 | elementVar | |
526 |
570 |
527 elementVar := compiler allocateTemporaryVariableNamed: 'element'. |
571 elementVar := compiler allocateTemporaryVariableNamed: 'element'. |
528 compiler codeStoreValueOf: [ self visit: node child ] intoVariable: elementVar. |
572 compiler codeStoreValueOf: [ self visit: node child ] intoVariable: elementVar. |
529 compiler add: 'error ifFalse: [ '. |
573 compiler add: 'error ifFalse: [ '. |
530 compiler codeReturn: elementVar, ' ', node block asString, '.'. |
574 compiler codeReturn: elementVar, ' ', node block asString, '.'. |
531 compiler add: '] ifTrue: ['. |
575 compiler add: '] ifTrue: ['. |
532 compiler codeReturn: 'failure'. |
576 compiler codeReturn: 'failure'. |
533 compiler add: ']'. |
577 compiler add: ']'. |
534 ! |
578 ! |
535 |
579 |
536 visitTokenActionNode: node |
580 visitTokenActionNode: node |
537 " |
581 " |
538 Actually, do nothing, we are in Token mode and the |
582 Actually, do nothing, we are in Token mode and the |
539 child does not return any result and token takes only |
583 child does not return any result and token takes only |
540 the input value. |
584 the input value. |
541 " |
585 " |
542 |
586 |
543 compiler add: '^ '. |
587 compiler add: '^ '. |
544 compiler callOnLine: (node child compileWith: compiler). |
588 compiler callOnLine: (node child compileWith: compiler). |
545 ! |
589 ! |
546 |
590 |
547 visitTokenNode: node |
591 visitTokenNode: node |
548 | startVar endVar | |
592 | startVar endVar | |
549 startVar := compiler allocateTemporaryVariableNamed: 'start'. |
593 startVar := compiler allocateTemporaryVariableNamed: 'start'. |
550 endVar := compiler allocateTemporaryVariableNamed: 'end'. |
594 endVar := compiler allocateTemporaryVariableNamed: 'end'. |
551 |
595 |
552 compiler codeAssign: 'context position + 1.' to: startVar. |
596 compiler codeAssign: 'context position + 1.' to: startVar. |
553 compiler codeStoreValueOf: [ self visit: node child ] intoVariable: #whatever. |
597 compiler codeStoreValueOf: [ self visit: node child ] intoVariable: #whatever. |
554 compiler add: 'error ifFalse: [ '. |
598 compiler add: 'error ifFalse: [ '. |
555 compiler indent. |
599 compiler indent. |
556 compiler codeAssign: 'context position.' to: endVar. |
600 compiler codeAssign: 'context position.' to: endVar. |
557 |
601 |
558 compiler codeReturn: node tokenClass asString, ' on: (context collection) |
602 compiler codeReturn: node tokenClass asString, ' on: (context collection) |
559 start: ', startVar, ' |
603 start: ', startVar, ' |
560 stop: ', endVar, ' |
604 stop: ', endVar, ' |
561 value: nil.'. |
605 value: nil.'. |
562 compiler dedent. |
606 compiler dedent. |
563 compiler add: '].'. |
607 compiler add: '].'. |
564 ! |
|
565 |
|
566 visitTokenSequenceNode: node |
|
567 |
|
568 |
|
569 compiler addVariable: 'memento'. |
|
570 compiler add: (compiler smartRemember: node). |
|
571 |
|
572 " self addGuard: compiler." |
|
573 |
|
574 compiler codeStoreValueOf: [ self visit: (node children at: 1) ] intoVariable: #whatever. |
|
575 compiler add: 'error ifTrue: [ ^ failure ].'. |
|
576 |
|
577 2 to: (node children size) do: [ :idx | |child| |
|
578 child := node children at: idx. |
|
579 compiler codeStoreValueOf: [ self visit: child ] intoVariable: #whatever. |
|
580 compiler add: 'error ifTrue: [ ', (compiler smartRestore: node) ,' ^ failure ].'. |
|
581 ]. |
|
582 ! |
608 ! |
583 |
609 |
584 visitTokenStarMessagePredicateNode: node |
610 visitTokenStarMessagePredicateNode: node |
585 |
611 |
586 compiler add: '[ context peek ', node message,' ] whileTrue: ['. |
612 compiler add: '[ context peek ', node message,' ] whileTrue: ['. |
587 compiler indent. |
613 compiler indent. |
588 compiler add: 'context next'. |
614 compiler add: 'context next'. |
589 compiler indent. |
615 compiler indent. |
590 compiler dedent. |
616 compiler dedent. |
591 compiler add: '].'. |
617 compiler add: '].'. |
592 ! |
618 ! |
593 |
619 |
594 visitTokenStarSeparatorNode: node |
620 visitTokenStarSeparatorNode: node |
595 |
621 |
596 compiler add: 'context skipSeparators.'. |
622 compiler add: 'context skipSeparators.'. |
|
623 ! |
|
624 |
|
625 visitTokenWhitespaceNode: node |
|
626 compiler codeStoreValueOf: [ self visit: node child ] intoVariable: #whatever. |
|
627 compiler codeReturn. |
597 ! |
628 ! |
598 |
629 |
599 visitTrimNode: node |
630 visitTrimNode: node |
600 | mementoVar | |
631 | mementoVar | |
601 "TODO: This ignores the TrimmingParser trimmer object!!" |
632 "TODO: This ignores the TrimmingParser trimmer object!!" |
602 |
633 |
603 mementoVar := compiler allocateTemporaryVariableNamed: 'memento'. |
634 mementoVar := compiler allocateTemporaryVariableNamed: 'memento'. |
604 |
635 |
605 compiler add: (compiler smartRemember: node child to: mementoVar). |
636 compiler smartRemember: node child to: mementoVar. |
606 compiler add: 'context skipSeparators.'. |
637 compiler add: 'context skipSeparators.'. |
607 |
638 |
608 compiler codeStoreValueOf: [ self visit: node child ] intoVariable: self retvalVar. |
639 compiler codeStoreValueOf: [ self visit: node child ] intoVariable: self retvalVar. |
609 |
640 |
610 compiler add: 'error ifTrue: [ '. |
641 compiler add: 'error ifTrue: [ '. |
611 compiler indent. |
642 compiler indent. |
612 compiler add: (compiler smartRestore: node child from: mementoVar). |
643 compiler smartRestore: node child from: mementoVar. |
613 compiler codeReturn. |
644 compiler codeReturn. |
614 compiler dedent. |
645 compiler dedent. |
615 compiler add: '] ifFalse: [' . |
646 compiler add: '] ifFalse: [' . |
616 compiler indent. |
647 compiler indent. |
617 compiler add: 'context skipSeparators.'. |
648 compiler add: 'context skipSeparators.'. |
618 compiler codeReturn. |
649 compiler codeReturn. |
619 compiler dedent. |
650 compiler dedent. |
620 compiler add: '].'. |
651 compiler add: '].'. |
621 ! |
652 ! |
622 |
653 |
623 visitTrimmingTokenNode: node |
654 visitTrimmingTokenNode: node |
624 | id guard startVar endVar | |
655 | id guard startVar endVar | |
625 |
656 |
626 startVar := compiler allocateTemporaryVariableNamed: 'start'. |
657 startVar := compiler allocateTemporaryVariableNamed: 'start'. |
627 endVar := compiler allocateTemporaryVariableNamed: 'end'. |
658 endVar := compiler allocateTemporaryVariableNamed: 'end'. |
628 |
659 |
629 id := compiler idFor: node. |
660 id := compiler idFor: node. |
630 " (id beginsWith: 'kw') ifTrue: [ self halt. ]." |
661 " (id beginsWith: 'kw') ifTrue: [ self halt. ]." |
631 "self compileFirstWhitespace: compiler." |
662 "self compileFirstWhitespace: compiler." |
632 self compileTokenWhitespace: node. |
663 self compileTokenWhitespace: node. |
633 |
664 |
634 (arguments guards and: [(guard := PPCGuard on: node) makesSense]) ifTrue: [ |
665 (arguments guards and: [(guard := PPCGuard on: node) makesSense]) ifTrue: [ |
635 compiler add: 'context atEnd ifTrue: [ ^ self error ].'. |
666 guard id: id, '_guard'. |
636 guard id: id, '_guard'. |
667 compiler add: 'context atEnd ifTrue: [ self error ].'. |
637 guard compileGuard: compiler. |
668 guard compileGuard: compiler. |
638 compiler addOnLine: 'ifFalse: [ ^ self error ].' |
669 compiler addOnLine: 'ifFalse: [ self error ].'. |
639 ]. |
670 compiler add: 'error ifFalse: ['. |
640 |
671 compiler indent. |
641 compiler codeAssign: 'context position + 1.' to: startVar. |
672 ]. |
642 compiler codeStoreValueOf: [ self visit: node child ] intoVariable: #whatever. |
673 |
643 compiler add: 'error ifFalse: [ '. |
674 compiler codeAssign: 'context position + 1.' to: startVar. |
644 compiler indent. |
675 compiler codeStoreValueOf: [ self visit: node child ] intoVariable: #whatever. |
645 compiler codeAssign: 'context position.' to: endVar. |
676 |
646 |
677 (arguments guards and: [(guard := PPCGuard on: node) makesSense]) ifTrue: [ |
|
678 compiler dedent. |
|
679 compiler add: '].'. |
|
680 ]. |
|
681 |
|
682 compiler add: 'error ifFalse: [ '. |
|
683 compiler indent. |
|
684 compiler codeAssign: 'context position.' to: endVar. |
|
685 |
647 " self compileSecondWhitespace: compiler." |
686 " self compileSecondWhitespace: compiler." |
648 self compileTokenWhitespace: node. |
687 self compileTokenWhitespace: node. |
649 |
688 |
650 compiler codeReturn: node tokenClass asString, ' on: (context collection) |
689 compiler codeReturn: node tokenClass asString, ' on: (context collection) |
651 start: ', startVar, ' |
690 start: ', startVar, ' |
652 stop: ', endVar, ' |
691 stop: ', endVar, ' |
653 value: nil'. |
692 value: nil'. |
654 compiler dedent. |
693 compiler dedent. |
655 compiler add: '].' |
694 compiler add: '].' |
656 ! |
695 ! |
657 |
696 |
658 visitUnknownNode: node |
697 visitUnknownNode: node |
659 | compiledChild compiledParser id | |
698 | compiledChild compiledParser id | |
660 |
699 |
661 id := compiler idFor: node. |
700 id := compiler idFor: node. |
662 |
701 |
663 compiledParser := node parser copy. |
702 compiledParser := node parser copy. |
664 "Compile all the children and call compiled version of them instead of the original one" |
703 "Compile all the children and call compiled version of them instead of the original one" |
665 compiledParser children do: [ :child | |
704 compiledParser children do: [ :child | |
666 compiledChild := self visit: child. |
705 compiledChild := self visit: child. |
667 compiledParser replace: child with: compiledChild bridge. |
706 compiledParser replace: child with: compiledChild bridge. |
668 ]. |
707 ]. |
669 |
708 |
670 compiler addConstant: compiledParser as: id. |
709 compiler addConstant: compiledParser as: id. |
671 |
710 |
672 compiler codeClearError. |
711 compiler codeClearError. |
673 compiler add: '(', self retvalVar, ' := ', id, ' parseOn: context) isPetitFailure'. |
712 compiler add: '(', self retvalVar, ' := ', id, ' parseOn: context) isPetitFailure'. |
674 compiler indent. |
713 compiler indent. |
675 compiler add: ' ifTrue: [self error: retval message at: ', self retvalVar, ' position ].'. |
714 compiler add: ' ifTrue: [self error: retval message at: ', self retvalVar, ' position ].'. |
676 compiler dedent. |
715 compiler dedent. |
677 compiler add: 'error := ', self retvalVar, ' isPetitFailure.'. |
716 compiler add: 'error := ', self retvalVar, ' isPetitFailure.'. |
678 compiler codeReturn. |
717 compiler codeReturn. |
679 ! ! |
718 ! ! |
680 |
719 |