From a1e5b4cb797c0cccc0e67dab3f0f139b0c14bae9 Mon Sep 17 00:00:00 2001 From: ctsk <9384305+ctsk@users.noreply.github.com> Date: Tue, 13 Sep 2022 20:51:33 +0200 Subject: [PATCH] [tlox] Add Equality and Unary operands --- .../lox/nodes/{expr => }/LoxBinaryNode.java | 2 +- .../java/xyz/ctsk/lox/nodes/LoxUnaryNode.java | 7 ++++++ .../xyz/ctsk/lox/nodes/expr/LoxAddNode.java | 1 + .../xyz/ctsk/lox/nodes/expr/LoxDivNode.java | 1 + .../xyz/ctsk/lox/nodes/expr/LoxEqualNode.java | 25 +++++++++++++++++++ .../ctsk/lox/nodes/expr/LoxGreaterNode.java | 1 + .../lox/nodes/expr/LoxGreaterOrEqualNode.java | 1 + .../xyz/ctsk/lox/nodes/expr/LoxLessNode.java | 1 + .../lox/nodes/expr/LoxLessOrEqualNode.java | 1 + .../lox/nodes/expr/LoxLogicalNotNode.java | 18 +++++++++++++ .../xyz/ctsk/lox/nodes/expr/LoxMulNode.java | 1 + .../xyz/ctsk/lox/nodes/expr/LoxNegNode.java | 18 +++++++++++++ .../xyz/ctsk/lox/nodes/expr/LoxSubNode.java | 1 + .../xyz/ctsk/lox/parser/LoxNodeFactory.java | 13 +++++++++- .../main/resources/xyz/ctsk/lox/parser/Lox.g4 | 11 +++++--- 15 files changed, 97 insertions(+), 5 deletions(-) rename jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/{expr => }/LoxBinaryNode.java (86%) create mode 100644 jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/LoxUnaryNode.java create mode 100644 jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxEqualNode.java create mode 100644 jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxLogicalNotNode.java create mode 100644 jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxNegNode.java 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/LoxBinaryNode.java similarity index 86% rename from jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxBinaryNode.java rename to jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/LoxBinaryNode.java index e90b363..f9c52e6 100644 --- a/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxBinaryNode.java +++ b/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/LoxBinaryNode.java @@ -1,4 +1,4 @@ -package xyz.ctsk.lox.nodes.expr; +package xyz.ctsk.lox.nodes; import com.oracle.truffle.api.dsl.NodeChild; import xyz.ctsk.lox.nodes.LoxExpressionNode; diff --git a/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/LoxUnaryNode.java b/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/LoxUnaryNode.java new file mode 100644 index 0000000..856d53a --- /dev/null +++ b/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/LoxUnaryNode.java @@ -0,0 +1,7 @@ +package xyz.ctsk.lox.nodes; + +import com.oracle.truffle.api.dsl.NodeChild; + +@NodeChild("value") +public abstract class LoxUnaryNode extends LoxExpressionNode { +} 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 a83cf2d..c1412b5 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 @@ -3,6 +3,7 @@ package xyz.ctsk.lox.nodes.expr; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import xyz.ctsk.lox.LoxException; +import xyz.ctsk.lox.nodes.LoxBinaryNode; public abstract class LoxAddNode extends LoxBinaryNode { @Specialization 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 0fd446d..d71de48 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 @@ -3,6 +3,7 @@ package xyz.ctsk.lox.nodes.expr; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import xyz.ctsk.lox.LoxException; +import xyz.ctsk.lox.nodes.LoxBinaryNode; public abstract class LoxDivNode extends LoxBinaryNode { @Specialization diff --git a/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxEqualNode.java b/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxEqualNode.java new file mode 100644 index 0000000..0599f29 --- /dev/null +++ b/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxEqualNode.java @@ -0,0 +1,25 @@ +package xyz.ctsk.lox.nodes.expr; + +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.Specialization; +import xyz.ctsk.lox.nodes.LoxBinaryNode; + +import java.util.Objects; + +public abstract class LoxEqualNode extends LoxBinaryNode { + @Specialization + public boolean equal(double left, double right) { + return left == right; + } + + @Specialization + public boolean equal(boolean left, boolean right) { + return left == right; + } + + @Fallback + protected Object typeError(Object left, Object right) { + return Objects.equals(left, right); + } + +} diff --git a/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxGreaterNode.java b/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxGreaterNode.java index aecdcbf..a73c14b 100644 --- a/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxGreaterNode.java +++ b/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxGreaterNode.java @@ -3,6 +3,7 @@ package xyz.ctsk.lox.nodes.expr; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import xyz.ctsk.lox.LoxException; +import xyz.ctsk.lox.nodes.LoxBinaryNode; public abstract class LoxGreaterNode extends LoxBinaryNode { @Specialization diff --git a/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxGreaterOrEqualNode.java b/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxGreaterOrEqualNode.java index 6ca04a3..0d8976b 100644 --- a/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxGreaterOrEqualNode.java +++ b/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxGreaterOrEqualNode.java @@ -3,6 +3,7 @@ package xyz.ctsk.lox.nodes.expr; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import xyz.ctsk.lox.LoxException; +import xyz.ctsk.lox.nodes.LoxBinaryNode; public abstract class LoxGreaterOrEqualNode extends LoxBinaryNode { @Specialization diff --git a/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxLessNode.java b/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxLessNode.java index 7e4050c..0db2380 100644 --- a/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxLessNode.java +++ b/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxLessNode.java @@ -3,6 +3,7 @@ package xyz.ctsk.lox.nodes.expr; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import xyz.ctsk.lox.LoxException; +import xyz.ctsk.lox.nodes.LoxBinaryNode; public abstract class LoxLessNode extends LoxBinaryNode { @Specialization diff --git a/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxLessOrEqualNode.java b/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxLessOrEqualNode.java index 58b1726..3caa83f 100644 --- a/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxLessOrEqualNode.java +++ b/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxLessOrEqualNode.java @@ -3,6 +3,7 @@ package xyz.ctsk.lox.nodes.expr; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import xyz.ctsk.lox.LoxException; +import xyz.ctsk.lox.nodes.LoxBinaryNode; public abstract class LoxLessOrEqualNode extends LoxBinaryNode { @Specialization diff --git a/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxLogicalNotNode.java b/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxLogicalNotNode.java new file mode 100644 index 0000000..0a7c61d --- /dev/null +++ b/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxLogicalNotNode.java @@ -0,0 +1,18 @@ +package xyz.ctsk.lox.nodes.expr; + +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.Specialization; +import xyz.ctsk.lox.LoxException; +import xyz.ctsk.lox.nodes.LoxUnaryNode; + +public abstract class LoxLogicalNotNode extends LoxUnaryNode { + @Specialization + public boolean not(boolean value) { + return !value; + } + + @Fallback + protected Object typeError(Object value) { + throw LoxException.typeError(this, value); + } +} 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 f5e5d04..4d9b5b9 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 @@ -3,6 +3,7 @@ package xyz.ctsk.lox.nodes.expr; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import xyz.ctsk.lox.LoxException; +import xyz.ctsk.lox.nodes.LoxBinaryNode; public abstract class LoxMulNode extends LoxBinaryNode { @Specialization diff --git a/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxNegNode.java b/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxNegNode.java new file mode 100644 index 0000000..7e2c96b --- /dev/null +++ b/jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/expr/LoxNegNode.java @@ -0,0 +1,18 @@ +package xyz.ctsk.lox.nodes.expr; + +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.Specialization; +import xyz.ctsk.lox.LoxException; +import xyz.ctsk.lox.nodes.LoxUnaryNode; + +public abstract class LoxNegNode extends LoxUnaryNode { + @Specialization + public double negate(double value) { + return -value; + } + + @Fallback + protected Object typeError(Object value) { + throw LoxException.typeError(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 9c7adbe..20ebbcb 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 @@ -3,6 +3,7 @@ package xyz.ctsk.lox.nodes.expr; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import xyz.ctsk.lox.LoxException; +import xyz.ctsk.lox.nodes.LoxBinaryNode; public abstract class LoxSubNode extends LoxBinaryNode { @Specialization 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 fd0dd58..7568d6b 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 @@ -1,6 +1,7 @@ package xyz.ctsk.lox.parser; import org.antlr.v4.runtime.Token; +import xyz.ctsk.lox.LoxException; import xyz.ctsk.lox.nodes.LoxExpressionNode; import xyz.ctsk.lox.nodes.expr.*; @@ -10,7 +11,15 @@ public class LoxNodeFactory { return new LoxNumberLiteralNode(value); } - public static LoxExpressionNode createBinaryNode(Token op, LoxExpressionNode left, LoxExpressionNode right) { + public static LoxExpressionNode createUnary(Token op, LoxExpressionNode value) { + return switch (op.getText()) { + case "-" -> LoxNegNodeGen.create(value); + case "!" -> LoxLogicalNotNodeGen.create(value); + default -> null; + }; + } + + public static LoxExpressionNode createBinary(Token op, LoxExpressionNode left, LoxExpressionNode right) { return switch (op.getText()) { case "+" -> LoxAddNodeGen.create(left, right); case "-" -> LoxSubNodeGen.create(left, right); @@ -20,6 +29,8 @@ public class LoxNodeFactory { case "<=" -> LoxLessOrEqualNodeGen.create(left, right); case ">" -> LoxGreaterNodeGen.create(left, right); case ">=" -> LoxGreaterOrEqualNodeGen.create(left, right); + case "==" -> LoxEqualNodeGen.create(left, right); + case "!=" -> LoxLogicalNotNodeGen.create(LoxEqualNodeGen.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 dced7d2..1195f36 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 @@ -27,15 +27,20 @@ file returns [LoxExpressionNode result] : expression EOF { $result = $expression.result; } ; + expression returns [LoxExpressionNode result] : literal { $result = $literal.result; } + | op=( '-' | BANG ) expression + { $result = factory.createUnary($op, $expression.result); } | left=expression op=( '*' | '/' ) right=expression - { $result = factory.createBinaryNode($op, $left.result, $right.result); } + { $result = factory.createBinary($op, $left.result, $right.result); } | left=expression op=( '+' | '-' ) right=expression - { $result = factory.createBinaryNode($op, $left.result, $right.result); } + { $result = factory.createBinary($op, $left.result, $right.result); } | left=expression op=( LESS | LESS_EQUAL | GREATER | GREATER_EQUAL) right=expression - { $result = factory.createBinaryNode($op, $left.result, $right.result); } + { $result = factory.createBinary($op, $left.result, $right.result); } + | left=expression op=( EQUAL_EQUAL | BANG_EQUAL ) right=expression + { $result = factory.createBinary($op, $left.result, $right.result); } ; literal returns [LoxExpressionNode result]