compiler/PPCCodeBlock.st
changeset 502 1e45d3c96ec5
child 503 ff58cd9f1f3c
child 515 b5316ef15274
equal deleted inserted replaced
464:f6d77fee9811 502:1e45d3c96ec5
       
     1 "{ Package: 'stx:goodies/petitparser/compiler' }"
       
     2 
       
     3 "{ NameSpace: Smalltalk }"
       
     4 
       
     5 Object subclass:#PPCCodeBlock
       
     6 	instanceVariableNames:'buffer indentation temporaries'
       
     7 	classVariableNames:''
       
     8 	poolDictionaries:''
       
     9 	category:'PetitCompiler-Compiler-Codegen'
       
    10 !
       
    11 
       
    12 !PPCCodeBlock class methodsFor:'instance creation'!
       
    13 
       
    14 new
       
    15     "return an initialized instance"
       
    16 
       
    17     ^ self basicNew initialize.
       
    18 ! !
       
    19 
       
    20 !PPCCodeBlock methodsFor:'as yet unclassified'!
       
    21 
       
    22 add: string
       
    23     self nl.
       
    24     self codeIndent.
       
    25     self addOnLine: string.
       
    26 
       
    27     "Modified: / 01-06-2015 / 22:58:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
    28 !
       
    29 
       
    30 addOnLine: string
       
    31     buffer nextPutAll: string.
       
    32 !
       
    33 
       
    34 nl
       
    35     ^ buffer nextPut: Character cr
       
    36 ! !
       
    37 
       
    38 !PPCCodeBlock methodsFor:'code generation'!
       
    39 
       
    40 code: aStringOrBlockOrRBParseNode
       
    41     aStringOrBlockOrRBParseNode isString ifTrue:[ 
       
    42         self emitCodeAsString: aStringOrBlockOrRBParseNode
       
    43     ] ifFalse:[
       
    44         (aStringOrBlockOrRBParseNode isKindOf: RBProgramNode) ifTrue:[ 
       
    45             self emitCodeAsRBNode: aStringOrBlockOrRBParseNode.
       
    46         ] ifFalse:[  
       
    47             self emitCodeAsBlock: aStringOrBlockOrRBParseNode
       
    48         ].
       
    49     ].
       
    50 
       
    51     "Created: / 01-06-2015 / 21:07:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
    52     "Modified: / 03-06-2015 / 05:52:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
    53 !
       
    54 
       
    55 codeIndent
       
    56     self codeIndent:indentation
       
    57 
       
    58     "Created: / 01-06-2015 / 22:58:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
    59 !
       
    60 
       
    61 codeIndent: level
       
    62     ((Smalltalk respondsTo:#isSmalltalkX) and:[ Smalltalk isSmalltalkX ]) ifTrue:[ 
       
    63         level * 4 timesRepeat: [ buffer nextPut: Character space  ].
       
    64     ] ifFalse:[ 
       
    65         level timesRepeat: [ buffer nextPut: Character tab  ].
       
    66     ].
       
    67 
       
    68     "Created: / 01-06-2015 / 22:58:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
    69 ! !
       
    70 
       
    71 !PPCCodeBlock methodsFor:'code generation - variables'!
       
    72 
       
    73 allocateTemporaryVariableNamed:preferredName 
       
    74     "Allocate a new variable with (preferably) given name.
       
    75      Returns a real variable name that should be used."
       
    76     
       
    77     (temporaries includes:preferredName) ifFalse:[
       
    78         temporaries add:preferredName.
       
    79         ^ preferredName
       
    80     ] ifTrue:[
       
    81         | name |
       
    82 
       
    83         name := preferredName , '_' , (temporaries size + 1) printString.
       
    84         temporaries add:name.
       
    85         ^ name
       
    86     ].
       
    87 
       
    88     "Created: / 23-04-2015 / 17:37:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
    89     "Modified: / 01-06-2015 / 21:03:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
    90 ! !
       
    91 
       
    92 !PPCCodeBlock methodsFor:'indentation'!
       
    93 
       
    94 dedent
       
    95     indentation := indentation - 1
       
    96 !
       
    97 
       
    98 indent 
       
    99     indentation := indentation + 1
       
   100 !
       
   101 
       
   102 indentationLevel
       
   103     ^ indentation
       
   104 !
       
   105 
       
   106 indentationLevel: value
       
   107     indentation := value
       
   108 ! !
       
   109 
       
   110 !PPCCodeBlock methodsFor:'initialization'!
       
   111 
       
   112 initialize
       
   113     "Invoked when a new instance is created."
       
   114 
       
   115     buffer := String new writeStream.
       
   116     indentation := 1.
       
   117     temporaries := OrderedCollection new.
       
   118 
       
   119     "Modified: / 01-06-2015 / 20:57:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   120     "Modified (comment): / 18-06-2015 / 06:04:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   121 ! !
       
   122 
       
   123 !PPCCodeBlock methodsFor:'printing and storing'!
       
   124 
       
   125 codeOn: aStream
       
   126     "Dumps generated code on given stream"
       
   127 
       
   128     temporaries notEmpty ifTrue:[
       
   129         ((Smalltalk respondsTo:#isSmalltalkX) and:[ Smalltalk isSmalltalkX ]) ifTrue:[ 
       
   130             indentation * 4 timesRepeat: [ aStream nextPut: Character space  ].
       
   131         ] ifFalse:[ 
       
   132             indentation timesRepeat: [ aStream nextPut: Character tab  ].
       
   133         ].
       
   134         aStream nextPut: $|.
       
   135         temporaries do:[:e | aStream space; nextPutAll: e  ].
       
   136         aStream space.
       
   137         aStream nextPut: $|. 
       
   138         self nl.
       
   139         "In Smalltalk/X, there should be a blank line after temporaries"
       
   140         ((Smalltalk respondsTo:#isSmalltalkX) and:[ Smalltalk isSmalltalkX ]) ifTrue:[ 
       
   141             self nl.
       
   142         ].
       
   143     ].
       
   144     aStream nextPutAll: buffer contents
       
   145 
       
   146     "Created: / 01-06-2015 / 21:26:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   147 ! !
       
   148 
       
   149 !PPCCodeBlock methodsFor:'private'!
       
   150 
       
   151 emitCodeAsBlock: aBlock
       
   152     aBlock value
       
   153 !
       
   154 
       
   155 emitCodeAsRBNode: anRBNode
       
   156     anRBNode isSequence ifTrue:[
       
   157         anRBNode temporaries do:[:e |  
       
   158             (temporaries includes: e name) ifFalse:[ 
       
   159                 temporaries add: e name
       
   160             ].
       
   161         ].
       
   162         anRBNode statements do:[:e|
       
   163             self 	add: (self formatRBNode: e); 
       
   164                     addOnLine: '.'.
       
   165         ].
       
   166     ] ifFalse:[  
       
   167         buffer nextPutAll: anRBNode formattedCode.  
       
   168     ].
       
   169 
       
   170 !
       
   171 
       
   172 emitCodeAsString: aString
       
   173     buffer nextPutAll: aString
       
   174 !
       
   175 
       
   176 formatRBNode: anRBNode
       
   177     | formatter |
       
   178     formatter := anRBNode formatterClass new.
       
   179     formatter indent: indentation.
       
   180     ^ formatter format: anRBNode 
       
   181 ! !
       
   182