Now clement what is the difference with a plain AST interpreter?
On Tue, Apr 17, 2018 at 6:57 PM, Cl��ment Bera <bera.clement@gmail.com> wrote:Starting from here you can build a full AST interpreter that mutates a context instance that you create by interpreting MessageNode...--On Tue, Apr 17, 2018 at 5:45 PM, Marcus Denker <marcus.denker@inria.fr> wrote: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 thatwill 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 executingself method ast assignmentNodes first variable evaluateWithContext: selfand 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: #DoItbody: (RBReturnNode value: self) asSequenceNode.^methodNode generate valueWithReceiver: nil arguments: #().and then you can do things likeblockNode: = RBBlockNodebody: (RBLiteralNode value: 5) asSequenceNodeblockNode evaluateto create blocks.Marcus