# HG changeset patch # User Jan Vrany # Date 1434433526 -3600 # Node ID 0ca7a70db0f5ff9be317beb4bda1865f1bccf8b0 # Parent 19a9c25960ef499d61f1b006cf4d9becd1195d2e Fix in codegen for inlined sequence nodes. For inlined sequence nodes, generate nested ifs rather than sequential code which does not work when inlined. The reason is that #codeReturn: in inline generates instvar assignment, not method return, so in sequential code the next child of a sequence will be probed even if previous failed. If that happends, the whole sequence fail and therefore we must generate nested ifs to correctly handle this w.r.t. inlining. diff -r 19a9c25960ef -r 0ca7a70db0f5 compiler/PPCCodeGenerator.st --- a/compiler/PPCCodeGenerator.st Mon Jun 15 19:13:49 2015 +0100 +++ b/compiler/PPCCodeGenerator.st Tue Jun 16 06:45:26 2015 +0100 @@ -686,7 +686,7 @@ visitSequenceNode: node - | elementVars mementoVar canBacktrack | + | elementVars mementoVar canBacktrack coding | elementVars := node preferredChildrenVariableNames. elementVars do:[:e | @@ -708,34 +708,47 @@ compiler codeAssign: 'Array new: ', node children size asString, '.' to: self retvalVar. ]. - compiler - codeAssignParsedValueOf:[ self visit:(node children at:1) ] - to:(elementVars at:1). - compiler add: 'error ifTrue: [ ^ failure ].'. - node returnParsedObjectsAsCollection ifTrue:[ - compiler add: self retvalVar , ' at: 1 put: ', (elementVars at: 1), '.'. + coding := [ :index | + | child childValueVar | + + child := node children at: index. + childValueVar := elementVars at: index. + compiler codeAssignParsedValueOf: [ self visit:child ] + to: childValueVar. + child acceptsEpsilon ifFalse: [ + compiler codeIfErrorThen: [ + "Handle error in the first element specially" + "TODO: JK, please explain here why!!!!!!" + index == 1 ifTrue:[ + compiler add: 'error ifTrue: [ ^ failure ].'. + ] ifFalse:[ + compiler smartRestore: node from: mementoVar. + compiler codeReturn: 'failure.'. + ] + ] else:[ + node returnParsedObjectsAsCollection ifTrue:[ + compiler add: self retvalVar , ' at: ', index asString, ' put: ', childValueVar, '.'. + ]. + (index < node children size) ifTrue:[ + coding value: index + 1. + ]. + ] + + ] ifTrue:[ + node returnParsedObjectsAsCollection ifTrue:[ + compiler add: self retvalVar , ' at: ', index asString, ' put: ', childValueVar, '.'. + ]. + (index < node children size) ifTrue:[ + coding value: index + 1. + ]. + ] ]. - 2 to: (node children size) do: [ :idx | |child| - child := node children at: idx. - compiler - codeAssignParsedValueOf:[ self visit:child ] - to:(elementVars at:idx). - - child acceptsEpsilon ifFalse: [ - compiler add: 'error ifTrue: [ '. - compiler indent. - compiler smartRestore: node from: mementoVar. - compiler codeReturn: 'failure.'. - compiler dedent. - compiler add: '].'. - ]. - node returnParsedObjectsAsCollection ifTrue:[ - compiler add: self retvalVar , ' at: ', idx asString, ' put: ',(elementVars at: idx),'.'. - ]. - ]. + + coding value:1. + compiler codeReturn - "Modified: / 04-06-2015 / 23:47:52 / Jan Vrany " + "Modified (comment): / 16-06-2015 / 06:38:02 / Jan Vrany " ! visitStarAnyNode: node diff -r 19a9c25960ef -r 0ca7a70db0f5 compiler/PPCCompiler.st --- a/compiler/PPCCompiler.st Mon Jun 15 19:13:49 2015 +0100 +++ b/compiler/PPCCompiler.st Tue Jun 16 06:45:26 2015 +0100 @@ -218,6 +218,12 @@ self add: 'self clearError.'. ! +codeDot + self addOnLine:'.'. + + "Created: / 16-06-2015 / 06:09:07 / Jan Vrany " +! + codeError self add: 'self error: ''message notspecified''.'. ! @@ -270,6 +276,12 @@ "Modified: / 10-05-2015 / 07:39:47 / Jan Vrany " ! +codeIf: condition then: then + self codeIf: condition then: then else: nil + + "Created: / 16-06-2015 / 06:07:06 / Jan Vrany " +! + codeIf: condition then: then else: else currentMethod add: '('; @@ -285,8 +297,22 @@ addOnLine:' ifFalse:'; codeBlock: else. ]. + self codeDot. "Created: / 01-06-2015 / 22:43:15 / Jan Vrany " + "Modified: / 16-06-2015 / 06:09:33 / Jan Vrany " +! + +codeIfErrorThen: then + ^ self codeIf: 'error' then: then else: nil + + "Created: / 16-06-2015 / 06:06:44 / Jan Vrany " +! + +codeIfErrorThen: then else: else + ^ self codeIf: 'error' then: then else: else + + "Created: / 16-06-2015 / 06:05:56 / Jan Vrany " ! codeNextToken diff -r 19a9c25960ef -r 0ca7a70db0f5 compiler/PPCMappedActionNode.st --- a/compiler/PPCMappedActionNode.st Mon Jun 15 19:13:49 2015 +0100 +++ b/compiler/PPCMappedActionNode.st Tue Jun 16 06:45:26 2015 +0100 @@ -9,6 +9,7 @@ category:'PetitParser-Parsers' ! + !PPCMappedActionNode methodsFor:'visiting'! accept: visitor @@ -17,3 +18,10 @@ "Created: / 02-06-2015 / 17:27:54 / Jan Vrany " ! ! +!PPCMappedActionNode class methodsFor:'documentation'! + +version_HG + + ^ '$Changeset: $' +! ! + diff -r 19a9c25960ef -r 0ca7a70db0f5 compiler/tests/PPCCodeGeneratorTest.st --- a/compiler/tests/PPCCodeGeneratorTest.st Mon Jun 15 19:13:49 2015 +0100 +++ b/compiler/tests/PPCCodeGeneratorTest.st Tue Jun 16 06:45:26 2015 +0100 @@ -488,6 +488,45 @@ "Created: / 15-06-2015 / 18:27:18 / Jan Vrany " ! +testMappedNode3 + node := ((#letter asParser , #letter asParser) + ==> [:nodes | String with:(nodes first) with:(nodes second) ]) asCompilerTree. + node child markForInline. + + self compileTree:node. + + self assert:parser parse:'ab' to:'ab'. + self assert:parser parse:'cz' to:'cz'. + self assert:parser fail:''. + + "Created: / 16-06-2015 / 06:01:53 / Jan Vrany " +! + +testMappedNode4 + node := ((#letter asParser , #letter asParser) + ==> [:nodes | String with:(nodes first) with:(nodes second) ]) asCompilerTree. + node child markForInline. + + self compileTree:node. + + self assert:parser fail:'a'. + + "Created: / 16-06-2015 / 06:13:37 / Jan Vrany " +! + +testMappedNode5 + node := ((#letter asParser , #letter asParser optional) + ==> [:nodes | String with:(nodes first) with:((nodes second) isNil ifTrue:[$?] ifFalse:[nodes second]) ]) asCompilerTree. + node child markForInline. + + self compileTree:node. + + self assert:parser parse:'cz' to:'cz'. + self assert:parser parse:'c' to:'c?'. + + "Created: / 16-06-2015 / 06:32:24 / Jan Vrany " +! + testMessagePredicate | messageNode | messageNode := PPCMessagePredicateNode new diff -r 19a9c25960ef -r 0ca7a70db0f5 compiler/tests/extras/PPTokenizedExpressionGrammarResource.st --- a/compiler/tests/extras/PPTokenizedExpressionGrammarResource.st Mon Jun 15 19:13:49 2015 +0100 +++ b/compiler/tests/extras/PPTokenizedExpressionGrammarResource.st Tue Jun 16 06:45:26 2015 +0100 @@ -9,6 +9,7 @@ category:'PetitCompiler-Extras-Tests-Expressions' ! + !PPTokenizedExpressionGrammarResource methodsFor:'as yet unclassified'! setUp @@ -25,3 +26,10 @@ "Modified: / 26-05-2015 / 07:25:13 / Jan Vrany " ! ! +!PPTokenizedExpressionGrammarResource class methodsFor:'documentation'! + +version_HG + + ^ '$Changeset: $' +! ! +