[tlox] Initial Expression parsing and evaluation
This commit is contained in:
38
jlox/tlox/src/main/java/xyz/ctsk/lox/Main.java
Normal file
38
jlox/tlox/src/main/java/xyz/ctsk/lox/Main.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package xyz.ctsk.lox;
|
||||
|
||||
import com.oracle.truffle.api.Truffle;
|
||||
import xyz.ctsk.lox.nodes.LoxRootNode;
|
||||
import xyz.ctsk.lox.parser.LoxParser;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
public class Main {
|
||||
|
||||
public static void repl() throws IOException {
|
||||
var input = new InputStreamReader(System.in);
|
||||
var reader = new BufferedReader(input);
|
||||
|
||||
while (true) {
|
||||
System.out.print(" >> ");
|
||||
var line = reader.readLine();
|
||||
if (line == null) break;
|
||||
run(line);
|
||||
}
|
||||
}
|
||||
|
||||
public static void run(String program) {
|
||||
var parsed = LoxParser.parseLox(program);
|
||||
|
||||
if (parsed instanceof LoxParser.ExpressionContext expr) {
|
||||
var root = new LoxRootNode(expr.result);
|
||||
var callTarget = root.getCallTarget();
|
||||
System.out.println(callTarget.call());
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
repl();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package xyz.ctsk.lox.nodes;
|
||||
|
||||
import com.oracle.truffle.api.frame.VirtualFrame;
|
||||
|
||||
public abstract class LoxExpressionNode extends LoxNode {
|
||||
public abstract double executeDouble(VirtualFrame frame);
|
||||
}
|
||||
6
jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/LoxNode.java
Normal file
6
jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/LoxNode.java
Normal file
@@ -0,0 +1,6 @@
|
||||
package xyz.ctsk.lox.nodes;
|
||||
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
|
||||
public class LoxNode extends Node {
|
||||
}
|
||||
20
jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/LoxRootNode.java
Normal file
20
jlox/tlox/src/main/java/xyz/ctsk/lox/nodes/LoxRootNode.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package xyz.ctsk.lox.nodes;
|
||||
|
||||
import com.oracle.truffle.api.frame.VirtualFrame;
|
||||
import com.oracle.truffle.api.nodes.RootNode;
|
||||
|
||||
public class LoxRootNode extends RootNode {
|
||||
@SuppressWarnings("FieldMayBeFinal")
|
||||
@Child
|
||||
private LoxExpressionNode exprNode;
|
||||
|
||||
public LoxRootNode(LoxExpressionNode exprNode) {
|
||||
super(null);
|
||||
this.exprNode = exprNode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object execute(VirtualFrame frame) {
|
||||
return this.exprNode.executeDouble(frame);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public double executeDouble(VirtualFrame frame) {
|
||||
var leftValue = leftNode.executeDouble(frame);
|
||||
var rightValue = rightNode.executeDouble(frame);
|
||||
return leftValue + rightValue;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package xyz.ctsk.lox.nodes.expr;
|
||||
|
||||
import com.oracle.truffle.api.frame.VirtualFrame;
|
||||
import xyz.ctsk.lox.nodes.LoxExpressionNode;
|
||||
|
||||
public class LoxDivNode extends LoxExpressionNode {
|
||||
@SuppressWarnings("FieldMayBeFinal")
|
||||
@Child
|
||||
private LoxExpressionNode leftNode, rightNode;
|
||||
|
||||
public LoxDivNode(LoxExpressionNode leftNode, LoxExpressionNode rightNode) {
|
||||
this.leftNode = leftNode;
|
||||
this.rightNode = rightNode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double executeDouble(VirtualFrame frame) {
|
||||
var leftValue = leftNode.executeDouble(frame);
|
||||
var rightValue = rightNode.executeDouble(frame);
|
||||
return leftValue / rightValue;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package xyz.ctsk.lox.nodes.expr;
|
||||
|
||||
import com.oracle.truffle.api.frame.VirtualFrame;
|
||||
import xyz.ctsk.lox.nodes.LoxExpressionNode;
|
||||
|
||||
public class LoxMulNode extends LoxExpressionNode {
|
||||
@SuppressWarnings("FieldMayBeFinal")
|
||||
@Child
|
||||
private LoxExpressionNode leftNode, rightNode;
|
||||
|
||||
public LoxMulNode(LoxExpressionNode leftNode, LoxExpressionNode rightNode) {
|
||||
this.leftNode = leftNode;
|
||||
this.rightNode = rightNode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double executeDouble(VirtualFrame frame) {
|
||||
var leftValue = leftNode.executeDouble(frame);
|
||||
var rightValue = rightNode.executeDouble(frame);
|
||||
return leftValue * rightValue;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package xyz.ctsk.lox.nodes.expr;
|
||||
|
||||
import com.oracle.truffle.api.frame.VirtualFrame;
|
||||
import xyz.ctsk.lox.nodes.LoxExpressionNode;
|
||||
|
||||
public class LoxNumberLiteralNode extends LoxExpressionNode {
|
||||
private final double value;
|
||||
|
||||
public LoxNumberLiteralNode(double value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public double executeDouble(VirtualFrame frame) {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package xyz.ctsk.lox.nodes.expr;
|
||||
|
||||
import com.oracle.truffle.api.frame.VirtualFrame;
|
||||
import xyz.ctsk.lox.nodes.LoxExpressionNode;
|
||||
|
||||
public class LoxSubNode extends LoxExpressionNode {
|
||||
@SuppressWarnings("FieldMayBeFinal")
|
||||
@Child
|
||||
private LoxExpressionNode leftNode, rightNode;
|
||||
|
||||
public LoxSubNode(LoxExpressionNode leftNode, LoxExpressionNode rightNode) {
|
||||
this.leftNode = leftNode;
|
||||
this.rightNode = rightNode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double executeDouble(VirtualFrame frame) {
|
||||
var leftValue = leftNode.executeDouble(frame);
|
||||
var rightValue = rightNode.executeDouble(frame);
|
||||
return leftValue - rightValue;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package xyz.ctsk.lox.parser;
|
||||
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import xyz.ctsk.lox.nodes.LoxExpressionNode;
|
||||
import xyz.ctsk.lox.nodes.expr.*;
|
||||
|
||||
public class LoxNodeFactory {
|
||||
public static LoxNumberLiteralNode createNumberLiteral(Token literalToken) {
|
||||
var value = Double.parseDouble(literalToken.getText());
|
||||
return new LoxNumberLiteralNode(value);
|
||||
}
|
||||
|
||||
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);
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user