diff --git a/stackvm/src/main/java/com/compilerprogramming/ezlang/compiler/CompiledFunction.java b/stackvm/src/main/java/com/compilerprogramming/ezlang/compiler/CompiledFunction.java index ed83aca..4d384c1 100644 --- a/stackvm/src/main/java/com/compilerprogramming/ezlang/compiler/CompiledFunction.java +++ b/stackvm/src/main/java/com/compilerprogramming/ezlang/compiler/CompiledFunction.java @@ -343,7 +343,39 @@ private boolean compileSymbolExpr(AST.NameExpr symbolExpr) { return false; } + private boolean codeBoolean(AST.BinaryExpr binaryExpr) { + boolean isAnd = binaryExpr.op.str.equals("&&"); + BasicBlock l1 = createBlock(); + BasicBlock l2 = createBlock(); + BasicBlock l3 = createBlock(); + boolean indexed = compileExpr(binaryExpr.expr1); + if (indexed) + codeIndexedLoad(); + if (isAnd) { + code(new Instruction.ConditionalBranch(currentBlock, l1, l2)); + } else { + code(new Instruction.ConditionalBranch(currentBlock, l2, l1)); + } + startBlock(l1); + indexed = compileExpr(binaryExpr.expr2); + if (indexed) + codeIndexedLoad(); + jumpTo(l3); + startBlock(l2); + // Below we must write to the same temp + code(new Instruction.PushConst(isAnd ? 0 : 1)); + jumpTo(l3); + startBlock(l3); + // leaves result on stack + return false; + } + private boolean compileBinaryExpr(AST.BinaryExpr binaryExpr) { + String binOp = binaryExpr.op.str; + if (binOp.equals("&&") || + binOp.equals("||")) { + return codeBoolean(binaryExpr); + } int opCode = 0; boolean indexed = compileExpr(binaryExpr.expr1); if (indexed) @@ -351,7 +383,7 @@ private boolean compileBinaryExpr(AST.BinaryExpr binaryExpr) { indexed = compileExpr(binaryExpr.expr2); if (indexed) codeIndexedLoad(); - switch (binaryExpr.op.str) { + switch (binOp) { case "+" -> opCode = Instruction.ADD_I; case "-" -> opCode = Instruction.SUB_I; case "*" -> opCode = Instruction.MUL_I; diff --git a/stackvm/src/test/java/com/compilerprogramming/ezlang/compiler/TestCompiler.java b/stackvm/src/test/java/com/compilerprogramming/ezlang/compiler/TestCompiler.java index 6393090..2d828ee 100644 --- a/stackvm/src/test/java/com/compilerprogramming/ezlang/compiler/TestCompiler.java +++ b/stackvm/src/test/java/com/compilerprogramming/ezlang/compiler/TestCompiler.java @@ -634,4 +634,34 @@ public void testFunction28() { L1: """, result); } + + @Test + public void testFunction104() { + String src = """ + func foo()->Int + { + return 1 == 1 && 2 == 2 + } + """; + String result = compileSrc(src); + Assert.assertEquals(""" +L0: + pushi 1 + pushi 1 + eq + cbr L2 L3 +L2: + pushi 2 + pushi 2 + eq + jump L4 +L4: + jump L1 +L1: +L3: + pushi 0 + jump L4 +""", result); + } + }