compiler/PPCCodeGenerator.st
changeset 503 ff58cd9f1f3c
parent 500 cf3cbf3933f1
parent 502 1e45d3c96ec5
child 506 e5d63143737f
equal deleted inserted replaced
501:e29bd90f388e 503:ff58cd9f1f3c
     7 	classVariableNames:''
     7 	classVariableNames:''
     8 	poolDictionaries:''
     8 	poolDictionaries:''
     9 	category:'PetitCompiler-Visitors'
     9 	category:'PetitCompiler-Visitors'
    10 !
    10 !
    11 
    11 
    12 
       
    13 !PPCCodeGenerator class methodsFor:'as yet unclassified'!
    12 !PPCCodeGenerator class methodsFor:'as yet unclassified'!
    14 
    13 
    15 new
    14 new
    16     ^ self basicNew
    15     ^ self basicNew
    17         initialize;
    16         initialize;
    30     compiler := aPPCCompiler 
    29     compiler := aPPCCompiler 
    31 !
    30 !
    32 
    31 
    33 guards
    32 guards
    34     ^ arguments guards
    33     ^ arguments guards
       
    34 ! !
       
    35 
       
    36 !PPCCodeGenerator methodsFor:'code generation'!
       
    37 
       
    38 generateChoiceChildOf: choiceNode atIndex: choiceChildNodeIndex useGuards: useGuards storeResultInto: resultVar
       
    39 
       
    40     | children |
       
    41 
       
    42     children := choiceNode children.
       
    43     useGuards ifTrue:[
       
    44         self addGuard: (children at: choiceChildNodeIndex) ifTrue: [ 
       
    45                     compiler add: 'self clearError.'.
       
    46                     compiler 
       
    47                           codeAssignParsedValueOf:[ self visit:(children at: choiceChildNodeIndex) ]
       
    48                           to: resultVar.
       
    49                     compiler add: 'error ifFalse: [ '.
       
    50                     compiler codeReturn: resultVar.  
       
    51                     compiler add: ' ].'.
       
    52                 ] ifFalse:[ 
       
    53                     compiler add: 'error := true.'.
       
    54                 ].
       
    55                 compiler add: 'error ifTrue:[ '.
       
    56                 choiceChildNodeIndex < children size ifTrue:[ 
       
    57                     self generateChoiceChildOf: choiceNode atIndex: choiceChildNodeIndex + 1 useGuards: useGuards storeResultInto: resultVar.
       
    58                 ] ifFalse:[ 
       
    59                     compiler codeError: 'no choice suitable'.
       
    60                 ].
       
    61                 compiler addOnLine: '].'.
       
    62     
       
    63     ] ifFalse:[ 
       
    64                 choiceChildNodeIndex <= children size ifTrue:[ 
       
    65                     compiler add: 'self clearError.'.
       
    66                     compiler 
       
    67                           codeAssignParsedValueOf:[ self visit:(children at: choiceChildNodeIndex) ]
       
    68                           to: resultVar.
       
    69                     compiler add: 'error ifFalse: [ '.
       
    70                     compiler codeReturn: resultVar.  
       
    71                     compiler add: ' ].'.
       
    72                     self generateChoiceChildOf: choiceNode atIndex: choiceChildNodeIndex + 1 useGuards: useGuards storeResultInto: resultVar.
       
    73                 ] ifFalse:[ 
       
    74                     compiler codeError: 'no choice suitable'.
       
    75                 ].
       
    76     ].
       
    77 
       
    78     
       
    79 !
       
    80 
       
    81 generateSequenceChildOf: sequenceNode atIndex: sequenceNodeChildIndex useMememntoVar: mementoVar storeResultInto: elementVars
       
    82         | child childValueVar |
       
    83 
       
    84         child := sequenceNode children at: sequenceNodeChildIndex.
       
    85         childValueVar := elementVars at: sequenceNodeChildIndex.
       
    86         compiler codeAssignParsedValueOf: [ self visit:child ] 
       
    87                                       to: childValueVar.
       
    88         child acceptsEpsilon ifFalse: [   
       
    89             compiler codeIfErrorThen: [
       
    90                 "Handle error in the first element in a special way,
       
    91                  because one does not need to do backtracking  if the first element fails."
       
    92                 (sequenceNodeChildIndex == 1) ifTrue: [                         
       
    93                     compiler codeReturn: 'failure'
       
    94                 ] ifFalse: [
       
    95                     compiler smartRestore: sequenceNode from: mementoVar.
       
    96                     compiler codeReturn: 'failure.'.
       
    97                 ]
       
    98             ] else:[ 
       
    99                 sequenceNode returnParsedObjectsAsCollection ifTrue:[
       
   100                     compiler add: self retvalVar , ' at: ', sequenceNodeChildIndex asString, ' put: ', childValueVar, '.'.
       
   101                 ].
       
   102                 (sequenceNodeChildIndex < sequenceNode children size) ifTrue:[ 
       
   103                     self generateSequenceChildOf: sequenceNode atIndex: sequenceNodeChildIndex + 1 useMememntoVar: mementoVar storeResultInto: elementVars.
       
   104                 ].
       
   105             ]
       
   106 
       
   107         ] ifTrue:[
       
   108             sequenceNode returnParsedObjectsAsCollection ifTrue:[
       
   109                 compiler add: self retvalVar , ' at: ', sequenceNodeChildIndex asString, ' put: ', childValueVar, '.'.
       
   110             ].
       
   111             (sequenceNodeChildIndex < sequenceNode children size) ifTrue:[ 
       
   112                     self generateSequenceChildOf: sequenceNode atIndex: sequenceNodeChildIndex + 1 useMememntoVar: mementoVar storeResultInto: elementVars.
       
   113 
       
   114             ].
       
   115         ]
    35 ! !
   116 ! !
    36 
   117 
    37 !PPCCodeGenerator methodsFor:'guards'!
   118 !PPCCodeGenerator methodsFor:'guards'!
    38 
   119 
    39 addGuard: node ifTrue: trueBlock ifFalse: falseBlock
   120 addGuard: node ifTrue: trueBlock ifFalse: falseBlock
   399 
   480 
   400     ^ self visit: child.
   481     ^ self visit: child.
   401 !
   482 !
   402 
   483 
   403 visitChoiceNode: node
   484 visitChoiceNode: node
   404     |  whitespaceConsumed allowGuard elementVar coding |
   485     |  whitespaceConsumed useGuards resultVar  |
   405 
   486 
   406 
   487     resultVar := compiler allocateTemporaryVariableNamed: 'element'.
   407     elementVar := compiler allocateTemporaryVariableNamed: 'element'.
       
   408     whitespaceConsumed := self addGuardTrimming: node.
   488     whitespaceConsumed := self addGuardTrimming: node.
   409     allowGuard := whitespaceConsumed.
   489     useGuards := whitespaceConsumed.
   410 
   490     self generateChoiceChildOf: node atIndex: 1 useGuards: useGuards storeResultInto: resultVar
   411     allowGuard ifTrue:[
   491     
   412         coding := 
       
   413             [ :children :index |
       
   414                 self addGuard: (children at: index) ifTrue: [ 
       
   415                     compiler add: 'self clearError.'.
       
   416                     compiler 
       
   417                           codeAssignParsedValueOf:[ self visit:(children at:index) ]
       
   418                           to:elementVar.
       
   419                     compiler add: 'error ifFalse: [ '.
       
   420                     compiler codeReturn: elementVar.  
       
   421                     compiler add: ' ].'.
       
   422                 ] ifFalse:[ 
       
   423                     compiler add: 'error := true.'.
       
   424                 ].
       
   425                 compiler add: 'error ifTrue:[ '.
       
   426                 index < children size ifTrue:[ 
       
   427                     coding value: children value: index + 1.
       
   428                 ] ifFalse:[ 
       
   429                     compiler codeError: 'no choice suitable'.
       
   430                 ].
       
   431                 compiler add: '] '.
       
   432         ]
       
   433     ] ifFalse:[ 
       
   434         coding := 
       
   435             [ :children :index |
       
   436                 index <= children size ifTrue:[ 
       
   437                     compiler add: 'self clearError.'.
       
   438                     compiler 
       
   439                           codeAssignParsedValueOf:[ self visit:(children at:index) ]
       
   440                           to:elementVar.
       
   441                     compiler add: 'error ifFalse: [ '.
       
   442                     compiler codeReturn: elementVar.  
       
   443                     compiler add: ' ].'.
       
   444                     coding value: children value: index + 1.
       
   445                 ] ifFalse:[ 
       
   446                     compiler codeError: 'no choice suitable'.
       
   447                 ].
       
   448             ]
       
   449     ].
       
   450 
       
   451     coding value: node children value: 1.
       
   452 
   492 
   453     "Modified: / 29-05-2015 / 07:17:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   493     "Modified: / 29-05-2015 / 07:17:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   454 !
   494 !
   455 
   495 
   456 visitEndOfFileNode: node
   496 visitEndOfFileNode: node
   460 visitEndOfInputNode: node
   500 visitEndOfInputNode: node
   461 
   501 
   462     compiler 
   502     compiler 
   463           codeAssignParsedValueOf:[ self visit:node child ]
   503           codeAssignParsedValueOf:[ self visit:node child ]
   464           to:self retvalVar.
   504           to:self retvalVar.
   465     compiler add: 'context atEnd ifTrue: ['.
   505     compiler codeIf: 'context atEnd' 
   466     compiler codeReturn.        
   506                 then: [ compiler codeReturn ]
   467     compiler add: '] ifFalse: ['.
   507                 else: [ compiler codeError: 'End of input expected' ].
   468     compiler codeError: 'End of input expected'.
   508         
   469     compiler add: '].'.
       
   470 
       
   471     "Modified: / 26-05-2015 / 19:03:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   509     "Modified: / 26-05-2015 / 19:03:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   472 !
   510 !
   473 
   511 
   474 visitForwardNode: node
   512 visitForwardNode: node
   475 
   513 
   760     ].
   798     ].
   761 !
   799 !
   762 
   800 
   763 visitSequenceNode: node
   801 visitSequenceNode: node
   764 
   802 
   765     | elementVars mementoVar canBacktrack coding |
   803     | elementVars mementoVar canBacktrack  |
   766 
   804 
   767     elementVars := node preferredChildrenVariableNames.
   805     elementVars := node preferredChildrenVariableNames.
   768     elementVars do:[:e | 
   806     elementVars do:[:e | 
   769         compiler allocateTemporaryVariableNamed: e.  
   807         compiler allocateTemporaryVariableNamed: e.  
   770     ].
   808     ].
   771 
       
   772 
   809 
   773     canBacktrack := (node children allButFirst allSatisfy: [:e | e acceptsEpsilon ]) not.
   810     canBacktrack := (node children allButFirst allSatisfy: [:e | e acceptsEpsilon ]) not.
   774 
   811 
   775 "       self addGuardTrimming: node.
   812 "       self addGuardTrimming: node.
   776     self addGuard: node ifTrue: nil ifFalse: [ compiler addOnLine: ' ^ self error' ].
   813     self addGuard: node ifTrue: nil ifFalse: [ compiler addOnLine: ' ^ self error' ].
   781     ].
   818     ].
   782 
   819 
   783     node returnParsedObjectsAsCollection ifTrue:[
   820     node returnParsedObjectsAsCollection ifTrue:[
   784         compiler codeAssign: 'Array new: ', node children size asString, '.' to: self retvalVar.
   821         compiler codeAssign: 'Array new: ', node children size asString, '.' to: self retvalVar.
   785     ].
   822     ].
   786 
   823     self generateSequenceChildOf: node atIndex: 1 useMememntoVar: mementoVar storeResultInto: elementVars.
   787     coding := [ :index |
       
   788         | child childValueVar |
       
   789 
       
   790         child := node children at: index.
       
   791         childValueVar := elementVars at: index.
       
   792         compiler codeAssignParsedValueOf: [ self visit:child ] 
       
   793                                       to: childValueVar.
       
   794         child acceptsEpsilon ifFalse: [   
       
   795             compiler codeIfErrorThen: [
       
   796                 "Handle error in the first element specially"
       
   797                 "TODO: JK, please explain here why!!!!!!"
       
   798                 index == 1 ifTrue:[                         
       
   799                     compiler add: 'error ifTrue: [ ^ failure ].'.
       
   800                 ] ifFalse:[
       
   801                     compiler smartRestore: node from: mementoVar.
       
   802                     compiler codeReturn: 'failure.'.
       
   803                 ]
       
   804             ] else:[ 
       
   805                 node returnParsedObjectsAsCollection ifTrue:[
       
   806                     compiler add: self retvalVar , ' at: ', index asString, ' put: ', childValueVar, '.'.
       
   807                 ].
       
   808                 (index < node children size) ifTrue:[ 
       
   809                     coding value: index + 1.
       
   810                 ].
       
   811             ]
       
   812 
       
   813         ] ifTrue:[
       
   814             node returnParsedObjectsAsCollection ifTrue:[
       
   815                 compiler add: self retvalVar , ' at: ', index asString, ' put: ', childValueVar, '.'.
       
   816             ].
       
   817             (index < node children size) ifTrue:[ 
       
   818                 coding value: index + 1.
       
   819             ].
       
   820         ]
       
   821     ].
       
   822 
       
   823     coding value:1.
       
   824 
       
   825     compiler codeReturn
   824     compiler codeReturn
   826 
   825 
   827     "Modified (comment): / 16-06-2015 / 06:38:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   826     "Modified (comment): / 16-06-2015 / 06:38:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   828 !
   827 !
   829 
   828 
  1049     compiler codeReturn.
  1048     compiler codeReturn.
  1050 
  1049 
  1051     "Modified: / 15-06-2015 / 17:59:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
  1050     "Modified: / 15-06-2015 / 17:59:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
  1052 ! !
  1051 ! !
  1053 
  1052 
  1054 !PPCCodeGenerator class methodsFor:'documentation'!
       
  1055 
       
  1056 version_HG
       
  1057 
       
  1058     ^ '$Changeset: <not expanded> $'
       
  1059 ! !
       
  1060