[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Help-smalltalk] [patch] Behaviors understand method nodes as source cod
From: |
Stephen Compall |
Subject: |
[Help-smalltalk] [patch] Behaviors understand method nodes as source code |
Date: |
Mon, 16 Jul 2007 03:40:54 -0500 |
User-agent: |
Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1.4) Gecko/20070509 SeaMonkey/1.1.2 |
smalltalk--backstage--2.2--patch-48
Behaviors understand method nodes as source code
This lets the #compile: methods on Behaviors accept method nodes,
skipping the parsing step in those cases. It also includes some fixes
for STCompiler I found while making it.
--
;;; Stephen Compall ** http://scompall.nocandysw.com/blog **
But you know how reluctant paranormal phenomena are to reveal
themselves when skeptics are present. --Robert Sheaffer, SkI 9/2003
2007-07-16 Stephen Compall <address@hidden>
* kernel/Behavior.st: Use #compileString:ifError: instead of
#compileString: in #compile:ifError:. Remove vacuous "code class
== String" case in compile methods.
* packages/stinst/parser/STCompiler.st: Add #canCompile: to
STCompiler class.
(#compileBoolean:) Don't put receiver's bytecodes if refusing to
optimize the given message send.
(#compileTimesRepeat:, #compileLoop:): Likewise.
* packages/stinst/compiler/StartCompiler.st: Allow method nodes to
be given directly to Behavior's compile methods, by checking
whether the compilerClass can directly compile the given `code'
object.
--- orig/kernel/Behavior.st
+++ mod/kernel/Behavior.st
@@ -216,7 +216,7 @@
Else, return a CompiledMethod result of compilation"
(code isKindOf: WriteStream)
ifTrue: [ ^self compileString: code readStream ].
- ((code isKindOf: Stream) or: [ code class == String ])
+ (code isKindOf: Stream)
ifTrue: [ ^self compileString: code ].
^self compileString: code asString
@@ -224,14 +224,14 @@
compile: code ifError: block
"Compile method source. If there are parsing errors, invoke
- exception block, 'block' passing file name, line number and error.
- description. Return a CompiledMethod result of compilation"
+ exception block, 'block' passing file name, line number and
+ error. Return a CompiledMethod result of compilation"
(code isKindOf: WriteStream)
- ifTrue: [ ^self compileString: code readStream ].
- ((code isKindOf: Stream) or: [ code class == String ])
- ifTrue: [ ^self compileString: code ].
+ ifTrue: [ ^self compileString: code readStream ifError: block ].
+ (code isKindOf: Stream)
+ ifTrue: [ ^self compileString: code ifError: block ].
- ^self compileString: code asString
+ ^self compileString: code asString ifError: block
!
compile: code notifying: requestor
--- orig/packages/stinst/compiler/StartCompiler.st
+++ mod/packages/stinst/compiler/StartCompiler.st
@@ -300,7 +300,42 @@
]
!
+compile: code
+ "Compile code as method source, which may be a stream, a parse
+ node, or anything that responds to #asString. If there are
+ parsing errors, answer nil. Else, answer a CompiledMethod, the
+ result of compilation."
+ ^self compile: code ifError: [:f :l :m | nil]
+!
+
+compile: code ifError: block
+ "Compile code as method source, which may be a stream, a parse
+ node, or anything that responds to #asString. If there are
+ parsing errors, invoke exception block, 'block' passing file
+ name, line number and error. Answer a CompiledMethod, the result
+ of compilation."
+ (self compilerClass canCompile: code)
+ ifTrue: [| dummyParser |
+ dummyParser := self parserClass new.
+ dummyParser errorBlock: [:m :l |
+ ^block value: 'a Smalltalk %1' % {code class}
+ value: l - 1 value: m].
+ ^self compilerClass
+ compile: code for: self
+ classified: nil parser: dummyParser].
+ (code isKindOf: WriteStream)
+ ifTrue: [ ^self compileString: code readStream ifError: block ].
+ (code isKindOf: Stream)
+ ifTrue: [ ^self compileString: code ifError: block ].
+
+ ^self compileString: code asString ifError: block
+!
+
compileString: aString
+ "Compile aString, which should be a string or stream, as a method
+ for my instances, installing it in my method dictionary. Signal
+ an error if parsing or compilation fail, otherwise answer the
+ resulting CompiledMethod."
| parser source |
source := aString isString
ifTrue: [ aString ]
--- orig/packages/stinst/parser/STCompiler.st
+++ mod/packages/stinst/parser/STCompiler.st
@@ -124,6 +124,12 @@
!STCompiler class methodsFor: 'compilation'!
+canCompile: code
+ "Answer whether I know how to compile the given code directly, on
+ behalf of a Behavior."
+ ^(code isKindOf: RBProgramNode) and: [code isMethod]
+!
+
compile: methodNode for: aBehavior classified: aString parser: aParser
^aBehavior
addSelector: methodNode selector
@@ -735,7 +741,7 @@
compileTimesRepeat: aNode
| block |
- aNode receiver acceptVisitor: self.
+ "aNode receiver acceptVisitor: self."
block := aNode arguments first.
(block arguments isEmpty and: [
block body temporaries isEmpty ]) ifFalse: [ ^false ].
@@ -745,7 +751,7 @@
compileLoop: aNode
| stop step block |
- aNode receiver acceptVisitor: self.
+ "aNode receiver acceptVisitor: self."
aNode arguments do: [ :each |
stop := step. "to:"
step := block. "by:"
@@ -763,7 +769,6 @@
compileBoolean: aNode
| bc1 ret1 bc2 selector |
- aNode receiver acceptVisitor: self.
aNode arguments do: [ :each |
(each arguments isEmpty and: [
each body temporaries isEmpty ]) ifFalse: [ ^false ].
@@ -776,6 +781,7 @@
bc2 := self bytecodesFor: each ].
].
+ aNode receiver acceptVisitor: self.
selector := aNode selector.
bc2 isNil ifTrue: [
"Transform everything into #ifTrue:ifFalse: or #ifFalse:ifTrue:"
@@ -804,7 +810,7 @@
selector == #ifFalse:ifTrue: ifTrue: [
^self compileIfFalse: bc1 returns: ret1 ifTrue: bc2
].
- ^false "What happened?!?"
+ ^self error: 'bad boolean message selector'
!
compileBoolean: aNode longBranch: bc1 returns: ret1 shortBranch: bc2
- [Help-smalltalk] [patch] Behaviors understand method nodes as source code,
Stephen Compall <=