Child nodes

Of course, any language would be practically useless if all that was available to you was a single hardwired root node. For this reason, Truffle allows for child nodes. Their uses include:

  • Multiple statements in a program or block
  • Evaluation of arguments
  • Operators (e.g. 2+2)

Here, I’ll create a root node that has two child nodes, calls them, and returns the sum of the values they return when executed. This would be something akin to 101 + 101, where the two numerical values were child nodes of a parent node that adds the two sides together. By having more complex child nodes, something like functioncall() + variable can be represented, although true function calls and variables are not available to us yet.

Here is the code I wrote for this purpose:

 package com.wordpress.hextruffle.tests;

import com.oracle.truffle.api.CallTarget;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.TruffleRuntime;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.RootNode;

public class ChildNodeDemo {

    static class AdditionRootNode extends RootNode {
        @Child
        private TestChildNode left;
        @Child
        private TestChildNode right;

        @Override
        public Object execute(VirtualFrame frame) {
            return left.execute() + right.execute();
        }

        public AdditionRootNode(TestChildNode left, TestChildNode right) {
            super(null);
            this.left = left;
            this.right = right;
        }

    }

    static class TestChildNode extends Node {

        public TestChildNode() {
            super(null);
        }

        public int execute() {
            return 101;
        }
    }

    public static void main(String[] args) {
        TruffleRuntime runtime = Truffle.getRuntime();
            TestChildNode leftChild = new TestChildNode();
            TestChildNode rightChild = new TestChildNode();
            AdditionRootNode root = new AdditionRootNode(leftChild, rightChild);
            CallTarget target = runtime.createCallTarget(root);
            System.out.println("Called the root node, which told us that 101 + 101 is "+target.call());
            
    }
}

The first step, of course, is to obtain a TruffleRuntime to work with. I’ve defined an addition root node that has two fields denoting its two children, the left and the right argument. Of course, these could be called foo and bar, ham and eggs, or for that matter, any valid Java identifiers. It is key, however, that they are annotated @Child, and are private and non-final (the reason for which we will see later). The next step is to construct two children that return the proper value when execute()d. After that, the root node can be constructed, and invoked as in the previous example. The result shows that they were indeed executed properly.

Of course, a child node can itself contain children. That would reflect something akin to (2+1)+(3+20) if we stick with the example of addition.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s