|
|
@@ -83,6 +83,12 @@ VAR
|
|
|
allowDefer: BOOLEAN;
|
|
|
curProcNode: AST.Node;
|
|
|
|
|
|
+ (* The last actual argument parsed by ActParam: folded value and type.
|
|
|
+ A conversion T(x) has exactly one actual, so these let Fact
|
|
|
+ constant-fold it (needed for `CONST c = T(x)`). *)
|
|
|
+ convQ: QbeGen.QVal;
|
|
|
+ convT: SymTab.TypeIndex;
|
|
|
+
|
|
|
(* Result slot for the expression-AST builder (slice 2). Every
|
|
|
Expr/SimExpr/Term/Fact leaves its node here; the combination
|
|
|
productions save it into locals before parsing the next operand.
|
|
|
@@ -356,6 +362,17 @@ PROCEDURE Adv;
|
|
|
INC(errDist)
|
|
|
END Adv;
|
|
|
|
|
|
+PROCEDURE OrdClass (t: SymTab.TypeIndex): BOOLEAN;
|
|
|
+(* TRUE for scalar ordinal classes (int/char/bool/enum/uchar); a
|
|
|
+ conversion between two of these is representation-preserving, so its
|
|
|
+ folded value equals the operand's. *)
|
|
|
+ VAR c: INTEGER;
|
|
|
+ BEGIN
|
|
|
+ c := SymTab.ClassOf(t);
|
|
|
+ RETURN (c = SymTab.ClInt) OR (c = SymTab.ClChar) OR (c = SymTab.ClBool)
|
|
|
+ OR (c = SymTab.ClEnum) OR (c = SymTab.ClUChar)
|
|
|
+ END OrdClass;
|
|
|
+
|
|
|
PROCEDURE NoteSpan (pn: SymTab.Name; start: M2S.INT32);
|
|
|
(* Records an outermost body span for the re-parse pass (milestone 2).
|
|
|
Diagnostic only for now: nothing consumes the table yet. Declared
|
|
|
@@ -2068,7 +2085,8 @@ PRODUCTIONS
|
|
|
savedArgs[aj] := astArgs[aj];
|
|
|
INC(aj)
|
|
|
END; .)
|
|
|
- Expr<at, qe> (. astActual := astCur;
|
|
|
+ Expr<at, qe> (. QbeGen.CopyOp(qe, convQ); convT := at;
|
|
|
+ astActual := astCur;
|
|
|
astNArgs := savedN; aj := 0;
|
|
|
WHILE aj <= HIGH(astArgs) DO
|
|
|
astArgs[aj] := savedArgs[aj];
|
|
|
@@ -3012,7 +3030,8 @@ PRODUCTIONS
|
|
|
j: CARDINAL;
|
|
|
astArg2: AST.Node;
|
|
|
astBrace: AST.Node;
|
|
|
- astRes: AST.Node; mname: SymTab.Name; isM: BOOLEAN; .)
|
|
|
+ astRes: AST.Node; mname: SymTab.Name; isM: BOOLEAN;
|
|
|
+ isConvF: BOOLEAN; .)
|
|
|
= (. astIsLit := FALSE; .)
|
|
|
( integer (. LexString(s);
|
|
|
QbeGen.NormInt(s, q); astIsLit := TRUE; astCur := AST.MakeLeaf(AST.NkIntLit, s);
|
|
|
@@ -3079,12 +3098,17 @@ PRODUCTIONS
|
|
|
AST.MakeLeaf(AST.NkIdent, qn));
|
|
|
IF astNArgs = 1 THEN
|
|
|
AST.SetChild(astNode, 2, astArgs[0])
|
|
|
- END
|
|
|
+ END;
|
|
|
+ isConvF := TRUE
|
|
|
ELSE astNode := AstCallNode(astD)
|
|
|
END;
|
|
|
astRes := astNode;
|
|
|
t := ct2;
|
|
|
QbeGen.CopyOp(q2, q);
|
|
|
+ IF isConvF AND QbeGen.IsImm(convQ)
|
|
|
+ AND OrdClass(convT) AND OrdClass(ct2) THEN
|
|
|
+ QbeGen.CopyOp(convQ, q)
|
|
|
+ END;
|
|
|
sfx := FALSE; .)
|
|
|
{ ResultComp<t, q, sfx, astRes, mname, methCls, isM>
|
|
|
[ (. astNArgs := 0; .)
|