compiler/PPCCompiler.st
changeset 502 1e45d3c96ec5
parent 464 f6d77fee9811
child 503 ff58cd9f1f3c
child 515 b5316ef15274
equal deleted inserted replaced
464:f6d77fee9811 502:1e45d3c96ec5
    15 !PPCCompiler class methodsFor:'instance creation'!
    15 !PPCCompiler class methodsFor:'instance creation'!
    16 
    16 
    17 new
    17 new
    18     "return an initialized instance"
    18     "return an initialized instance"
    19 
    19 
    20     ^ self basicNew initializeForCompiledClassName: 'PPGeneratedParser'
    20     ^ self on: PPCArguments default
    21 !
       
    22 
       
    23 newForCompiledClassName: aString
       
    24     "return an initialized instance"
       
    25 	self halt: 'deprecated'.
       
    26     ^ self basicNew initializeForCompiledClassName: aString
       
    27 !
    21 !
    28 
    22 
    29 on: aPPCArguments
    23 on: aPPCArguments
    30     "return an initialized instance"
    24     "return an initialized instance"
    31 
    25 
    32     ^ self basicNew
    26     ^ self basicNew
    33 		arguments: aPPCArguments;
    27                 arguments: aPPCArguments;
    34 		initializeForCompiledClassName: aPPCArguments name
    28                 initializeForCompiledClassName: aPPCArguments parserName
    35 ! !
    29 ! !
    36 
    30 
    37 !PPCCompiler methodsFor:'accessing'!
    31 !PPCCompiler methodsFor:'accessing'!
    38 
    32 
    39 arguments: args
    33 arguments: args
    69 ! !
    63 ! !
    70 
    64 
    71 !PPCCompiler methodsFor:'cleaning'!
    65 !PPCCompiler methodsFor:'cleaning'!
    72 
    66 
    73 clean: class
    67 clean: class
    74 "	Transcript crShow: 'Cleaning time: ',
    68 "	Transcript show: ('Cleaning time: ',
    75     [	
    69     [	
    76 "		self cleanGeneratedMethods: class.
    70 "		self cleanGeneratedMethods: class.
    77         self cleanInstVars: class.
    71         self cleanInstVars: class.
    78         self cleanConstants: class.
    72         self cleanConstants: class.
    79 "	] timeToRun asMilliSeconds asString, 'ms'."
    73 "	] timeToRun asMilliSeconds asString, 'ms'); cr. "
    80 !
    74 !
    81 
    75 
    82 cleanConstants: class
    76 cleanConstants: class
    83     class constants removeAll.
    77     class constants removeAll.
    84 !
    78 !
   115 
   109 
   116 addComment: string
   110 addComment: string
   117     currentMethod add: '"', string, '"'.
   111     currentMethod add: '"', string, '"'.
   118 !
   112 !
   119 
   113 
   120 addConstant: value as: name
   114 addConstant: value as: name    
       
   115     (constants includesKey: name) ifTrue:[ 
       
   116         (constants at: name) ~= value ifTrue:[ 
       
   117             self error:'Duplicate constant!!'.
       
   118         ].
       
   119         ^ self.
       
   120     ].
   121     constants at: name put: value
   121     constants at: name put: value
       
   122 
       
   123     "Modified: / 29-05-2015 / 07:22:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   122 !
   124 !
   123 
   125 
   124 addOnLine: string
   126 addOnLine: string
   125     currentMethod addOnLine: string.
   127     currentMethod addOnLine: string.
   126 !
   128 !
   169     ]
   171     ]
   170 ! !
   172 ! !
   171 
   173 
   172 !PPCCompiler methodsFor:'code generation - coding'!
   174 !PPCCompiler methodsFor:'code generation - coding'!
   173 
   175 
       
   176 code:aStringOrBlockOrRBParseNode
       
   177     currentMethod code: aStringOrBlockOrRBParseNode
       
   178 
       
   179     "Created: / 01-06-2015 / 23:49:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   180 !
       
   181 
   174 codeAssign: code to: variable
   182 codeAssign: code to: variable
   175     self assert: variable isNil not.
   183     self assert: variable isNil not.
   176     
   184     
   177     "TODO JK: Hack alert, whatever is magic constant!!"
   185     "TODO JK: Hack alert, whatever is magic constant!!"
   178     (variable == #whatever) ifFalse: [ 
   186     (variable == #whatever) ifFalse: [ 
   179         "Do not assign, if somebody does not care!!"
   187         "Do not assign, if somebody does not care!!"
   180         self add: variable ,' := ', code.
   188         self add: variable ,' := ', code.
   181     ]
   189     ]
   182 !
   190 !
   183 
   191 
       
   192 codeAssignParsedValueOf:aBlock to:aString 
       
   193     | tmpVarirable  method |
       
   194 
       
   195     self assert:aBlock isBlock.
       
   196     self assert:aString isNil not.
       
   197     tmpVarirable := returnVariable.
       
   198     returnVariable := aString.
       
   199     method := [
       
   200             aBlock value
       
   201         ] ensure:[ returnVariable := tmpVarirable ].
       
   202     self assert: (method isKindOf: PPCMethod).
       
   203     method isInline ifTrue:[
       
   204         self callOnLine:method
       
   205     ] ifFalse:[
       
   206         self codeEvaluateAndAssign:(method call) to:aString.
       
   207     ]
       
   208 
       
   209     "Created: / 23-04-2015 / 18:21:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   210 !
       
   211 
       
   212 codeBlock: contents
       
   213     currentMethod codeBlock: contents
       
   214 
       
   215     "Created: / 01-06-2015 / 22:35:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   216 !
       
   217 
   184 codeClearError
   218 codeClearError
   185     self add: 'self clearError.'.
   219     self add: 'self clearError.'.
       
   220 !
       
   221 
       
   222 codeDot
       
   223     self addOnLine:'.'.
       
   224 
       
   225     "Created: / 16-06-2015 / 06:09:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   186 !
   226 !
   187 
   227 
   188 codeError
   228 codeError
   189     self add: 'self error: ''message notspecified''.'.
   229     self add: 'self error: ''message notspecified''.'.
   190 !
   230 !
   202     
   242     
   203     "TODO JK: Hack alert, whatever is magic constant!!"
   243     "TODO JK: Hack alert, whatever is magic constant!!"
   204     (variable == #whatever) ifFalse: [ 
   244     (variable == #whatever) ifFalse: [ 
   205         "Do not assign, if somebody does not care!!"
   245         "Do not assign, if somebody does not care!!"
   206         self add: variable, ' ', selector,' ', argument.
   246         self add: variable, ' ', selector,' ', argument.
   207  	] ifTrue: [ 
   247  		] ifTrue: [ 
   208         "In case argument has a side effect"
   248         "In case argument has a side effect"
   209  		self add: argument	
   249  				self add: argument	
   210     ]
   250     ]
   211 !
   251 !
   212 
   252 
   213 codeEvaluateAndAssign: argument to: variable
   253 codeEvaluateAndAssign: argument to: variable
   214     self assert: variable isNil not.
   254     self assert: variable isNil not.
   235     ]
   275     ]
   236 
   276 
   237     "Modified: / 10-05-2015 / 07:39:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   277     "Modified: / 10-05-2015 / 07:39:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   238 !
   278 !
   239 
   279 
       
   280 codeIf: condition then: then 
       
   281     self codeIf: condition then: then else: nil
       
   282 
       
   283     "Created: / 16-06-2015 / 06:07:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   284 !
       
   285 
       
   286 codeIf: condition then: then else: else
       
   287     currentMethod 
       
   288         add: '(';
       
   289         code: condition;
       
   290         addOnLine: ')'.
       
   291     then notNil ifTrue:[ 
       
   292         currentMethod 
       
   293             addOnLine:' ifTrue:';
       
   294             codeBlock: then.
       
   295     ].
       
   296     else notNil ifTrue:[ 
       
   297         currentMethod 
       
   298             addOnLine:' ifFalse:';
       
   299             codeBlock: else.
       
   300     ].
       
   301     self codeDot.
       
   302 
       
   303     "Created: / 01-06-2015 / 22:43:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   304     "Modified: / 16-06-2015 / 06:09:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   305 !
       
   306 
       
   307 codeIfErrorThen: then
       
   308     ^ self codeIf: 'error' then: then else: nil
       
   309 
       
   310     "Created: / 16-06-2015 / 06:06:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   311 !
       
   312 
       
   313 codeIfErrorThen: then else: else
       
   314     ^ self codeIf: 'error' then: then else: else
       
   315 
       
   316     "Created: / 16-06-2015 / 06:05:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   317 !
       
   318 
   240 codeNextToken
   319 codeNextToken
   241     self add: 'self nextToken.'
   320     self add: 'self nextToken.'
   242 
   321 
   243     "Created: / 23-04-2015 / 18:01:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   322     "Created: / 23-04-2015 / 18:01:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   244     "Modified: / 23-04-2015 / 20:51:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   323     "Modified: / 23-04-2015 / 20:51:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   245 !
   324 !
   246 
   325 
       
   326 codeProfileStart
       
   327     self add: 'context methodInvoked: #', currentMethod methodName, '.'
       
   328 
       
   329     "Created: / 01-06-2015 / 21:17:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   330 !
       
   331 
       
   332 codeProfileStop
       
   333     self add: 'context methodFinished: #', currentMethod methodName, '.'
       
   334 
       
   335     "Created: / 01-06-2015 / 21:19:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   336 !
       
   337 
   247 codeReturn
   338 codeReturn
   248    currentMethod isInline ifTrue: [
   339    currentMethod isInline ifTrue: [
   249 				"If inlined, the return variable already holds the value"
   340 		"If inlined, the return variable already holds the value"
   250 		] ifFalse: [
   341 	] ifFalse: [
   251 				self add: '^ ', currentMethod returnVariable  
   342 		arguments profile ifTrue:[ 
   252    ].
   343 			self codeProfileStop.
       
   344 		]. 
       
   345 		self add: '^ ', currentMethod returnVariable  
       
   346 	].
   253 
   347 
   254 	"Created: / 23-04-2015 / 18:01:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   348 	"Created: / 23-04-2015 / 18:01:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   255 	"Modified: / 23-04-2015 / 20:51:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   349 	"Modified: / 01-06-2015 / 21:49:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   256 !
   350 !
   257 
   351 
   258 codeReturn: code
   352 codeReturn: code
   259     " - returns whatever is in code OR
   353     " - returns whatever is in code OR
   260       - assigns whatever is in code into the returnVariable"
   354       - assigns whatever is in code into the returnVariable"
   261    currentMethod isInline ifTrue:[ 
   355     currentMethod isInline ifTrue:[
   262         self codeEvaluateAndAssign: code to: currentMethod returnVariable. 
   356         self codeEvaluateAndAssign: code to: currentMethod returnVariable. 
   263    ] ifFalse: [ 
   357     ] ifFalse: [ 
   264         self add: '^ ', code 		
   358         arguments profile ifTrue:[ 
       
   359             self codeProfileStop.
       
   360         ].   
       
   361         self add: '^ ', code            
   265     ]
   362     ]
   266 
   363 
   267     "Created: / 23-04-2015 / 18:01:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   364     "Created: / 23-04-2015 / 18:01:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   268     "Modified: / 23-04-2015 / 20:51:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   365     "Modified: / 01-06-2015 / 21:48:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   366 !
       
   367 
       
   368 codeReturnParsedValueOf:aBlock 
       
   369     | tmpVarirable  method |
       
   370 
       
   371     self assert:aBlock isBlock.	
       
   372     tmpVarirable := returnVariable.
       
   373     method := aBlock value. 
       
   374     self assert: returnVariable == tmpVarirable.
       
   375     self assert: (method isKindOf: PPCMethod).
       
   376     method isInline ifTrue:[
       
   377         self callOnLine:method.
       
   378         self codeReturn: returnVariable.
       
   379     ] ifFalse:[
       
   380         self codeReturn: method call.
       
   381         
       
   382     ]
       
   383 
       
   384     "Created: / 23-04-2015 / 18:21:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   269 !
   385 !
   270 
   386 
   271 codeStoreValueOf: aBlock intoVariable: aString
   387 codeStoreValueOf: aBlock intoVariable: aString
   272     | tmpVarirable method |
   388     | tmpVarirable method |
   273     self assert: aBlock isBlock.
   389     self assert: aBlock isBlock.
   417     (cache includesKey: id) ifTrue: [ self error: 'OOOUPS!!' ].
   533     (cache includesKey: id) ifTrue: [ self error: 'OOOUPS!!' ].
   418     indentationLevel := currentMethod indentationLevel.
   534     indentationLevel := currentMethod indentationLevel.
   419     
   535     
   420     currentMethod := PPCInlinedMethod new.
   536     currentMethod := PPCInlinedMethod new.
   421     currentMethod id: id.   
   537     currentMethod id: id.   
   422     currentMethod profile: arguments profile.
       
   423     currentMethod returnVariable: returnVariable.
   538     currentMethod returnVariable: returnVariable.
   424     currentMethod indentationLevel: indentationLevel.
   539     currentMethod indentationLevel: indentationLevel.
   425     self push.
   540     self push.
   426 
   541 
   427     "Modified: / 23-04-2015 / 18:28:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   542     "Modified: / 01-06-2015 / 21:48:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   428 !
   543 !
   429 
   544 
   430 startMethod: id
   545 startMethod: id
   431     (cache includesKey: id) ifTrue: [ self error: 'OOOUPS!!' ].
   546     (cache includesKey: id) ifTrue: [ self error: 'OOOUPS!!' ].
   432 
   547 
   433     currentMethod := PPCMethod new.
   548     currentMethod := PPCMethod new.
   434     currentMethod id: id.
   549     currentMethod id: id.
   435     currentMethod profile: arguments profile.    
   550     arguments profile ifTrue:[ 
       
   551         self codeProfileStart.
       
   552     ].
   436     self push.      
   553     self push.      
   437                 
   554                 
   438     self cache: id as: currentMethod.
   555     self cache: id as: currentMethod.
   439 
   556 
   440     "Modified: / 23-04-2015 / 18:36:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   557     "Modified: / 01-06-2015 / 21:19:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   441 !
   558 !
   442 
   559 
   443 stopInline
   560 stopInline
   444 
       
   445     ^ self pop.
   561     ^ self pop.
   446 
   562 
   447     "Modified: / 23-04-2015 / 18:28:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   563     "Modified: / 01-06-2015 / 21:37:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   448 !
   564 !
   449 
   565 
   450 stopMethod
   566 stopMethod
   451     self cache: currentMethod methodName as: currentMethod.
   567    self cache: currentMethod methodName as: currentMethod.
   452     
   568 	
   453     "arguments profile ifTrue: [ Transcript show: currentMethod code; cr. ]."
   569 	"arguments profile ifTrue: [ Transcript show: currentMethod code; cr. ]."
   454     ^ self pop.
   570 	^ self pop.
   455 
   571 
   456     "Modified: / 01-05-2015 / 14:18:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   572 	"Modified: / 01-06-2015 / 21:38:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   457 !
   573 !
   458 
   574 
   459 top
   575 top
   460     ^ compilerStack top
   576     ^ compilerStack top
   461 ! !
   577 ! !
   462 
   578 
   463 !PPCCompiler methodsFor:'code generation - variables'!
   579 !PPCCompiler methodsFor:'code generation - variables'!
   464 
   580 
   465 allocateReturnVariable
   581 allocateReturnVariable    
   466     "Return a new variable to store parsed value"
   582     ^ self allocateReturnVariableNamed: 'retval'
   467 
   583 
   468    ^ currentMethod allocateReturnVariable 
   584     "Created: / 23-04-2015 / 18:03:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   469 
   585     "Modified: / 15-06-2015 / 17:52:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   470     "Created: / 23-04-2015 / 17:58:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   586 !
   471     "Modified (comment): / 23-04-2015 / 21:12:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   587 
       
   588 allocateReturnVariableNamed: name
       
   589     "Allocate (or return previously allocated one) temporary variable used for
       
   590      storing a parser's return value (the parsed object)"                 
       
   591     ^ currentMethod allocateReturnVariableNamed: name
       
   592 
       
   593     "Created: / 15-06-2015 / 18:04:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   472 !
   594 !
   473 
   595 
   474 allocateTemporaryVariableNamed: preferredName 
   596 allocateTemporaryVariableNamed: preferredName 
   475     "Allocate a new variable with (preferably) given name.
   597     "Allocate a new variable with (preferably) given name.
   476      Returns a real variable name that should be used."
   598      Returns a real variable name that should be used."
   525 initializeForCompiledClassName: aString
   647 initializeForCompiledClassName: aString
   526     
   648     
   527     self initialize.
   649     self initialize.
   528     compilerStack := Stack new.
   650     compilerStack := Stack new.
   529     cache := IdentityDictionary new.
   651     cache := IdentityDictionary new.
   530     constants := IdentityDictionary new.
   652     constants := Dictionary new.
   531     ids := IdentityDictionary new.
   653     ids := IdentityDictionary new.
   532     
   654     
   533 
   655 
   534     compiledParserName := aString asSymbol.
   656     compiledParserName := aString asSymbol.
   535     
   657     
   548         self clean: compiledParser.
   670         self clean: compiledParser.
   549     ].
   671     ].
   550 
   672 
   551 
   673 
   552     Transcript cr; show: 'intialized for: ', aString; cr.
   674     Transcript cr; show: 'intialized for: ', aString; cr.
       
   675 
       
   676     "Modified: / 26-05-2015 / 17:09:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   553 ! !
   677 ! !
   554 
   678 
   555 !PPCCompiler class methodsFor:'documentation'!
   679 !PPCCompiler class methodsFor:'documentation'!
   556 
   680 
   557 version_HG
   681 version_HG