compiler/PPCSequenceNode.st
changeset 391 553a5456963b
child 392 9b297f0d949c
equal deleted inserted replaced
390:17ba167b8ee1 391:553a5456963b
       
     1 "{ Package: 'stx:goodies/petitparser/compiler' }"
       
     2 
       
     3 PPCListNode subclass:#PPCSequenceNode
       
     4 	instanceVariableNames:''
       
     5 	classVariableNames:''
       
     6 	poolDictionaries:''
       
     7 	category:'PetitCompiler-Nodes'
       
     8 !
       
     9 
       
    10 PPCSequenceNode comment:''
       
    11 !
       
    12 
       
    13 !PPCSequenceNode methodsFor:'accessing'!
       
    14 
       
    15 prefix
       
    16 	^ #seq
       
    17 ! !
       
    18 
       
    19 !PPCSequenceNode methodsFor:'analysis'!
       
    20 
       
    21 acceptsEpsilon
       
    22 	^ self acceptsEpsilonOpenSet: IdentitySet new.
       
    23 !
       
    24 
       
    25 acceptsEpsilonOpenSet: set
       
    26 	set add: self.
       
    27 	^ self children allSatisfy: [:e | e acceptsEpsilonOpenSet: set ]
       
    28 !
       
    29 
       
    30 firstSetSuchThat: block into: aCollection openSet: aSet
       
    31 	(aSet includes: self) ifTrue: [ ^ aCollection ].
       
    32 	aSet add: self.
       
    33 	
       
    34 	(block value: self) ifTrue: [ aCollection add: self. ^ aCollection ].
       
    35 	
       
    36 	self children do: [ :child | 
       
    37 		child firstSetSuchThat: block into: aCollection openSet: aSet.
       
    38 		child acceptsEpsilon ifFalse: [ ^ aCollection ]
       
    39 	].
       
    40 	^ aCollection
       
    41 ! !
       
    42 
       
    43 !PPCSequenceNode methodsFor:'compiling'!
       
    44 
       
    45 addGuard: compiler id: id
       
    46 	|  guard firsts |
       
    47 	(compiler guards not or: [(guard := PPCGuard on: self) makesSense not]) ifTrue: [ ^ self].
       
    48 
       
    49 	firsts := (self firstSetSuchThat: [ :e | (e isKindOf: PPCTrimmingTokenNode) or: [ e isTerminal ] ]).
       
    50 
       
    51 	
       
    52 	(firsts allSatisfy: [ :e | e isKindOf: PPCTrimmingTokenNode ]) ifTrue: [  
       
    53 		"If we start with trimming, we should invoke the whitespace parser"
       
    54 		firsts anyOne compileWhitespace: compiler.
       
    55 		
       
    56 		compiler add: 'context atEnd ifTrue: [ ^ self error ].'.
       
    57 		guard id: id, '_guard'.
       
    58 		guard compileGuard: compiler.
       
    59 		compiler addOnLine: 'ifFalse: [ ^ self error ].'
       
    60 	].
       
    61 
       
    62 	(firsts allSatisfy: [ :e | e isTerminal ]) ifTrue: [  
       
    63 		compiler add: 'context atEnd ifTrue: [ ^ self error ].'.
       
    64 		guard id: id, '_guard'.
       
    65 		guard compileGuard: compiler.
       
    66 		compiler addOnLine: 'ifFalse: [ ^ self error ].'
       
    67 	].
       
    68 !
       
    69 
       
    70 compileWith: compiler effect: effect id: id
       
    71 	compiler startMethod: id.
       
    72 	compiler addVariable: 'retval'.
       
    73 	compiler addVariable: 'element'.
       
    74 	compiler addVariable: 'memento'.			
       
    75 	compiler add: (compiler smartRemember: self).
       
    76 	compiler add: 'retval := Array new: ', children size asString, '.'.
       
    77 	self addGuard: compiler id: id.
       
    78 
       
    79 	(1 to: children size) do: [ :idx  | |child|
       
    80 		child := children at: idx.
       
    81 		compiler add: 'element := '.
       
    82 		compiler callOnLine: (child compileWith: compiler).
       
    83 	
       
    84 		compiler add: 'error ifTrue: [ ', (compiler smartRestore: self) ,' ^ failure ].'.
       
    85 		compiler add: 'retval at: ', idx asString, ' put: element.'.
       
    86 	].
       
    87 	compiler add: '^ retval'.
       
    88  ^ compiler stopMethod.
       
    89 ! !
       
    90 
       
    91 !PPCSequenceNode methodsFor:'optimizing'!
       
    92 
       
    93 asFast
       
    94 	^ PPCTokenSequenceNode new
       
    95 		children: children;
       
    96 		name: self name;
       
    97 		yourself
       
    98 ! !
       
    99