|
@@ -12,6 +12,12 @@ PROCEDURE Name (n: AST.Node; VAR s: ARRAY OF CHAR);
|
|
|
END
|
|
END
|
|
|
END Name;
|
|
END Name;
|
|
|
|
|
|
|
|
|
|
+PROCEDURE ParamName (proc: ARRAY OF CHAR; i: CARDINAL;
|
|
|
|
|
+ VAR s: ARRAY OF CHAR);
|
|
|
|
|
+ BEGIN
|
|
|
|
|
+ IF NOT SymTab.ParamName(proc, i, s) THEN s[0] := CHR(0) END
|
|
|
|
|
+ END ParamName;
|
|
|
|
|
+
|
|
|
PROCEDURE IsArith (op: INTEGER): BOOLEAN;
|
|
PROCEDURE IsArith (op: INTEGER): BOOLEAN;
|
|
|
BEGIN
|
|
BEGIN
|
|
|
RETURN (op = AST.OpAdd) OR (op = AST.OpSub) OR (op = AST.OpMul)
|
|
RETURN (op = AST.OpAdd) OR (op = AST.OpSub) OR (op = AST.OpMul)
|
|
@@ -60,12 +66,45 @@ PROCEDURE IsSimpleScalar (n: AST.Node): BOOLEAN;
|
|
|
RETURN IsScalarClass(SymTab.ClassOf(SymTab.SymType(nm)))
|
|
RETURN IsScalarClass(SymTab.ClassOf(SymTab.SymType(nm)))
|
|
|
END IsSimpleScalar;
|
|
END IsSimpleScalar;
|
|
|
|
|
|
|
|
|
|
+PROCEDURE CalleeName (call: AST.Node; VAR nm: SymTab.Name);
|
|
|
|
|
+(* The callee of NkCall: child 0 is a designator (or bare ident). *)
|
|
|
|
|
+ VAR d: AST.Node;
|
|
|
|
|
+ BEGIN
|
|
|
|
|
+ nm[0] := CHR(0);
|
|
|
|
|
+ d := AST.Child(call, 0);
|
|
|
|
|
+ IF d = AST.NoNode THEN RETURN END;
|
|
|
|
|
+ IF AST.Kind(d) = AST.NkDesignator THEN d := AST.Child(d, 0) END;
|
|
|
|
|
+ IF (d # AST.NoNode) AND (AST.Kind(d) = AST.NkIdent) THEN Name(d, nm) END
|
|
|
|
|
+ END CalleeName;
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE IsCall (n: AST.Node): BOOLEAN;
|
|
|
|
|
+ VAR nm: SymTab.Name;
|
|
|
|
|
+ BEGIN
|
|
|
|
|
+ IF (AST.Kind(n) # AST.NkCall) OR (AST.NChild(n) < 1) THEN RETURN FALSE END;
|
|
|
|
|
+ CalleeName(n, nm);
|
|
|
|
|
+ RETURN SymTab.Lookup(nm) AND (SymTab.SymKind(nm) = SymTab.KindProc)
|
|
|
|
|
+ END IsCall;
|
|
|
|
|
+
|
|
|
|
|
+PROCEDURE CanCallArgs (n: AST.Node): BOOLEAN;
|
|
|
|
|
+ VAR nm: SymTab.Name; i: CARDINAL;
|
|
|
|
|
+ BEGIN
|
|
|
|
|
+ CalleeName(n, nm);
|
|
|
|
|
+ IF SymTab.ProcNPar(nm) # (AST.NChild(n) - 1) THEN RETURN FALSE END;
|
|
|
|
|
+ i := 1;
|
|
|
|
|
+ WHILE i < AST.NChild(n) DO
|
|
|
|
|
+ IF NOT CanExpr(AST.Child(n, i)) THEN RETURN FALSE END;
|
|
|
|
|
+ INC(i)
|
|
|
|
|
+ END;
|
|
|
|
|
+ RETURN TRUE
|
|
|
|
|
+ END CanCallArgs;
|
|
|
|
|
+
|
|
|
PROCEDURE CanExpr (n: AST.Node): BOOLEAN;
|
|
PROCEDURE CanExpr (n: AST.Node): BOOLEAN;
|
|
|
VAR op: INTEGER;
|
|
VAR op: INTEGER;
|
|
|
BEGIN
|
|
BEGIN
|
|
|
IF n = AST.NoNode THEN RETURN FALSE END;
|
|
IF n = AST.NoNode THEN RETURN FALSE END;
|
|
|
IF AST.Kind(n) = AST.NkIntLit THEN RETURN TRUE END;
|
|
IF AST.Kind(n) = AST.NkIntLit THEN RETURN TRUE END;
|
|
|
IF AST.Kind(n) = AST.NkDesignator THEN RETURN IsSimpleScalar(n) END;
|
|
IF AST.Kind(n) = AST.NkDesignator THEN RETURN IsSimpleScalar(n) END;
|
|
|
|
|
+ IF AST.Kind(n) = AST.NkCall THEN RETURN IsCall(n) AND CanCallArgs(n) END;
|
|
|
IF AST.Kind(n) = AST.NkUnary THEN
|
|
IF AST.Kind(n) = AST.NkUnary THEN
|
|
|
op := AST.Op(n);
|
|
op := AST.Op(n);
|
|
|
IF (op # AST.OpSub) AND (op # AST.OpNot) THEN RETURN FALSE END;
|
|
IF (op # AST.OpSub) AND (op # AST.OpNot) THEN RETURN FALSE END;
|
|
@@ -121,6 +160,11 @@ PROCEDURE CanStmt (n: AST.Node): BOOLEAN;
|
|
|
IF AST.Child(n, 0) = AST.NoNode THEN RETURN TRUE END;
|
|
IF AST.Child(n, 0) = AST.NoNode THEN RETURN TRUE END;
|
|
|
RETURN CanExpr(AST.Child(n, 0))
|
|
RETURN CanExpr(AST.Child(n, 0))
|
|
|
END;
|
|
END;
|
|
|
|
|
+ IF k = AST.NkReturn THEN
|
|
|
|
|
+ IF AST.Child(n, 0) = AST.NoNode THEN RETURN TRUE END;
|
|
|
|
|
+ RETURN CanExpr(AST.Child(n, 0))
|
|
|
|
|
+ END;
|
|
|
|
|
+ IF k = AST.NkCall THEN RETURN IsCall(n) AND CanCallArgs(n) END;
|
|
|
RETURN FALSE
|
|
RETURN FALSE
|
|
|
END CanStmt;
|
|
END CanStmt;
|
|
|
|
|
|
|
@@ -141,6 +185,7 @@ PROCEDURE CanDecl (c: AST.Node): BOOLEAN;
|
|
|
RETURN IsScalarClass(SymTab.ClassOf(AST.Ty(c)))
|
|
RETURN IsScalarClass(SymTab.ClassOf(AST.Ty(c)))
|
|
|
AND (AST.Kind(AST.Child(c, 1)) = AST.NkIntLit)
|
|
AND (AST.Kind(AST.Child(c, 1)) = AST.NkIntLit)
|
|
|
END;
|
|
END;
|
|
|
|
|
+ IF AST.Kind(c) = AST.NkProcDecl THEN RETURN CanProc(c) END;
|
|
|
RETURN FALSE
|
|
RETURN FALSE
|
|
|
END CanDecl;
|
|
END CanDecl;
|
|
|
|
|
|
|
@@ -170,6 +215,23 @@ PROCEDURE CanLower (unit: AST.Node): BOOLEAN;
|
|
|
RETURN CanDecls(AST.Child(unit, 1)) AND CanStmt(AST.Child(unit, 2))
|
|
RETURN CanDecls(AST.Child(unit, 1)) AND CanStmt(AST.Child(unit, 2))
|
|
|
END CanLower;
|
|
END CanLower;
|
|
|
|
|
|
|
|
|
|
+PROCEDURE CanProc (proc: AST.Node): BOOLEAN;
|
|
|
|
|
+ VAR nm: SymTab.Name; i: CARDINAL;
|
|
|
|
|
+ BEGIN
|
|
|
|
|
+ IF AST.Op(proc) # 0 THEN RETURN FALSE END;
|
|
|
|
|
+ Name(AST.Child(proc, 0), nm);
|
|
|
|
|
+ IF NOT SymTab.Lookup(nm) THEN RETURN FALSE END;
|
|
|
|
|
+ IF (SymTab.ProcRes(nm) # SymTab.InvalidType)
|
|
|
|
|
+ AND NOT IsScalarClass(SymTab.ClassOf(SymTab.ProcRes(nm))) THEN
|
|
|
|
|
+ RETURN FALSE END;
|
|
|
|
|
+ i := 0;
|
|
|
|
|
+ WHILE i < SymTab.ProcNPar(nm) DO
|
|
|
|
|
+ IF NOT IsScalarClass(SymTab.ClassOf(SymTab.ParamType(nm, i))) THEN
|
|
|
|
|
+ RETURN FALSE END;
|
|
|
|
|
+ INC(i)
|
|
|
|
|
+ END;
|
|
|
|
|
+ RETURN CanDecls(AST.Child(proc, 2)) AND CanStmt(AST.Child(proc, 1))
|
|
|
|
|
+ END CanProc;
|
|
|
PROCEDURE LowerDesign (n: AST.Node; VAR t: SymTab.TypeIndex; VAR k: INTEGER;
|
|
PROCEDURE LowerDesign (n: AST.Node; VAR t: SymTab.TypeIndex; VAR k: INTEGER;
|
|
|
VAR q: QbeGen.QVal; VAR qn: SymTab.Name;
|
|
VAR q: QbeGen.QVal; VAR qn: SymTab.Name;
|
|
|
VAR sfx: BOOLEAN);
|
|
VAR sfx: BOOLEAN);
|
|
@@ -198,6 +260,44 @@ PROCEDURE LowerDesign (n: AST.Node; VAR t: SymTab.TypeIndex; VAR k: INTEGER;
|
|
|
END
|
|
END
|
|
|
END LowerDesign;
|
|
END LowerDesign;
|
|
|
|
|
|
|
|
|
|
+PROCEDURE LowerCall (n: AST.Node; VAR t: SymTab.TypeIndex;
|
|
|
|
|
+ VAR q: QbeGen.QVal; want: BOOLEAN);
|
|
|
|
|
+ VAR nm: SymTab.Name; i: CARDINAL; at, ft, res: SymTab.TypeIndex;
|
|
|
|
|
+ qa, qt, qe: QbeGen.QVal; mg: QbeGen.QVal; cls: CHAR; conv, isV: BOOLEAN;
|
|
|
|
|
+ BEGIN
|
|
|
|
|
+ Name(AST.Child(n, 0), nm);
|
|
|
|
|
+ CalleeName(n, nm);
|
|
|
|
|
+ QbeGen.Mangled(nm, SymTab.ProcUid(nm), mg);
|
|
|
|
|
+ res := SymTab.ProcRes(nm);
|
|
|
|
|
+ QbeGen.CallBegin(mg, res, SymTab.ProcDepthOf(nm), SymTab.IsExternal(nm));
|
|
|
|
|
+ i := 1;
|
|
|
|
|
+ WHILE i < AST.NChild(n) DO
|
|
|
|
|
+ LowerExpr(AST.Child(n, i), at, qe);
|
|
|
|
|
+ ft := SymTab.ParamType(nm, i - 1);
|
|
|
|
|
+ isV := SymTab.ParamIsVar(nm, i - 1);
|
|
|
|
|
+ IF isV THEN
|
|
|
|
|
+ IF QbeGen.AddrOfVal(qe, qa) THEN
|
|
|
|
|
+ IF NOT QbeGen.CallArg(qa, "l") THEN END
|
|
|
|
|
+ END
|
|
|
|
|
+ ELSE
|
|
|
|
|
+ conv := (SymTab.ClassOf(ft) = SymTab.ClReal)
|
|
|
|
|
+ AND SymTab.IsIntFamily(at);
|
|
|
|
|
+ IF conv THEN
|
|
|
|
|
+ QbeGen.ConvIR(qe, qt);
|
|
|
|
|
+ IF NOT QbeGen.CallArg(qt, "d") THEN END
|
|
|
|
|
+ ELSE
|
|
|
|
|
+ IF NOT QbeGen.CallArg(qe, QbeGen.ArgClass(ft)) THEN END
|
|
|
|
|
+ END
|
|
|
|
|
+ END;
|
|
|
|
|
+ INC(i)
|
|
|
|
|
+ END;
|
|
|
|
|
+ IF want THEN
|
|
|
|
|
+ t := res; QbeGen.CallEnd(TRUE, q)
|
|
|
|
|
+ ELSE
|
|
|
|
|
+ t := SymTab.InvalidType; QbeGen.CopyOp("0", q); QbeGen.CallEnd(FALSE, q)
|
|
|
|
|
+ END
|
|
|
|
|
+ END LowerCall;
|
|
|
|
|
+
|
|
|
PROCEDURE LowerExpr (n: AST.Node; VAR t: SymTab.TypeIndex;
|
|
PROCEDURE LowerExpr (n: AST.Node; VAR t: SymTab.TypeIndex;
|
|
|
VAR q: QbeGen.QVal);
|
|
VAR q: QbeGen.QVal);
|
|
|
VAR t2: SymTab.TypeIndex; q2, qt, qf, qs, qr: QbeGen.QVal;
|
|
VAR t2: SymTab.TypeIndex; q2, qt, qf, qs, qr: QbeGen.QVal;
|
|
@@ -209,6 +309,8 @@ PROCEDURE LowerExpr (n: AST.Node; VAR t: SymTab.TypeIndex;
|
|
|
Name(n, qn); QbeGen.NormInt(qn, q); t := SymTab.IntType()
|
|
Name(n, qn); QbeGen.NormInt(qn, q); t := SymTab.IntType()
|
|
|
ELSIF AST.Kind(n) = AST.NkDesignator THEN
|
|
ELSIF AST.Kind(n) = AST.NkDesignator THEN
|
|
|
LowerDesign(n, t, k, q, qn, sfx)
|
|
LowerDesign(n, t, k, q, qn, sfx)
|
|
|
|
|
+ ELSIF AST.Kind(n) = AST.NkCall THEN
|
|
|
|
|
+ LowerCall(n, t, q, TRUE)
|
|
|
ELSIF AST.Kind(n) = AST.NkUnary THEN
|
|
ELSIF AST.Kind(n) = AST.NkUnary THEN
|
|
|
LowerExpr(AST.Child(n, 0), t, q);
|
|
LowerExpr(AST.Child(n, 0), t, q);
|
|
|
IF AST.Op(n) = AST.OpSub THEN
|
|
IF AST.Op(n) = AST.OpSub THEN
|
|
@@ -388,11 +490,25 @@ PROCEDURE LowerStmt (seq: AST.Node);
|
|
|
IF AST.Child(seq, 0) # AST.NoNode THEN
|
|
IF AST.Child(seq, 0) # AST.NoNode THEN
|
|
|
LowerExpr(AST.Child(seq, 0), t, q) END;
|
|
LowerExpr(AST.Child(seq, 0), t, q) END;
|
|
|
QbeGen.HaltQ
|
|
QbeGen.HaltQ
|
|
|
|
|
+ ELSIF k = AST.NkReturn THEN
|
|
|
|
|
+ IF AST.Child(seq, 0) = AST.NoNode THEN
|
|
|
|
|
+ QbeGen.EmitRet(q, FALSE)
|
|
|
|
|
+ ELSE
|
|
|
|
|
+ LowerExpr(AST.Child(seq, 0), t, q);
|
|
|
|
|
+ conv := (SymTab.ClassOf(SymTab.CurRes()) = SymTab.ClReal)
|
|
|
|
|
+ AND SymTab.IsIntFamily(t);
|
|
|
|
|
+ IF conv THEN QbeGen.ConvIR(q, qt); QbeGen.EmitRet(qt, TRUE)
|
|
|
|
|
+ ELSE QbeGen.EmitRet(q, TRUE)
|
|
|
|
|
+ END
|
|
|
|
|
+ END
|
|
|
|
|
+ ELSIF k = AST.NkCall THEN
|
|
|
|
|
+ LowerCall(seq, t, q, FALSE)
|
|
|
END
|
|
END
|
|
|
END LowerStmt;
|
|
END LowerStmt;
|
|
|
|
|
|
|
|
PROCEDURE LowerDecls (seq: AST.Node);
|
|
PROCEDURE LowerDecls (seq: AST.Node);
|
|
|
VAR i, j: CARDINAL; c: AST.Node; nm, txt: SymTab.Name; qv: QbeGen.QVal;
|
|
VAR i, j: CARDINAL; c: AST.Node; nm, txt: SymTab.Name; qv: QbeGen.QVal;
|
|
|
|
|
+ mg: QbeGen.QVal;
|
|
|
BEGIN
|
|
BEGIN
|
|
|
IF seq = AST.NoNode THEN RETURN END;
|
|
IF seq = AST.NoNode THEN RETURN END;
|
|
|
i := 0;
|
|
i := 0;
|
|
@@ -412,6 +528,23 @@ PROCEDURE LowerDecls (seq: AST.Node);
|
|
|
Name(AST.Child(c, 1), txt);
|
|
Name(AST.Child(c, 1), txt);
|
|
|
QbeGen.NormInt(txt, qv);
|
|
QbeGen.NormInt(txt, qv);
|
|
|
QbeGen.DeclConst(nm, qv, AST.Ty(c))
|
|
QbeGen.DeclConst(nm, qv, AST.Ty(c))
|
|
|
|
|
+ ELSIF AST.Kind(c) = AST.NkProcDecl THEN
|
|
|
|
|
+ Name(AST.Child(c, 0), nm);
|
|
|
|
|
+ QbeGen.Mangled(nm, SymTab.ProcUid(nm), mg);
|
|
|
|
|
+ QbeGen.BeginFunc(mg);
|
|
|
|
|
+ j := 0;
|
|
|
|
|
+ WHILE j < SymTab.ProcNPar(nm) DO
|
|
|
|
|
+ ParamName(nm, j, txt);
|
|
|
|
|
+ IF NOT QbeGen.FuncParam(txt, SymTab.ParamIsVar(nm, j),
|
|
|
|
|
+ SymTab.ParamType(nm, j)) THEN
|
|
|
|
|
+ END;
|
|
|
|
|
+ INC(j)
|
|
|
|
|
+ END;
|
|
|
|
|
+ QbeGen.SetFuncRes(SymTab.ProcRes(nm));
|
|
|
|
|
+ QbeGen.EndFuncHeader;
|
|
|
|
|
+ LowerDecls(AST.Child(c, 2));
|
|
|
|
|
+ LowerStmt(AST.Child(c, 1));
|
|
|
|
|
+ QbeGen.EndFunc(SymTab.ProcRes(nm))
|
|
|
END;
|
|
END;
|
|
|
INC(i)
|
|
INC(i)
|
|
|
END
|
|
END
|