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); }
;