|
|
@@ -254,7 +254,8 @@ PRODUCTIONS
|
|
|
IF (t # SymTab.InvalidType)
|
|
|
& (cls # SymTab.ClInt)
|
|
|
& (cls # SymTab.ClBool)
|
|
|
- & (cls # SymTab.ClChar) THEN
|
|
|
+ & (cls # SymTab.ClChar)
|
|
|
+ & (cls # SymTab.ClReal) THEN
|
|
|
SemError(230) END;
|
|
|
i := 0;
|
|
|
WHILE i < SymTab.PendCount() DO
|
|
|
@@ -324,8 +325,9 @@ PRODUCTIONS
|
|
|
ELSE SemError(230) END; .) .
|
|
|
Assign (. VAR dt, et: SymTab.TypeIndex;
|
|
|
dk: INTEGER;
|
|
|
- qd, qe: QbeGen.QVal;
|
|
|
- qn: SymTab.Name; .)
|
|
|
+ qd, qe, qt: QbeGen.QVal;
|
|
|
+ qn: SymTab.Name;
|
|
|
+ isR, conv: BOOLEAN; .)
|
|
|
= Design<dt, dk, qd, qn> ":="
|
|
|
Expr<et, qe> (. IF (dt # SymTab.InvalidType)
|
|
|
& (dk # SymTab.KindVar)
|
|
|
@@ -334,11 +336,22 @@ PRODUCTIONS
|
|
|
ELSIF ~SymTab.Assignable(et,
|
|
|
dt) THEN
|
|
|
SemError(210) END;
|
|
|
+ isR := (dt #
|
|
|
+ SymTab.InvalidType)
|
|
|
+ & (SymTab.ClassOf(dt)
|
|
|
+ = SymTab.ClReal);
|
|
|
+ conv := isR
|
|
|
+ & SymTab.IsIntFamily(et);
|
|
|
IF ((dk = SymTab.KindVar)
|
|
|
OR (dk = SymTab.KindParam))
|
|
|
& (dt # SymTab.InvalidType)
|
|
|
& (et # SymTab.InvalidType) THEN
|
|
|
- QbeGen.StoreVar(qn, qe, FALSE)
|
|
|
+ IF conv THEN
|
|
|
+ QbeGen.ConvIR(qe, qt);
|
|
|
+ QbeGen.StoreVar(qn, qt, TRUE)
|
|
|
+ ELSE
|
|
|
+ QbeGen.StoreVar(qn, qe, isR)
|
|
|
+ END
|
|
|
END; .) .
|
|
|
IfStat (. VAR t: SymTab.TypeIndex;
|
|
|
q, lThen, lElse, lEnd:
|
|
|
@@ -585,9 +598,11 @@ PRODUCTIONS
|
|
|
SymTab.InvalidType)
|
|
|
& ((cls = SymTab.ClInt)
|
|
|
OR (cls
|
|
|
- = SymTab.ClChar)) THEN
|
|
|
+ = SymTab.ClChar)
|
|
|
+ OR (cls
|
|
|
+ = SymTab.ClReal)) THEN
|
|
|
QbeGen.LoadVar(n,
|
|
|
- FALSE, q)
|
|
|
+ cls = SymTab.ClReal, q)
|
|
|
ELSE
|
|
|
IF t #
|
|
|
SymTab.InvalidType THEN
|
|
|
@@ -602,9 +617,11 @@ PRODUCTIONS
|
|
|
SymTab.ClassOf(t);
|
|
|
IF (cls = SymTab.ClInt)
|
|
|
OR (cls = SymTab.ClBool)
|
|
|
- OR (cls = SymTab.ClChar) THEN
|
|
|
+ OR (cls = SymTab.ClChar)
|
|
|
+ OR (cls
|
|
|
+ = SymTab.ClReal) THEN
|
|
|
QbeGen.LoadVar(n,
|
|
|
- FALSE, q)
|
|
|
+ cls = SymTab.ClReal, q)
|
|
|
ELSE SemError(230);
|
|
|
QbeGen.CopyOp("0", q)
|
|
|
END
|
|
|
@@ -618,14 +635,17 @@ PRODUCTIONS
|
|
|
Expr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
(. VAR t2: SymTab.TypeIndex;
|
|
|
op: INTEGER;
|
|
|
- q2, qt: QbeGen.QVal; .)
|
|
|
+ q2, qt: QbeGen.QVal;
|
|
|
+ isR: BOOLEAN; .)
|
|
|
= SimExpr<t, q>
|
|
|
[ Rel<op> SimExpr<t2, q2>
|
|
|
(. IF SymTab.RelCheck(t, t2, op) THEN
|
|
|
+ isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
t := SymTab.BoolType()
|
|
|
- ELSE SemError(213); t := SymTab.InvalidType END;
|
|
|
+ ELSE SemError(213); t := SymTab.InvalidType;
|
|
|
+ isR := FALSE END;
|
|
|
IF t # SymTab.InvalidType THEN
|
|
|
- QbeGen.Cmp(op, q, q2, qt, FALSE);
|
|
|
+ QbeGen.Cmp(op, q, q2, qt, isR);
|
|
|
QbeGen.CopyOp(qt, q)
|
|
|
ELSE QbeGen.CopyOp("0", q)
|
|
|
END; .) ] .
|
|
|
@@ -640,14 +660,16 @@ PRODUCTIONS
|
|
|
(. VAR t2, res2: SymTab.TypeIndex;
|
|
|
op: INTEGER;
|
|
|
q2, qt: QbeGen.QVal;
|
|
|
- neg: BOOLEAN; .)
|
|
|
+ neg, isR: BOOLEAN; .)
|
|
|
= (. neg := FALSE; .)
|
|
|
[ "+" | "-" (. neg := TRUE; .) ]
|
|
|
Term<t, q> (. IF neg THEN
|
|
|
IF QbeGen.IsImm(q) THEN
|
|
|
QbeGen.NegFold(q, q)
|
|
|
ELSE QbeGen.NewTemp(qt);
|
|
|
- QbeGen.NegQ(q, qt, FALSE);
|
|
|
+ QbeGen.NegQ(q, qt,
|
|
|
+ SymTab.ClassOf(t)
|
|
|
+ = SymTab.ClReal);
|
|
|
QbeGen.CopyOp(qt, q)
|
|
|
END
|
|
|
END; .)
|
|
|
@@ -666,12 +688,13 @@ PRODUCTIONS
|
|
|
IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
|
|
|
t := res2
|
|
|
ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
+ isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
IF t # SymTab.InvalidType THEN
|
|
|
QbeGen.NewTemp(qt);
|
|
|
IF op = SymTab.OpAdd THEN
|
|
|
- QbeGen.Op3("add", qt, q, q2, FALSE)
|
|
|
+ QbeGen.Op3("add", qt, q, q2, isR)
|
|
|
ELSE
|
|
|
- QbeGen.Op3("sub", qt, q, q2, FALSE)
|
|
|
+ QbeGen.Op3("sub", qt, q, q2, isR)
|
|
|
END;
|
|
|
QbeGen.CopyOp(qt, q)
|
|
|
ELSE QbeGen.CopyOp("0", q)
|
|
|
@@ -684,7 +707,8 @@ PRODUCTIONS
|
|
|
Term<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
(. VAR t2, res2: SymTab.TypeIndex;
|
|
|
op: INTEGER;
|
|
|
- q2, qt: QbeGen.QVal; .)
|
|
|
+ q2, qt: QbeGen.QVal;
|
|
|
+ isR: BOOLEAN; .)
|
|
|
= Fact<t, q> { MulOp<op> Fact<t2, q2>
|
|
|
(. IF op = SymTab.OpAnd THEN
|
|
|
IF SymTab.BoolCheck(t) & SymTab.BoolCheck(t2) THEN
|
|
|
@@ -701,14 +725,16 @@ PRODUCTIONS
|
|
|
(op = SymTab.OpDiv) OR (op = SymTab.OpMod),
|
|
|
res2) THEN t := res2
|
|
|
ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
+ isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
IF t # SymTab.InvalidType THEN
|
|
|
QbeGen.NewTemp(qt);
|
|
|
IF op = SymTab.OpTimes THEN
|
|
|
- QbeGen.Op3("mul", qt, q, q2, FALSE)
|
|
|
- ELSIF op = SymTab.OpDiv THEN
|
|
|
- QbeGen.Op3("div", qt, q, q2, FALSE)
|
|
|
+ QbeGen.Op3("mul", qt, q, q2, isR)
|
|
|
+ ELSIF (op = SymTab.OpDiv)
|
|
|
+ OR (op = SymTab.OpSlash) THEN
|
|
|
+ QbeGen.Op3("div", qt, q, q2, isR)
|
|
|
ELSE
|
|
|
- QbeGen.Op3("rem", qt, q, q2, FALSE)
|
|
|
+ QbeGen.Op3("rem", qt, q, q2, isR)
|
|
|
END;
|
|
|
QbeGen.CopyOp(qt, q)
|
|
|
ELSE QbeGen.CopyOp("0", q)
|
|
|
@@ -716,6 +742,7 @@ PRODUCTIONS
|
|
|
END; .) } .
|
|
|
MulOp<VAR op: INTEGER>
|
|
|
= "*" (. op := SymTab.OpTimes; .)
|
|
|
+ | "/" (. op := SymTab.OpSlash; .)
|
|
|
| "DIV" (. op := SymTab.OpDiv; .)
|
|
|
| "MOD" (. op := SymTab.OpMod; .)
|
|
|
| "AND" (. op := SymTab.OpAnd; .) .
|
|
|
@@ -729,9 +756,8 @@ PRODUCTIONS
|
|
|
QbeGen.NormInt(s, q);
|
|
|
t := SymTab.IntType(); .)
|
|
|
| real (. LexString(s);
|
|
|
- t := SymTab.RealType();
|
|
|
- SemError(230);
|
|
|
- QbeGen.CopyOp("0", q); .)
|
|
|
+ QbeGen.NormReal(s, q);
|
|
|
+ t := SymTab.RealType(); .)
|
|
|
| string (. LexString(s);
|
|
|
IF SymTab.StrLen(s) <= 3 THEN
|
|
|
t := SymTab.CharType();
|