add support for AND, NOT, OR in exprs

This commit is contained in:
ChUrl
2021-01-22 13:50:18 +01:00
parent 27201dfd0d
commit 7212dd8180

View File

@ -23,14 +23,15 @@ public final class CodeGenerator {
try { try {
final Class<?> gen = CodeGenerator.class; final Class<?> gen = CodeGenerator.class;
map = Map.ofEntries( map = Map.ofEntries(
entry("cond", gen.getDeclaredMethod("cond", ASTNode.class)),
entry("assignment", gen.getDeclaredMethod("assign", ASTNode.class)), entry("assignment", gen.getDeclaredMethod("assign", ASTNode.class)),
entry("expr", gen.getDeclaredMethod("expr", ASTNode.class)), entry("expr", gen.getDeclaredMethod("expr", ASTNode.class)),
// Leafs
entry("INTEGER_LIT", gen.getDeclaredMethod("intLiteral", ASTNode.class)), entry("INTEGER_LIT", gen.getDeclaredMethod("intLiteral", ASTNode.class)),
entry("BOOLEAN_LIT", gen.getDeclaredMethod("booleanLiteral", ASTNode.class)), entry("BOOLEAN_LIT", gen.getDeclaredMethod("boolLiteral", ASTNode.class)),
entry("STRING_LIT", gen.getDeclaredMethod("stringLiteral", ASTNode.class)), entry("STRING_LIT", gen.getDeclaredMethod("stringLiteral", ASTNode.class)),
entry("IDENTIFIER", gen.getDeclaredMethod("identifier", ASTNode.class)), entry("IDENTIFIER", gen.getDeclaredMethod("identifier", ASTNode.class)),
entry("print", gen.getDeclaredMethod("println", ASTNode.class)), entry("print", gen.getDeclaredMethod("println", ASTNode.class))
entry("cond", gen.getDeclaredMethod("cond", ASTNode.class))
); );
} catch (NoSuchMethodException e) { } catch (NoSuchMethodException e) {
map = null; map = null;
@ -196,6 +197,14 @@ public final class CodeGenerator {
} }
private void expr(ASTNode node) { private void expr(ASTNode node) {
if ("INTEGER_TYPE".equals(this.nodeTypeMap.get(node))) {
this.intExpr(node);
} else if ("BOOLEAN_TYPE".equals(this.nodeTypeMap.get(node))) {
this.boolExpr(node);
}
}
private void intExpr(ASTNode node) {
String inst = ""; String inst = "";
if (node.getChildren().size() == 1) { if (node.getChildren().size() == 1) {
@ -203,7 +212,7 @@ public final class CodeGenerator {
this.generateNode(node.getChildren().get(0)); this.generateNode(node.getChildren().get(0));
inst = switch (node.getValue()) { //!: Type dependant inst = switch (node.getValue()) {
case "ADD" -> ""; case "ADD" -> "";
case "SUB" -> "ldc -1\n\t\timul"; case "SUB" -> "ldc -1\n\t\timul";
// case "NOT" -> ... // case "NOT" -> ...
@ -215,7 +224,7 @@ public final class CodeGenerator {
this.generateNode(node.getChildren().get(0)); this.generateNode(node.getChildren().get(0));
this.generateNode(node.getChildren().get(1)); this.generateNode(node.getChildren().get(1));
inst = switch (node.getValue()) { //!: Type dependant inst = switch (node.getValue()) {
case "ADD" -> "iadd"; // Integer case "ADD" -> "iadd"; // Integer
case "SUB" -> "isub"; case "SUB" -> "isub";
case "MUL" -> "imul"; case "MUL" -> "imul";
@ -225,7 +234,43 @@ public final class CodeGenerator {
}; };
} }
log("expr(): " + node.getName() + ": " + node.getValue() + " => " + inst); log("intExpr(): " + node.getName() + ": " + node.getValue() + " => " + inst);
this.jasmin.append("\t\t")
.append(inst)
.append("\n");
}
private void boolExpr(ASTNode node) {
String inst = "";
if (node.getChildren().size() == 1) {
// Unary operator
if (!"NOT".equals(node.getValue())) {
// Diese Möglichkeit gibts eigentlich nicht
throw new IllegalStateException("Unexpected value: " + node.getValue());
}
this.generateNode(node.getChildren().get(0));
// 1 -> 0, 0 -> 1?
inst = "ldc 1\n\t\tisub\n\t\tdup\n\t\timul"; // Subtract 1 and square for now
} else if (node.getChildren().size() == 2) {
// Binary operator
this.generateNode(node.getChildren().get(0));
this.generateNode(node.getChildren().get(1));
inst = switch (node.getValue()) {
case "AND" -> "iand"; // Boolean
case "OR" -> "ior";
default -> throw new IllegalStateException("Unexpected value: " + node.getValue());
};
}
log("boolExpr(): " + node.getName() + ": " + node.getValue() + " => " + inst);
this.jasmin.append("\t\t") this.jasmin.append("\t\t")
.append(inst) .append(inst)
@ -252,7 +297,7 @@ public final class CodeGenerator {
.append("\n"); .append("\n");
} }
private void booleanLiteral(ASTNode node) { private void boolLiteral(ASTNode node) {
log("booleanLiteral(): " + node.getName() + ": " + node.getValue() + " => ldc"); log("booleanLiteral(): " + node.getName() + ": " + node.getValue() + " => ldc");
final String val = "true".equals(node.getValue()) ? "1" : "0"; final String val = "true".equals(node.getValue()) ? "1" : "0";