[tlox] Refactor to use Truffle DSL

This commit is contained in:
ctsk
2022-09-13 18:21:31 +02:00
parent 3c12f50b6f
commit a93b1018ca
12 changed files with 85 additions and 67 deletions

View File

@@ -26,6 +26,12 @@
<artifactId>truffle-api</artifactId> <artifactId>truffle-api</artifactId>
<version>22.2.0</version> <version>22.2.0</version>
</dependency> </dependency>
<dependency>
<groupId>org.graalvm.truffle</groupId>
<artifactId>truffle-dsl-processor</artifactId>
<version>22.2.0</version>
<scope>provided</scope>
</dependency>
<dependency> <dependency>
<groupId>org.antlr</groupId> <groupId>org.antlr</groupId>
<artifactId>antlr4</artifactId> <artifactId>antlr4</artifactId>

View File

@@ -0,0 +1,14 @@
package xyz.ctsk.lox;
import com.oracle.truffle.api.exception.AbstractTruffleException;
import com.oracle.truffle.api.nodes.Node;
public class LoxException extends AbstractTruffleException {
public LoxException(String message) {
super(message);
}
public static LoxException typeError(Node operation, Object... values) {
return new LoxException(operation.toString());
}
}

View File

@@ -4,4 +4,6 @@ import com.oracle.truffle.api.frame.VirtualFrame;
public abstract class LoxExpressionNode extends LoxNode { public abstract class LoxExpressionNode extends LoxNode {
public abstract double executeDouble(VirtualFrame frame); public abstract double executeDouble(VirtualFrame frame);
public abstract Object executeGeneric(VirtualFrame frame);
} }

View File

@@ -1,5 +1,6 @@
package xyz.ctsk.lox.nodes; package xyz.ctsk.lox.nodes;
import com.oracle.truffle.api.dsl.TypeSystemReference;
import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.Node;
public class LoxNode extends Node { public class LoxNode extends Node {

View File

@@ -1,24 +1,17 @@
package xyz.ctsk.lox.nodes.expr; package xyz.ctsk.lox.nodes.expr;
import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.dsl.Specialization;
import xyz.ctsk.lox.nodes.LoxExpressionNode; import xyz.ctsk.lox.LoxException;
public class LoxAddNode extends LoxExpressionNode { public abstract class LoxAddNode extends LoxBinaryNode {
@SuppressWarnings("FieldMayBeFinal") @Specialization
@Node.Child public double add(double left, double right) {
private LoxExpressionNode leftNode, rightNode; return left + right;
public LoxAddNode(LoxExpressionNode leftNode, LoxExpressionNode rightNode) {
this.leftNode = leftNode;
this.rightNode = rightNode;
} }
@Fallback
@Override protected Object typeError(Object left, Object right) {
public double executeDouble(VirtualFrame frame) { throw LoxException.typeError(this, left, right);
var leftValue = leftNode.executeDouble(frame);
var rightValue = rightNode.executeDouble(frame);
return leftValue + rightValue;
} }
} }

View File

@@ -0,0 +1,9 @@
package xyz.ctsk.lox.nodes.expr;
import com.oracle.truffle.api.dsl.NodeChild;
import xyz.ctsk.lox.nodes.LoxExpressionNode;
@NodeChild("leftValue")
@NodeChild("rightValue")
public abstract class LoxBinaryNode extends LoxExpressionNode {
}

View File

@@ -1,22 +1,18 @@
package xyz.ctsk.lox.nodes.expr; package xyz.ctsk.lox.nodes.expr;
import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.dsl.Fallback;
import xyz.ctsk.lox.nodes.LoxExpressionNode; import com.oracle.truffle.api.dsl.Specialization;
import xyz.ctsk.lox.LoxException;
public class LoxDivNode extends LoxExpressionNode { public abstract class LoxDivNode extends LoxBinaryNode {
@SuppressWarnings("FieldMayBeFinal") @Specialization
@Child public double div(double left, double right) {
private LoxExpressionNode leftNode, rightNode; return left / right;
public LoxDivNode(LoxExpressionNode leftNode, LoxExpressionNode rightNode) {
this.leftNode = leftNode;
this.rightNode = rightNode;
} }
@Override @Fallback
public double executeDouble(VirtualFrame frame) { protected Object typeError(Object left, Object right) {
var leftValue = leftNode.executeDouble(frame); throw LoxException.typeError(this, left, right);
var rightValue = rightNode.executeDouble(frame);
return leftValue / rightValue;
} }
} }

View File

@@ -1,22 +1,18 @@
package xyz.ctsk.lox.nodes.expr; package xyz.ctsk.lox.nodes.expr;
import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.dsl.Fallback;
import xyz.ctsk.lox.nodes.LoxExpressionNode; import com.oracle.truffle.api.dsl.Specialization;
import xyz.ctsk.lox.LoxException;
public class LoxMulNode extends LoxExpressionNode { public abstract class LoxMulNode extends LoxBinaryNode {
@SuppressWarnings("FieldMayBeFinal") @Specialization
@Child public double mul(double left, double right) {
private LoxExpressionNode leftNode, rightNode; return left * right;
public LoxMulNode(LoxExpressionNode leftNode, LoxExpressionNode rightNode) {
this.leftNode = leftNode;
this.rightNode = rightNode;
} }
@Override @Fallback
public double executeDouble(VirtualFrame frame) { protected Object typeError(Object left, Object right) {
var leftValue = leftNode.executeDouble(frame); throw LoxException.typeError(this, left, right);
var rightValue = rightNode.executeDouble(frame);
return leftValue * rightValue;
} }
} }

View File

@@ -13,4 +13,9 @@ public class LoxNumberLiteralNode extends LoxExpressionNode {
public double executeDouble(VirtualFrame frame) { public double executeDouble(VirtualFrame frame) {
return this.value; return this.value;
} }
@Override
public Object executeGeneric(VirtualFrame frame) {
return this.value;
}
} }

View File

@@ -1,22 +1,18 @@
package xyz.ctsk.lox.nodes.expr; package xyz.ctsk.lox.nodes.expr;
import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.dsl.Fallback;
import xyz.ctsk.lox.nodes.LoxExpressionNode; import com.oracle.truffle.api.dsl.Specialization;
import xyz.ctsk.lox.LoxException;
public class LoxSubNode extends LoxExpressionNode { public abstract class LoxSubNode extends LoxBinaryNode {
@SuppressWarnings("FieldMayBeFinal") @Specialization
@Child public double sub(double left, double right) {
private LoxExpressionNode leftNode, rightNode; return left - right;
public LoxSubNode(LoxExpressionNode leftNode, LoxExpressionNode rightNode) {
this.leftNode = leftNode;
this.rightNode = rightNode;
} }
@Override @Fallback
public double executeDouble(VirtualFrame frame) { protected Object typeError(Object left, Object right) {
var leftValue = leftNode.executeDouble(frame); throw LoxException.typeError(this, left, right);
var rightValue = rightNode.executeDouble(frame);
return leftValue - rightValue;
} }
} }

View File

@@ -12,10 +12,10 @@ public class LoxNodeFactory {
public static LoxExpressionNode createBinaryNode(Token op, LoxExpressionNode left, LoxExpressionNode right) { public static LoxExpressionNode createBinaryNode(Token op, LoxExpressionNode left, LoxExpressionNode right) {
return switch (op.getText()) { return switch (op.getText()) {
case "+" -> new LoxAddNode(left, right); case "+" -> LoxAddNodeGen.create(left, right);
case "-" -> new LoxSubNode(left, right); case "-" -> LoxSubNodeGen.create(left, right);
case "*" -> new LoxMulNode(left, right); case "*" -> LoxMulNodeGen.create(left, right);
case "/" -> new LoxDivNode(left, right); case "/" -> LoxDivNodeGen.create(left, right);
default -> null; default -> null;
}; };
} }

View File

@@ -28,7 +28,7 @@ file returns [LoxExpressionNode result]
; ;
expression returns [LoxExpressionNode result] expression returns [LoxExpressionNode result]
: literal { $result = $literal.result; } : literal { $result = $literal.result; }
| left=expression op=( '*' | '/' ) right=expression { $result = factory.createBinaryNode($op, $left.result, $right.result); } | left=expression op=( '*' | '/' ) right=expression { $result = factory.createBinaryNode($op, $left.result, $right.result); }
| left=expression op=( '+' | '-' ) right=expression { $result = factory.createBinaryNode($op, $left.result, $right.result); } | left=expression op=( '+' | '-' ) right=expression { $result = factory.createBinaryNode($op, $left.result, $right.result); }
; ;