Skip to content

Commit 0c82836

Browse files
more work on boolean binary expressions
Fix bug in EnterSSA caused by mutable operands shared across instructions, replacing the phi register cause other instructions to change inadvertantly. Ensure SSA tests check output
1 parent cfd9b76 commit 0c82836

File tree

2 files changed

+110
-25
lines changed

2 files changed

+110
-25
lines changed

registervm/src/main/java/com/compilerprogramming/ezlang/compiler/CompiledFunction.java

Lines changed: 42 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -412,42 +412,28 @@ private boolean compileSymbolExpr(AST.NameExpr symbolExpr) {
412412
}
413413

414414
private boolean codeBoolean(AST.BinaryExpr binaryExpr) {
415-
BasicBlock l1;
416-
BasicBlock l2;
417-
BasicBlock l3;
418-
boolean indexed;
419-
boolean isAnd;
420-
421-
l1 = createBlock();
422-
l2 = createBlock();
423-
l3 = createBlock();
424-
indexed = compileExpr(binaryExpr.expr1);
425-
if (indexed) {
415+
boolean isAnd = binaryExpr.op.str.equals("&&");
416+
BasicBlock l1 = createBlock();
417+
BasicBlock l2 = createBlock();
418+
BasicBlock l3 = createBlock();
419+
boolean indexed = compileExpr(binaryExpr.expr1);
420+
if (indexed)
426421
codeIndexedLoad();
427-
}
428-
isAnd = binaryExpr.op.str.equals("&&");
429-
// FIXME ensure temp
430-
var operand = pop();
431-
var temp = createTemp(typeDictionary.INT);
432-
code(new Instruction.Move(operand, temp));
433422
if (isAnd) {
434423
code(new Instruction.ConditionalBranch(currentBlock, pop(), l1, l2));
435424
} else {
436425
code(new Instruction.ConditionalBranch(currentBlock, pop(), l2, l1));
437426
}
438427
startBlock(l1);
439-
indexed = compileExpr(binaryExpr.expr2);
440-
if (indexed) {
441-
codeIndexedLoad();
442-
}
443-
operand = pop();
444-
temp = createTemp(typeDictionary.INT);
445-
code(new Instruction.Move(operand, temp));
428+
compileExpr(binaryExpr.expr2);
429+
var temp = ensureTemp();
446430
jumpTo(l3);
447431
startBlock(l2);
432+
// Below we must write to the same temp
448433
code(new Instruction.Move(new Operand.ConstantOperand(isAnd ? 0 : 1, typeDictionary.INT), temp));
449434
jumpTo(l3);
450435
startBlock(l3);
436+
// leave temp on virtual stack
451437
return false;
452438
}
453439

@@ -549,6 +535,36 @@ private Operand.TempRegisterOperand createTemp(Type type) {
549535
return tempRegister;
550536
}
551537

538+
Type typeOfOperand(Operand operand) {
539+
if (operand instanceof Operand.ConstantOperand constant)
540+
return constant.type;
541+
else if (operand instanceof Operand.NullConstantOperand nullConstantOperand)
542+
return nullConstantOperand.type;
543+
else if (operand instanceof Operand.RegisterOperand registerOperand)
544+
return registerOperand.type;
545+
else throw new CompilerException("Invalid operand");
546+
}
547+
548+
private Operand.TempRegisterOperand createTempAndMove(Operand src) {
549+
Type type = typeOfOperand(src);
550+
var temp = createTemp(type);
551+
code(new Instruction.Move(src, temp));
552+
return temp;
553+
}
554+
555+
private Operand.RegisterOperand ensureTemp() {
556+
Operand top = top();
557+
if (top instanceof Operand.ConstantOperand
558+
|| top instanceof Operand.NullConstantOperand
559+
|| top instanceof Operand.LocalRegisterOperand) {
560+
return createTempAndMove(pop());
561+
} else if (top instanceof Operand.IndexedOperand) {
562+
return codeIndexedLoad();
563+
} else if (top instanceof Operand.TempRegisterOperand tempRegisterOperand) {
564+
return tempRegisterOperand;
565+
} else throw new CompilerException("Cannot convert to temporary register");
566+
}
567+
552568
private void pushLocal(int regnum, String varName) {
553569
pushOperand(new Operand.LocalRegisterOperand(regnum, varName));
554570
}
@@ -565,7 +581,7 @@ private Operand top() {
565581
return virtualStack.getLast();
566582
}
567583

568-
private void codeIndexedLoad() {
584+
private Operand.TempRegisterOperand codeIndexedLoad() {
569585
Operand indexed = pop();
570586
var temp = createTemp(indexed.type);
571587
if (indexed instanceof Operand.LoadIndexedOperand loadIndexedOperand) {
@@ -576,6 +592,7 @@ else if (indexed instanceof Operand.LoadFieldOperand loadFieldOperand) {
576592
}
577593
else
578594
code(new Instruction.Move(indexed, temp));
595+
return temp;
579596
}
580597

581598
private void codeIndexedStore() {

registervm/src/test/java/com/compilerprogramming/ezlang/interpreter/TestInterpreter.java

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,4 +176,72 @@ func foo()->Int
176176
integerValue.value == 1);
177177
}
178178

179+
@Test
180+
public void testFunction104() {
181+
String src = """
182+
func foo()->Int
183+
{
184+
return 1 == 1 && 2 == 2
185+
}
186+
187+
""";
188+
var value = compileAndRun(src, "foo");
189+
Assert.assertNotNull(value);
190+
Assert.assertTrue(value instanceof Value.IntegerValue integerValue &&
191+
integerValue.value == 1);
192+
}
193+
194+
@Test
195+
public void testFunction105() {
196+
String src = """
197+
func bar(a: Int, b: Int)->Int
198+
{
199+
return a+1 == b-1 && b / a == 2
200+
}
201+
func foo()->Int
202+
{
203+
return bar(3,5)
204+
}
205+
""";
206+
var value = compileAndRun(src, "foo");
207+
Assert.assertNotNull(value);
208+
Assert.assertTrue(value instanceof Value.IntegerValue integerValue &&
209+
integerValue.value == 0);
210+
}
211+
212+
@Test
213+
public void testFunction106() {
214+
String src = """
215+
func bar(a: Int, b: Int)->Int
216+
{
217+
return a+1 == b-1 || b / a == 2
218+
}
219+
func foo()->Int
220+
{
221+
return bar(3,5)
222+
}
223+
""";
224+
var value = compileAndRun(src, "foo");
225+
Assert.assertNotNull(value);
226+
Assert.assertTrue(value instanceof Value.IntegerValue integerValue &&
227+
integerValue.value == 1);
228+
}
229+
230+
@Test
231+
public void testFunction107() {
232+
String src = """
233+
func bar(a: [Int])->Int
234+
{
235+
return a[0]+a[2] == a[1]-a[2] || a[1] / a[0] == 2
236+
}
237+
func foo()->Int
238+
{
239+
return bar(new [Int] {3,5,1})
240+
}
241+
""";
242+
var value = compileAndRun(src, "foo");
243+
Assert.assertNotNull(value);
244+
Assert.assertTrue(value instanceof Value.IntegerValue integerValue &&
245+
integerValue.value == 1);
246+
}
179247
}

0 commit comments

Comments
 (0)