|
|
@@ -217,7 +217,7 @@ PROCEDURE IsArith (op: INTEGER): BOOLEAN;
|
|
|
|
|
|
PROCEDURE IsRel (op: INTEGER): BOOLEAN;
|
|
|
BEGIN
|
|
|
- RETURN (op >= AST.OpEq) AND (op <= AST.OpGe)
|
|
|
+ RETURN ((op >= AST.OpEq) AND (op <= AST.OpGe)) OR (op = AST.OpIn)
|
|
|
END IsRel;
|
|
|
|
|
|
PROCEDURE RelSym (a: INTEGER; VAR s: INTEGER): BOOLEAN;
|
|
|
@@ -408,10 +408,25 @@ PROCEDURE CanCaseLabel (lab: AST.Node): BOOLEAN;
|
|
|
END CanCaseLabel;
|
|
|
|
|
|
PROCEDURE CanExpr (n: AST.Node): BOOLEAN;
|
|
|
- VAR op: INTEGER; nm: SymTab.Name;
|
|
|
+ VAR op: INTEGER; nm: SymTab.Name; i: CARDINAL;
|
|
|
BEGIN
|
|
|
IF n = AST.NoNode THEN RETURN FALSE END;
|
|
|
IF AST.Kind(n) = AST.NkIntLit THEN RETURN TRUE END;
|
|
|
+ IF AST.Kind(n) = AST.NkCharLit THEN RETURN TRUE END;
|
|
|
+ IF AST.Kind(n) = AST.NkRealLit THEN RETURN TRUE END;
|
|
|
+ IF AST.Kind(n) = AST.NkStrLit THEN RETURN TRUE END;
|
|
|
+ IF AST.Kind(n) = AST.NkSetLit THEN
|
|
|
+ i := 0;
|
|
|
+ WHILE i < AST.NChild(n) DO
|
|
|
+ IF AST.Kind(AST.Child(n, i)) = AST.NkSubrange THEN
|
|
|
+ IF NOT CanExpr(AST.Child(AST.Child(n, i), 0)) THEN RETURN FALSE END;
|
|
|
+ IF NOT CanExpr(AST.Child(AST.Child(n, i), 1)) THEN RETURN FALSE END
|
|
|
+ ELSIF NOT CanExpr(AST.Child(n, i)) THEN RETURN FALSE
|
|
|
+ END;
|
|
|
+ INC(i)
|
|
|
+ END;
|
|
|
+ RETURN TRUE
|
|
|
+ END;
|
|
|
IF AST.Kind(n) = AST.NkDesignator THEN RETURN CanDesign(n) END;
|
|
|
IF AST.Kind(n) = AST.NkCall THEN
|
|
|
CalleeName(n, nm);
|
|
|
@@ -956,7 +971,8 @@ PROCEDURE LowerExprFull (n: AST.Node; VAR t: SymTab.TypeIndex;
|
|
|
VAR t2: SymTab.TypeIndex; q2, qt, qf, qs, qr: QbeGen.QVal;
|
|
|
lNext, lFalse, lTrue, lDone: QbeGen.QVal;
|
|
|
kind, op, rop: INTEGER;
|
|
|
- folded, isR: BOOLEAN;
|
|
|
+ folded, isR, isCh: BOOLEAN;
|
|
|
+ i: CARDINAL; el: AST.Node;
|
|
|
BEGIN
|
|
|
IF AST.Kind(n) = AST.NkDesignator THEN
|
|
|
LowerDesign(n, t, k, q, qn, sfx);
|
|
|
@@ -966,6 +982,33 @@ PROCEDURE LowerExprFull (n: AST.Node; VAR t: SymTab.TypeIndex;
|
|
|
k := -1; qn[0] := CHR(0); sfx := FALSE;
|
|
|
IF AST.Kind(n) = AST.NkIntLit THEN
|
|
|
Name(n, qn); QbeGen.NormInt(qn, q); t := SymTab.IntType()
|
|
|
+ ELSIF AST.Kind(n) = AST.NkCharLit THEN
|
|
|
+ Name(n, qn); QbeGen.NormLit(qn, q, isCh); t := SymTab.CharType()
|
|
|
+ ELSIF AST.Kind(n) = AST.NkRealLit THEN
|
|
|
+ Name(n, qn); QbeGen.NormReal(qn, q); t := SymTab.RealType()
|
|
|
+ ELSIF AST.Kind(n) = AST.NkStrLit THEN
|
|
|
+ Name(n, qn);
|
|
|
+ IF SymTab.StrLen(qn) = 3 THEN
|
|
|
+ t := SymTab.CharType(); QbeGen.IntStr(QbeGen.CharVal(qn), q)
|
|
|
+ ELSE
|
|
|
+ t := SymTab.NewStr(); QbeGen.DeclStr(qn, q); QbeGen.NoteAddr(q, q)
|
|
|
+ END
|
|
|
+ ELSIF AST.Kind(n) = AST.NkSetLit THEN
|
|
|
+ t := SymTab.NewSet(SymTab.NewSubR(0, 255));
|
|
|
+ QbeGen.NewSetTemp(8, q); QbeGen.SetZero(q, 8);
|
|
|
+ i := 0;
|
|
|
+ WHILE i < AST.NChild(n) DO
|
|
|
+ el := AST.Child(n, i);
|
|
|
+ IF AST.Kind(el) = AST.NkSubrange THEN
|
|
|
+ LowerExpr(AST.Child(el, 0), t2, q2);
|
|
|
+ LowerExpr(AST.Child(el, 1), t2, qt);
|
|
|
+ QbeGen.SetRange(q, q2, qt, SymTab.SetBaseLo(t), SymTab.SetCount(t))
|
|
|
+ ELSE
|
|
|
+ LowerExpr(el, t2, q2);
|
|
|
+ QbeGen.SetBit(q, q2, SymTab.SetBaseLo(t), SymTab.SetCount(t))
|
|
|
+ END;
|
|
|
+ INC(i)
|
|
|
+ END
|
|
|
ELSIF AST.Kind(n) = AST.NkDesignator THEN
|
|
|
LowerDesign(n, t, k, q, qn, sfx)
|
|
|
ELSIF AST.Kind(n) = AST.NkCall THEN
|
|
|
@@ -988,10 +1031,31 @@ PROCEDURE LowerExprFull (n: AST.Node; VAR t: SymTab.TypeIndex;
|
|
|
LowerExpr(AST.Child(n, 0), t, q);
|
|
|
LowerExpr(AST.Child(n, 1), t2, q2);
|
|
|
rop := SymTab.OpEq; folded := RelSym(op, rop);
|
|
|
- isR := (t # SymTab.InvalidType) AND (SymTab.ClassOf(t) = SymTab.ClReal);
|
|
|
- t := SymTab.BoolType();
|
|
|
- QbeGen.Cmp(rop, q, q2, qt, isR);
|
|
|
- QbeGen.CopyOp(qt, q)
|
|
|
+ IF op = AST.OpIn THEN
|
|
|
+ QbeGen.InSet(q, q2, SymTab.SetBaseLo(t2), SymTab.SetCount(t2), qt);
|
|
|
+ t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ ELSIF (SymTab.ClassOf(t) = SymTab.ClPtr)
|
|
|
+ OR (SymTab.ClassOf(t2) = SymTab.ClPtr) THEN
|
|
|
+ QbeGen.CmpL(rop, q, q2, qt);
|
|
|
+ t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ ELSIF (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ OR (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ QbeGen.CmpSet(rop, q, q2, SymTab.SetWords(t), SymTab.SetWords(t2), qt);
|
|
|
+ t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ ELSIF SymTab.StrCompat(t, t2) THEN
|
|
|
+ QbeGen.StrEq(rop, q, q2, qt);
|
|
|
+ t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ ELSIF SymTab.IsLongFamily(t) OR SymTab.IsLongFamily(t2) THEN
|
|
|
+ IF SymTab.IsIntFamily(t) THEN QbeGen.WidenLong(q, qf); QbeGen.CopyOp(qf, q) END;
|
|
|
+ IF SymTab.IsIntFamily(t2) THEN QbeGen.WidenLong(q2, qf); QbeGen.CopyOp(qf, q2) END;
|
|
|
+ QbeGen.CmpLong(rop, q, q2, qt);
|
|
|
+ t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ ELSE
|
|
|
+ isR := (t # SymTab.InvalidType) AND (SymTab.ClassOf(t) = SymTab.ClReal);
|
|
|
+ t := SymTab.BoolType();
|
|
|
+ QbeGen.Cmp(rop, q, q2, qt, isR);
|
|
|
+ QbeGen.CopyOp(qt, q)
|
|
|
+ END
|
|
|
ELSIF op = AST.OpAnd THEN
|
|
|
LowerExpr(AST.Child(n, 0), t, q);
|
|
|
QbeGen.DelayBegin;
|