|
|
@@ -1721,7 +1721,9 @@ PRODUCTIONS
|
|
|
QbeGen.QVal;
|
|
|
neg, isR, isL, folded:
|
|
|
BOOLEAN;
|
|
|
- lw, rw, mw: CARDINAL; .)
|
|
|
+ lw, rw, mw: CARDINAL;
|
|
|
+ lTrue, lNext, lDone:
|
|
|
+ QbeGen.QVal; .)
|
|
|
= (. neg := FALSE; .)
|
|
|
[ "+" | "-" (. neg := TRUE; .) ]
|
|
|
Term<t, q> (. IF neg THEN
|
|
|
@@ -1734,16 +1736,28 @@ PRODUCTIONS
|
|
|
QbeGen.CopyOp(qt, q)
|
|
|
END
|
|
|
END; .)
|
|
|
- { AddOp<op> Term<t2, q2>
|
|
|
+ { AddOp<op> (. IF op = SymTab.OpOr THEN
|
|
|
+ QbeGen.DelayBegin END; .)
|
|
|
+ Term<t2, q2> (. IF op = SymTab.OpOr THEN
|
|
|
+ QbeGen.DelayEnd END; .)
|
|
|
(. IF op = SymTab.OpOr THEN
|
|
|
+ (* short-circuit: if q is true the RHS is skipped *)
|
|
|
IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
t := SymTab.BoolType()
|
|
|
ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
IF t # SymTab.InvalidType THEN
|
|
|
- QbeGen.NewTemp(qt);
|
|
|
- QbeGen.Op3("or", qt, q, q2, FALSE);
|
|
|
- QbeGen.CopyOp(qt, q)
|
|
|
- ELSE QbeGen.CopyOp("0", q)
|
|
|
+ QbeGen.NewLabel(lTrue);
|
|
|
+ QbeGen.NewLabel(lNext);
|
|
|
+ QbeGen.NewLabel(lDone);
|
|
|
+ QbeGen.Jnz(q, lTrue, lNext);
|
|
|
+ QbeGen.EmitLabel(lNext);
|
|
|
+ QbeGen.DelayFlush;
|
|
|
+ QbeGen.CopyOp(q2, q);
|
|
|
+ QbeGen.Jmp(lDone);
|
|
|
+ QbeGen.EmitLabel(lTrue);
|
|
|
+ QbeGen.CopyOp("1", q);
|
|
|
+ QbeGen.EmitLabel(lDone)
|
|
|
+ ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
END
|
|
|
ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
@@ -1815,17 +1829,31 @@ PRODUCTIONS
|
|
|
q2, qt, wq, qf:
|
|
|
QbeGen.QVal;
|
|
|
isR, isL, folded: BOOLEAN;
|
|
|
- lw, rw, mw: CARDINAL; .)
|
|
|
- = Fact<t, q> { MulOp<op> Fact<t2, q2>
|
|
|
+ lw, rw, mw: CARDINAL;
|
|
|
+ lNext, lFalse, lDone:
|
|
|
+ QbeGen.QVal; .)
|
|
|
+ = Fact<t, q> { MulOp<op> (. IF op = SymTab.OpAnd THEN
|
|
|
+ QbeGen.DelayBegin END; .)
|
|
|
+ Fact<t2, q2> (. IF op = SymTab.OpAnd THEN
|
|
|
+ QbeGen.DelayEnd END; .)
|
|
|
(. IF op = SymTab.OpAnd THEN
|
|
|
+ (* short-circuit: if q is false the RHS is skipped *)
|
|
|
IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
t := SymTab.BoolType()
|
|
|
ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
IF t # SymTab.InvalidType THEN
|
|
|
- QbeGen.NewTemp(qt);
|
|
|
- QbeGen.Op3("and", qt, q, q2, FALSE);
|
|
|
- QbeGen.CopyOp(qt, q)
|
|
|
- ELSE QbeGen.CopyOp("0", q)
|
|
|
+ QbeGen.NewLabel(lNext);
|
|
|
+ QbeGen.NewLabel(lFalse);
|
|
|
+ QbeGen.NewLabel(lDone);
|
|
|
+ QbeGen.Jnz(q, lNext, lFalse);
|
|
|
+ QbeGen.EmitLabel(lNext);
|
|
|
+ QbeGen.DelayFlush;
|
|
|
+ QbeGen.CopyOp(q2, q);
|
|
|
+ QbeGen.Jmp(lDone);
|
|
|
+ QbeGen.EmitLabel(lFalse);
|
|
|
+ QbeGen.CopyOp("0", q);
|
|
|
+ QbeGen.EmitLabel(lDone)
|
|
|
+ ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
END
|
|
|
ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
AND (SymTab.ClassOf(t) = SymTab.ClSet)
|