Hi,
>
> has anyone tried to accomplish something like
>
> MyNewClass addMethod:#doSomethingWith: with: [ :arg |
> Transcript show: arg].
>
> MyNewClass new doSomethingWith: 'Hello World'.
>
> in Squeak? This would mean, to convert a block into a method, thus
> changing the hole semantics. Outer temporaries or other variables
> are of
> course forbidden. Literals have to be fetched out of the defining
> method
> and brought into a new compiled method and so on. Or perhaps there are
> other possibilities? Any ideas?
>
one idea could be to just build a tiny compiledmethod that calls the
Block.
e.g., you can store the block in the literalframe of the that method
and then
call value:... on it with the correct arguments. As it's just a
"pushLiteral, send value",
with #value being a primitive method, this should be not too slow.
Especially it preserves the semantics of the block, converting blocks
into non-blocks
is normally no good idea as you need to explain people that they are
not allowed
to use outer references...
So I would keep the block. Blocks are cool.
This would be fairly easy to do with IRBuilder, as you can just push
the block as a
literal, generate a method that calls this then with the correct
value:... this
would look like this:
addMethod: selector with: aBlock
| irBuilder args |
args := (aBlock tempNames collect: #asSymbol) asArray.
irBuilder := IRBuilder new
numRargs: 1 + aBlock numArgs;
addTemps: #(self);
addTemps: args;
pushLiteral: aBlock. "push the block as a literal"
args do: [:each | "maybe this needs to be done in reverse?"
irBuilder pushTemp: each
].
irBuilder send: aBlock valueSelector.
irBuilder returnTop.
self basicAddSelector: selector withMethod: irBuilder ir compiledMethod
(this needs the latest NewCompiler and the attached changeset).
Marcus
--
Marcus Denker --
[hidden email]
http://www.iam.unibe.ch/~denker