Hi,
This is fun experiment:
Every RBValueNode subclass evaluates to something. So why not implement a #evaluate method?
This is especially fun to do for a specific context, as this means that you could evaluate every RBVariableNode to see the value.
So lets implement a method in RBValueNode:
evaluateWithContext: aContext
| methodNode |
If we want to compile a method for it, we need to wrap it into a return and a method. Like when evaluating in the debugger, we create a #DoItIn: method that
will get the context as a parameter to read the values from (temps from the context, ivars from context receiver).
This works like this:
methodNode := RBMethodNode
selector: #DoItIn:
arguments: { RBVariableNode named: 'ThisContext' }
body: (RBReturnNode value: self) asSequenceNode.
to read temps from the context parameter, we use the rewrite method that is used by doits already:
methodNode rewriteTempsForContext: aContext.
and now we can execute:
^methodNode generate valueWithReceiver: aContext receiver arguments: {aContext}.
For testing, I put a #haltOnce into Rectangle>>#area and then use the inspector on the context to evaluate a AST node that is a temporary variable.
The screenshot shows executing
self method ast assignmentNodes first variable evaluateWithContext: self
and it returns correctly 104:
Of course there are simpler ways to read variables by name from a context (e.g. we added #lookupSymbol: ), but #evaluateWithContext: can be called on other Nodes, too.
E.g. just a #evaluate could be nice for creating Blocks programmatically (instead of calling the compiler on a Pretty-Print result like #createBlockFor: in the ParseTreeSearcher).
A version that does not take context and receiver into account is this:
evaluate
| methodNode |
methodNode := RBMethodNode
selector: #DoIt
body: (RBReturnNode value: self) asSequenceNode.
^methodNode generate valueWithReceiver: nil arguments: #().
and then you can do things like
blockNode: = RBBlockNode
body: (RBLiteralNode value: 5) asSequenceNode
blockNode evaluate
to create blocks.
Marcus