From a93b1018cae3433fe075f8e652256a379cba6e6b Mon Sep 17 00:00:00 2001 From: ctsk <9384305+ctsk@users.noreply.github.com> Date: Tue, 13 Sep 2022 18:21:31 +0200 Subject: [PATCH] [tlox] Refactor to use Truffle DSL --- jlox/tlox/pom.xml | 6 +++++ .../main/java/xyz/ctsk/lox/LoxException.java | 14 ++++++++++ .../xyz/ctsk/lox/nodes/LoxExpressionNode.java | 2 ++ .../main/java/xyz/ctsk/lox/nodes/LoxNode.java | 1 + .../xyz/ctsk/lox/nodes/expr/LoxAddNode.java | 27 +++++++------------ .../ctsk/lox/nodes/expr/LoxBinaryNode.java | 9 +++++++ .../xyz/ctsk/lox/nodes/expr/LoxDivNode.java | 26 ++++++++---------- .../xyz/ctsk/lox/nodes/expr/LoxMulNode.java | 26 ++++++++---------- .../lox/nodes/expr/LoxNumberLiteralNode.java | 5 ++++ .../xyz/ctsk/lox/nodes/expr/LoxSubNode.java | 26 ++++++++---------- .../xyz/ctsk/lox/parser/LoxNodeFactory.java | 8 +++--- .../main/resources/xyz/ctsk/lox/parser/Lox.g4 | 2 +- 12 files changed, 85 insertions(+), 67 deletions(-) create mode 100644 jlox/tlox/src/main/java/xyz/ctsk/lox/LoxException.java create mode 100644 jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxBinaryNode.java diff --git a/jlox/tlox/pom.xml b/jlox/tlox/pom.xml index a96ad22..d55ed3a 100644 --- a/jlox/tlox/pom.xml +++ b/jlox/tlox/pom.xml @@ -26,6 +26,12 @@ truffle-api 22.2.0 + + org.graalvm.truffle + truffle-dsl-processor + 22.2.0 + provided + org.antlr antlr4 diff --git a/jlox/tlox/src/main/java/xyz/ctsk/lox/LoxException.java b/jlox/tlox/src/main/java/xyz/ctsk/lox/LoxException.java new file mode 100644 index 0000000..641e49c --- /dev/null +++ b/jlox/tlox/src/main/java/xyz/ctsk/lox/LoxException.java @@ -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()); + } +} diff --git a/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/LoxExpressionNode.java b/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/LoxExpressionNode.java index 75de126..6b9e800 100644 --- a/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/LoxExpressionNode.java +++ b/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/LoxExpressionNode.java @@ -4,4 +4,6 @@ import com.oracle.truffle.api.frame.VirtualFrame; public abstract class LoxExpressionNode extends LoxNode { public abstract double executeDouble(VirtualFrame frame); + + public abstract Object executeGeneric(VirtualFrame frame); } diff --git a/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/LoxNode.java b/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/LoxNode.java index d186c3e..3686d93 100644 --- a/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/LoxNode.java +++ b/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/LoxNode.java @@ -1,5 +1,6 @@ package xyz.ctsk.lox.nodes; +import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.nodes.Node; public class LoxNode extends Node { diff --git a/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxAddNode.java b/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxAddNode.java index 3b0c25c..a83cf2d 100644 --- a/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxAddNode.java +++ b/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxAddNode.java @@ -1,24 +1,17 @@ package xyz.ctsk.lox.nodes.expr; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; -import xyz.ctsk.lox.nodes.LoxExpressionNode; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.Specialization; +import xyz.ctsk.lox.LoxException; -public class LoxAddNode extends LoxExpressionNode { - @SuppressWarnings("FieldMayBeFinal") - @Node.Child - private LoxExpressionNode leftNode, rightNode; - - public LoxAddNode(LoxExpressionNode leftNode, LoxExpressionNode rightNode) { - this.leftNode = leftNode; - this.rightNode = rightNode; +public abstract class LoxAddNode extends LoxBinaryNode { + @Specialization + public double add(double left, double right) { + return left + right; } - - @Override - public double executeDouble(VirtualFrame frame) { - var leftValue = leftNode.executeDouble(frame); - var rightValue = rightNode.executeDouble(frame); - return leftValue + rightValue; + @Fallback + protected Object typeError(Object left, Object right) { + throw LoxException.typeError(this, left, right); } } diff --git a/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxBinaryNode.java b/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxBinaryNode.java new file mode 100644 index 0000000..e90b363 --- /dev/null +++ b/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxBinaryNode.java @@ -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 { +} diff --git a/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxDivNode.java b/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxDivNode.java index 93e5dfa..0fd446d 100644 --- a/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxDivNode.java +++ b/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxDivNode.java @@ -1,22 +1,18 @@ package xyz.ctsk.lox.nodes.expr; -import com.oracle.truffle.api.frame.VirtualFrame; -import xyz.ctsk.lox.nodes.LoxExpressionNode; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.Specialization; +import xyz.ctsk.lox.LoxException; -public class LoxDivNode extends LoxExpressionNode { - @SuppressWarnings("FieldMayBeFinal") - @Child - private LoxExpressionNode leftNode, rightNode; - - public LoxDivNode(LoxExpressionNode leftNode, LoxExpressionNode rightNode) { - this.leftNode = leftNode; - this.rightNode = rightNode; +public abstract class LoxDivNode extends LoxBinaryNode { + @Specialization + public double div(double left, double right) { + return left / right; } - @Override - public double executeDouble(VirtualFrame frame) { - var leftValue = leftNode.executeDouble(frame); - var rightValue = rightNode.executeDouble(frame); - return leftValue / rightValue; + @Fallback + protected Object typeError(Object left, Object right) { + throw LoxException.typeError(this, left, right); } + } diff --git a/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxMulNode.java b/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxMulNode.java index 948bf36..f5e5d04 100644 --- a/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxMulNode.java +++ b/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxMulNode.java @@ -1,22 +1,18 @@ package xyz.ctsk.lox.nodes.expr; -import com.oracle.truffle.api.frame.VirtualFrame; -import xyz.ctsk.lox.nodes.LoxExpressionNode; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.Specialization; +import xyz.ctsk.lox.LoxException; -public class LoxMulNode extends LoxExpressionNode { - @SuppressWarnings("FieldMayBeFinal") - @Child - private LoxExpressionNode leftNode, rightNode; - - public LoxMulNode(LoxExpressionNode leftNode, LoxExpressionNode rightNode) { - this.leftNode = leftNode; - this.rightNode = rightNode; +public abstract class LoxMulNode extends LoxBinaryNode { + @Specialization + public double mul(double left, double right) { + return left * right; } - @Override - public double executeDouble(VirtualFrame frame) { - var leftValue = leftNode.executeDouble(frame); - var rightValue = rightNode.executeDouble(frame); - return leftValue * rightValue; + @Fallback + protected Object typeError(Object left, Object right) { + throw LoxException.typeError(this, left, right); } + } diff --git a/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxNumberLiteralNode.java b/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxNumberLiteralNode.java index c90e3fd..a29a898 100644 --- a/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxNumberLiteralNode.java +++ b/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxNumberLiteralNode.java @@ -13,4 +13,9 @@ public class LoxNumberLiteralNode extends LoxExpressionNode { public double executeDouble(VirtualFrame frame) { return this.value; } + + @Override + public Object executeGeneric(VirtualFrame frame) { + return this.value; + } } diff --git a/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxSubNode.java b/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxSubNode.java index d6917b3..9c7adbe 100644 --- a/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxSubNode.java +++ b/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxSubNode.java @@ -1,22 +1,18 @@ package xyz.ctsk.lox.nodes.expr; -import com.oracle.truffle.api.frame.VirtualFrame; -import xyz.ctsk.lox.nodes.LoxExpressionNode; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.Specialization; +import xyz.ctsk.lox.LoxException; -public class LoxSubNode extends LoxExpressionNode { - @SuppressWarnings("FieldMayBeFinal") - @Child - private LoxExpressionNode leftNode, rightNode; - - public LoxSubNode(LoxExpressionNode leftNode, LoxExpressionNode rightNode) { - this.leftNode = leftNode; - this.rightNode = rightNode; +public abstract class LoxSubNode extends LoxBinaryNode { + @Specialization + public double sub(double left, double right) { + return left - right; } - @Override - public double executeDouble(VirtualFrame frame) { - var leftValue = leftNode.executeDouble(frame); - var rightValue = rightNode.executeDouble(frame); - return leftValue - rightValue; + @Fallback + protected Object typeError(Object left, Object right) { + throw LoxException.typeError(this, left, right); } + } diff --git a/jlox/tlox/src/main/java/xyz/ctsk/lox/parser/LoxNodeFactory.java b/jlox/tlox/src/main/java/xyz/ctsk/lox/parser/LoxNodeFactory.java index 263cdf1..54644b4 100644 --- a/jlox/tlox/src/main/java/xyz/ctsk/lox/parser/LoxNodeFactory.java +++ b/jlox/tlox/src/main/java/xyz/ctsk/lox/parser/LoxNodeFactory.java @@ -12,10 +12,10 @@ public class LoxNodeFactory { public static LoxExpressionNode createBinaryNode(Token op, LoxExpressionNode left, LoxExpressionNode right) { return switch (op.getText()) { - case "+" -> new LoxAddNode(left, right); - case "-" -> new LoxSubNode(left, right); - case "*" -> new LoxMulNode(left, right); - case "/" -> new LoxDivNode(left, right); + case "+" -> LoxAddNodeGen.create(left, right); + case "-" -> LoxSubNodeGen.create(left, right); + case "*" -> LoxMulNodeGen.create(left, right); + case "/" -> LoxDivNodeGen.create(left, right); default -> null; }; } diff --git a/jlox/tlox/src/main/resources/xyz/ctsk/lox/parser/Lox.g4 b/jlox/tlox/src/main/resources/xyz/ctsk/lox/parser/Lox.g4 index d5b2e85..722b77f 100644 --- a/jlox/tlox/src/main/resources/xyz/ctsk/lox/parser/Lox.g4 +++ b/jlox/tlox/src/main/resources/xyz/ctsk/lox/parser/Lox.g4 @@ -28,7 +28,7 @@ file 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); } ;