|
|
@@ -261,7 +261,7 @@ Listing:
|
|
|
243
|
|
|
244 PRODUCTIONS
|
|
|
245 M2
|
|
|
- 246 = (. AST.Init; twoPhase := TRUE; astCur := AST.NoNode; astStmt := AST.NoNode; astDecl := AST.NoNode; astImp := AST.NoNode; astImpTail := AST.NoNode;
|
|
|
+ 246 = (. AST.Init; twoPhase := TRUE; astCur := AST.NoNode; astStmt := AST.NoNode; astDecl := AST.NoNode; astImp := AST.NoNode; astImpTail := AST.NoNode; Lower.Reset;
|
|
|
247 astImp := AST.NoNode;
|
|
|
248 astImpTail := AST.NoNode; .)
|
|
|
249 Unit "." (. FileIO.WriteString(FileIO.StdOut, "ASTDUMP:"); FileIO.WriteLn(FileIO.StdOut); AST.Dump(astUnit, 0); .) .
|
|
|
@@ -1037,2789 +1037,2804 @@ Listing:
|
|
|
1019 AST.SetChild(astNode, 1, astCur);
|
|
|
1020 AST.SetTy(astNode, t);
|
|
|
1021 astDecl := astNode;
|
|
|
- 1022 SymTab.SetSymType(n, t);
|
|
|
- 1023 cls := SymTab.ClassOf(t);
|
|
|
- 1024 IF (cls = SymTab.ClArray)
|
|
|
- 1025 OR (cls = SymTab.ClRecord)
|
|
|
- 1026 OR (cls = SymTab.ClClass)
|
|
|
- 1027 OR (cls = SymTab.ClStr)
|
|
|
- 1028 OR (cls = SymTab.ClUStr) THEN
|
|
|
- 1029 (* an aggregate/string
|
|
|
- 1030 constant: qv is its
|
|
|
- 1031 descriptor address; no
|
|
|
- 1032 scalar data *)
|
|
|
- 1033 SymTab.SetSymVal(n, qv)
|
|
|
- 1034 ELSIF NOT QbeGen.IsImm(qv) THEN
|
|
|
- 1035 SemError(230)
|
|
|
- 1036 ELSE
|
|
|
- 1037 SymTab.SetSymVal(n, qv);
|
|
|
- 1038 QbeGen.DeclConst(n, qv, t)
|
|
|
- 1039 END; .) .
|
|
|
- 1040 VarBlock (. VAR astSeq, astTail: AST.Node; .)
|
|
|
- 1041 = "VAR" (. astSeq := AST.NoNode;
|
|
|
- 1042 astTail := AST.NoNode; .)
|
|
|
- 1043 { VarDecl ";" (. AstAppend(AST.NkDeclSeq,
|
|
|
- 1044 astSeq, astTail, astDecl); .) }
|
|
|
- 1045 (. astDecl := astSeq; .) .
|
|
|
- 1046 VarDecl (. VAR nm: SymTab.Name;
|
|
|
- 1047 t: SymTab.TypeIndex;
|
|
|
- 1048 i: CARDINAL;
|
|
|
- 1049 cls: INTEGER;
|
|
|
- 1050 astNode: AST.Node; .)
|
|
|
- 1051 = VarIdents ":"
|
|
|
- 1052 Type<t, FALSE> (. astNode := AST.MakeNode(AST.NkVarDecl);
|
|
|
- 1053 i := 0;
|
|
|
- 1054 WHILE i < SymTab.PendCount() DO
|
|
|
- 1055 SymTab.PendName(i, nm);
|
|
|
- 1056 AST.SetChild(astNode,
|
|
|
- 1057 AST.NChild(astNode),
|
|
|
- 1058 AST.MakeLeaf(AST.NkIdent, nm));
|
|
|
- 1059 INC(i)
|
|
|
- 1060 END;
|
|
|
- 1061 AST.SetTy(astNode, t);
|
|
|
- 1062 astDecl := astNode;
|
|
|
- 1063 cls := SymTab.ClassOf(t);
|
|
|
- 1064 IF (t # SymTab.InvalidType)
|
|
|
- 1065 AND NOT SymTab.IsUnresolved(t)
|
|
|
- 1066 AND (cls # SymTab.ClInt)
|
|
|
- 1067 AND (cls # SymTab.ClBool)
|
|
|
- 1068 AND (cls # SymTab.ClChar)
|
|
|
- 1069 AND (cls # SymTab.ClReal)
|
|
|
- 1070 AND (cls # SymTab.ClArray)
|
|
|
- 1071 AND (cls # SymTab.ClSet)
|
|
|
- 1072 AND (cls # SymTab.ClRecord)
|
|
|
- 1073 AND (cls # SymTab.ClPtr)
|
|
|
- 1074 AND (cls # SymTab.ClLong)
|
|
|
- 1075 AND (cls # SymTab.ClProc)
|
|
|
- 1076 AND (cls # SymTab.ClUChar)
|
|
|
- 1077 AND (cls # SymTab.ClUStr)
|
|
|
- 1078 AND (cls # SymTab.ClEnum)
|
|
|
- 1079 AND (cls # SymTab.ClClass) THEN
|
|
|
- 1080 SemError(230) END;
|
|
|
- 1081 IF QbeGen.LocFull() THEN
|
|
|
- 1082 SemError(233) END;
|
|
|
- 1083 i := 0;
|
|
|
- 1084 IF SymTab.IsUnresolved(t)
|
|
|
- 1085 AND NOT SymTab.InProc() THEN
|
|
|
- 1086 (* a forward-typed global:
|
|
|
- 1087 defer emission until the
|
|
|
- 1088 TYPE block completes *)
|
|
|
- 1089 WHILE i < SymTab.PendCount() DO
|
|
|
- 1090 SymTab.PendName(i, nm);
|
|
|
- 1091 IF nPendVar <=
|
|
|
- 1092 HIGH(pendVarName) THEN
|
|
|
- 1093 pendVarName[nPendVar] := nm;
|
|
|
- 1094 pendVarT[nPendVar] := t;
|
|
|
- 1095 INC(nPendVar)
|
|
|
- 1096 END;
|
|
|
- 1097 INC(i)
|
|
|
- 1098 END
|
|
|
- 1099 ELSE
|
|
|
- 1100 WHILE i < SymTab.PendCount() DO
|
|
|
- 1101 SymTab.PendName(i, nm);
|
|
|
- 1102 QbeGen.DeclVar(nm, t);
|
|
|
- 1103 INC(i)
|
|
|
- 1104 END
|
|
|
- 1105 END;
|
|
|
- 1106 (* a plain VAR list, not a
|
|
|
- 1107 heading: the signature
|
|
|
- 1108 result is discarded *)
|
|
|
- 1109 IF NOT SymTab.FixPending(t) THEN
|
|
|
- 1110 END; .) .
|
|
|
- 1111 VarIdents (. VAR n: SymTab.Name; .)
|
|
|
- 1112 = GetIdent<n> (. IF NOT SymTab.EnterPending(n,
|
|
|
- 1113 SymTab.KindVar) THEN
|
|
|
- 1114 SemError(200) END; .)
|
|
|
- 1115 { ","
|
|
|
- 1116 GetIdent<n> (. IF NOT SymTab.EnterPending(n,
|
|
|
- 1117 SymTab.KindVar) THEN
|
|
|
- 1118 SemError(200) END; .) } .
|
|
|
- 1119 ParIdents<isV: BOOLEAN> (. VAR n: SymTab.Name; .)
|
|
|
- 1120 = GetIdent<n> (. IF NOT SymTab.EnterParam(n, isV) THEN
|
|
|
- 1121 SemError(200) END; .)
|
|
|
- 1122 { "," GetIdent<n> (. IF NOT SymTab.EnterParam(n, isV) THEN
|
|
|
- 1123 SemError(200) END; .) } .
|
|
|
- 1124 (* Procedure headings enter scopes/params/result and buffer the
|
|
|
- 1125 QBE header; bodies lower to functions (4.1, module level only).
|
|
|
- 1126 FORWARD marks; the body heading re-enters (signature compare
|
|
|
- 1127 deferred). Nested procedures parse + check, lowering = 4.2. *)
|
|
|
- 1128 ProcHeading<VAR pn: SymTab.Name; methCls: SymTab.TypeIndex>
|
|
|
- 1129 (. VAR t: SymTab.TypeIndex;
|
|
|
- 1130 mg: QbeGen.QVal; .)
|
|
|
- 1131 = "PROCEDURE"
|
|
|
- 1132 GetIdent<pn> (. IF methCls #
|
|
|
- 1133 SymTab.InvalidType THEN
|
|
|
- 1134 (* a method: resume the
|
|
|
- 1135 declared symbol (reuse
|
|
|
- 1136 its uid) *)
|
|
|
- 1137 IF NOT SymTab.ResumeMethod(
|
|
|
- 1138 methCls, pn) THEN
|
|
|
- 1139 SemError(200) END
|
|
|
- 1140 ELSIF NOT SymTab.EnterProc(pn) THEN
|
|
|
- 1141 IF NOT SymTab.ReenterProc(pn) THEN
|
|
|
- 1142 IF NOT SymTab.ResumeProc(pn) THEN
|
|
|
- 1143 SemError(200) END
|
|
|
- 1144 END
|
|
|
- 1145 END;
|
|
|
- 1146 IF methCls #
|
|
|
- 1147 SymTab.InvalidType THEN
|
|
|
- 1148 QbeGen.Mangled(pn,
|
|
|
- 1149 SymTab.MethUid(), mg)
|
|
|
- 1150 ELSE
|
|
|
- 1151 QbeGen.Mangled(pn,
|
|
|
- 1152 SymTab.ProcUid(pn), mg)
|
|
|
- 1153 END;
|
|
|
- 1154 QbeGen.BeginFunc(mg);
|
|
|
- 1155 IF methCls #
|
|
|
- 1156 SymTab.InvalidType THEN
|
|
|
- 1157 (* hidden THIS receiver:
|
|
|
- 1158 a VAR param of the
|
|
|
- 1159 class type, pushed as
|
|
|
- 1160 the WITH base *)
|
|
|
- 1161 IF NOT SymTab.EnterThisParam(
|
|
|
- 1162 methCls) THEN
|
|
|
- 1163 SemError(200) END;
|
|
|
- 1164 IF NOT QbeGen.FuncParam(
|
|
|
- 1165 "THIS", TRUE,
|
|
|
- 1166 methCls) THEN
|
|
|
- 1167 SemError(233) END
|
|
|
- 1168 END; .)
|
|
|
- 1169 [ FormalParams ]
|
|
|
- 1170 [ ":" TypeIdent<t> (. IF NOT SymTab.SetProcRes(t) THEN
|
|
|
- 1171 SemError(235) END;
|
|
|
- 1172 QbeGen.SetFuncRes(t);
|
|
|
- 1173 IF (t #
|
|
|
- 1174 SymTab.InvalidType)
|
|
|
- 1175 AND ((SymTab.ClassOf(t)
|
|
|
- 1176 = SymTab.ClArray)
|
|
|
- 1177 OR (SymTab.ClassOf(t)
|
|
|
- 1178 = SymTab.ClRecord)
|
|
|
- 1179 OR (SymTab.ClassOf(t)
|
|
|
- 1180 = SymTab.ClSet)
|
|
|
- 1181 OR (SymTab.ClassOf(t)
|
|
|
- 1182 = SymTab.ClClass)) THEN
|
|
|
- 1183 SemError(230) END; .) ] .
|
|
|
- 1184 FormalParams
|
|
|
- 1185 = "(" [ ParamSection { ";" ParamSection } ] ")" .
|
|
|
- 1186 ParamSection (. VAR t: SymTab.TypeIndex;
|
|
|
- 1187 nm: SymTab.Name;
|
|
|
- 1188 i: CARDINAL;
|
|
|
- 1189 isV: BOOLEAN; .)
|
|
|
- 1190 = (. isV := FALSE; .)
|
|
|
- 1191 [ "VAR" (. isV := TRUE; .) ]
|
|
|
- 1192 ParIdents<isV> ":" Type<t, TRUE> (. i := 0;
|
|
|
- 1193 WHILE i < SymTab.PendCount() DO
|
|
|
- 1194 SymTab.PendName(i, nm);
|
|
|
- 1195 (* value open arrays are
|
|
|
- 1196 passed as descriptor
|
|
|
- 1197 addresses (no copy):
|
|
|
- 1198 same representation as
|
|
|
- 1199 VAR formals *)
|
|
|
- 1200 IF NOT QbeGen.FuncParam(nm,
|
|
|
- 1201 isV
|
|
|
- 1202 OR SymTab.IsOpenArray(t),
|
|
|
- 1203 t) THEN
|
|
|
- 1204 SemError(233) END;
|
|
|
- 1205 INC(i)
|
|
|
- 1206 END;
|
|
|
- 1207 IF NOT SymTab.FixPending(t) THEN
|
|
|
- 1208 SemError(235) END; .) .
|
|
|
- 1209 (* Nested procedures lower like top-level ones (4.2): the
|
|
|
- 1210 static link gives them their parent's frame. Methods keep
|
|
|
- 1211 parse-now/230-later. *)
|
|
|
- 1212 ProcDecl (. VAR pn: SymTab.Name;
|
|
|
- 1213 astNode: AST.Node; .)
|
|
|
- 1214 = ProcHeading<pn, SymTab.InvalidType> ";"
|
|
|
- 1215 (. astNode := AST.MakeNode(AST.NkProcDecl);
|
|
|
- 1216 AST.SetChild(astNode, 0,
|
|
|
- 1217 AST.MakeLeaf(AST.NkIdent, pn)); .)
|
|
|
- 1218 ( "FORWARD" (. AST.SetOp(astNode, 1);
|
|
|
- 1219 astDecl := astNode;
|
|
|
- 1220 SymTab.MarkFwd;
|
|
|
- 1221 SymTab.CloseProc;
|
|
|
- 1222 QbeGen.AbortFunc; .)
|
|
|
- 1223 | "EXTERNAL" (. AST.SetOp(astNode, 2);
|
|
|
- 1224 astDecl := astNode;
|
|
|
- 1225 SymTab.MarkExternal("");
|
|
|
- 1226 SymTab.CloseProc;
|
|
|
- 1227 QbeGen.AbortFunc; .)
|
|
|
- 1228 | (. QbeGen.EndFuncHeader; .)
|
|
|
- 1229 Block<pn> (. AST.SetChild(astNode, 1, astStmt);
|
|
|
- 1230 AST.SetChild(astNode, 2, astBlkDecls);
|
|
|
+ 1022 Lower.NoteVar(n, SymTab.KindConst, t);
|
|
|
+ 1023 SymTab.SetSymType(n, t);
|
|
|
+ 1024 cls := SymTab.ClassOf(t);
|
|
|
+ 1025 IF (cls = SymTab.ClArray)
|
|
|
+ 1026 OR (cls = SymTab.ClRecord)
|
|
|
+ 1027 OR (cls = SymTab.ClClass)
|
|
|
+ 1028 OR (cls = SymTab.ClStr)
|
|
|
+ 1029 OR (cls = SymTab.ClUStr) THEN
|
|
|
+ 1030 (* an aggregate/string
|
|
|
+ 1031 constant: qv is its
|
|
|
+ 1032 descriptor address; no
|
|
|
+ 1033 scalar data *)
|
|
|
+ 1034 SymTab.SetSymVal(n, qv)
|
|
|
+ 1035 ELSIF NOT QbeGen.IsImm(qv) THEN
|
|
|
+ 1036 SemError(230)
|
|
|
+ 1037 ELSE
|
|
|
+ 1038 SymTab.SetSymVal(n, qv);
|
|
|
+ 1039 QbeGen.DeclConst(n, qv, t)
|
|
|
+ 1040 END; .) .
|
|
|
+ 1041 VarBlock (. VAR astSeq, astTail: AST.Node; .)
|
|
|
+ 1042 = "VAR" (. astSeq := AST.NoNode;
|
|
|
+ 1043 astTail := AST.NoNode; .)
|
|
|
+ 1044 { VarDecl ";" (. AstAppend(AST.NkDeclSeq,
|
|
|
+ 1045 astSeq, astTail, astDecl); .) }
|
|
|
+ 1046 (. astDecl := astSeq; .) .
|
|
|
+ 1047 VarDecl (. VAR nm: SymTab.Name;
|
|
|
+ 1048 t: SymTab.TypeIndex;
|
|
|
+ 1049 i: CARDINAL;
|
|
|
+ 1050 cls: INTEGER;
|
|
|
+ 1051 astNode: AST.Node; .)
|
|
|
+ 1052 = VarIdents ":"
|
|
|
+ 1053 Type<t, FALSE> (. astNode := AST.MakeNode(AST.NkVarDecl);
|
|
|
+ 1054 i := 0;
|
|
|
+ 1055 WHILE i < SymTab.PendCount() DO
|
|
|
+ 1056 SymTab.PendName(i, nm);
|
|
|
+ 1057 Lower.NoteVar(nm, SymTab.KindVar, t);
|
|
|
+ 1058 AST.SetChild(astNode,
|
|
|
+ 1059 AST.NChild(astNode),
|
|
|
+ 1060 AST.MakeLeaf(AST.NkIdent, nm));
|
|
|
+ 1061 INC(i)
|
|
|
+ 1062 END;
|
|
|
+ 1063 AST.SetTy(astNode, t);
|
|
|
+ 1064 astDecl := astNode;
|
|
|
+ 1065 cls := SymTab.ClassOf(t);
|
|
|
+ 1066 IF (t # SymTab.InvalidType)
|
|
|
+ 1067 AND NOT SymTab.IsUnresolved(t)
|
|
|
+ 1068 AND (cls # SymTab.ClInt)
|
|
|
+ 1069 AND (cls # SymTab.ClBool)
|
|
|
+ 1070 AND (cls # SymTab.ClChar)
|
|
|
+ 1071 AND (cls # SymTab.ClReal)
|
|
|
+ 1072 AND (cls # SymTab.ClArray)
|
|
|
+ 1073 AND (cls # SymTab.ClSet)
|
|
|
+ 1074 AND (cls # SymTab.ClRecord)
|
|
|
+ 1075 AND (cls # SymTab.ClPtr)
|
|
|
+ 1076 AND (cls # SymTab.ClLong)
|
|
|
+ 1077 AND (cls # SymTab.ClProc)
|
|
|
+ 1078 AND (cls # SymTab.ClUChar)
|
|
|
+ 1079 AND (cls # SymTab.ClUStr)
|
|
|
+ 1080 AND (cls # SymTab.ClEnum)
|
|
|
+ 1081 AND (cls # SymTab.ClClass) THEN
|
|
|
+ 1082 SemError(230) END;
|
|
|
+ 1083 IF QbeGen.LocFull() THEN
|
|
|
+ 1084 SemError(233) END;
|
|
|
+ 1085 i := 0;
|
|
|
+ 1086 IF SymTab.IsUnresolved(t)
|
|
|
+ 1087 AND NOT SymTab.InProc() THEN
|
|
|
+ 1088 (* a forward-typed global:
|
|
|
+ 1089 defer emission until the
|
|
|
+ 1090 TYPE block completes *)
|
|
|
+ 1091 WHILE i < SymTab.PendCount() DO
|
|
|
+ 1092 SymTab.PendName(i, nm);
|
|
|
+ 1093 IF nPendVar <=
|
|
|
+ 1094 HIGH(pendVarName) THEN
|
|
|
+ 1095 pendVarName[nPendVar] := nm;
|
|
|
+ 1096 pendVarT[nPendVar] := t;
|
|
|
+ 1097 INC(nPendVar)
|
|
|
+ 1098 END;
|
|
|
+ 1099 INC(i)
|
|
|
+ 1100 END
|
|
|
+ 1101 ELSE
|
|
|
+ 1102 WHILE i < SymTab.PendCount() DO
|
|
|
+ 1103 SymTab.PendName(i, nm);
|
|
|
+ 1104 QbeGen.DeclVar(nm, t);
|
|
|
+ 1105 INC(i)
|
|
|
+ 1106 END
|
|
|
+ 1107 END;
|
|
|
+ 1108 (* a plain VAR list, not a
|
|
|
+ 1109 heading: the signature
|
|
|
+ 1110 result is discarded *)
|
|
|
+ 1111 IF NOT SymTab.FixPending(t) THEN
|
|
|
+ 1112 END; .) .
|
|
|
+ 1113 VarIdents (. VAR n: SymTab.Name; .)
|
|
|
+ 1114 = GetIdent<n> (. IF NOT SymTab.EnterPending(n,
|
|
|
+ 1115 SymTab.KindVar) THEN
|
|
|
+ 1116 SemError(200) END; .)
|
|
|
+ 1117 { ","
|
|
|
+ 1118 GetIdent<n> (. IF NOT SymTab.EnterPending(n,
|
|
|
+ 1119 SymTab.KindVar) THEN
|
|
|
+ 1120 SemError(200) END; .) } .
|
|
|
+ 1121 ParIdents<isV: BOOLEAN> (. VAR n: SymTab.Name; .)
|
|
|
+ 1122 = GetIdent<n> (. IF NOT SymTab.EnterParam(n, isV) THEN
|
|
|
+ 1123 SemError(200) END; .)
|
|
|
+ 1124 { "," GetIdent<n> (. IF NOT SymTab.EnterParam(n, isV) THEN
|
|
|
+ 1125 SemError(200) END; .) } .
|
|
|
+ 1126 (* Procedure headings enter scopes/params/result and buffer the
|
|
|
+ 1127 QBE header; bodies lower to functions (4.1, module level only).
|
|
|
+ 1128 FORWARD marks; the body heading re-enters (signature compare
|
|
|
+ 1129 deferred). Nested procedures parse + check, lowering = 4.2. *)
|
|
|
+ 1130 ProcHeading<VAR pn: SymTab.Name; methCls: SymTab.TypeIndex>
|
|
|
+ 1131 (. VAR t: SymTab.TypeIndex;
|
|
|
+ 1132 mg: QbeGen.QVal; .)
|
|
|
+ 1133 = "PROCEDURE"
|
|
|
+ 1134 GetIdent<pn> (. IF methCls #
|
|
|
+ 1135 SymTab.InvalidType THEN
|
|
|
+ 1136 (* a method: resume the
|
|
|
+ 1137 declared symbol (reuse
|
|
|
+ 1138 its uid) *)
|
|
|
+ 1139 IF NOT SymTab.ResumeMethod(
|
|
|
+ 1140 methCls, pn) THEN
|
|
|
+ 1141 SemError(200) END
|
|
|
+ 1142 ELSIF NOT SymTab.EnterProc(pn) THEN
|
|
|
+ 1143 IF NOT SymTab.ReenterProc(pn) THEN
|
|
|
+ 1144 IF NOT SymTab.ResumeProc(pn) THEN
|
|
|
+ 1145 SemError(200) END
|
|
|
+ 1146 END
|
|
|
+ 1147 END;
|
|
|
+ 1148 Lower.ScopeEnter;
|
|
|
+ 1149 Lower.NoteProc(pn,
|
|
|
+ 1150 SymTab.ProcUid(pn),
|
|
|
+ 1151 SymTab.InvalidType,
|
|
|
+ 1152 SymTab.ProcDepthOf(pn),
|
|
|
+ 1153 FALSE);
|
|
|
+ 1154 IF methCls #
|
|
|
+ 1155 SymTab.InvalidType THEN
|
|
|
+ 1156 QbeGen.Mangled(pn,
|
|
|
+ 1157 SymTab.MethUid(), mg)
|
|
|
+ 1158 ELSE
|
|
|
+ 1159 QbeGen.Mangled(pn,
|
|
|
+ 1160 SymTab.ProcUid(pn), mg)
|
|
|
+ 1161 END;
|
|
|
+ 1162 QbeGen.BeginFunc(mg);
|
|
|
+ 1163 IF methCls #
|
|
|
+ 1164 SymTab.InvalidType THEN
|
|
|
+ 1165 (* hidden THIS receiver:
|
|
|
+ 1166 a VAR param of the
|
|
|
+ 1167 class type, pushed as
|
|
|
+ 1168 the WITH base *)
|
|
|
+ 1169 IF NOT SymTab.EnterThisParam(
|
|
|
+ 1170 methCls) THEN
|
|
|
+ 1171 SemError(200) END;
|
|
|
+ 1172 IF NOT QbeGen.FuncParam(
|
|
|
+ 1173 "THIS", TRUE,
|
|
|
+ 1174 methCls) THEN
|
|
|
+ 1175 SemError(233) END
|
|
|
+ 1176 END; .)
|
|
|
+ 1177 [ FormalParams ]
|
|
|
+ 1178 [ ":" TypeIdent<t> (. IF NOT SymTab.SetProcRes(t) THEN
|
|
|
+ 1179 SemError(235) END;
|
|
|
+ 1180 Lower.SetProcRes(t);
|
|
|
+ 1181 QbeGen.SetFuncRes(t);
|
|
|
+ 1182 IF (t #
|
|
|
+ 1183 SymTab.InvalidType)
|
|
|
+ 1184 AND ((SymTab.ClassOf(t)
|
|
|
+ 1185 = SymTab.ClArray)
|
|
|
+ 1186 OR (SymTab.ClassOf(t)
|
|
|
+ 1187 = SymTab.ClRecord)
|
|
|
+ 1188 OR (SymTab.ClassOf(t)
|
|
|
+ 1189 = SymTab.ClSet)
|
|
|
+ 1190 OR (SymTab.ClassOf(t)
|
|
|
+ 1191 = SymTab.ClClass)) THEN
|
|
|
+ 1192 SemError(230) END; .) ] .
|
|
|
+ 1193 FormalParams
|
|
|
+ 1194 = "(" [ ParamSection { ";" ParamSection } ] ")" .
|
|
|
+ 1195 ParamSection (. VAR t: SymTab.TypeIndex;
|
|
|
+ 1196 nm: SymTab.Name;
|
|
|
+ 1197 i: CARDINAL;
|
|
|
+ 1198 isV: BOOLEAN; .)
|
|
|
+ 1199 = (. isV := FALSE; .)
|
|
|
+ 1200 [ "VAR" (. isV := TRUE; .) ]
|
|
|
+ 1201 ParIdents<isV> ":" Type<t, TRUE> (. i := 0;
|
|
|
+ 1202 WHILE i < SymTab.PendCount() DO
|
|
|
+ 1203 SymTab.PendName(i, nm);
|
|
|
+ 1204 Lower.NoteParam(nm, t, isV);
|
|
|
+ 1205 Lower.NoteVar(nm, SymTab.KindParam, t);
|
|
|
+ 1206 (* value open arrays are
|
|
|
+ 1207 passed as descriptor
|
|
|
+ 1208 addresses (no copy):
|
|
|
+ 1209 same representation as
|
|
|
+ 1210 VAR formals *)
|
|
|
+ 1211 IF NOT QbeGen.FuncParam(nm,
|
|
|
+ 1212 isV
|
|
|
+ 1213 OR SymTab.IsOpenArray(t),
|
|
|
+ 1214 t) THEN
|
|
|
+ 1215 SemError(233) END;
|
|
|
+ 1216 INC(i)
|
|
|
+ 1217 END;
|
|
|
+ 1218 IF NOT SymTab.FixPending(t) THEN
|
|
|
+ 1219 SemError(235) END; .) .
|
|
|
+ 1220 (* Nested procedures lower like top-level ones (4.2): the
|
|
|
+ 1221 static link gives them their parent's frame. Methods keep
|
|
|
+ 1222 parse-now/230-later. *)
|
|
|
+ 1223 ProcDecl (. VAR pn: SymTab.Name;
|
|
|
+ 1224 astNode: AST.Node; .)
|
|
|
+ 1225 = ProcHeading<pn, SymTab.InvalidType> ";"
|
|
|
+ 1226 (. astNode := AST.MakeNode(AST.NkProcDecl);
|
|
|
+ 1227 AST.SetOp(astNode, 0);
|
|
|
+ 1228 AST.SetChild(astNode, 0,
|
|
|
+ 1229 AST.MakeLeaf(AST.NkIdent, pn)); .)
|
|
|
+ 1230 ( "FORWARD" (. AST.SetOp(astNode, 1);
|
|
|
1231 astDecl := astNode;
|
|
|
- 1232 SymTab.CloseProc;
|
|
|
- 1233 QbeGen.EndFunc(
|
|
|
- 1234 SymTab.ProcRes(pn)); .) ) .
|
|
|
- 1235 Block<pn: SymTab.Name> (. VAR m2: SymTab.Name; .)
|
|
|
- 1236 = DeclSeq (. astBlkDecls := astDecl;
|
|
|
- 1237 astStmt := AST.NoNode; .)
|
|
|
- 1238 [ "BEGIN"
|
|
|
- 1239 [ StatSeq ] ]
|
|
|
- 1240 "END"
|
|
|
- 1241 GetIdent<m2> (. IF NOT SymTab.Equal(pn, m2) THEN
|
|
|
- 1242 SemError(202) END; .) .
|
|
|
- 1243 StatSeq (. VAR astSeq, astTail: AST.Node; .)
|
|
|
- 1244 = (. astSeq := AST.NoNode;
|
|
|
- 1245 astTail := AST.NoNode; .)
|
|
|
- 1246 Statement (. AstAppend(AST.NkBlock,
|
|
|
- 1247 astSeq, astTail, astStmt); .)
|
|
|
- 1248 { ";" [ Statement (. AstAppend(AST.NkBlock,
|
|
|
- 1249 astSeq, astTail, astStmt); .) ] }
|
|
|
- 1250 (. astStmt := astSeq; .) .
|
|
|
- 1251 (* Trailing/empty statements (`a; ; b`, Coco/R's generated `;;`)
|
|
|
- 1252 are accepted: the statement after ';' is optional. *)
|
|
|
- 1253 Statement (. VAR lx: QbeGen.QVal; .)
|
|
|
- 1254 = (. astStmt := AST.NoNode; .)
|
|
|
- 1255 ( AssOrCall
|
|
|
- 1256 | IfStat
|
|
|
- 1257 | WhileStat
|
|
|
- 1258 | RepeatStat
|
|
|
- 1259 | LoopStat
|
|
|
- 1260 | ForStat
|
|
|
- 1261 | CaseStat
|
|
|
- 1262 | WithStat
|
|
|
- 1263 | ReturnStat
|
|
|
- 1264 | HaltStat
|
|
|
- 1265 | NewStat
|
|
|
- 1266 | DisposeStat
|
|
|
- 1267 | IncDecStat
|
|
|
- 1268 | InclExclStat
|
|
|
- 1269 | "EXIT" (. IF QbeGen.TopLoop(lx) THEN
|
|
|
- 1270 QbeGen.Jmp(lx)
|
|
|
- 1271 ELSE SemError(230) END;
|
|
|
- 1272 astStmt := AST.MakeNode(AST.NkExit); .) ) .
|
|
|
- 1273 (* INCL(set, elem) / EXCL(set, elem): PIM set-element builtins. *)
|
|
|
- 1274 InclExclStat (. VAR at, et2: SymTab.TypeIndex;
|
|
|
- 1275 dk: INTEGER;
|
|
|
- 1276 qd, qe: QbeGen.QVal;
|
|
|
- 1277 qn: SymTab.Name;
|
|
|
- 1278 sfx, isInc: BOOLEAN;
|
|
|
- 1279 astNode, astD: AST.Node; .)
|
|
|
- 1280 = ( "INCL" (. isInc := TRUE; .)
|
|
|
- 1281 | "EXCL" (. isInc := FALSE; .) )
|
|
|
- 1282 "(" Design<at, dk, qd, qn, sfx> (. astD := astCur; .) ","
|
|
|
- 1283 Expr<et2, qe> ")"
|
|
|
- 1284 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 1285 IF isInc THEN
|
|
|
- 1286 AST.SetChild(astNode, 0,
|
|
|
- 1287 AST.MakeLeaf(AST.NkIdent, "INCL"))
|
|
|
- 1288 ELSE AST.SetChild(astNode, 0,
|
|
|
- 1289 AST.MakeLeaf(AST.NkIdent, "EXCL"))
|
|
|
- 1290 END;
|
|
|
- 1291 IF astD # AST.NoNode THEN
|
|
|
- 1292 AST.SetChild(astNode, 1, astD) END;
|
|
|
- 1293 IF astCur # AST.NoNode THEN
|
|
|
- 1294 AST.SetChild(astNode, 2, astCur) END;
|
|
|
- 1295 astStmt := astNode; .)
|
|
|
- 1296 (. IF at = SymTab.InvalidType THEN
|
|
|
- 1297 ELSIF SymTab.ClassOf(at) #
|
|
|
- 1298 SymTab.ClSet THEN
|
|
|
- 1299 SemError(222)
|
|
|
- 1300 ELSE
|
|
|
- 1301 IF isInc THEN
|
|
|
- 1302 QbeGen.SetBit(qd, qe,
|
|
|
- 1303 SymTab.SetBaseLo(at),
|
|
|
- 1304 SymTab.SetCount(at))
|
|
|
- 1305 ELSE
|
|
|
- 1306 QbeGen.SetClearBit(qd, qe,
|
|
|
- 1307 SymTab.SetBaseLo(at),
|
|
|
- 1308 SymTab.SetCount(at))
|
|
|
- 1309 END
|
|
|
- 1310 END; .) .
|
|
|
- 1311 (* INC(v [,step]) / DEC(v [,step]) as builtin statements over an
|
|
|
- 1312 integer designator. *)
|
|
|
- 1313 IncDecStat (. VAR dt, et2: SymTab.TypeIndex;
|
|
|
- 1314 dk: INTEGER;
|
|
|
- 1315 qd, qv, qn2, qstep:
|
|
|
- 1316 QbeGen.QVal;
|
|
|
- 1317 qn: SymTab.Name;
|
|
|
- 1318 sfx, isInc: BOOLEAN;
|
|
|
- 1319 astNode, astD, astStep:
|
|
|
- 1320 AST.Node; .)
|
|
|
- 1321 = (. isInc := TRUE; .)
|
|
|
- 1322 ( "INC" (. isInc := TRUE; .)
|
|
|
- 1323 | "DEC" (. isInc := FALSE; .) )
|
|
|
- 1324 "(" (. QbeGen.CopyOp("1", qstep); astStep := AST.NoNode; .)
|
|
|
- 1325 Design<dt, dk, qd, qn, sfx> (. astD := astCur; .)
|
|
|
- 1326 [ "," Expr<et2, qstep> (. astStep := astCur; .) ]
|
|
|
- 1327 ")" (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 1328 IF isInc THEN
|
|
|
- 1329 AST.SetChild(astNode, 0,
|
|
|
- 1330 AST.MakeLeaf(AST.NkIdent, "INC"))
|
|
|
- 1331 ELSE AST.SetChild(astNode, 0,
|
|
|
- 1332 AST.MakeLeaf(AST.NkIdent, "DEC"))
|
|
|
- 1333 END;
|
|
|
- 1334 IF astD # AST.NoNode THEN
|
|
|
- 1335 AST.SetChild(astNode, 1, astD) END;
|
|
|
- 1336 IF astStep # AST.NoNode THEN
|
|
|
- 1337 AST.SetChild(astNode, 2, astStep) END;
|
|
|
- 1338 astStmt := astNode; .) (. IF dt = SymTab.InvalidType THEN
|
|
|
- 1339 ELSIF (dk # SymTab.KindVar)
|
|
|
- 1340 AND (dk # SymTab.KindParam)
|
|
|
- 1341 AND (dk # SymTab.KindField) THEN
|
|
|
- 1342 SemError(210)
|
|
|
- 1343 ELSIF NOT SymTab.IsIntFamily(dt) THEN
|
|
|
- 1344 SemError(211)
|
|
|
- 1345 ELSE
|
|
|
- 1346 IF sfx
|
|
|
- 1347 OR (dk = SymTab.KindField) THEN
|
|
|
- 1348 QbeGen.ElemLoad(qd, dt, qv)
|
|
|
- 1349 ELSE QbeGen.LoadVar(qn,
|
|
|
- 1350 FALSE, qv)
|
|
|
- 1351 END;
|
|
|
- 1352 QbeGen.NewTemp(qn2);
|
|
|
- 1353 IF isInc THEN
|
|
|
- 1354 QbeGen.Op3("add", qn2, qv,
|
|
|
- 1355 qstep, FALSE)
|
|
|
- 1356 ELSE QbeGen.Op3("sub", qn2, qv,
|
|
|
- 1357 qstep, FALSE)
|
|
|
- 1358 END;
|
|
|
- 1359 IF sfx
|
|
|
- 1360 OR (dk = SymTab.KindField) THEN
|
|
|
- 1361 QbeGen.ElemStore(qd, qn2,
|
|
|
- 1362 dt)
|
|
|
- 1363 ELSE QbeGen.StoreVar(qn,
|
|
|
- 1364 qn2, FALSE)
|
|
|
- 1365 END
|
|
|
- 1366 END; .) .
|
|
|
- 1367 (* NEW/DISPOSE as builtin statements (no call syntax until step 4).
|
|
|
- 1368 Targets are pointer designators; DISPOSE nils afterwards (safer
|
|
|
- 1369 than Wirth-undefined; documented). DISPOSE is shallow. *)
|
|
|
- 1370 NewStat (. VAR dt: SymTab.TypeIndex;
|
|
|
- 1371 dk: INTEGER;
|
|
|
- 1372 qd, qm: QbeGen.QVal;
|
|
|
- 1373 qn: SymTab.Name;
|
|
|
- 1374 sfx: BOOLEAN;
|
|
|
- 1375 bt: SymTab.TypeIndex;
|
|
|
- 1376 astNode, astD: AST.Node; .)
|
|
|
- 1377 = "NEW" "(" Design<dt, dk, qd, qn, sfx> (. astD := astCur; .) ")"
|
|
|
- 1378 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 1379 AST.SetChild(astNode, 0,
|
|
|
- 1380 AST.MakeLeaf(AST.NkIdent, "NEW"));
|
|
|
- 1381 IF astD # AST.NoNode THEN
|
|
|
- 1382 AST.SetChild(astNode, 1, astD) END;
|
|
|
- 1383 astStmt := astNode; .)
|
|
|
- 1384 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 1385 ELSIF (dk # SymTab.KindVar)
|
|
|
- 1386 AND (dk # SymTab.KindParam)
|
|
|
- 1387 AND (dk # SymTab.KindField) THEN
|
|
|
- 1388 SemError(210)
|
|
|
- 1389 ELSIF SymTab.ClassOf(dt) #
|
|
|
- 1390 SymTab.ClPtr THEN
|
|
|
- 1391 SemError(219)
|
|
|
- 1392 ELSE bt := SymTab.PtrBase(dt);
|
|
|
- 1393 IF bt #
|
|
|
- 1394 SymTab.InvalidType THEN
|
|
|
- 1395 QbeGen.NewHeap(bt, qm);
|
|
|
- 1396 QbeGen.InitHeap(qm, bt);
|
|
|
- 1397 IF sfx
|
|
|
- 1398 OR (dk =
|
|
|
- 1399 SymTab.KindField) THEN
|
|
|
- 1400 QbeGen.ElemStore(qd, qm,
|
|
|
- 1401 dt)
|
|
|
- 1402 ELSE QbeGen.StorePtr(qn,
|
|
|
- 1403 qm)
|
|
|
- 1404 END
|
|
|
- 1405 END
|
|
|
- 1406 END; .) .
|
|
|
- 1407 DisposeStat (. VAR dt: SymTab.TypeIndex;
|
|
|
- 1408 dk: INTEGER;
|
|
|
- 1409 qd, qv: QbeGen.QVal;
|
|
|
- 1410 qn: SymTab.Name;
|
|
|
- 1411 sfx: BOOLEAN;
|
|
|
- 1412 astNode, astD: AST.Node; .)
|
|
|
- 1413 = "DISPOSE" "(" Design<dt, dk, qd, qn, sfx> (. astD := astCur; .) ")"
|
|
|
- 1414 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 1415 AST.SetChild(astNode, 0,
|
|
|
- 1416 AST.MakeLeaf(AST.NkIdent, "DISPOSE"));
|
|
|
- 1417 IF astD # AST.NoNode THEN
|
|
|
- 1418 AST.SetChild(astNode, 1, astD) END;
|
|
|
- 1419 astStmt := astNode; .)
|
|
|
- 1420 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 1421 ELSIF (dk # SymTab.KindVar)
|
|
|
- 1422 AND (dk # SymTab.KindParam)
|
|
|
- 1423 AND (dk # SymTab.KindField) THEN
|
|
|
- 1424 SemError(210)
|
|
|
- 1425 ELSIF SymTab.ClassOf(dt) #
|
|
|
- 1426 SymTab.ClPtr THEN
|
|
|
- 1427 SemError(219)
|
|
|
- 1428 ELSE
|
|
|
- 1429 IF sfx
|
|
|
- 1430 OR (dk =
|
|
|
- 1431 SymTab.KindField) THEN
|
|
|
- 1432 QbeGen.ElemLoad(qd, dt,
|
|
|
- 1433 qv)
|
|
|
- 1434 ELSE QbeGen.LoadPtr(qn, qv)
|
|
|
- 1435 END;
|
|
|
- 1436 QbeGen.FreeHeap(qv);
|
|
|
- 1437 IF sfx
|
|
|
- 1438 OR (dk =
|
|
|
- 1439 SymTab.KindField) THEN
|
|
|
- 1440 QbeGen.ElemStore(qd, "0",
|
|
|
- 1441 dt)
|
|
|
- 1442 ELSE QbeGen.StorePtr(qn,
|
|
|
- 1443 "0")
|
|
|
- 1444 END
|
|
|
- 1445 END; .) .
|
|
|
- 1446 (* WITH pushes each record's fields (inner wins) plus its base
|
|
|
- 1447 address; field designators resolve through both stacks. *)
|
|
|
- 1448 WithStat (. VAR nW: CARDINAL;
|
|
|
- 1449 astNode: AST.Node; .)
|
|
|
- 1450 = "WITH" (. nW := 0;
|
|
|
- 1451 astNode := AST.MakeNode(AST.NkWith); .)
|
|
|
- 1452 WithItem<nW, astNode> { "," WithItem<nW, astNode> }
|
|
|
- 1453 "DO" (. astStmt := AST.NoNode; .)
|
|
|
- 1454 [ StatSeq ] "END" (. AST.SetChild(astNode,
|
|
|
- 1455 AST.NChild(astNode), astStmt);
|
|
|
- 1456 astStmt := astNode;
|
|
|
- 1457 WHILE nW > 0 DO
|
|
|
- 1458 SymTab.PopScope;
|
|
|
- 1459 QbeGen.PopWith;
|
|
|
- 1460 DEC(nW)
|
|
|
- 1461 END; .) .
|
|
|
- 1462 WithItem<VAR nW: CARDINAL; wnode: AST.Node>
|
|
|
- 1463 (. VAR dt: SymTab.TypeIndex;
|
|
|
- 1464 dk: INTEGER;
|
|
|
- 1465 qd, qe: QbeGen.QVal;
|
|
|
- 1466 qn: SymTab.Name;
|
|
|
- 1467 sfx: BOOLEAN; .)
|
|
|
- 1468 = Design<dt, dk, qd, qn, sfx>
|
|
|
- 1469 (. IF astCur # AST.NoNode THEN
|
|
|
- 1470 AST.SetChild(wnode,
|
|
|
- 1471 AST.NChild(wnode), astCur) END;
|
|
|
- 1472 IF dt = SymTab.InvalidType THEN
|
|
|
- 1473 ELSIF (SymTab.ClassOf(dt) #
|
|
|
- 1474 SymTab.ClRecord)
|
|
|
- 1475 AND (SymTab.ClassOf(dt) #
|
|
|
- 1476 SymTab.ClClass) THEN
|
|
|
- 1477 SemError(215)
|
|
|
- 1478 ELSIF SymTab.PushRecord(dt) THEN
|
|
|
- 1479 QbeGen.PushWith(qd);
|
|
|
- 1480 INC(nW)
|
|
|
- 1481 END; .) .
|
|
|
- 1482 (* Assignment or procedure-statement call (4.1, module level).
|
|
|
- 1483 Bare `P;` is a syntax error; function-as-statement is 233. *)
|
|
|
- 1484 AssOrCall (. VAR dt, et: SymTab.TypeIndex;
|
|
|
- 1485 dk: INTEGER;
|
|
|
- 1486 qd, qe, qt, ql: QbeGen.QVal;
|
|
|
- 1487 qn: SymTab.Name;
|
|
|
- 1488 ct2, res0: SymTab.TypeIndex;
|
|
|
- 1489 q2, mg0: QbeGen.QVal;
|
|
|
- 1490 isR, conv, wconv: BOOLEAN;
|
|
|
- 1491 called, sfx: BOOLEAN;
|
|
|
- 1492 astLhs: AST.Node; .)
|
|
|
- 1493 = Design<dt, dk, qd, qn, sfx>
|
|
|
- 1494 (. astLhs := astCur; astNArgs := 0; .)
|
|
|
- 1495 ( ":="
|
|
|
- 1496 Expr<et, qe> (. astStmt := AST.MakeBin(
|
|
|
- 1497 AST.NkAssign, 0, astLhs, astCur);
|
|
|
- 1498 IF (dt # SymTab.InvalidType)
|
|
|
- 1499 AND (dk # SymTab.KindVar)
|
|
|
- 1500 AND (dk # SymTab.KindParam)
|
|
|
- 1501 AND (dk # SymTab.KindField) THEN
|
|
|
- 1502 SemError(210)
|
|
|
- 1503 ELSIF NOT SymTab.Assignable(et,
|
|
|
- 1504 dt) THEN
|
|
|
- 1505 SemError(210)
|
|
|
- 1506 ELSIF (dt # SymTab.InvalidType)
|
|
|
- 1507 AND (SymTab.ClassOf(dt) =
|
|
|
- 1508 SymTab.ClClass) THEN
|
|
|
- 1509 SemError(230) END;
|
|
|
- 1510 isR := (dt #
|
|
|
- 1511 SymTab.InvalidType)
|
|
|
- 1512 AND (SymTab.ClassOf(dt)
|
|
|
- 1513 = SymTab.ClReal);
|
|
|
- 1514 conv := isR
|
|
|
- 1515 AND SymTab.IsIntFamily(et);
|
|
|
- 1516 wconv := (dt #
|
|
|
- 1517 SymTab.InvalidType)
|
|
|
- 1518 AND SymTab.IsLongFamily(dt)
|
|
|
- 1519 AND SymTab.IsIntFamily(et);
|
|
|
- 1520 IF ((dk = SymTab.KindVar)
|
|
|
- 1521 OR (dk = SymTab.KindParam)
|
|
|
- 1522 OR (dk = SymTab.KindField))
|
|
|
- 1523 AND (dt # SymTab.InvalidType)
|
|
|
- 1524 AND (et # SymTab.InvalidType)
|
|
|
- 1525 AND (SymTab.ClassOf(dt) #
|
|
|
- 1526 SymTab.ClClass) THEN
|
|
|
- 1527 IF sfx
|
|
|
- 1528 OR (dk = SymTab.KindField) THEN
|
|
|
- 1529 IF SymTab.ClassOf(dt) =
|
|
|
- 1530 SymTab.ClArray THEN
|
|
|
- 1531 IF (et # SymTab.InvalidType)
|
|
|
- 1532 AND (SymTab.ClassOf(et) = SymTab.ClUStr)
|
|
|
- 1533 AND SymTab.IsUCharArray(dt) THEN
|
|
|
- 1534 QbeGen.UAssign(qd, qe)
|
|
|
- 1535 ELSIF SymTab.StrCompat(dt,
|
|
|
- 1536 et) THEN
|
|
|
- 1537 QbeGen.StrAssign(qd,
|
|
|
- 1538 qe)
|
|
|
- 1539 ELSE
|
|
|
- 1540 QbeGen.CopyArray(qd,
|
|
|
- 1541 qe, dt)
|
|
|
- 1542 END
|
|
|
- 1543 ELSIF SymTab.ClassOf(dt) =
|
|
|
- 1544 SymTab.ClSet THEN
|
|
|
- 1545 QbeGen.CopySet(qd, qe,
|
|
|
- 1546 SymTab.SetWords(dt),
|
|
|
- 1547 SymTab.SetWords(et))
|
|
|
- 1548 ELSIF SymTab.ClassOf(dt) =
|
|
|
- 1549 SymTab.ClRecord THEN
|
|
|
- 1550 QbeGen.CopyRecord(qd, qe,
|
|
|
- 1551 dt)
|
|
|
- 1552 ELSIF SymTab.IsLongFamily(dt) THEN
|
|
|
- 1553 IF wconv THEN
|
|
|
- 1554 QbeGen.WidenLong(qe, ql);
|
|
|
- 1555 QbeGen.ElemStore(qd, ql,
|
|
|
- 1556 dt)
|
|
|
- 1557 ELSE QbeGen.ElemStore(qd, qe,
|
|
|
- 1558 dt)
|
|
|
- 1559 END
|
|
|
- 1560 ELSIF conv THEN
|
|
|
- 1561 QbeGen.ConvIR(qe, qt);
|
|
|
- 1562 QbeGen.ElemStore(qd, qt,
|
|
|
- 1563 dt)
|
|
|
- 1564 ELSE QbeGen.ElemStore(qd, qe,
|
|
|
- 1565 dt)
|
|
|
- 1566 END
|
|
|
- 1567 ELSIF SymTab.ClassOf(dt) =
|
|
|
- 1568 SymTab.ClArray THEN
|
|
|
- 1569 IF (et # SymTab.InvalidType)
|
|
|
- 1570 AND (SymTab.ClassOf(et) = SymTab.ClUStr)
|
|
|
- 1571 AND SymTab.IsUCharArray(dt) THEN
|
|
|
- 1572 QbeGen.UAssign(qd, qe)
|
|
|
- 1573 ELSIF SymTab.StrCompat(dt,
|
|
|
- 1574 et) THEN
|
|
|
- 1575 QbeGen.StrAssign(qd, qe)
|
|
|
- 1576 ELSE
|
|
|
- 1577 QbeGen.CopyArray(qd, qe,
|
|
|
+ 1232 Lower.ScopeLeave;
|
|
|
+ 1233 SymTab.MarkFwd;
|
|
|
+ 1234 SymTab.CloseProc;
|
|
|
+ 1235 QbeGen.AbortFunc; .)
|
|
|
+ 1236 | "EXTERNAL" (. AST.SetOp(astNode, 2);
|
|
|
+ 1237 astDecl := astNode;
|
|
|
+ 1238 Lower.ScopeLeave;
|
|
|
+ 1239 SymTab.MarkExternal("");
|
|
|
+ 1240 SymTab.CloseProc;
|
|
|
+ 1241 QbeGen.AbortFunc; .)
|
|
|
+ 1242 | (. QbeGen.EndFuncHeader; .)
|
|
|
+ 1243 Block<pn> (. AST.SetChild(astNode, 1, astStmt);
|
|
|
+ 1244 AST.SetChild(astNode, 2, astBlkDecls);
|
|
|
+ 1245 astDecl := astNode;
|
|
|
+ 1246 Lower.ScopeLeave;
|
|
|
+ 1247 SymTab.CloseProc;
|
|
|
+ 1248 QbeGen.EndFunc(
|
|
|
+ 1249 SymTab.ProcRes(pn)); .) ) .
|
|
|
+ 1250 Block<pn: SymTab.Name> (. VAR m2: SymTab.Name; .)
|
|
|
+ 1251 = DeclSeq (. astBlkDecls := astDecl;
|
|
|
+ 1252 astStmt := AST.NoNode; .)
|
|
|
+ 1253 [ "BEGIN"
|
|
|
+ 1254 [ StatSeq ] ]
|
|
|
+ 1255 "END"
|
|
|
+ 1256 GetIdent<m2> (. IF NOT SymTab.Equal(pn, m2) THEN
|
|
|
+ 1257 SemError(202) END; .) .
|
|
|
+ 1258 StatSeq (. VAR astSeq, astTail: AST.Node; .)
|
|
|
+ 1259 = (. astSeq := AST.NoNode;
|
|
|
+ 1260 astTail := AST.NoNode; .)
|
|
|
+ 1261 Statement (. AstAppend(AST.NkBlock,
|
|
|
+ 1262 astSeq, astTail, astStmt); .)
|
|
|
+ 1263 { ";" [ Statement (. AstAppend(AST.NkBlock,
|
|
|
+ 1264 astSeq, astTail, astStmt); .) ] }
|
|
|
+ 1265 (. astStmt := astSeq; .) .
|
|
|
+ 1266 (* Trailing/empty statements (`a; ; b`, Coco/R's generated `;;`)
|
|
|
+ 1267 are accepted: the statement after ';' is optional. *)
|
|
|
+ 1268 Statement (. VAR lx: QbeGen.QVal; .)
|
|
|
+ 1269 = (. astStmt := AST.NoNode; .)
|
|
|
+ 1270 ( AssOrCall
|
|
|
+ 1271 | IfStat
|
|
|
+ 1272 | WhileStat
|
|
|
+ 1273 | RepeatStat
|
|
|
+ 1274 | LoopStat
|
|
|
+ 1275 | ForStat
|
|
|
+ 1276 | CaseStat
|
|
|
+ 1277 | WithStat
|
|
|
+ 1278 | ReturnStat
|
|
|
+ 1279 | HaltStat
|
|
|
+ 1280 | NewStat
|
|
|
+ 1281 | DisposeStat
|
|
|
+ 1282 | IncDecStat
|
|
|
+ 1283 | InclExclStat
|
|
|
+ 1284 | "EXIT" (. IF QbeGen.TopLoop(lx) THEN
|
|
|
+ 1285 QbeGen.Jmp(lx)
|
|
|
+ 1286 ELSE SemError(230) END;
|
|
|
+ 1287 astStmt := AST.MakeNode(AST.NkExit); .) ) .
|
|
|
+ 1288 (* INCL(set, elem) / EXCL(set, elem): PIM set-element builtins. *)
|
|
|
+ 1289 InclExclStat (. VAR at, et2: SymTab.TypeIndex;
|
|
|
+ 1290 dk: INTEGER;
|
|
|
+ 1291 qd, qe: QbeGen.QVal;
|
|
|
+ 1292 qn: SymTab.Name;
|
|
|
+ 1293 sfx, isInc: BOOLEAN;
|
|
|
+ 1294 astNode, astD: AST.Node; .)
|
|
|
+ 1295 = ( "INCL" (. isInc := TRUE; .)
|
|
|
+ 1296 | "EXCL" (. isInc := FALSE; .) )
|
|
|
+ 1297 "(" Design<at, dk, qd, qn, sfx> (. astD := astCur; .) ","
|
|
|
+ 1298 Expr<et2, qe> ")"
|
|
|
+ 1299 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 1300 IF isInc THEN
|
|
|
+ 1301 AST.SetChild(astNode, 0,
|
|
|
+ 1302 AST.MakeLeaf(AST.NkIdent, "INCL"))
|
|
|
+ 1303 ELSE AST.SetChild(astNode, 0,
|
|
|
+ 1304 AST.MakeLeaf(AST.NkIdent, "EXCL"))
|
|
|
+ 1305 END;
|
|
|
+ 1306 IF astD # AST.NoNode THEN
|
|
|
+ 1307 AST.SetChild(astNode, 1, astD) END;
|
|
|
+ 1308 IF astCur # AST.NoNode THEN
|
|
|
+ 1309 AST.SetChild(astNode, 2, astCur) END;
|
|
|
+ 1310 astStmt := astNode; .)
|
|
|
+ 1311 (. IF at = SymTab.InvalidType THEN
|
|
|
+ 1312 ELSIF SymTab.ClassOf(at) #
|
|
|
+ 1313 SymTab.ClSet THEN
|
|
|
+ 1314 SemError(222)
|
|
|
+ 1315 ELSE
|
|
|
+ 1316 IF isInc THEN
|
|
|
+ 1317 QbeGen.SetBit(qd, qe,
|
|
|
+ 1318 SymTab.SetBaseLo(at),
|
|
|
+ 1319 SymTab.SetCount(at))
|
|
|
+ 1320 ELSE
|
|
|
+ 1321 QbeGen.SetClearBit(qd, qe,
|
|
|
+ 1322 SymTab.SetBaseLo(at),
|
|
|
+ 1323 SymTab.SetCount(at))
|
|
|
+ 1324 END
|
|
|
+ 1325 END; .) .
|
|
|
+ 1326 (* INC(v [,step]) / DEC(v [,step]) as builtin statements over an
|
|
|
+ 1327 integer designator. *)
|
|
|
+ 1328 IncDecStat (. VAR dt, et2: SymTab.TypeIndex;
|
|
|
+ 1329 dk: INTEGER;
|
|
|
+ 1330 qd, qv, qn2, qstep:
|
|
|
+ 1331 QbeGen.QVal;
|
|
|
+ 1332 qn: SymTab.Name;
|
|
|
+ 1333 sfx, isInc: BOOLEAN;
|
|
|
+ 1334 astNode, astD, astStep:
|
|
|
+ 1335 AST.Node; .)
|
|
|
+ 1336 = (. isInc := TRUE; .)
|
|
|
+ 1337 ( "INC" (. isInc := TRUE; .)
|
|
|
+ 1338 | "DEC" (. isInc := FALSE; .) )
|
|
|
+ 1339 "(" (. QbeGen.CopyOp("1", qstep); astStep := AST.NoNode; .)
|
|
|
+ 1340 Design<dt, dk, qd, qn, sfx> (. astD := astCur; .)
|
|
|
+ 1341 [ "," Expr<et2, qstep> (. astStep := astCur; .) ]
|
|
|
+ 1342 ")" (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 1343 IF isInc THEN
|
|
|
+ 1344 AST.SetChild(astNode, 0,
|
|
|
+ 1345 AST.MakeLeaf(AST.NkIdent, "INC"))
|
|
|
+ 1346 ELSE AST.SetChild(astNode, 0,
|
|
|
+ 1347 AST.MakeLeaf(AST.NkIdent, "DEC"))
|
|
|
+ 1348 END;
|
|
|
+ 1349 IF astD # AST.NoNode THEN
|
|
|
+ 1350 AST.SetChild(astNode, 1, astD) END;
|
|
|
+ 1351 IF astStep # AST.NoNode THEN
|
|
|
+ 1352 AST.SetChild(astNode, 2, astStep) END;
|
|
|
+ 1353 astStmt := astNode; .) (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 1354 ELSIF (dk # SymTab.KindVar)
|
|
|
+ 1355 AND (dk # SymTab.KindParam)
|
|
|
+ 1356 AND (dk # SymTab.KindField) THEN
|
|
|
+ 1357 SemError(210)
|
|
|
+ 1358 ELSIF NOT SymTab.IsIntFamily(dt) THEN
|
|
|
+ 1359 SemError(211)
|
|
|
+ 1360 ELSE
|
|
|
+ 1361 IF sfx
|
|
|
+ 1362 OR (dk = SymTab.KindField) THEN
|
|
|
+ 1363 QbeGen.ElemLoad(qd, dt, qv)
|
|
|
+ 1364 ELSE QbeGen.LoadVar(qn,
|
|
|
+ 1365 FALSE, qv)
|
|
|
+ 1366 END;
|
|
|
+ 1367 QbeGen.NewTemp(qn2);
|
|
|
+ 1368 IF isInc THEN
|
|
|
+ 1369 QbeGen.Op3("add", qn2, qv,
|
|
|
+ 1370 qstep, FALSE)
|
|
|
+ 1371 ELSE QbeGen.Op3("sub", qn2, qv,
|
|
|
+ 1372 qstep, FALSE)
|
|
|
+ 1373 END;
|
|
|
+ 1374 IF sfx
|
|
|
+ 1375 OR (dk = SymTab.KindField) THEN
|
|
|
+ 1376 QbeGen.ElemStore(qd, qn2,
|
|
|
+ 1377 dt)
|
|
|
+ 1378 ELSE QbeGen.StoreVar(qn,
|
|
|
+ 1379 qn2, FALSE)
|
|
|
+ 1380 END
|
|
|
+ 1381 END; .) .
|
|
|
+ 1382 (* NEW/DISPOSE as builtin statements (no call syntax until step 4).
|
|
|
+ 1383 Targets are pointer designators; DISPOSE nils afterwards (safer
|
|
|
+ 1384 than Wirth-undefined; documented). DISPOSE is shallow. *)
|
|
|
+ 1385 NewStat (. VAR dt: SymTab.TypeIndex;
|
|
|
+ 1386 dk: INTEGER;
|
|
|
+ 1387 qd, qm: QbeGen.QVal;
|
|
|
+ 1388 qn: SymTab.Name;
|
|
|
+ 1389 sfx: BOOLEAN;
|
|
|
+ 1390 bt: SymTab.TypeIndex;
|
|
|
+ 1391 astNode, astD: AST.Node; .)
|
|
|
+ 1392 = "NEW" "(" Design<dt, dk, qd, qn, sfx> (. astD := astCur; .) ")"
|
|
|
+ 1393 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 1394 AST.SetChild(astNode, 0,
|
|
|
+ 1395 AST.MakeLeaf(AST.NkIdent, "NEW"));
|
|
|
+ 1396 IF astD # AST.NoNode THEN
|
|
|
+ 1397 AST.SetChild(astNode, 1, astD) END;
|
|
|
+ 1398 astStmt := astNode; .)
|
|
|
+ 1399 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 1400 ELSIF (dk # SymTab.KindVar)
|
|
|
+ 1401 AND (dk # SymTab.KindParam)
|
|
|
+ 1402 AND (dk # SymTab.KindField) THEN
|
|
|
+ 1403 SemError(210)
|
|
|
+ 1404 ELSIF SymTab.ClassOf(dt) #
|
|
|
+ 1405 SymTab.ClPtr THEN
|
|
|
+ 1406 SemError(219)
|
|
|
+ 1407 ELSE bt := SymTab.PtrBase(dt);
|
|
|
+ 1408 IF bt #
|
|
|
+ 1409 SymTab.InvalidType THEN
|
|
|
+ 1410 QbeGen.NewHeap(bt, qm);
|
|
|
+ 1411 QbeGen.InitHeap(qm, bt);
|
|
|
+ 1412 IF sfx
|
|
|
+ 1413 OR (dk =
|
|
|
+ 1414 SymTab.KindField) THEN
|
|
|
+ 1415 QbeGen.ElemStore(qd, qm,
|
|
|
+ 1416 dt)
|
|
|
+ 1417 ELSE QbeGen.StorePtr(qn,
|
|
|
+ 1418 qm)
|
|
|
+ 1419 END
|
|
|
+ 1420 END
|
|
|
+ 1421 END; .) .
|
|
|
+ 1422 DisposeStat (. VAR dt: SymTab.TypeIndex;
|
|
|
+ 1423 dk: INTEGER;
|
|
|
+ 1424 qd, qv: QbeGen.QVal;
|
|
|
+ 1425 qn: SymTab.Name;
|
|
|
+ 1426 sfx: BOOLEAN;
|
|
|
+ 1427 astNode, astD: AST.Node; .)
|
|
|
+ 1428 = "DISPOSE" "(" Design<dt, dk, qd, qn, sfx> (. astD := astCur; .) ")"
|
|
|
+ 1429 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 1430 AST.SetChild(astNode, 0,
|
|
|
+ 1431 AST.MakeLeaf(AST.NkIdent, "DISPOSE"));
|
|
|
+ 1432 IF astD # AST.NoNode THEN
|
|
|
+ 1433 AST.SetChild(astNode, 1, astD) END;
|
|
|
+ 1434 astStmt := astNode; .)
|
|
|
+ 1435 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 1436 ELSIF (dk # SymTab.KindVar)
|
|
|
+ 1437 AND (dk # SymTab.KindParam)
|
|
|
+ 1438 AND (dk # SymTab.KindField) THEN
|
|
|
+ 1439 SemError(210)
|
|
|
+ 1440 ELSIF SymTab.ClassOf(dt) #
|
|
|
+ 1441 SymTab.ClPtr THEN
|
|
|
+ 1442 SemError(219)
|
|
|
+ 1443 ELSE
|
|
|
+ 1444 IF sfx
|
|
|
+ 1445 OR (dk =
|
|
|
+ 1446 SymTab.KindField) THEN
|
|
|
+ 1447 QbeGen.ElemLoad(qd, dt,
|
|
|
+ 1448 qv)
|
|
|
+ 1449 ELSE QbeGen.LoadPtr(qn, qv)
|
|
|
+ 1450 END;
|
|
|
+ 1451 QbeGen.FreeHeap(qv);
|
|
|
+ 1452 IF sfx
|
|
|
+ 1453 OR (dk =
|
|
|
+ 1454 SymTab.KindField) THEN
|
|
|
+ 1455 QbeGen.ElemStore(qd, "0",
|
|
|
+ 1456 dt)
|
|
|
+ 1457 ELSE QbeGen.StorePtr(qn,
|
|
|
+ 1458 "0")
|
|
|
+ 1459 END
|
|
|
+ 1460 END; .) .
|
|
|
+ 1461 (* WITH pushes each record's fields (inner wins) plus its base
|
|
|
+ 1462 address; field designators resolve through both stacks. *)
|
|
|
+ 1463 WithStat (. VAR nW: CARDINAL;
|
|
|
+ 1464 astNode: AST.Node; .)
|
|
|
+ 1465 = "WITH" (. nW := 0;
|
|
|
+ 1466 astNode := AST.MakeNode(AST.NkWith); .)
|
|
|
+ 1467 WithItem<nW, astNode> { "," WithItem<nW, astNode> }
|
|
|
+ 1468 "DO" (. astStmt := AST.NoNode; .)
|
|
|
+ 1469 [ StatSeq ] "END" (. AST.SetChild(astNode,
|
|
|
+ 1470 AST.NChild(astNode), astStmt);
|
|
|
+ 1471 astStmt := astNode;
|
|
|
+ 1472 WHILE nW > 0 DO
|
|
|
+ 1473 SymTab.PopScope;
|
|
|
+ 1474 QbeGen.PopWith;
|
|
|
+ 1475 DEC(nW)
|
|
|
+ 1476 END; .) .
|
|
|
+ 1477 WithItem<VAR nW: CARDINAL; wnode: AST.Node>
|
|
|
+ 1478 (. VAR dt: SymTab.TypeIndex;
|
|
|
+ 1479 dk: INTEGER;
|
|
|
+ 1480 qd, qe: QbeGen.QVal;
|
|
|
+ 1481 qn: SymTab.Name;
|
|
|
+ 1482 sfx: BOOLEAN; .)
|
|
|
+ 1483 = Design<dt, dk, qd, qn, sfx>
|
|
|
+ 1484 (. IF astCur # AST.NoNode THEN
|
|
|
+ 1485 AST.SetChild(wnode,
|
|
|
+ 1486 AST.NChild(wnode), astCur) END;
|
|
|
+ 1487 IF dt = SymTab.InvalidType THEN
|
|
|
+ 1488 ELSIF (SymTab.ClassOf(dt) #
|
|
|
+ 1489 SymTab.ClRecord)
|
|
|
+ 1490 AND (SymTab.ClassOf(dt) #
|
|
|
+ 1491 SymTab.ClClass) THEN
|
|
|
+ 1492 SemError(215)
|
|
|
+ 1493 ELSIF SymTab.PushRecord(dt) THEN
|
|
|
+ 1494 QbeGen.PushWith(qd);
|
|
|
+ 1495 INC(nW)
|
|
|
+ 1496 END; .) .
|
|
|
+ 1497 (* Assignment or procedure-statement call (4.1, module level).
|
|
|
+ 1498 Bare `P;` is a syntax error; function-as-statement is 233. *)
|
|
|
+ 1499 AssOrCall (. VAR dt, et: SymTab.TypeIndex;
|
|
|
+ 1500 dk: INTEGER;
|
|
|
+ 1501 qd, qe, qt, ql: QbeGen.QVal;
|
|
|
+ 1502 qn: SymTab.Name;
|
|
|
+ 1503 ct2, res0: SymTab.TypeIndex;
|
|
|
+ 1504 q2, mg0: QbeGen.QVal;
|
|
|
+ 1505 isR, conv, wconv: BOOLEAN;
|
|
|
+ 1506 called, sfx: BOOLEAN;
|
|
|
+ 1507 astLhs: AST.Node; .)
|
|
|
+ 1508 = Design<dt, dk, qd, qn, sfx>
|
|
|
+ 1509 (. astLhs := astCur; astNArgs := 0; .)
|
|
|
+ 1510 ( ":="
|
|
|
+ 1511 Expr<et, qe> (. astStmt := AST.MakeBin(
|
|
|
+ 1512 AST.NkAssign, 0, astLhs, astCur);
|
|
|
+ 1513 IF (dt # SymTab.InvalidType)
|
|
|
+ 1514 AND (dk # SymTab.KindVar)
|
|
|
+ 1515 AND (dk # SymTab.KindParam)
|
|
|
+ 1516 AND (dk # SymTab.KindField) THEN
|
|
|
+ 1517 SemError(210)
|
|
|
+ 1518 ELSIF NOT SymTab.Assignable(et,
|
|
|
+ 1519 dt) THEN
|
|
|
+ 1520 SemError(210)
|
|
|
+ 1521 ELSIF (dt # SymTab.InvalidType)
|
|
|
+ 1522 AND (SymTab.ClassOf(dt) =
|
|
|
+ 1523 SymTab.ClClass) THEN
|
|
|
+ 1524 SemError(230) END;
|
|
|
+ 1525 isR := (dt #
|
|
|
+ 1526 SymTab.InvalidType)
|
|
|
+ 1527 AND (SymTab.ClassOf(dt)
|
|
|
+ 1528 = SymTab.ClReal);
|
|
|
+ 1529 conv := isR
|
|
|
+ 1530 AND SymTab.IsIntFamily(et);
|
|
|
+ 1531 wconv := (dt #
|
|
|
+ 1532 SymTab.InvalidType)
|
|
|
+ 1533 AND SymTab.IsLongFamily(dt)
|
|
|
+ 1534 AND SymTab.IsIntFamily(et);
|
|
|
+ 1535 IF ((dk = SymTab.KindVar)
|
|
|
+ 1536 OR (dk = SymTab.KindParam)
|
|
|
+ 1537 OR (dk = SymTab.KindField))
|
|
|
+ 1538 AND (dt # SymTab.InvalidType)
|
|
|
+ 1539 AND (et # SymTab.InvalidType)
|
|
|
+ 1540 AND (SymTab.ClassOf(dt) #
|
|
|
+ 1541 SymTab.ClClass) THEN
|
|
|
+ 1542 IF sfx
|
|
|
+ 1543 OR (dk = SymTab.KindField) THEN
|
|
|
+ 1544 IF SymTab.ClassOf(dt) =
|
|
|
+ 1545 SymTab.ClArray THEN
|
|
|
+ 1546 IF (et # SymTab.InvalidType)
|
|
|
+ 1547 AND (SymTab.ClassOf(et) = SymTab.ClUStr)
|
|
|
+ 1548 AND SymTab.IsUCharArray(dt) THEN
|
|
|
+ 1549 QbeGen.UAssign(qd, qe)
|
|
|
+ 1550 ELSIF SymTab.StrCompat(dt,
|
|
|
+ 1551 et) THEN
|
|
|
+ 1552 QbeGen.StrAssign(qd,
|
|
|
+ 1553 qe)
|
|
|
+ 1554 ELSE
|
|
|
+ 1555 QbeGen.CopyArray(qd,
|
|
|
+ 1556 qe, dt)
|
|
|
+ 1557 END
|
|
|
+ 1558 ELSIF SymTab.ClassOf(dt) =
|
|
|
+ 1559 SymTab.ClSet THEN
|
|
|
+ 1560 QbeGen.CopySet(qd, qe,
|
|
|
+ 1561 SymTab.SetWords(dt),
|
|
|
+ 1562 SymTab.SetWords(et))
|
|
|
+ 1563 ELSIF SymTab.ClassOf(dt) =
|
|
|
+ 1564 SymTab.ClRecord THEN
|
|
|
+ 1565 QbeGen.CopyRecord(qd, qe,
|
|
|
+ 1566 dt)
|
|
|
+ 1567 ELSIF SymTab.IsLongFamily(dt) THEN
|
|
|
+ 1568 IF wconv THEN
|
|
|
+ 1569 QbeGen.WidenLong(qe, ql);
|
|
|
+ 1570 QbeGen.ElemStore(qd, ql,
|
|
|
+ 1571 dt)
|
|
|
+ 1572 ELSE QbeGen.ElemStore(qd, qe,
|
|
|
+ 1573 dt)
|
|
|
+ 1574 END
|
|
|
+ 1575 ELSIF conv THEN
|
|
|
+ 1576 QbeGen.ConvIR(qe, qt);
|
|
|
+ 1577 QbeGen.ElemStore(qd, qt,
|
|
|
1578 dt)
|
|
|
- 1579 END
|
|
|
- 1580 ELSIF SymTab.ClassOf(dt) =
|
|
|
- 1581 SymTab.ClSet THEN
|
|
|
- 1582 QbeGen.CopySet(qd, qe,
|
|
|
- 1583 SymTab.SetWords(dt),
|
|
|
- 1584 SymTab.SetWords(et))
|
|
|
- 1585 ELSIF SymTab.ClassOf(dt) =
|
|
|
- 1586 SymTab.ClRecord THEN
|
|
|
- 1587 QbeGen.CopyRecord(qd, qe, dt)
|
|
|
- 1588 ELSIF (SymTab.ClassOf(dt) =
|
|
|
- 1589 SymTab.ClPtr)
|
|
|
- 1590 OR (SymTab.ClassOf(dt) =
|
|
|
- 1591 SymTab.ClProc) THEN
|
|
|
- 1592 QbeGen.StorePtr(qn, qe)
|
|
|
- 1593 ELSIF SymTab.IsLongFamily(dt) THEN
|
|
|
- 1594 IF wconv THEN
|
|
|
- 1595 QbeGen.WidenLong(qe, ql);
|
|
|
- 1596 QbeGen.StoreLong(qn, ql)
|
|
|
- 1597 ELSE QbeGen.StoreLong(qn, qe)
|
|
|
- 1598 END
|
|
|
- 1599 ELSIF conv THEN
|
|
|
- 1600 QbeGen.ConvIR(qe, qt);
|
|
|
- 1601 QbeGen.StoreVar(qn, qt, TRUE)
|
|
|
- 1602 ELSE
|
|
|
- 1603 QbeGen.StoreVar(qn, qe, isR)
|
|
|
- 1604 END
|
|
|
- 1605 END; .)
|
|
|
- 1606 | ArgList<qn, dt, qd, FALSE, FALSE, methCls, ct2, q2, called>
|
|
|
- 1607 (. astStmt := AstCallNode(astLhs); .)
|
|
|
- 1608 | (* bare `P;`: proper parameterless
|
|
|
- 1609 procedure call; anything else
|
|
|
- 1610 here is 233 (was a bare syntax
|
|
|
- 1611 error before 4.2) *)
|
|
|
- 1612 (. astStmt := AstCallNode(astLhs);
|
|
|
- 1613 IF (dk = SymTab.KindProc)
|
|
|
- 1614 AND NOT sfx THEN
|
|
|
- 1615 res0 := SymTab.ProcRes(qn);
|
|
|
- 1616 IF res0 #
|
|
|
- 1617 SymTab.InvalidType THEN
|
|
|
- 1618 SemError(233)
|
|
|
- 1619 ELSIF SymTab.ProcNPar(qn) #
|
|
|
- 1620 0 THEN
|
|
|
- 1621 SemError(233)
|
|
|
- 1622 ELSE QbeGen.Mangled(qn,
|
|
|
- 1623 SymTab.ProcUid(qn), mg0);
|
|
|
- 1624 QbeGen.CallBegin(mg0,
|
|
|
- 1625 res0,
|
|
|
- 1626 SymTab.ProcDepthOf(qn),
|
|
|
- 1627 SymTab.IsExternal(qn));
|
|
|
- 1628 QbeGen.CallEnd(FALSE, q2)
|
|
|
- 1629 END
|
|
|
- 1630 ELSE SemError(233)
|
|
|
- 1631 END; .) ) .
|
|
|
- 1632 (* Actual-parameter list shared by statement and expression calls.
|
|
|
- 1633 want selects CallEnd's result handling; t/q carry the call
|
|
|
- 1634 value (statement calls discard). Arity/type failures are 233;
|
|
|
- 1635 evaluation code still emits so the .ssa stays assembleable. *)
|
|
|
- 1636 ArgList<pn: SymTab.Name; pt: SymTab.TypeIndex; callee: QbeGen.QVal;
|
|
|
- 1637 want: BOOLEAN; soft: BOOLEAN; methCls: SymTab.TypeIndex;
|
|
|
- 1638 VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal;
|
|
|
- 1639 VAR called: BOOLEAN> (. VAR i, np: CARDINAL;
|
|
|
- 1640 vs: INTEGER;
|
|
|
- 1641 res: SymTab.TypeIndex;
|
|
|
- 1642 mg: QbeGen.QVal;
|
|
|
- 1643 ok, ind, isMeth, va: BOOLEAN; .)
|
|
|
- 1644 = "(" (. called := TRUE;
|
|
|
- 1645 ok := TRUE;
|
|
|
- 1646 ind := FALSE;
|
|
|
- 1647 isMeth := methCls #
|
|
|
- 1648 SymTab.InvalidType;
|
|
|
- 1649 IF isMeth THEN
|
|
|
- 1650 (* class method: the
|
|
|
- 1651 receiver is armed.
|
|
|
- 1652 Virtual -> dispatch
|
|
|
- 1653 through the vtable;
|
|
|
- 1654 otherwise a static
|
|
|
- 1655 call. *)
|
|
|
- 1656 res := SymTab.ClassMethodRes(
|
|
|
- 1657 methCls, pn);
|
|
|
- 1658 vs := SymTab.VirtSlot(
|
|
|
- 1659 methCls, pn);
|
|
|
- 1660 IF vs >= 0 THEN
|
|
|
- 1661 QbeGen.VirtCallBegin(
|
|
|
- 1662 callee, vs, res)
|
|
|
- 1663 ELSE
|
|
|
- 1664 QbeGen.Mangled(pn,
|
|
|
- 1665 SymTab.ClassMethodUid(
|
|
|
- 1666 methCls, pn), mg);
|
|
|
- 1667 QbeGen.CallBegin(mg, res, 0,
|
|
|
- 1668 FALSE)
|
|
|
- 1669 END
|
|
|
- 1670 ELSIF SymTab.SymKind(pn) =
|
|
|
- 1671 SymTab.KindProc THEN
|
|
|
- 1672 res := SymTab.ProcRes(pn);
|
|
|
- 1673 QbeGen.Mangled(pn,
|
|
|
- 1674 SymTab.ProcUid(pn), mg);
|
|
|
- 1675 QbeGen.CallBegin(mg, res,
|
|
|
- 1676 SymTab.ProcDepthOf(pn),
|
|
|
- 1677 SymTab.IsExternal(pn))
|
|
|
- 1678 ELSIF (pt # SymTab.InvalidType)
|
|
|
- 1679 AND (SymTab.ClassOf(pt) = SymTab.ClProc) THEN
|
|
|
- 1680 ind := TRUE;
|
|
|
- 1681 res :=
|
|
|
- 1682 SymTab.ProcTypeRes(pt);
|
|
|
- 1683 QbeGen.CallBeginInd(callee,
|
|
|
- 1684 res, FALSE)
|
|
|
- 1685 ELSE SemError(233);
|
|
|
- 1686 ok := FALSE;
|
|
|
- 1687 res := SymTab.InvalidType
|
|
|
- 1688 END;
|
|
|
- 1689 i := 0; .)
|
|
|
- 1690 [ ActParam<pn, pt, ind, methCls, i> (. INC(i); .)
|
|
|
- 1691 { "," ActParam<pn, pt, ind, methCls, i> (. INC(i); .) } ]
|
|
|
- 1692 ")" (. IF ok THEN
|
|
|
- 1693 IF isMeth THEN
|
|
|
- 1694 np := SymTab.ClassMethodNPar(
|
|
|
- 1695 methCls, pn)
|
|
|
- 1696 ELSIF ind THEN
|
|
|
- 1697 np := SymTab.ProcTypeNPar(pt)
|
|
|
- 1698 ELSE np := SymTab.ProcNPar(pn)
|
|
|
- 1699 END;
|
|
|
- 1700 va := (NOT isMeth) AND (NOT ind)
|
|
|
- 1701 AND (SymTab.SymKind(pn) =
|
|
|
- 1702 SymTab.KindProc)
|
|
|
- 1703 AND SymTab.Varargs(pn);
|
|
|
- 1704 IF (i # np) AND NOT va THEN
|
|
|
- 1705 SemError(233); ok := FALSE
|
|
|
- 1706 END
|
|
|
- 1707 END;
|
|
|
- 1708 IF NOT ok THEN
|
|
|
- 1709 t := SymTab.InvalidType;
|
|
|
- 1710 QbeGen.CopyOp("0", q)
|
|
|
- 1711 ELSIF want THEN
|
|
|
- 1712 IF res =
|
|
|
- 1713 SymTab.InvalidType THEN
|
|
|
- 1714 SemError(233);
|
|
|
- 1715 t := SymTab.InvalidType;
|
|
|
- 1716 QbeGen.CopyOp("0", q)
|
|
|
- 1717 ELSE t := res;
|
|
|
- 1718 QbeGen.CallEnd(TRUE, q)
|
|
|
- 1719 END
|
|
|
- 1720 ELSE
|
|
|
- 1721 IF res #
|
|
|
- 1722 SymTab.InvalidType THEN
|
|
|
- 1723 SemError(233)
|
|
|
- 1724 END;
|
|
|
- 1725 t := SymTab.InvalidType;
|
|
|
- 1726 QbeGen.CopyOp("0", q);
|
|
|
- 1727 QbeGen.CallEnd(FALSE, q)
|
|
|
- 1728 END; .) .
|
|
|
- 1729 (* One actual: VAR formals take recorded designator addresses
|
|
|
- 1730 (233 otherwise); value formals take converted expressions. *)
|
|
|
- 1731 ActParam<pn: SymTab.Name; pt: SymTab.TypeIndex; ind: BOOLEAN;
|
|
|
- 1732 methCls: SymTab.TypeIndex; i: CARDINAL>
|
|
|
- 1733 (. VAR at, ft: SymTab.TypeIndex;
|
|
|
- 1734 qe, qa, qt: QbeGen.QVal;
|
|
|
- 1735 isV, conv, va: BOOLEAN;
|
|
|
- 1736 cl: CHAR; .)
|
|
|
- 1737 = Expr<at, qe> (. IF astNArgs <= HIGH(astArgs) THEN
|
|
|
- 1738 astArgs[astNArgs] := astCur;
|
|
|
- 1739 INC(astNArgs)
|
|
|
- 1740 END;
|
|
|
- 1741 va := (NOT ind)
|
|
|
- 1742 AND (methCls =
|
|
|
- 1743 SymTab.InvalidType)
|
|
|
- 1744 AND (SymTab.SymKind(pn) =
|
|
|
- 1745 SymTab.KindProc)
|
|
|
- 1746 AND SymTab.Varargs(pn);
|
|
|
- 1747 IF ind THEN
|
|
|
- 1748 ft :=
|
|
|
- 1749 SymTab.ProcTypeParamType(pt,
|
|
|
- 1750 i);
|
|
|
- 1751 isV :=
|
|
|
- 1752 SymTab.ProcTypeParamIsVar(pt,
|
|
|
- 1753 i)
|
|
|
- 1754 ELSIF methCls #
|
|
|
- 1755 SymTab.InvalidType THEN
|
|
|
- 1756 ft :=
|
|
|
- 1757 SymTab.ClassMethodParamType(
|
|
|
- 1758 methCls, pn, i);
|
|
|
- 1759 isV :=
|
|
|
- 1760 SymTab.ClassMethodParamIsVar(
|
|
|
- 1761 methCls, pn, i)
|
|
|
- 1762 ELSE
|
|
|
- 1763 ft := SymTab.ParamType(pn, i);
|
|
|
- 1764 isV := SymTab.ParamIsVar(pn, i)
|
|
|
- 1765 END;
|
|
|
- 1766 IF (at = SymTab.InvalidType) THEN
|
|
|
- 1767 ELSIF ft = SymTab.InvalidType THEN
|
|
|
- 1768 IF va THEN
|
|
|
- 1769 QbeGen.CArgAdd(qe, at, qa, cl)
|
|
|
- 1770 END
|
|
|
- 1771 ELSIF isV THEN
|
|
|
- 1772 IF (SymTab.ClassOf(at)
|
|
|
- 1773 = SymTab.ClChar)
|
|
|
- 1774 AND (SymTab.ClassOf(ft) = SymTab.ClArray)
|
|
|
- 1775 AND (SymTab.ClassOf(SymTab.ArrayElem(ft))
|
|
|
- 1776 = SymTab.ClChar)
|
|
|
- 1777 AND QbeGen.IsImm(qe) THEN
|
|
|
- 1778 (* 1-char string
|
|
|
- 1779 literal passed to
|
|
|
- 1780 a VAR ARRAY OF CHAR *)
|
|
|
- 1781 QbeGen.DeclCharStr(qe,
|
|
|
- 1782 qa);
|
|
|
- 1783 IF NOT QbeGen.CallArg(qa,
|
|
|
- 1784 "l") THEN
|
|
|
- 1785 SemError(233)
|
|
|
- 1786 END
|
|
|
- 1787 ELSIF NOT QbeGen.AddrOfVal(qe,
|
|
|
- 1788 qa) THEN
|
|
|
- 1789 SemError(233)
|
|
|
- 1790 ELSIF NOT SymTab.VarParamOk(at,
|
|
|
- 1791 ft) THEN
|
|
|
- 1792 SemError(233)
|
|
|
- 1793 ELSIF NOT QbeGen.CallArg(qa,
|
|
|
- 1794 "l") THEN
|
|
|
- 1795 SemError(233)
|
|
|
- 1796 END
|
|
|
- 1797 ELSE
|
|
|
- 1798 IF (SymTab.ClassOf(at)
|
|
|
- 1799 = SymTab.ClChar)
|
|
|
- 1800 AND (SymTab.ClassOf(ft) = SymTab.ClArray)
|
|
|
- 1801 AND (SymTab.ClassOf(SymTab.ArrayElem(ft))
|
|
|
- 1802 = SymTab.ClChar)
|
|
|
- 1803 AND QbeGen.IsImm(qe) THEN
|
|
|
- 1804 (* 1-char string
|
|
|
- 1805 literal passed to
|
|
|
- 1806 ARRAY OF CHAR *)
|
|
|
- 1807 QbeGen.DeclCharStr(qe,
|
|
|
- 1808 qa);
|
|
|
- 1809 IF NOT QbeGen.CallArg(qa,
|
|
|
- 1810 "l") THEN
|
|
|
- 1811 SemError(233)
|
|
|
- 1812 END
|
|
|
- 1813 ELSIF NOT SymTab.Assignable(at,
|
|
|
- 1814 ft) THEN
|
|
|
- 1815 SemError(233)
|
|
|
- 1816 ELSE
|
|
|
- 1817 conv := (SymTab.ClassOf(
|
|
|
- 1818 ft) = SymTab.ClReal)
|
|
|
- 1819 AND SymTab.IsIntFamily(at);
|
|
|
- 1820 IF conv THEN
|
|
|
- 1821 QbeGen.ConvIR(qe, qt);
|
|
|
- 1822 IF NOT QbeGen.CallArg(qt,
|
|
|
- 1823 "d") THEN
|
|
|
- 1824 SemError(233)
|
|
|
- 1825 END
|
|
|
- 1826 ELSIF NOT QbeGen.CallArg(qe,
|
|
|
- 1827 QbeGen.ArgClass(ft)) THEN
|
|
|
- 1828 SemError(233)
|
|
|
- 1829 END
|
|
|
- 1830 END
|
|
|
- 1831 END; .) .
|
|
|
- 1832 IfStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 1833 q, lThen, lElse, lEnd:
|
|
|
- 1834 QbeGen.QVal;
|
|
|
- 1835 hasElse: BOOLEAN;
|
|
|
- 1836 astCond, astIf, astLast,
|
|
|
- 1837 astNode: AST.Node; .)
|
|
|
- 1838 = "IF" (. hasElse := FALSE; .)
|
|
|
- 1839 Expr<t, q> (. astCond := astCur; astStmt := AST.NoNode;
|
|
|
- 1840 IF NOT SymTab.BoolCheck(t) THEN
|
|
|
- 1841 SemError(214) END;
|
|
|
- 1842 QbeGen.NewLabel(lThen);
|
|
|
- 1843 QbeGen.NewLabel(lElse);
|
|
|
- 1844 QbeGen.NewLabel(lEnd);
|
|
|
- 1845 QbeGen.Jnz(q, lThen, lElse);
|
|
|
- 1846 QbeGen.EmitLabel(lThen); .)
|
|
|
- 1847 "THEN" [ StatSeq ] (. astNode := AST.MakeNode(AST.NkIf);
|
|
|
- 1848 AST.SetChild(astNode, 0, astCond);
|
|
|
- 1849 AST.SetChild(astNode, 1, astStmt);
|
|
|
- 1850 astIf := astNode;
|
|
|
- 1851 astLast := astNode;
|
|
|
- 1852 QbeGen.Jmp(lEnd); .)
|
|
|
- 1853 { "ELSIF" (. QbeGen.EmitLabel(lElse);
|
|
|
- 1854 QbeGen.NewLabel(lElse); .)
|
|
|
- 1855 Expr<t, q> (. astCond := astCur; astStmt := AST.NoNode;
|
|
|
- 1856 IF NOT SymTab.BoolCheck(t) THEN
|
|
|
- 1857 SemError(214) END;
|
|
|
- 1858 QbeGen.NewLabel(lThen);
|
|
|
- 1859 QbeGen.Jnz(q, lThen, lElse);
|
|
|
- 1860 QbeGen.EmitLabel(lThen); .)
|
|
|
- 1861 "THEN" [ StatSeq ] (. astNode := AST.MakeNode(AST.NkIf);
|
|
|
- 1862 AST.SetChild(astNode, 0, astCond);
|
|
|
- 1863 AST.SetChild(astNode, 1, astStmt);
|
|
|
- 1864 AST.SetChild(astLast, 2, astNode);
|
|
|
- 1865 astLast := astNode;
|
|
|
- 1866 QbeGen.Jmp(lEnd); .) }
|
|
|
- 1867 [ "ELSE" (. QbeGen.EmitLabel(lElse);
|
|
|
- 1868 hasElse := TRUE;
|
|
|
- 1869 astStmt := AST.NoNode; .)
|
|
|
- 1870 [ StatSeq ] (. AST.SetChild(astLast, 2, astStmt); .) ]
|
|
|
- 1871 "END" (. astStmt := astIf;
|
|
|
- 1872 IF hasElse THEN
|
|
|
- 1873 QbeGen.EmitLabel(lEnd)
|
|
|
- 1874 ELSE QbeGen.EmitLabel(lElse);
|
|
|
- 1875 QbeGen.EmitLabel(lEnd)
|
|
|
- 1876 END; .) .
|
|
|
- 1877 WhileStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 1878 q, lTop, lBody, lEnd:
|
|
|
- 1879 QbeGen.QVal;
|
|
|
- 1880 astCond, astNode: AST.Node; .)
|
|
|
- 1881 = "WHILE" (. astStmt := AST.NoNode;
|
|
|
- 1882 QbeGen.NewLabel(lTop);
|
|
|
- 1883 QbeGen.NewLabel(lBody);
|
|
|
- 1884 QbeGen.NewLabel(lEnd);
|
|
|
- 1885 QbeGen.EmitLabel(lTop); .)
|
|
|
- 1886 Expr<t, q> (. astCond := astCur;
|
|
|
- 1887 IF NOT SymTab.BoolCheck(t) THEN
|
|
|
- 1888 SemError(214) END;
|
|
|
- 1889 QbeGen.Jnz(q, lBody, lEnd);
|
|
|
- 1890 QbeGen.EmitLabel(lBody); .)
|
|
|
- 1891 "DO" [ StatSeq ] (. astNode := AST.MakeNode(AST.NkWhile);
|
|
|
- 1892 AST.SetChild(astNode, 0, astCond);
|
|
|
- 1893 AST.SetChild(astNode, 1, astStmt);
|
|
|
- 1894 astStmt := astNode;
|
|
|
- 1895 QbeGen.Jmp(lTop); .)
|
|
|
- 1896 "END" (. QbeGen.EmitLabel(lEnd); .) .
|
|
|
- 1897 RepeatStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 1898 q, lTop, lEnd: QbeGen.QVal;
|
|
|
- 1899 astCond, astBody, astNode:
|
|
|
- 1900 AST.Node; .)
|
|
|
- 1901 = "REPEAT" (. astStmt := AST.NoNode;
|
|
|
- 1902 QbeGen.NewLabel(lTop);
|
|
|
- 1903 QbeGen.NewLabel(lEnd);
|
|
|
- 1904 QbeGen.EmitLabel(lTop); .)
|
|
|
- 1905 [ StatSeq ] (. astBody := astStmt; .)
|
|
|
- 1906 "UNTIL" Expr<t, q> (. astCond := astCur;
|
|
|
- 1907 astNode := AST.MakeNode(AST.NkRepeat);
|
|
|
- 1908 AST.SetChild(astNode, 0, astBody);
|
|
|
- 1909 AST.SetChild(astNode, 1, astCond);
|
|
|
- 1910 astStmt := astNode;
|
|
|
- 1911 IF NOT SymTab.BoolCheck(t) THEN
|
|
|
- 1912 SemError(214) END;
|
|
|
- 1913 QbeGen.Jnz(q, lEnd, lTop);
|
|
|
- 1914 QbeGen.EmitLabel(lEnd); .) .
|
|
|
- 1915 LoopStat (. VAR lTop, lEnd: QbeGen.QVal; astNode: AST.Node; .)
|
|
|
- 1916 = "LOOP" (. QbeGen.NewLabel(lTop);
|
|
|
- 1917 astStmt := AST.NoNode;
|
|
|
+ 1579 ELSE QbeGen.ElemStore(qd, qe,
|
|
|
+ 1580 dt)
|
|
|
+ 1581 END
|
|
|
+ 1582 ELSIF SymTab.ClassOf(dt) =
|
|
|
+ 1583 SymTab.ClArray THEN
|
|
|
+ 1584 IF (et # SymTab.InvalidType)
|
|
|
+ 1585 AND (SymTab.ClassOf(et) = SymTab.ClUStr)
|
|
|
+ 1586 AND SymTab.IsUCharArray(dt) THEN
|
|
|
+ 1587 QbeGen.UAssign(qd, qe)
|
|
|
+ 1588 ELSIF SymTab.StrCompat(dt,
|
|
|
+ 1589 et) THEN
|
|
|
+ 1590 QbeGen.StrAssign(qd, qe)
|
|
|
+ 1591 ELSE
|
|
|
+ 1592 QbeGen.CopyArray(qd, qe,
|
|
|
+ 1593 dt)
|
|
|
+ 1594 END
|
|
|
+ 1595 ELSIF SymTab.ClassOf(dt) =
|
|
|
+ 1596 SymTab.ClSet THEN
|
|
|
+ 1597 QbeGen.CopySet(qd, qe,
|
|
|
+ 1598 SymTab.SetWords(dt),
|
|
|
+ 1599 SymTab.SetWords(et))
|
|
|
+ 1600 ELSIF SymTab.ClassOf(dt) =
|
|
|
+ 1601 SymTab.ClRecord THEN
|
|
|
+ 1602 QbeGen.CopyRecord(qd, qe, dt)
|
|
|
+ 1603 ELSIF (SymTab.ClassOf(dt) =
|
|
|
+ 1604 SymTab.ClPtr)
|
|
|
+ 1605 OR (SymTab.ClassOf(dt) =
|
|
|
+ 1606 SymTab.ClProc) THEN
|
|
|
+ 1607 QbeGen.StorePtr(qn, qe)
|
|
|
+ 1608 ELSIF SymTab.IsLongFamily(dt) THEN
|
|
|
+ 1609 IF wconv THEN
|
|
|
+ 1610 QbeGen.WidenLong(qe, ql);
|
|
|
+ 1611 QbeGen.StoreLong(qn, ql)
|
|
|
+ 1612 ELSE QbeGen.StoreLong(qn, qe)
|
|
|
+ 1613 END
|
|
|
+ 1614 ELSIF conv THEN
|
|
|
+ 1615 QbeGen.ConvIR(qe, qt);
|
|
|
+ 1616 QbeGen.StoreVar(qn, qt, TRUE)
|
|
|
+ 1617 ELSE
|
|
|
+ 1618 QbeGen.StoreVar(qn, qe, isR)
|
|
|
+ 1619 END
|
|
|
+ 1620 END; .)
|
|
|
+ 1621 | ArgList<qn, dt, qd, FALSE, FALSE, methCls, ct2, q2, called>
|
|
|
+ 1622 (. astStmt := AstCallNode(astLhs); .)
|
|
|
+ 1623 | (* bare `P;`: proper parameterless
|
|
|
+ 1624 procedure call; anything else
|
|
|
+ 1625 here is 233 (was a bare syntax
|
|
|
+ 1626 error before 4.2) *)
|
|
|
+ 1627 (. astStmt := AstCallNode(astLhs);
|
|
|
+ 1628 IF (dk = SymTab.KindProc)
|
|
|
+ 1629 AND NOT sfx THEN
|
|
|
+ 1630 res0 := SymTab.ProcRes(qn);
|
|
|
+ 1631 IF res0 #
|
|
|
+ 1632 SymTab.InvalidType THEN
|
|
|
+ 1633 SemError(233)
|
|
|
+ 1634 ELSIF SymTab.ProcNPar(qn) #
|
|
|
+ 1635 0 THEN
|
|
|
+ 1636 SemError(233)
|
|
|
+ 1637 ELSE QbeGen.Mangled(qn,
|
|
|
+ 1638 SymTab.ProcUid(qn), mg0);
|
|
|
+ 1639 QbeGen.CallBegin(mg0,
|
|
|
+ 1640 res0,
|
|
|
+ 1641 SymTab.ProcDepthOf(qn),
|
|
|
+ 1642 SymTab.IsExternal(qn));
|
|
|
+ 1643 QbeGen.CallEnd(FALSE, q2)
|
|
|
+ 1644 END
|
|
|
+ 1645 ELSE SemError(233)
|
|
|
+ 1646 END; .) ) .
|
|
|
+ 1647 (* Actual-parameter list shared by statement and expression calls.
|
|
|
+ 1648 want selects CallEnd's result handling; t/q carry the call
|
|
|
+ 1649 value (statement calls discard). Arity/type failures are 233;
|
|
|
+ 1650 evaluation code still emits so the .ssa stays assembleable. *)
|
|
|
+ 1651 ArgList<pn: SymTab.Name; pt: SymTab.TypeIndex; callee: QbeGen.QVal;
|
|
|
+ 1652 want: BOOLEAN; soft: BOOLEAN; methCls: SymTab.TypeIndex;
|
|
|
+ 1653 VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal;
|
|
|
+ 1654 VAR called: BOOLEAN> (. VAR i, np: CARDINAL;
|
|
|
+ 1655 vs: INTEGER;
|
|
|
+ 1656 res: SymTab.TypeIndex;
|
|
|
+ 1657 mg: QbeGen.QVal;
|
|
|
+ 1658 ok, ind, isMeth, va: BOOLEAN; .)
|
|
|
+ 1659 = "(" (. called := TRUE;
|
|
|
+ 1660 ok := TRUE;
|
|
|
+ 1661 ind := FALSE;
|
|
|
+ 1662 isMeth := methCls #
|
|
|
+ 1663 SymTab.InvalidType;
|
|
|
+ 1664 IF isMeth THEN
|
|
|
+ 1665 (* class method: the
|
|
|
+ 1666 receiver is armed.
|
|
|
+ 1667 Virtual -> dispatch
|
|
|
+ 1668 through the vtable;
|
|
|
+ 1669 otherwise a static
|
|
|
+ 1670 call. *)
|
|
|
+ 1671 res := SymTab.ClassMethodRes(
|
|
|
+ 1672 methCls, pn);
|
|
|
+ 1673 vs := SymTab.VirtSlot(
|
|
|
+ 1674 methCls, pn);
|
|
|
+ 1675 IF vs >= 0 THEN
|
|
|
+ 1676 QbeGen.VirtCallBegin(
|
|
|
+ 1677 callee, vs, res)
|
|
|
+ 1678 ELSE
|
|
|
+ 1679 QbeGen.Mangled(pn,
|
|
|
+ 1680 SymTab.ClassMethodUid(
|
|
|
+ 1681 methCls, pn), mg);
|
|
|
+ 1682 QbeGen.CallBegin(mg, res, 0,
|
|
|
+ 1683 FALSE)
|
|
|
+ 1684 END
|
|
|
+ 1685 ELSIF SymTab.SymKind(pn) =
|
|
|
+ 1686 SymTab.KindProc THEN
|
|
|
+ 1687 res := SymTab.ProcRes(pn);
|
|
|
+ 1688 QbeGen.Mangled(pn,
|
|
|
+ 1689 SymTab.ProcUid(pn), mg);
|
|
|
+ 1690 QbeGen.CallBegin(mg, res,
|
|
|
+ 1691 SymTab.ProcDepthOf(pn),
|
|
|
+ 1692 SymTab.IsExternal(pn))
|
|
|
+ 1693 ELSIF (pt # SymTab.InvalidType)
|
|
|
+ 1694 AND (SymTab.ClassOf(pt) = SymTab.ClProc) THEN
|
|
|
+ 1695 ind := TRUE;
|
|
|
+ 1696 res :=
|
|
|
+ 1697 SymTab.ProcTypeRes(pt);
|
|
|
+ 1698 QbeGen.CallBeginInd(callee,
|
|
|
+ 1699 res, FALSE)
|
|
|
+ 1700 ELSE SemError(233);
|
|
|
+ 1701 ok := FALSE;
|
|
|
+ 1702 res := SymTab.InvalidType
|
|
|
+ 1703 END;
|
|
|
+ 1704 i := 0; .)
|
|
|
+ 1705 [ ActParam<pn, pt, ind, methCls, i> (. INC(i); .)
|
|
|
+ 1706 { "," ActParam<pn, pt, ind, methCls, i> (. INC(i); .) } ]
|
|
|
+ 1707 ")" (. IF ok THEN
|
|
|
+ 1708 IF isMeth THEN
|
|
|
+ 1709 np := SymTab.ClassMethodNPar(
|
|
|
+ 1710 methCls, pn)
|
|
|
+ 1711 ELSIF ind THEN
|
|
|
+ 1712 np := SymTab.ProcTypeNPar(pt)
|
|
|
+ 1713 ELSE np := SymTab.ProcNPar(pn)
|
|
|
+ 1714 END;
|
|
|
+ 1715 va := (NOT isMeth) AND (NOT ind)
|
|
|
+ 1716 AND (SymTab.SymKind(pn) =
|
|
|
+ 1717 SymTab.KindProc)
|
|
|
+ 1718 AND SymTab.Varargs(pn);
|
|
|
+ 1719 IF (i # np) AND NOT va THEN
|
|
|
+ 1720 SemError(233); ok := FALSE
|
|
|
+ 1721 END
|
|
|
+ 1722 END;
|
|
|
+ 1723 IF NOT ok THEN
|
|
|
+ 1724 t := SymTab.InvalidType;
|
|
|
+ 1725 QbeGen.CopyOp("0", q)
|
|
|
+ 1726 ELSIF want THEN
|
|
|
+ 1727 IF res =
|
|
|
+ 1728 SymTab.InvalidType THEN
|
|
|
+ 1729 SemError(233);
|
|
|
+ 1730 t := SymTab.InvalidType;
|
|
|
+ 1731 QbeGen.CopyOp("0", q)
|
|
|
+ 1732 ELSE t := res;
|
|
|
+ 1733 QbeGen.CallEnd(TRUE, q)
|
|
|
+ 1734 END
|
|
|
+ 1735 ELSE
|
|
|
+ 1736 IF res #
|
|
|
+ 1737 SymTab.InvalidType THEN
|
|
|
+ 1738 SemError(233)
|
|
|
+ 1739 END;
|
|
|
+ 1740 t := SymTab.InvalidType;
|
|
|
+ 1741 QbeGen.CopyOp("0", q);
|
|
|
+ 1742 QbeGen.CallEnd(FALSE, q)
|
|
|
+ 1743 END; .) .
|
|
|
+ 1744 (* One actual: VAR formals take recorded designator addresses
|
|
|
+ 1745 (233 otherwise); value formals take converted expressions. *)
|
|
|
+ 1746 ActParam<pn: SymTab.Name; pt: SymTab.TypeIndex; ind: BOOLEAN;
|
|
|
+ 1747 methCls: SymTab.TypeIndex; i: CARDINAL>
|
|
|
+ 1748 (. VAR at, ft: SymTab.TypeIndex;
|
|
|
+ 1749 qe, qa, qt: QbeGen.QVal;
|
|
|
+ 1750 isV, conv, va: BOOLEAN;
|
|
|
+ 1751 cl: CHAR; .)
|
|
|
+ 1752 = Expr<at, qe> (. IF astNArgs <= HIGH(astArgs) THEN
|
|
|
+ 1753 astArgs[astNArgs] := astCur;
|
|
|
+ 1754 INC(astNArgs)
|
|
|
+ 1755 END;
|
|
|
+ 1756 va := (NOT ind)
|
|
|
+ 1757 AND (methCls =
|
|
|
+ 1758 SymTab.InvalidType)
|
|
|
+ 1759 AND (SymTab.SymKind(pn) =
|
|
|
+ 1760 SymTab.KindProc)
|
|
|
+ 1761 AND SymTab.Varargs(pn);
|
|
|
+ 1762 IF ind THEN
|
|
|
+ 1763 ft :=
|
|
|
+ 1764 SymTab.ProcTypeParamType(pt,
|
|
|
+ 1765 i);
|
|
|
+ 1766 isV :=
|
|
|
+ 1767 SymTab.ProcTypeParamIsVar(pt,
|
|
|
+ 1768 i)
|
|
|
+ 1769 ELSIF methCls #
|
|
|
+ 1770 SymTab.InvalidType THEN
|
|
|
+ 1771 ft :=
|
|
|
+ 1772 SymTab.ClassMethodParamType(
|
|
|
+ 1773 methCls, pn, i);
|
|
|
+ 1774 isV :=
|
|
|
+ 1775 SymTab.ClassMethodParamIsVar(
|
|
|
+ 1776 methCls, pn, i)
|
|
|
+ 1777 ELSE
|
|
|
+ 1778 ft := SymTab.ParamType(pn, i);
|
|
|
+ 1779 isV := SymTab.ParamIsVar(pn, i)
|
|
|
+ 1780 END;
|
|
|
+ 1781 IF (at = SymTab.InvalidType) THEN
|
|
|
+ 1782 ELSIF ft = SymTab.InvalidType THEN
|
|
|
+ 1783 IF va THEN
|
|
|
+ 1784 QbeGen.CArgAdd(qe, at, qa, cl)
|
|
|
+ 1785 END
|
|
|
+ 1786 ELSIF isV THEN
|
|
|
+ 1787 IF (SymTab.ClassOf(at)
|
|
|
+ 1788 = SymTab.ClChar)
|
|
|
+ 1789 AND (SymTab.ClassOf(ft) = SymTab.ClArray)
|
|
|
+ 1790 AND (SymTab.ClassOf(SymTab.ArrayElem(ft))
|
|
|
+ 1791 = SymTab.ClChar)
|
|
|
+ 1792 AND QbeGen.IsImm(qe) THEN
|
|
|
+ 1793 (* 1-char string
|
|
|
+ 1794 literal passed to
|
|
|
+ 1795 a VAR ARRAY OF CHAR *)
|
|
|
+ 1796 QbeGen.DeclCharStr(qe,
|
|
|
+ 1797 qa);
|
|
|
+ 1798 IF NOT QbeGen.CallArg(qa,
|
|
|
+ 1799 "l") THEN
|
|
|
+ 1800 SemError(233)
|
|
|
+ 1801 END
|
|
|
+ 1802 ELSIF NOT QbeGen.AddrOfVal(qe,
|
|
|
+ 1803 qa) THEN
|
|
|
+ 1804 SemError(233)
|
|
|
+ 1805 ELSIF NOT SymTab.VarParamOk(at,
|
|
|
+ 1806 ft) THEN
|
|
|
+ 1807 SemError(233)
|
|
|
+ 1808 ELSIF NOT QbeGen.CallArg(qa,
|
|
|
+ 1809 "l") THEN
|
|
|
+ 1810 SemError(233)
|
|
|
+ 1811 END
|
|
|
+ 1812 ELSE
|
|
|
+ 1813 IF (SymTab.ClassOf(at)
|
|
|
+ 1814 = SymTab.ClChar)
|
|
|
+ 1815 AND (SymTab.ClassOf(ft) = SymTab.ClArray)
|
|
|
+ 1816 AND (SymTab.ClassOf(SymTab.ArrayElem(ft))
|
|
|
+ 1817 = SymTab.ClChar)
|
|
|
+ 1818 AND QbeGen.IsImm(qe) THEN
|
|
|
+ 1819 (* 1-char string
|
|
|
+ 1820 literal passed to
|
|
|
+ 1821 ARRAY OF CHAR *)
|
|
|
+ 1822 QbeGen.DeclCharStr(qe,
|
|
|
+ 1823 qa);
|
|
|
+ 1824 IF NOT QbeGen.CallArg(qa,
|
|
|
+ 1825 "l") THEN
|
|
|
+ 1826 SemError(233)
|
|
|
+ 1827 END
|
|
|
+ 1828 ELSIF NOT SymTab.Assignable(at,
|
|
|
+ 1829 ft) THEN
|
|
|
+ 1830 SemError(233)
|
|
|
+ 1831 ELSE
|
|
|
+ 1832 conv := (SymTab.ClassOf(
|
|
|
+ 1833 ft) = SymTab.ClReal)
|
|
|
+ 1834 AND SymTab.IsIntFamily(at);
|
|
|
+ 1835 IF conv THEN
|
|
|
+ 1836 QbeGen.ConvIR(qe, qt);
|
|
|
+ 1837 IF NOT QbeGen.CallArg(qt,
|
|
|
+ 1838 "d") THEN
|
|
|
+ 1839 SemError(233)
|
|
|
+ 1840 END
|
|
|
+ 1841 ELSIF NOT QbeGen.CallArg(qe,
|
|
|
+ 1842 QbeGen.ArgClass(ft)) THEN
|
|
|
+ 1843 SemError(233)
|
|
|
+ 1844 END
|
|
|
+ 1845 END
|
|
|
+ 1846 END; .) .
|
|
|
+ 1847 IfStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 1848 q, lThen, lElse, lEnd:
|
|
|
+ 1849 QbeGen.QVal;
|
|
|
+ 1850 hasElse: BOOLEAN;
|
|
|
+ 1851 astCond, astIf, astLast,
|
|
|
+ 1852 astNode: AST.Node; .)
|
|
|
+ 1853 = "IF" (. hasElse := FALSE; .)
|
|
|
+ 1854 Expr<t, q> (. astCond := astCur; astStmt := AST.NoNode;
|
|
|
+ 1855 IF NOT SymTab.BoolCheck(t) THEN
|
|
|
+ 1856 SemError(214) END;
|
|
|
+ 1857 QbeGen.NewLabel(lThen);
|
|
|
+ 1858 QbeGen.NewLabel(lElse);
|
|
|
+ 1859 QbeGen.NewLabel(lEnd);
|
|
|
+ 1860 QbeGen.Jnz(q, lThen, lElse);
|
|
|
+ 1861 QbeGen.EmitLabel(lThen); .)
|
|
|
+ 1862 "THEN" [ StatSeq ] (. astNode := AST.MakeNode(AST.NkIf);
|
|
|
+ 1863 AST.SetChild(astNode, 0, astCond);
|
|
|
+ 1864 AST.SetChild(astNode, 1, astStmt);
|
|
|
+ 1865 astIf := astNode;
|
|
|
+ 1866 astLast := astNode;
|
|
|
+ 1867 QbeGen.Jmp(lEnd); .)
|
|
|
+ 1868 { "ELSIF" (. QbeGen.EmitLabel(lElse);
|
|
|
+ 1869 QbeGen.NewLabel(lElse); .)
|
|
|
+ 1870 Expr<t, q> (. astCond := astCur; astStmt := AST.NoNode;
|
|
|
+ 1871 IF NOT SymTab.BoolCheck(t) THEN
|
|
|
+ 1872 SemError(214) END;
|
|
|
+ 1873 QbeGen.NewLabel(lThen);
|
|
|
+ 1874 QbeGen.Jnz(q, lThen, lElse);
|
|
|
+ 1875 QbeGen.EmitLabel(lThen); .)
|
|
|
+ 1876 "THEN" [ StatSeq ] (. astNode := AST.MakeNode(AST.NkIf);
|
|
|
+ 1877 AST.SetChild(astNode, 0, astCond);
|
|
|
+ 1878 AST.SetChild(astNode, 1, astStmt);
|
|
|
+ 1879 AST.SetChild(astLast, 2, astNode);
|
|
|
+ 1880 astLast := astNode;
|
|
|
+ 1881 QbeGen.Jmp(lEnd); .) }
|
|
|
+ 1882 [ "ELSE" (. QbeGen.EmitLabel(lElse);
|
|
|
+ 1883 hasElse := TRUE;
|
|
|
+ 1884 astStmt := AST.NoNode; .)
|
|
|
+ 1885 [ StatSeq ] (. AST.SetChild(astLast, 2, astStmt); .) ]
|
|
|
+ 1886 "END" (. astStmt := astIf;
|
|
|
+ 1887 IF hasElse THEN
|
|
|
+ 1888 QbeGen.EmitLabel(lEnd)
|
|
|
+ 1889 ELSE QbeGen.EmitLabel(lElse);
|
|
|
+ 1890 QbeGen.EmitLabel(lEnd)
|
|
|
+ 1891 END; .) .
|
|
|
+ 1892 WhileStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 1893 q, lTop, lBody, lEnd:
|
|
|
+ 1894 QbeGen.QVal;
|
|
|
+ 1895 astCond, astNode: AST.Node; .)
|
|
|
+ 1896 = "WHILE" (. astStmt := AST.NoNode;
|
|
|
+ 1897 QbeGen.NewLabel(lTop);
|
|
|
+ 1898 QbeGen.NewLabel(lBody);
|
|
|
+ 1899 QbeGen.NewLabel(lEnd);
|
|
|
+ 1900 QbeGen.EmitLabel(lTop); .)
|
|
|
+ 1901 Expr<t, q> (. astCond := astCur;
|
|
|
+ 1902 IF NOT SymTab.BoolCheck(t) THEN
|
|
|
+ 1903 SemError(214) END;
|
|
|
+ 1904 QbeGen.Jnz(q, lBody, lEnd);
|
|
|
+ 1905 QbeGen.EmitLabel(lBody); .)
|
|
|
+ 1906 "DO" [ StatSeq ] (. astNode := AST.MakeNode(AST.NkWhile);
|
|
|
+ 1907 AST.SetChild(astNode, 0, astCond);
|
|
|
+ 1908 AST.SetChild(astNode, 1, astStmt);
|
|
|
+ 1909 astStmt := astNode;
|
|
|
+ 1910 QbeGen.Jmp(lTop); .)
|
|
|
+ 1911 "END" (. QbeGen.EmitLabel(lEnd); .) .
|
|
|
+ 1912 RepeatStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 1913 q, lTop, lEnd: QbeGen.QVal;
|
|
|
+ 1914 astCond, astBody, astNode:
|
|
|
+ 1915 AST.Node; .)
|
|
|
+ 1916 = "REPEAT" (. astStmt := AST.NoNode;
|
|
|
+ 1917 QbeGen.NewLabel(lTop);
|
|
|
1918 QbeGen.NewLabel(lEnd);
|
|
|
- 1919 QbeGen.PushLoop(lEnd);
|
|
|
- 1920 QbeGen.EmitLabel(lTop); .)
|
|
|
- 1921 [ StatSeq ]
|
|
|
- 1922 "END" (. astNode := AST.MakeNode(AST.NkLoop);
|
|
|
- 1923 AST.SetChild(astNode, 0, astStmt);
|
|
|
- 1924 astStmt := astNode;
|
|
|
- 1925 QbeGen.Jmp(lTop);
|
|
|
- 1926 QbeGen.PopLoop;
|
|
|
- 1927 QbeGen.EmitLabel(lEnd); .) .
|
|
|
- 1928 (* FOR with static-sign BY (literal, non-zero; 220 otherwise).
|
|
|
- 1929 Runtime direction would need a compare-select; the literal
|
|
|
- 1930 sign picks cslew/csegew at "DO" time. *)
|
|
|
- 1931 ForStat (. VAR lv: SymTab.Name;
|
|
|
- 1932 tlo, thi, tby:
|
|
|
- 1933 SymTab.TypeIndex;
|
|
|
- 1934 qlo, qhi, qby, qt, qk, qb:
|
|
|
- 1935 QbeGen.QVal;
|
|
|
- 1936 lTop, lBody, lEnd:
|
|
|
- 1937 QbeGen.QVal;
|
|
|
- 1938 by: INTEGER;
|
|
|
- 1939 ok: BOOLEAN;
|
|
|
- 1940 astVar, astLo, astHi, astBy,
|
|
|
- 1941 astNode: AST.Node; .)
|
|
|
- 1942 = "FOR" (. by := 1; .)
|
|
|
- 1943 GetIdent<lv> (. astVar := AST.MakeLeaf(AST.NkIdent, lv);
|
|
|
- 1944 astStmt := AST.NoNode;
|
|
|
- 1945 astBy := AST.NoNode;
|
|
|
- 1946 ok := SymTab.Lookup(lv);
|
|
|
- 1947 IF NOT ok THEN
|
|
|
- 1948 SemError(201)
|
|
|
- 1949 ELSIF (SymTab.SymKind(lv) #
|
|
|
- 1950 SymTab.KindVar)
|
|
|
- 1951 AND (SymTab.SymKind(lv) #
|
|
|
- 1952 SymTab.KindParam) THEN
|
|
|
- 1953 SemError(220); ok := FALSE
|
|
|
- 1954 ELSIF NOT SymTab.IsIntFamily(
|
|
|
- 1955 SymTab.SymType(lv)) THEN
|
|
|
- 1956 SemError(220); ok := FALSE
|
|
|
- 1957 END; .)
|
|
|
- 1958 ":=" Expr<tlo, qlo> (. astLo := astCur;
|
|
|
- 1959 IF NOT SymTab.IsIntFamily(tlo) THEN
|
|
|
- 1960 SemError(220); ok := FALSE
|
|
|
- 1961 END; .)
|
|
|
- 1962 "TO" Expr<thi, qhi> (. astHi := astCur;
|
|
|
- 1963 IF NOT SymTab.IsIntFamily(thi) THEN
|
|
|
- 1964 SemError(220); ok := FALSE
|
|
|
- 1965 END; .)
|
|
|
- 1966 [ "BY" Expr<tby, qby> (. astBy := astCur;
|
|
|
- 1967 IF (tby #
|
|
|
- 1968 SymTab.InvalidType)
|
|
|
- 1969 AND NOT SymTab.IsIntFamily(tby) THEN
|
|
|
- 1970 SemError(220); ok := FALSE
|
|
|
- 1971 END;
|
|
|
- 1972 IF NOT SymTab.ConstInt(qby, by) THEN
|
|
|
- 1973 SemError(230); by := 1
|
|
|
- 1974 ELSIF by = 0 THEN
|
|
|
- 1975 SemError(220); by := 1
|
|
|
- 1976 END; .) ]
|
|
|
- 1977 "DO" (. IF ok THEN
|
|
|
- 1978 QbeGen.StoreVar(lv, qlo,
|
|
|
- 1979 FALSE) END;
|
|
|
- 1980 QbeGen.NewLabel(lTop);
|
|
|
- 1981 QbeGen.NewLabel(lBody);
|
|
|
- 1982 QbeGen.NewLabel(lEnd);
|
|
|
- 1983 QbeGen.EmitLabel(lTop);
|
|
|
- 1984 QbeGen.LoadVar(lv, FALSE, qt);
|
|
|
- 1985 QbeGen.NewTemp(qk);
|
|
|
- 1986 IF by > 0 THEN
|
|
|
- 1987 QbeGen.Op3("cslew", qk,
|
|
|
- 1988 qt, qhi, FALSE)
|
|
|
- 1989 ELSE QbeGen.Op3("csgew", qk,
|
|
|
- 1990 qt, qhi, FALSE)
|
|
|
- 1991 END;
|
|
|
- 1992 QbeGen.Jnz(qk, lBody, lEnd);
|
|
|
- 1993 QbeGen.EmitLabel(lBody); .)
|
|
|
- 1994 [ StatSeq ]
|
|
|
- 1995 "END" (. astNode := AST.MakeNode(AST.NkFor);
|
|
|
- 1996 AST.SetChild(astNode, 0, astVar);
|
|
|
- 1997 AST.SetChild(astNode, 1, astLo);
|
|
|
- 1998 AST.SetChild(astNode, 2, astHi);
|
|
|
- 1999 AST.SetChild(astNode, 3, astBy);
|
|
|
- 2000 AST.SetChild(astNode, 4, astStmt);
|
|
|
- 2001 astStmt := astNode;
|
|
|
- 2002 IF ok THEN
|
|
|
- 2003 QbeGen.LoadVar(lv, FALSE,
|
|
|
- 2004 qt);
|
|
|
- 2005 QbeGen.IntStr(by, qb);
|
|
|
- 2006 QbeGen.NewTemp(qk);
|
|
|
- 2007 QbeGen.Op3("add", qk,
|
|
|
- 2008 qt, qb, FALSE);
|
|
|
- 2009 QbeGen.StoreVar(lv, qk,
|
|
|
- 2010 FALSE) END;
|
|
|
- 2011 QbeGen.Jmp(lTop);
|
|
|
- 2012 QbeGen.EmitLabel(lEnd); .) .
|
|
|
- 2013 CaseStat (. VAR tsel: SymTab.TypeIndex;
|
|
|
- 2014 qsel, lEnd: QbeGen.QVal;
|
|
|
- 2015 arm, astNode: AST.Node; .)
|
|
|
- 2016 = "CASE" Expr<tsel, qsel> (. astNode := AST.MakeNode(AST.NkCase);
|
|
|
- 2017 AST.SetChild(astNode, 0, astCur);
|
|
|
- 2018 QbeGen.NewLabel(lEnd); .)
|
|
|
- 2019 "OF" CaseAlt<tsel, qsel, lEnd, astNode>
|
|
|
- 2020 { "|" CaseAlt<tsel, qsel, lEnd, astNode> }
|
|
|
- 2021 [ "ELSE" (. astStmt := AST.NoNode; .)
|
|
|
- 2022 [ StatSeq ] (. arm := AST.MakeNode(AST.NkCaseArm);
|
|
|
- 2023 AST.SetOp(arm, 1);
|
|
|
- 2024 AST.SetChild(arm, 0, astStmt);
|
|
|
- 2025 AST.SetChild(astNode,
|
|
|
- 2026 AST.NChild(astNode), arm); .) ]
|
|
|
- 2027 "END" (. astStmt := astNode;
|
|
|
- 2028 QbeGen.EmitLabel(lEnd); .) .
|
|
|
- 2029 (* Compare-chain lowering: each alternative ends its match-tests
|
|
|
- 2030 with "jmp lAfter", so the no-match fallthrough skips the body:
|
|
|
- 2031 "cmp; jnz(lBody,lF); lF: ... ; jmp lAfter; lBody: S; jmp lEnd;
|
|
|
- 2032 lAfter:". Falls into the next alternative, ELSE, or END. *)
|
|
|
- 2033 CaseAlt<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
- 2034 lEnd: QbeGen.QVal; cnode: AST.Node>
|
|
|
- 2035 (. VAR lBody, lAfter: QbeGen.QVal;
|
|
|
- 2036 arm: AST.Node; .)
|
|
|
- 2037 = (. arm := AST.MakeNode(AST.NkCaseArm);
|
|
|
- 2038 QbeGen.NewLabel(lBody);
|
|
|
- 2039 QbeGen.NewLabel(lAfter); .)
|
|
|
- 2040 CaseLabel<tsel, qsel, lBody, arm>
|
|
|
- 2041 { "," CaseLabel<tsel, qsel, lBody, arm> }
|
|
|
- 2042 ":" (. astStmt := AST.NoNode;
|
|
|
- 2043 QbeGen.Jmp(lAfter);
|
|
|
- 2044 QbeGen.EmitLabel(lBody); .)
|
|
|
- 2045 [ StatSeq ] (. AST.SetChild(arm, AST.NChild(arm),
|
|
|
- 2046 astStmt);
|
|
|
- 2047 AST.SetChild(cnode,
|
|
|
- 2048 AST.NChild(cnode), arm);
|
|
|
- 2049 QbeGen.Jmp(lEnd);
|
|
|
- 2050 QbeGen.EmitLabel(lAfter); .) .
|
|
|
- 2051 CaseLabel<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
- 2052 lBody: QbeGen.QVal; arm: AST.Node>
|
|
|
- 2053 (. VAR t2, t3: SymTab.TypeIndex;
|
|
|
- 2054 q2, q3, qc, qd, qe:
|
|
|
- 2055 QbeGen.QVal;
|
|
|
- 2056 astLab: AST.Node;
|
|
|
- 2057 lNext: QbeGen.QVal; .)
|
|
|
- 2058 = Expr<t2, q2> (. astLab := astCur;
|
|
|
- 2059 IF (t2 #
|
|
|
- 2060 SymTab.InvalidType)
|
|
|
- 2061 AND (tsel #
|
|
|
- 2062 SymTab.InvalidType)
|
|
|
- 2063 AND ((SymTab.ClassOf(t2) =
|
|
|
- 2064 SymTab.ClSet)
|
|
|
- 2065 OR (SymTab.ClassOf(tsel) =
|
|
|
- 2066 SymTab.ClSet)) THEN
|
|
|
- 2067 SemError(230)
|
|
|
- 2068 ELSIF (t2 #
|
|
|
- 2069 SymTab.InvalidType)
|
|
|
- 2070 AND (tsel #
|
|
|
- 2071 SymTab.InvalidType)
|
|
|
- 2072 AND NOT SymTab.EqCheck(t2,
|
|
|
- 2073 tsel) THEN
|
|
|
- 2074 SemError(213) END;
|
|
|
- 2075 IF NOT QbeGen.IsImm(q2) THEN
|
|
|
- 2076 SemError(230);
|
|
|
- 2077 QbeGen.CopyOp("0", q2)
|
|
|
- 2078 END;
|
|
|
- 2079 QbeGen.NewLabel(lNext);
|
|
|
- 2080 QbeGen.Cmp(SymTab.OpEq,
|
|
|
- 2081 qsel, q2, qc, FALSE);
|
|
|
- 2082 QbeGen.Jnz(qc, lBody, lNext);
|
|
|
- 2083 QbeGen.EmitLabel(lNext); .)
|
|
|
- 2084 [ ".." Expr<t3, q3> (. astLab := AST.MakeBin(
|
|
|
- 2085 AST.NkSubrange, 0, astLab, astCur);
|
|
|
- 2086 IF (t3 #
|
|
|
- 2087 SymTab.InvalidType)
|
|
|
- 2088 AND (tsel #
|
|
|
- 2089 SymTab.InvalidType)
|
|
|
- 2090 AND NOT SymTab.EqCheck(t3,
|
|
|
- 2091 tsel) THEN
|
|
|
- 2092 SemError(213) END;
|
|
|
- 2093 IF NOT QbeGen.IsImm(q3) THEN
|
|
|
- 2094 SemError(230);
|
|
|
- 2095 QbeGen.CopyOp("0", q3)
|
|
|
- 2096 END;
|
|
|
- 2097 QbeGen.Cmp(SymTab.OpGe,
|
|
|
- 2098 qsel, q2, qc, FALSE);
|
|
|
- 2099 QbeGen.Cmp(SymTab.OpLe,
|
|
|
- 2100 qsel, q3, qd, FALSE);
|
|
|
- 2101 QbeGen.NewTemp(qe);
|
|
|
- 2102 QbeGen.Op3("and", qe, qc, qd,
|
|
|
- 2103 FALSE);
|
|
|
- 2104 QbeGen.NewLabel(lNext);
|
|
|
- 2105 QbeGen.Jnz(qe, lBody, lNext);
|
|
|
- 2106 QbeGen.EmitLabel(lNext); .) ]
|
|
|
- 2107 (. AST.SetChild(arm,
|
|
|
- 2108 AST.NChild(arm), astLab); .) .
|
|
|
- 2109 ReturnStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 2110 q, qt: QbeGen.QVal;
|
|
|
- 2111 res: SymTab.TypeIndex;
|
|
|
- 2112 hadE, conv: BOOLEAN;
|
|
|
- 2113 astVal, astNode: AST.Node; .)
|
|
|
- 2114 = "RETURN" (. hadE := FALSE; astStmt := AST.NoNode; .)
|
|
|
- 2115 [ Expr<t, q> (. hadE := TRUE; astVal := astCur; .) ]
|
|
|
- 2116 (. astNode := AST.MakeNode(AST.NkReturn);
|
|
|
- 2117 IF hadE THEN
|
|
|
- 2118 AST.SetChild(astNode, 0, astVal)
|
|
|
- 2119 END;
|
|
|
- 2120 astStmt := astNode;
|
|
|
- 2121 conv := FALSE;
|
|
|
- 2122 IF NOT SymTab.InProc() THEN
|
|
|
- 2123 SemError(232)
|
|
|
- 2124 ELSE res := SymTab.CurRes();
|
|
|
- 2125 IF NOT hadE THEN
|
|
|
- 2126 IF res #
|
|
|
- 2127 SymTab.InvalidType THEN
|
|
|
- 2128 SemError(232)
|
|
|
- 2129 ELSE QbeGen.EmitRet(q,
|
|
|
- 2130 FALSE)
|
|
|
- 2131 END
|
|
|
- 2132 ELSIF (res =
|
|
|
- 2133 SymTab.InvalidType)
|
|
|
- 2134 OR (t #
|
|
|
- 2135 SymTab.InvalidType)
|
|
|
- 2136 AND NOT SymTab.Assignable(t,
|
|
|
- 2137 res) THEN
|
|
|
- 2138 SemError(232)
|
|
|
- 2139 ELSE
|
|
|
- 2140 conv := (SymTab.ClassOf(
|
|
|
- 2141 res) = SymTab.ClReal)
|
|
|
- 2142 AND SymTab.IsIntFamily(t);
|
|
|
- 2143 IF conv THEN
|
|
|
- 2144 QbeGen.ConvIR(q, qt);
|
|
|
- 2145 QbeGen.EmitRet(qt, TRUE)
|
|
|
- 2146 ELSE QbeGen.EmitRet(q, TRUE)
|
|
|
- 2147 END
|
|
|
- 2148 END
|
|
|
- 2149 END; .) .
|
|
|
- 2150 HaltStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 2151 q: QbeGen.QVal;
|
|
|
- 2152 astVal, astNode: AST.Node; .)
|
|
|
- 2153 = "HALT" (. astVal := AST.NoNode; .)
|
|
|
- 2154 [ "(" Expr<t, q> (. astVal := astCur; .) ")" ]
|
|
|
- 2155 (. astNode := AST.MakeNode(AST.NkHalt);
|
|
|
- 2156 IF astVal # AST.NoNode THEN
|
|
|
- 2157 AST.SetChild(astNode, 0, astVal)
|
|
|
- 2158 END;
|
|
|
- 2159 astStmt := astNode;
|
|
|
- 2160 QbeGen.HaltQ; .) .
|
|
|
- 2161 (* Designator: scalar loads, array addresses, and index suffixes.
|
|
|
- 2162 Each index descends one level (bounds-checked, trap on breach);
|
|
|
- 2163 nested levels reload the inner descriptor address. q ends as the
|
|
|
- 2164 value (scalars), the descriptor address (plain arrays), or the
|
|
|
- 2165 element address (indexed); sfx marks the indexed form. *)
|
|
|
- 2166 Design<VAR t: SymTab.TypeIndex; VAR k: INTEGER;
|
|
|
- 2167 VAR q: QbeGen.QVal; VAR qn: SymTab.Name; VAR sfx: BOOLEAN>
|
|
|
- 2168 (. VAR n, fn, mal: SymTab.Name;
|
|
|
- 2169 cls: INTEGER;
|
|
|
- 2170 ic: SymTab.TypeIndex;
|
|
|
- 2171 curT, it, eT, bt:
|
|
|
- 2172 SymTab.TypeIndex;
|
|
|
- 2173 iq, ql, qlo, qhi, qe:
|
|
|
- 2174 QbeGen.QVal;
|
|
|
- 2175 lo, hi: INTEGER;
|
|
|
- 2176 fo: INTEGER;
|
|
|
- 2177 isOpen: BOOLEAN;
|
|
|
- 2178 qb, cv: QbeGen.QVal;
|
|
|
- 2179 fid, fref, slot: INTEGER;
|
|
|
- 2180 r: BOOLEAN;
|
|
|
- 2181 astDes, astSel: AST.Node; .)
|
|
|
- 2182 = GetIdent<n> (. methCls := SymTab.InvalidType;
|
|
|
- 2183 QbeGen.CopyOp(n, qn);
|
|
|
- 2184 sfx := FALSE;
|
|
|
- 2185 fid := 0; fref := 0; slot := 0;
|
|
|
- 2186 IF NOT SymTab.Lookup(n) THEN
|
|
|
- 2187 (* a bare method name inside
|
|
|
- 2188 a CLASS IMPLEMENTATION
|
|
|
- 2189 is a sibling call on
|
|
|
- 2190 THIS *)
|
|
|
- 2191 ic := SymTab.CurImplClass();
|
|
|
- 2192 IF (ic #
|
|
|
- 2193 SymTab.InvalidType)
|
|
|
- 2194 AND SymTab.MethodExists(ic, n) THEN
|
|
|
- 2195 sfx := FALSE;
|
|
|
- 2196 QbeGen.ThisBase(q);
|
|
|
- 2197 QbeGen.ArmRecv(q);
|
|
|
- 2198 methCls := ic;
|
|
|
- 2199 k := SymTab.KindProc;
|
|
|
- 2200 t := SymTab.InvalidType
|
|
|
- 2201 ELSIF SymTab.InProc() THEN
|
|
|
- 2202 (* not declared yet: a
|
|
|
- 2203 forward reference to a
|
|
|
- 2204 module-level variable
|
|
|
- 2205 declared further down. *)
|
|
|
- 2206 k := SymTab.KindVar;
|
|
|
- 2207 r := SymTab.FwdVarRef(n, k,
|
|
|
- 2208 fref, t);
|
|
|
- 2209 slot := QbeGen.FwdDesignator();
|
|
|
- 2210 FwdVarNote(fref, slot);
|
|
|
- 2211 fid := slot;
|
|
|
- 2212 QbeGen.FwdAddrOper(fid, q);
|
|
|
- 2213 sfx := TRUE
|
|
|
- 2214 ELSE
|
|
|
- 2215 SemError(201);
|
|
|
- 2216 t :=
|
|
|
- 2217 SymTab.InvalidType;
|
|
|
- 2218 k := -1;
|
|
|
- 2219 QbeGen.CopyOp("0", q)
|
|
|
- 2220 END
|
|
|
- 2221 ELSE
|
|
|
- 2222 t := SymTab.SymType(n);
|
|
|
- 2223 k := SymTab.SymKind(n);
|
|
|
- 2224 IF k = SymTab.KindConst THEN
|
|
|
- 2225 IF SymTab.Equal(n,
|
|
|
- 2226 "TRUE") THEN
|
|
|
- 2227 t := SymTab.BoolType();
|
|
|
- 2228 QbeGen.CopyOp("1", q)
|
|
|
- 2229 ELSIF SymTab.Equal(n,
|
|
|
- 2230 "FALSE") THEN
|
|
|
- 2231 t := SymTab.BoolType();
|
|
|
- 2232 QbeGen.CopyOp("0", q)
|
|
|
- 2233 ELSIF SymTab.Equal(n,
|
|
|
- 2234 "NIL") THEN
|
|
|
- 2235 QbeGen.CopyOp("0", q)
|
|
|
- 2236 ELSE
|
|
|
- 2237 cls :=
|
|
|
- 2238 SymTab.ClassOf(t);
|
|
|
- 2239 IF (t #
|
|
|
- 2240 SymTab.InvalidType)
|
|
|
- 2241 AND ((cls = SymTab.ClInt)
|
|
|
- 2242 OR (cls
|
|
|
- 2243 = SymTab.ClChar)
|
|
|
- 2244 OR (cls
|
|
|
- 2245 = SymTab.ClEnum)
|
|
|
- 2246 OR (cls
|
|
|
- 2247 = SymTab.ClReal)
|
|
|
- 2248 OR (cls
|
|
|
- 2249 = SymTab.ClLong)
|
|
|
- 2250 OR (cls
|
|
|
- 2251 = SymTab.ClNil)) THEN
|
|
|
- 2252 IF cls = SymTab.ClNil THEN
|
|
|
- 2253 QbeGen.CopyOp("0", q)
|
|
|
- 2254 ELSIF ((cls
|
|
|
- 2255 = SymTab.ClInt)
|
|
|
- 2256 OR (cls
|
|
|
- 2257 = SymTab.ClChar)
|
|
|
- 2258 OR (cls
|
|
|
- 2259 = SymTab.ClEnum)
|
|
|
- 2260 OR (cls
|
|
|
- 2261 = SymTab.ClLong))
|
|
|
- 2262 AND SymTab.GetSymVal(n, cv)
|
|
|
- 2263 AND QbeGen.IsImm(cv) THEN
|
|
|
- 2264 QbeGen.CopyOp(cv, q)
|
|
|
- 2265 ELSE
|
|
|
- 2266 QbeGen.LoadVar(n,
|
|
|
- 2267 cls = SymTab.ClReal,
|
|
|
- 2268 q)
|
|
|
- 2269 END
|
|
|
- 2270 ELSIF (cls = SymTab.ClArray)
|
|
|
- 2271 OR (cls = SymTab.ClRecord)
|
|
|
- 2272 OR (cls = SymTab.ClClass)
|
|
|
- 2273 OR (cls = SymTab.ClStr)
|
|
|
- 2274 OR (cls = SymTab.ClUStr) THEN
|
|
|
- 2275 (* aggregate constant:
|
|
|
- 2276 its value IS the
|
|
|
- 2277 descriptor address *)
|
|
|
- 2278 IF SymTab.GetSymVal(n, cv) THEN
|
|
|
+ 1919 QbeGen.EmitLabel(lTop); .)
|
|
|
+ 1920 [ StatSeq ] (. astBody := astStmt; .)
|
|
|
+ 1921 "UNTIL" Expr<t, q> (. astCond := astCur;
|
|
|
+ 1922 astNode := AST.MakeNode(AST.NkRepeat);
|
|
|
+ 1923 AST.SetChild(astNode, 0, astBody);
|
|
|
+ 1924 AST.SetChild(astNode, 1, astCond);
|
|
|
+ 1925 astStmt := astNode;
|
|
|
+ 1926 IF NOT SymTab.BoolCheck(t) THEN
|
|
|
+ 1927 SemError(214) END;
|
|
|
+ 1928 QbeGen.Jnz(q, lEnd, lTop);
|
|
|
+ 1929 QbeGen.EmitLabel(lEnd); .) .
|
|
|
+ 1930 LoopStat (. VAR lTop, lEnd: QbeGen.QVal; astNode: AST.Node; .)
|
|
|
+ 1931 = "LOOP" (. QbeGen.NewLabel(lTop);
|
|
|
+ 1932 astStmt := AST.NoNode;
|
|
|
+ 1933 QbeGen.NewLabel(lEnd);
|
|
|
+ 1934 QbeGen.PushLoop(lEnd);
|
|
|
+ 1935 QbeGen.EmitLabel(lTop); .)
|
|
|
+ 1936 [ StatSeq ]
|
|
|
+ 1937 "END" (. astNode := AST.MakeNode(AST.NkLoop);
|
|
|
+ 1938 AST.SetChild(astNode, 0, astStmt);
|
|
|
+ 1939 astStmt := astNode;
|
|
|
+ 1940 QbeGen.Jmp(lTop);
|
|
|
+ 1941 QbeGen.PopLoop;
|
|
|
+ 1942 QbeGen.EmitLabel(lEnd); .) .
|
|
|
+ 1943 (* FOR with static-sign BY (literal, non-zero; 220 otherwise).
|
|
|
+ 1944 Runtime direction would need a compare-select; the literal
|
|
|
+ 1945 sign picks cslew/csegew at "DO" time. *)
|
|
|
+ 1946 ForStat (. VAR lv: SymTab.Name;
|
|
|
+ 1947 tlo, thi, tby:
|
|
|
+ 1948 SymTab.TypeIndex;
|
|
|
+ 1949 qlo, qhi, qby, qt, qk, qb:
|
|
|
+ 1950 QbeGen.QVal;
|
|
|
+ 1951 lTop, lBody, lEnd:
|
|
|
+ 1952 QbeGen.QVal;
|
|
|
+ 1953 by: INTEGER;
|
|
|
+ 1954 ok: BOOLEAN;
|
|
|
+ 1955 astVar, astLo, astHi, astBy,
|
|
|
+ 1956 astNode: AST.Node; .)
|
|
|
+ 1957 = "FOR" (. by := 1; .)
|
|
|
+ 1958 GetIdent<lv> (. astVar := AST.MakeLeaf(AST.NkIdent, lv);
|
|
|
+ 1959 astStmt := AST.NoNode;
|
|
|
+ 1960 astBy := AST.NoNode;
|
|
|
+ 1961 ok := SymTab.Lookup(lv);
|
|
|
+ 1962 IF NOT ok THEN
|
|
|
+ 1963 SemError(201)
|
|
|
+ 1964 ELSIF (SymTab.SymKind(lv) #
|
|
|
+ 1965 SymTab.KindVar)
|
|
|
+ 1966 AND (SymTab.SymKind(lv) #
|
|
|
+ 1967 SymTab.KindParam) THEN
|
|
|
+ 1968 SemError(220); ok := FALSE
|
|
|
+ 1969 ELSIF NOT SymTab.IsIntFamily(
|
|
|
+ 1970 SymTab.SymType(lv)) THEN
|
|
|
+ 1971 SemError(220); ok := FALSE
|
|
|
+ 1972 END; .)
|
|
|
+ 1973 ":=" Expr<tlo, qlo> (. astLo := astCur;
|
|
|
+ 1974 IF NOT SymTab.IsIntFamily(tlo) THEN
|
|
|
+ 1975 SemError(220); ok := FALSE
|
|
|
+ 1976 END; .)
|
|
|
+ 1977 "TO" Expr<thi, qhi> (. astHi := astCur;
|
|
|
+ 1978 IF NOT SymTab.IsIntFamily(thi) THEN
|
|
|
+ 1979 SemError(220); ok := FALSE
|
|
|
+ 1980 END; .)
|
|
|
+ 1981 [ "BY" Expr<tby, qby> (. astBy := astCur;
|
|
|
+ 1982 IF (tby #
|
|
|
+ 1983 SymTab.InvalidType)
|
|
|
+ 1984 AND NOT SymTab.IsIntFamily(tby) THEN
|
|
|
+ 1985 SemError(220); ok := FALSE
|
|
|
+ 1986 END;
|
|
|
+ 1987 IF NOT SymTab.ConstInt(qby, by) THEN
|
|
|
+ 1988 SemError(230); by := 1
|
|
|
+ 1989 ELSIF by = 0 THEN
|
|
|
+ 1990 SemError(220); by := 1
|
|
|
+ 1991 END; .) ]
|
|
|
+ 1992 "DO" (. IF ok THEN
|
|
|
+ 1993 QbeGen.StoreVar(lv, qlo,
|
|
|
+ 1994 FALSE) END;
|
|
|
+ 1995 QbeGen.NewLabel(lTop);
|
|
|
+ 1996 QbeGen.NewLabel(lBody);
|
|
|
+ 1997 QbeGen.NewLabel(lEnd);
|
|
|
+ 1998 QbeGen.EmitLabel(lTop);
|
|
|
+ 1999 QbeGen.LoadVar(lv, FALSE, qt);
|
|
|
+ 2000 QbeGen.NewTemp(qk);
|
|
|
+ 2001 IF by > 0 THEN
|
|
|
+ 2002 QbeGen.Op3("cslew", qk,
|
|
|
+ 2003 qt, qhi, FALSE)
|
|
|
+ 2004 ELSE QbeGen.Op3("csgew", qk,
|
|
|
+ 2005 qt, qhi, FALSE)
|
|
|
+ 2006 END;
|
|
|
+ 2007 QbeGen.Jnz(qk, lBody, lEnd);
|
|
|
+ 2008 QbeGen.EmitLabel(lBody); .)
|
|
|
+ 2009 [ StatSeq ]
|
|
|
+ 2010 "END" (. astNode := AST.MakeNode(AST.NkFor);
|
|
|
+ 2011 AST.SetChild(astNode, 0, astVar);
|
|
|
+ 2012 AST.SetChild(astNode, 1, astLo);
|
|
|
+ 2013 AST.SetChild(astNode, 2, astHi);
|
|
|
+ 2014 AST.SetChild(astNode, 3, astBy);
|
|
|
+ 2015 AST.SetChild(astNode, 4, astStmt);
|
|
|
+ 2016 astStmt := astNode;
|
|
|
+ 2017 IF ok THEN
|
|
|
+ 2018 QbeGen.LoadVar(lv, FALSE,
|
|
|
+ 2019 qt);
|
|
|
+ 2020 QbeGen.IntStr(by, qb);
|
|
|
+ 2021 QbeGen.NewTemp(qk);
|
|
|
+ 2022 QbeGen.Op3("add", qk,
|
|
|
+ 2023 qt, qb, FALSE);
|
|
|
+ 2024 QbeGen.StoreVar(lv, qk,
|
|
|
+ 2025 FALSE) END;
|
|
|
+ 2026 QbeGen.Jmp(lTop);
|
|
|
+ 2027 QbeGen.EmitLabel(lEnd); .) .
|
|
|
+ 2028 CaseStat (. VAR tsel: SymTab.TypeIndex;
|
|
|
+ 2029 qsel, lEnd: QbeGen.QVal;
|
|
|
+ 2030 arm, astNode: AST.Node; .)
|
|
|
+ 2031 = "CASE" Expr<tsel, qsel> (. astNode := AST.MakeNode(AST.NkCase);
|
|
|
+ 2032 AST.SetChild(astNode, 0, astCur);
|
|
|
+ 2033 QbeGen.NewLabel(lEnd); .)
|
|
|
+ 2034 "OF" CaseAlt<tsel, qsel, lEnd, astNode>
|
|
|
+ 2035 { "|" CaseAlt<tsel, qsel, lEnd, astNode> }
|
|
|
+ 2036 [ "ELSE" (. astStmt := AST.NoNode; .)
|
|
|
+ 2037 [ StatSeq ] (. arm := AST.MakeNode(AST.NkCaseArm);
|
|
|
+ 2038 AST.SetOp(arm, 1);
|
|
|
+ 2039 AST.SetChild(arm, 0, astStmt);
|
|
|
+ 2040 AST.SetChild(astNode,
|
|
|
+ 2041 AST.NChild(astNode), arm); .) ]
|
|
|
+ 2042 "END" (. astStmt := astNode;
|
|
|
+ 2043 QbeGen.EmitLabel(lEnd); .) .
|
|
|
+ 2044 (* Compare-chain lowering: each alternative ends its match-tests
|
|
|
+ 2045 with "jmp lAfter", so the no-match fallthrough skips the body:
|
|
|
+ 2046 "cmp; jnz(lBody,lF); lF: ... ; jmp lAfter; lBody: S; jmp lEnd;
|
|
|
+ 2047 lAfter:". Falls into the next alternative, ELSE, or END. *)
|
|
|
+ 2048 CaseAlt<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
+ 2049 lEnd: QbeGen.QVal; cnode: AST.Node>
|
|
|
+ 2050 (. VAR lBody, lAfter: QbeGen.QVal;
|
|
|
+ 2051 arm: AST.Node; .)
|
|
|
+ 2052 = (. arm := AST.MakeNode(AST.NkCaseArm);
|
|
|
+ 2053 QbeGen.NewLabel(lBody);
|
|
|
+ 2054 QbeGen.NewLabel(lAfter); .)
|
|
|
+ 2055 CaseLabel<tsel, qsel, lBody, arm>
|
|
|
+ 2056 { "," CaseLabel<tsel, qsel, lBody, arm> }
|
|
|
+ 2057 ":" (. astStmt := AST.NoNode;
|
|
|
+ 2058 QbeGen.Jmp(lAfter);
|
|
|
+ 2059 QbeGen.EmitLabel(lBody); .)
|
|
|
+ 2060 [ StatSeq ] (. AST.SetChild(arm, AST.NChild(arm),
|
|
|
+ 2061 astStmt);
|
|
|
+ 2062 AST.SetChild(cnode,
|
|
|
+ 2063 AST.NChild(cnode), arm);
|
|
|
+ 2064 QbeGen.Jmp(lEnd);
|
|
|
+ 2065 QbeGen.EmitLabel(lAfter); .) .
|
|
|
+ 2066 CaseLabel<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
+ 2067 lBody: QbeGen.QVal; arm: AST.Node>
|
|
|
+ 2068 (. VAR t2, t3: SymTab.TypeIndex;
|
|
|
+ 2069 q2, q3, qc, qd, qe:
|
|
|
+ 2070 QbeGen.QVal;
|
|
|
+ 2071 astLab: AST.Node;
|
|
|
+ 2072 lNext: QbeGen.QVal; .)
|
|
|
+ 2073 = Expr<t2, q2> (. astLab := astCur;
|
|
|
+ 2074 IF (t2 #
|
|
|
+ 2075 SymTab.InvalidType)
|
|
|
+ 2076 AND (tsel #
|
|
|
+ 2077 SymTab.InvalidType)
|
|
|
+ 2078 AND ((SymTab.ClassOf(t2) =
|
|
|
+ 2079 SymTab.ClSet)
|
|
|
+ 2080 OR (SymTab.ClassOf(tsel) =
|
|
|
+ 2081 SymTab.ClSet)) THEN
|
|
|
+ 2082 SemError(230)
|
|
|
+ 2083 ELSIF (t2 #
|
|
|
+ 2084 SymTab.InvalidType)
|
|
|
+ 2085 AND (tsel #
|
|
|
+ 2086 SymTab.InvalidType)
|
|
|
+ 2087 AND NOT SymTab.EqCheck(t2,
|
|
|
+ 2088 tsel) THEN
|
|
|
+ 2089 SemError(213) END;
|
|
|
+ 2090 IF NOT QbeGen.IsImm(q2) THEN
|
|
|
+ 2091 SemError(230);
|
|
|
+ 2092 QbeGen.CopyOp("0", q2)
|
|
|
+ 2093 END;
|
|
|
+ 2094 QbeGen.NewLabel(lNext);
|
|
|
+ 2095 QbeGen.Cmp(SymTab.OpEq,
|
|
|
+ 2096 qsel, q2, qc, FALSE);
|
|
|
+ 2097 QbeGen.Jnz(qc, lBody, lNext);
|
|
|
+ 2098 QbeGen.EmitLabel(lNext); .)
|
|
|
+ 2099 [ ".." Expr<t3, q3> (. astLab := AST.MakeBin(
|
|
|
+ 2100 AST.NkSubrange, 0, astLab, astCur);
|
|
|
+ 2101 IF (t3 #
|
|
|
+ 2102 SymTab.InvalidType)
|
|
|
+ 2103 AND (tsel #
|
|
|
+ 2104 SymTab.InvalidType)
|
|
|
+ 2105 AND NOT SymTab.EqCheck(t3,
|
|
|
+ 2106 tsel) THEN
|
|
|
+ 2107 SemError(213) END;
|
|
|
+ 2108 IF NOT QbeGen.IsImm(q3) THEN
|
|
|
+ 2109 SemError(230);
|
|
|
+ 2110 QbeGen.CopyOp("0", q3)
|
|
|
+ 2111 END;
|
|
|
+ 2112 QbeGen.Cmp(SymTab.OpGe,
|
|
|
+ 2113 qsel, q2, qc, FALSE);
|
|
|
+ 2114 QbeGen.Cmp(SymTab.OpLe,
|
|
|
+ 2115 qsel, q3, qd, FALSE);
|
|
|
+ 2116 QbeGen.NewTemp(qe);
|
|
|
+ 2117 QbeGen.Op3("and", qe, qc, qd,
|
|
|
+ 2118 FALSE);
|
|
|
+ 2119 QbeGen.NewLabel(lNext);
|
|
|
+ 2120 QbeGen.Jnz(qe, lBody, lNext);
|
|
|
+ 2121 QbeGen.EmitLabel(lNext); .) ]
|
|
|
+ 2122 (. AST.SetChild(arm,
|
|
|
+ 2123 AST.NChild(arm), astLab); .) .
|
|
|
+ 2124 ReturnStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 2125 q, qt: QbeGen.QVal;
|
|
|
+ 2126 res: SymTab.TypeIndex;
|
|
|
+ 2127 hadE, conv: BOOLEAN;
|
|
|
+ 2128 astVal, astNode: AST.Node; .)
|
|
|
+ 2129 = "RETURN" (. hadE := FALSE; astStmt := AST.NoNode; .)
|
|
|
+ 2130 [ Expr<t, q> (. hadE := TRUE; astVal := astCur; .) ]
|
|
|
+ 2131 (. astNode := AST.MakeNode(AST.NkReturn);
|
|
|
+ 2132 IF hadE THEN
|
|
|
+ 2133 AST.SetChild(astNode, 0, astVal)
|
|
|
+ 2134 END;
|
|
|
+ 2135 astStmt := astNode;
|
|
|
+ 2136 conv := FALSE;
|
|
|
+ 2137 IF NOT SymTab.InProc() THEN
|
|
|
+ 2138 SemError(232)
|
|
|
+ 2139 ELSE res := SymTab.CurRes();
|
|
|
+ 2140 IF NOT hadE THEN
|
|
|
+ 2141 IF res #
|
|
|
+ 2142 SymTab.InvalidType THEN
|
|
|
+ 2143 SemError(232)
|
|
|
+ 2144 ELSE QbeGen.EmitRet(q,
|
|
|
+ 2145 FALSE)
|
|
|
+ 2146 END
|
|
|
+ 2147 ELSIF (res =
|
|
|
+ 2148 SymTab.InvalidType)
|
|
|
+ 2149 OR (t #
|
|
|
+ 2150 SymTab.InvalidType)
|
|
|
+ 2151 AND NOT SymTab.Assignable(t,
|
|
|
+ 2152 res) THEN
|
|
|
+ 2153 SemError(232)
|
|
|
+ 2154 ELSE
|
|
|
+ 2155 conv := (SymTab.ClassOf(
|
|
|
+ 2156 res) = SymTab.ClReal)
|
|
|
+ 2157 AND SymTab.IsIntFamily(t);
|
|
|
+ 2158 IF conv THEN
|
|
|
+ 2159 QbeGen.ConvIR(q, qt);
|
|
|
+ 2160 QbeGen.EmitRet(qt, TRUE)
|
|
|
+ 2161 ELSE QbeGen.EmitRet(q, TRUE)
|
|
|
+ 2162 END
|
|
|
+ 2163 END
|
|
|
+ 2164 END; .) .
|
|
|
+ 2165 HaltStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 2166 q: QbeGen.QVal;
|
|
|
+ 2167 astVal, astNode: AST.Node; .)
|
|
|
+ 2168 = "HALT" (. astVal := AST.NoNode; .)
|
|
|
+ 2169 [ "(" Expr<t, q> (. astVal := astCur; .) ")" ]
|
|
|
+ 2170 (. astNode := AST.MakeNode(AST.NkHalt);
|
|
|
+ 2171 IF astVal # AST.NoNode THEN
|
|
|
+ 2172 AST.SetChild(astNode, 0, astVal)
|
|
|
+ 2173 END;
|
|
|
+ 2174 astStmt := astNode;
|
|
|
+ 2175 QbeGen.HaltQ; .) .
|
|
|
+ 2176 (* Designator: scalar loads, array addresses, and index suffixes.
|
|
|
+ 2177 Each index descends one level (bounds-checked, trap on breach);
|
|
|
+ 2178 nested levels reload the inner descriptor address. q ends as the
|
|
|
+ 2179 value (scalars), the descriptor address (plain arrays), or the
|
|
|
+ 2180 element address (indexed); sfx marks the indexed form. *)
|
|
|
+ 2181 Design<VAR t: SymTab.TypeIndex; VAR k: INTEGER;
|
|
|
+ 2182 VAR q: QbeGen.QVal; VAR qn: SymTab.Name; VAR sfx: BOOLEAN>
|
|
|
+ 2183 (. VAR n, fn, mal: SymTab.Name;
|
|
|
+ 2184 cls: INTEGER;
|
|
|
+ 2185 ic: SymTab.TypeIndex;
|
|
|
+ 2186 curT, it, eT, bt:
|
|
|
+ 2187 SymTab.TypeIndex;
|
|
|
+ 2188 iq, ql, qlo, qhi, qe:
|
|
|
+ 2189 QbeGen.QVal;
|
|
|
+ 2190 lo, hi: INTEGER;
|
|
|
+ 2191 fo: INTEGER;
|
|
|
+ 2192 isOpen: BOOLEAN;
|
|
|
+ 2193 qb, cv: QbeGen.QVal;
|
|
|
+ 2194 fid, fref, slot: INTEGER;
|
|
|
+ 2195 r: BOOLEAN;
|
|
|
+ 2196 astDes, astSel: AST.Node; .)
|
|
|
+ 2197 = GetIdent<n> (. methCls := SymTab.InvalidType;
|
|
|
+ 2198 QbeGen.CopyOp(n, qn);
|
|
|
+ 2199 sfx := FALSE;
|
|
|
+ 2200 fid := 0; fref := 0; slot := 0;
|
|
|
+ 2201 IF NOT SymTab.Lookup(n) THEN
|
|
|
+ 2202 (* a bare method name inside
|
|
|
+ 2203 a CLASS IMPLEMENTATION
|
|
|
+ 2204 is a sibling call on
|
|
|
+ 2205 THIS *)
|
|
|
+ 2206 ic := SymTab.CurImplClass();
|
|
|
+ 2207 IF (ic #
|
|
|
+ 2208 SymTab.InvalidType)
|
|
|
+ 2209 AND SymTab.MethodExists(ic, n) THEN
|
|
|
+ 2210 sfx := FALSE;
|
|
|
+ 2211 QbeGen.ThisBase(q);
|
|
|
+ 2212 QbeGen.ArmRecv(q);
|
|
|
+ 2213 methCls := ic;
|
|
|
+ 2214 k := SymTab.KindProc;
|
|
|
+ 2215 t := SymTab.InvalidType
|
|
|
+ 2216 ELSIF SymTab.InProc() THEN
|
|
|
+ 2217 (* not declared yet: a
|
|
|
+ 2218 forward reference to a
|
|
|
+ 2219 module-level variable
|
|
|
+ 2220 declared further down. *)
|
|
|
+ 2221 k := SymTab.KindVar;
|
|
|
+ 2222 r := SymTab.FwdVarRef(n, k,
|
|
|
+ 2223 fref, t);
|
|
|
+ 2224 slot := QbeGen.FwdDesignator();
|
|
|
+ 2225 FwdVarNote(fref, slot);
|
|
|
+ 2226 fid := slot;
|
|
|
+ 2227 QbeGen.FwdAddrOper(fid, q);
|
|
|
+ 2228 sfx := TRUE
|
|
|
+ 2229 ELSE
|
|
|
+ 2230 SemError(201);
|
|
|
+ 2231 t :=
|
|
|
+ 2232 SymTab.InvalidType;
|
|
|
+ 2233 k := -1;
|
|
|
+ 2234 QbeGen.CopyOp("0", q)
|
|
|
+ 2235 END
|
|
|
+ 2236 ELSE
|
|
|
+ 2237 t := SymTab.SymType(n);
|
|
|
+ 2238 k := SymTab.SymKind(n);
|
|
|
+ 2239 IF k = SymTab.KindConst THEN
|
|
|
+ 2240 IF SymTab.Equal(n,
|
|
|
+ 2241 "TRUE") THEN
|
|
|
+ 2242 t := SymTab.BoolType();
|
|
|
+ 2243 QbeGen.CopyOp("1", q)
|
|
|
+ 2244 ELSIF SymTab.Equal(n,
|
|
|
+ 2245 "FALSE") THEN
|
|
|
+ 2246 t := SymTab.BoolType();
|
|
|
+ 2247 QbeGen.CopyOp("0", q)
|
|
|
+ 2248 ELSIF SymTab.Equal(n,
|
|
|
+ 2249 "NIL") THEN
|
|
|
+ 2250 QbeGen.CopyOp("0", q)
|
|
|
+ 2251 ELSE
|
|
|
+ 2252 cls :=
|
|
|
+ 2253 SymTab.ClassOf(t);
|
|
|
+ 2254 IF (t #
|
|
|
+ 2255 SymTab.InvalidType)
|
|
|
+ 2256 AND ((cls = SymTab.ClInt)
|
|
|
+ 2257 OR (cls
|
|
|
+ 2258 = SymTab.ClChar)
|
|
|
+ 2259 OR (cls
|
|
|
+ 2260 = SymTab.ClEnum)
|
|
|
+ 2261 OR (cls
|
|
|
+ 2262 = SymTab.ClReal)
|
|
|
+ 2263 OR (cls
|
|
|
+ 2264 = SymTab.ClLong)
|
|
|
+ 2265 OR (cls
|
|
|
+ 2266 = SymTab.ClNil)) THEN
|
|
|
+ 2267 IF cls = SymTab.ClNil THEN
|
|
|
+ 2268 QbeGen.CopyOp("0", q)
|
|
|
+ 2269 ELSIF ((cls
|
|
|
+ 2270 = SymTab.ClInt)
|
|
|
+ 2271 OR (cls
|
|
|
+ 2272 = SymTab.ClChar)
|
|
|
+ 2273 OR (cls
|
|
|
+ 2274 = SymTab.ClEnum)
|
|
|
+ 2275 OR (cls
|
|
|
+ 2276 = SymTab.ClLong))
|
|
|
+ 2277 AND SymTab.GetSymVal(n, cv)
|
|
|
+ 2278 AND QbeGen.IsImm(cv) THEN
|
|
|
2279 QbeGen.CopyOp(cv, q)
|
|
|
2280 ELSE
|
|
|
- 2281 QbeGen.CopyOp("0", q)
|
|
|
- 2282 END
|
|
|
- 2283 ELSE
|
|
|
- 2284 IF t #
|
|
|
- 2285 SymTab.InvalidType THEN
|
|
|
- 2286 SemError(230)
|
|
|
- 2287 END;
|
|
|
- 2288 QbeGen.CopyOp("0", q)
|
|
|
- 2289 END
|
|
|
- 2290 END
|
|
|
- 2291 ELSIF (k = SymTab.KindVar)
|
|
|
- 2292 OR (k = SymTab.KindParam) THEN
|
|
|
- 2293 cls :=
|
|
|
- 2294 SymTab.ClassOf(t);
|
|
|
- 2295 IF (cls = SymTab.ClInt)
|
|
|
- 2296 OR (cls = SymTab.ClBool)
|
|
|
- 2297 OR (cls = SymTab.ClChar)
|
|
|
- 2298 OR (cls = SymTab.ClUChar)
|
|
|
- 2299 OR (cls = SymTab.ClEnum)
|
|
|
- 2300 OR (cls
|
|
|
- 2301 = SymTab.ClReal) THEN
|
|
|
- 2302 QbeGen.LoadVar(n,
|
|
|
- 2303 cls = SymTab.ClReal, q)
|
|
|
- 2304 ELSIF (cls = SymTab.ClPtr)
|
|
|
- 2305 OR (cls = SymTab.ClProc) THEN
|
|
|
- 2306 QbeGen.LoadPtr(n, q)
|
|
|
- 2307 ELSIF cls = SymTab.ClLong THEN
|
|
|
- 2308 QbeGen.LoadLong(n, q)
|
|
|
- 2309 ELSIF (cls
|
|
|
- 2310 = SymTab.ClArray)
|
|
|
- 2311 OR (cls
|
|
|
- 2312 = SymTab.ClSet)
|
|
|
- 2313 OR (cls
|
|
|
- 2314 = SymTab.ClRecord)
|
|
|
+ 2281 QbeGen.LoadVar(n,
|
|
|
+ 2282 cls = SymTab.ClReal,
|
|
|
+ 2283 q)
|
|
|
+ 2284 END
|
|
|
+ 2285 ELSIF (cls = SymTab.ClArray)
|
|
|
+ 2286 OR (cls = SymTab.ClRecord)
|
|
|
+ 2287 OR (cls = SymTab.ClClass)
|
|
|
+ 2288 OR (cls = SymTab.ClStr)
|
|
|
+ 2289 OR (cls = SymTab.ClUStr) THEN
|
|
|
+ 2290 (* aggregate constant:
|
|
|
+ 2291 its value IS the
|
|
|
+ 2292 descriptor address *)
|
|
|
+ 2293 IF SymTab.GetSymVal(n, cv) THEN
|
|
|
+ 2294 QbeGen.CopyOp(cv, q)
|
|
|
+ 2295 ELSE
|
|
|
+ 2296 QbeGen.CopyOp("0", q)
|
|
|
+ 2297 END
|
|
|
+ 2298 ELSE
|
|
|
+ 2299 IF t #
|
|
|
+ 2300 SymTab.InvalidType THEN
|
|
|
+ 2301 SemError(230)
|
|
|
+ 2302 END;
|
|
|
+ 2303 QbeGen.CopyOp("0", q)
|
|
|
+ 2304 END
|
|
|
+ 2305 END
|
|
|
+ 2306 ELSIF (k = SymTab.KindVar)
|
|
|
+ 2307 OR (k = SymTab.KindParam) THEN
|
|
|
+ 2308 cls :=
|
|
|
+ 2309 SymTab.ClassOf(t);
|
|
|
+ 2310 IF (cls = SymTab.ClInt)
|
|
|
+ 2311 OR (cls = SymTab.ClBool)
|
|
|
+ 2312 OR (cls = SymTab.ClChar)
|
|
|
+ 2313 OR (cls = SymTab.ClUChar)
|
|
|
+ 2314 OR (cls = SymTab.ClEnum)
|
|
|
2315 OR (cls
|
|
|
- 2316 = SymTab.ClUStr)
|
|
|
- 2317 OR (cls
|
|
|
- 2318 = SymTab.ClClass) THEN
|
|
|
- 2319 QbeGen.AddrOf(n, q)
|
|
|
- 2320 ELSE SemError(230);
|
|
|
- 2321 QbeGen.CopyOp("0", q)
|
|
|
- 2322 END
|
|
|
- 2323 ELSE QbeGen.CopyOp("0", q);
|
|
|
- 2324 IF k = SymTab.KindImport THEN
|
|
|
- 2325 SemError(230)
|
|
|
- 2326 ELSIF k =
|
|
|
- 2327 SymTab.KindProc THEN
|
|
|
- 2328 (* bare procedure name:
|
|
|
- 2329 a following ArgList
|
|
|
- 2330 makes it a call;
|
|
|
- 2331 otherwise Fact
|
|
|
- 2332 reports 230 *)
|
|
|
- 2333 ELSE
|
|
|
- 2334 IF k = SymTab.KindField THEN
|
|
|
- 2335 IF QbeGen.TopWith(qb) THEN
|
|
|
- 2336 fo :=
|
|
|
- 2337 SymTab.FieldOffset(
|
|
|
- 2338 SymTab.FieldOwner(n),
|
|
|
- 2339 n);
|
|
|
- 2340 QbeGen.FieldAddr(qb,
|
|
|
- 2341 fo, q);
|
|
|
- 2342 sfx := TRUE
|
|
|
- 2343 ELSE SemError(230);
|
|
|
- 2344 QbeGen.CopyOp("0", q)
|
|
|
- 2345 END
|
|
|
- 2346 END
|
|
|
- 2347 END
|
|
|
- 2348 END
|
|
|
- 2349 END; .)
|
|
|
- 2350 (. astDes := AST.MakeNode(AST.NkDesignator);
|
|
|
- 2351 AST.SetChild(astDes, AST.NChild(astDes), AST.MakeLeaf(AST.NkIdent, n)); .)
|
|
|
- 2352 { "[" Expr<it, iq>
|
|
|
- 2353 (. AST.SetChild(astDes, AST.NChild(astDes),
|
|
|
- 2354 AST.MakeUn(AST.NkSelector, AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
- 2355 ELSIF SymTab.ClassOf(t) #
|
|
|
- 2356 SymTab.ClArray THEN
|
|
|
- 2357 SemError(217);
|
|
|
- 2358 t := SymTab.InvalidType
|
|
|
- 2359 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
- 2360 AND (SymTab.ClassOf(it) #
|
|
|
- 2361 SymTab.ClChar)
|
|
|
- 2362 AND (SymTab.ClassOf(it) #
|
|
|
- 2363 SymTab.ClEnum) THEN
|
|
|
- 2364 SemError(218);
|
|
|
- 2365 t := SymTab.InvalidType
|
|
|
- 2366 ELSE
|
|
|
- 2367 QbeGen.WidenIndex(iq, ql);
|
|
|
- 2368 isOpen :=
|
|
|
- 2369 SymTab.IsOpenArray(t);
|
|
|
- 2370 IF isOpen THEN
|
|
|
- 2371 QbeGen.CopyOp("0", qlo);
|
|
|
- 2372 IF SymTab.IsCharArray(t)
|
|
|
- 2373 OR SymTab.IsUCharArray(t) THEN
|
|
|
- 2374 QbeGen.OpenHiChar(q, qhi)
|
|
|
- 2375 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
- 2376 END
|
|
|
- 2377 ELSE
|
|
|
- 2378 lo := SymTab.ArrayLo(t);
|
|
|
- 2379 hi := SymTab.ArrayHi(t);
|
|
|
- 2380 IF SymTab.IsCharArray(t)
|
|
|
- 2381 OR SymTab.IsUCharArray(t) THEN
|
|
|
- 2382 hi := hi + 1
|
|
|
- 2383 END;
|
|
|
- 2384 QbeGen.IntStr(lo, qlo);
|
|
|
- 2385 QbeGen.IntStr(hi, qhi)
|
|
|
- 2386 END;
|
|
|
- 2387 QbeGen.CheckRange(ql, qlo,
|
|
|
- 2388 qhi);
|
|
|
- 2389 eT := SymTab.ArrayElem(t);
|
|
|
- 2390 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
- 2391 t, qe);
|
|
|
- 2392 IF SymTab.ClassOf(eT) =
|
|
|
- 2393 SymTab.ClArray THEN
|
|
|
- 2394 QbeGen.ElemLoad(qe, eT, q)
|
|
|
- 2395 ELSE QbeGen.CopyOp(qe, q)
|
|
|
- 2396 END;
|
|
|
- 2397 t := eT; sfx := TRUE
|
|
|
- 2398 END; .)
|
|
|
- 2399 { "," Expr<it, iq>
|
|
|
- 2400 (. AST.SetChild(astDes, AST.NChild(astDes),
|
|
|
- 2401 AST.MakeUn(AST.NkSelector, AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
- 2402 ELSIF SymTab.ClassOf(t) #
|
|
|
- 2403 SymTab.ClArray THEN
|
|
|
- 2404 SemError(217);
|
|
|
- 2405 t := SymTab.InvalidType
|
|
|
- 2406 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
- 2407 AND (SymTab.ClassOf(it) #
|
|
|
- 2408 SymTab.ClChar)
|
|
|
- 2409 AND (SymTab.ClassOf(it) #
|
|
|
- 2410 SymTab.ClEnum) THEN
|
|
|
- 2411 SemError(218);
|
|
|
- 2412 t := SymTab.InvalidType
|
|
|
- 2413 ELSE
|
|
|
- 2414 QbeGen.WidenIndex(iq, ql);
|
|
|
- 2415 isOpen :=
|
|
|
- 2416 SymTab.IsOpenArray(t);
|
|
|
- 2417 IF isOpen THEN
|
|
|
- 2418 QbeGen.CopyOp("0", qlo);
|
|
|
- 2419 IF SymTab.IsCharArray(t)
|
|
|
- 2420 OR SymTab.IsUCharArray(t) THEN
|
|
|
- 2421 QbeGen.OpenHiChar(q, qhi)
|
|
|
- 2422 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
- 2423 END
|
|
|
- 2424 ELSE
|
|
|
- 2425 lo := SymTab.ArrayLo(t);
|
|
|
- 2426 hi := SymTab.ArrayHi(t);
|
|
|
- 2427 IF SymTab.IsCharArray(t)
|
|
|
- 2428 OR SymTab.IsUCharArray(t) THEN
|
|
|
- 2429 hi := hi + 1
|
|
|
- 2430 END;
|
|
|
- 2431 QbeGen.IntStr(lo, qlo);
|
|
|
- 2432 QbeGen.IntStr(hi, qhi)
|
|
|
- 2433 END;
|
|
|
- 2434 QbeGen.CheckRange(ql, qlo,
|
|
|
- 2435 qhi);
|
|
|
- 2436 eT := SymTab.ArrayElem(t);
|
|
|
- 2437 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
- 2438 t, qe);
|
|
|
- 2439 IF SymTab.ClassOf(eT) =
|
|
|
- 2440 SymTab.ClArray THEN
|
|
|
- 2441 QbeGen.ElemLoad(qe, eT, q)
|
|
|
- 2442 ELSE QbeGen.CopyOp(qe, q)
|
|
|
- 2443 END;
|
|
|
- 2444 t := eT; sfx := TRUE
|
|
|
- 2445 END; .) }
|
|
|
- 2446 "]"
|
|
|
- 2447 | "." GetIdent<fn>
|
|
|
- 2448 (. astSel := AST.MakeNode(AST.NkSelector);
|
|
|
- 2449 AST.SetOp(astSel, AST.SelField);
|
|
|
- 2450 AST.SetChild(astSel, 0, AST.MakeLeaf(AST.NkIdent, fn));
|
|
|
- 2451 AST.SetChild(astDes, AST.NChild(astDes), astSel); IF k = SymTab.KindModule THEN
|
|
|
- 2452 (* qualified L.x: materialize
|
|
|
- 2453 the export, then load it *)
|
|
|
- 2454 IF NOT SymTab.MaterializeAlias(n,
|
|
|
- 2455 fn, mal) THEN
|
|
|
- 2456 SemError(201);
|
|
|
- 2457 t := SymTab.InvalidType;
|
|
|
- 2458 QbeGen.CopyOp("0", q)
|
|
|
- 2459 ELSE
|
|
|
- 2460 QbeGen.CopyOp(mal, qn);
|
|
|
- 2461 t := SymTab.SymType(mal);
|
|
|
- 2462 k := SymTab.SymKind(mal);
|
|
|
- 2463 sfx := FALSE;
|
|
|
- 2464 IF k = SymTab.KindProc THEN
|
|
|
- 2465 (* call: ArgList supplies
|
|
|
- 2466 the value *)
|
|
|
- 2467 QbeGen.CopyOp("0", q)
|
|
|
- 2468 ELSIF NOT QbeGen.LoadDesignator(
|
|
|
- 2469 mal, t, k, q) THEN
|
|
|
- 2470 SemError(230);
|
|
|
- 2471 QbeGen.CopyOp("0", q)
|
|
|
- 2472 END
|
|
|
- 2473 END
|
|
|
- 2474 ELSIF t = SymTab.InvalidType THEN
|
|
|
- 2475 ELSIF (SymTab.ClassOf(t) #
|
|
|
- 2476 SymTab.ClRecord)
|
|
|
- 2477 AND (SymTab.ClassOf(t) #
|
|
|
- 2478 SymTab.ClClass) THEN
|
|
|
- 2479 SemError(215);
|
|
|
- 2480 t := SymTab.InvalidType
|
|
|
- 2481 ELSIF (SymTab.ClassOf(t) =
|
|
|
- 2482 SymTab.ClClass)
|
|
|
- 2483 AND SymTab.MethodExists(t, fn) THEN
|
|
|
- 2484 (* obj.Method: bind the
|
|
|
- 2485 method and pass obj as
|
|
|
- 2486 the hidden receiver; q
|
|
|
- 2487 already holds the
|
|
|
- 2488 object's address *)
|
|
|
- 2489 QbeGen.ArmRecv(q);
|
|
|
- 2490 QbeGen.CopyOp(fn, n);
|
|
|
- 2491 QbeGen.CopyOp(fn, qn);
|
|
|
- 2492 methCls := t;
|
|
|
- 2493 k := SymTab.KindProc;
|
|
|
- 2494 t := SymTab.InvalidType
|
|
|
- 2495 ELSIF NOT SymTab.FieldExists(t,
|
|
|
- 2496 fn) THEN
|
|
|
- 2497 SemError(216);
|
|
|
- 2498 t := SymTab.InvalidType
|
|
|
- 2499 ELSE
|
|
|
- 2500 fo := SymTab.FieldOffset(t,
|
|
|
- 2501 fn);
|
|
|
- 2502 t := SymTab.FieldType(t, fn);
|
|
|
- 2503 QbeGen.FieldAddr(q, fo, qe);
|
|
|
- 2504 (* array fields are inline:
|
|
|
- 2505 the field address is the
|
|
|
- 2506 descriptor, like records *)
|
|
|
- 2507 QbeGen.CopyOp(qe, q);
|
|
|
- 2508 sfx := TRUE
|
|
|
- 2509 END; .)
|
|
|
- 2510 | "^"
|
|
|
- 2511 (. astSel := AST.MakeNode(AST.NkSelector);
|
|
|
- 2512 AST.SetOp(astSel, AST.SelDeref);
|
|
|
- 2513 AST.SetChild(astDes, AST.NChild(astDes), astSel); IF t = SymTab.InvalidType THEN
|
|
|
- 2514 ELSIF SymTab.ClassOf(t) #
|
|
|
- 2515 SymTab.ClPtr THEN
|
|
|
- 2516 SemError(219);
|
|
|
- 2517 t := SymTab.InvalidType
|
|
|
- 2518 ELSE
|
|
|
- 2519 bt := SymTab.PtrBase(t);
|
|
|
- 2520 IF bt = SymTab.InvalidType THEN
|
|
|
- 2521 ELSE
|
|
|
- 2522 IF sfx THEN
|
|
|
- 2523 QbeGen.ElemLoad(q, t,
|
|
|
- 2524 qb);
|
|
|
- 2525 QbeGen.CopyOp(qb, q)
|
|
|
- 2526 END;
|
|
|
- 2527 t := bt;
|
|
|
- 2528 (* q holds the pointee
|
|
|
- 2529 address: Fact loads
|
|
|
- 2530 scalars/pointers and uses
|
|
|
- 2531 the address for
|
|
|
- 2532 aggregates; the VAR-actual
|
|
|
- 2533 note is q itself. *)
|
|
|
- 2534 sfx := TRUE
|
|
|
- 2535 END
|
|
|
- 2536 END; .) } (. astCur := astDes; .) .
|
|
|
- 2537 (* Result suffix (ISO component after a function call): `F()^`,
|
|
|
- 2538 `F()[i]`, `F().field`. The call result is in t/q with sfx FALSE
|
|
|
- 2539 (a value, or a descriptor address for aggregates); each component
|
|
|
- 2540 descends one level exactly like the Design components. *)
|
|
|
- 2541 ResultComp<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal;
|
|
|
- 2542 VAR sfx: BOOLEAN; VAR node: AST.Node> (. VAR it, eT, bt: SymTab.TypeIndex;
|
|
|
- 2543 iq, ql, qlo, qhi, qe, qb:
|
|
|
- 2544 QbeGen.QVal;
|
|
|
- 2545 lo, hi, fo: INTEGER;
|
|
|
- 2546 isOpen: BOOLEAN;
|
|
|
- 2547 fname: SymTab.Name;
|
|
|
- 2548 astWrap, astSel: AST.Node; .)
|
|
|
- 2549 = "[" Expr<it, iq>
|
|
|
- 2550 (. IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
- 2551 astWrap := AST.MakeNode(
|
|
|
- 2552 AST.NkDesignator);
|
|
|
- 2553 AST.SetChild(astWrap, 0, node);
|
|
|
- 2554 node := astWrap
|
|
|
- 2555 END;
|
|
|
- 2556 AST.SetChild(node, AST.NChild(node),
|
|
|
- 2557 AST.MakeUn(AST.NkSelector,
|
|
|
- 2558 AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
- 2559 ELSIF SymTab.ClassOf(t) #
|
|
|
- 2560 SymTab.ClArray THEN
|
|
|
- 2561 SemError(217);
|
|
|
- 2562 t := SymTab.InvalidType
|
|
|
- 2563 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
- 2564 AND (SymTab.ClassOf(it) # SymTab.ClChar)
|
|
|
- 2565 AND (SymTab.ClassOf(it) # SymTab.ClEnum) THEN
|
|
|
- 2566 SemError(218);
|
|
|
- 2567 t := SymTab.InvalidType
|
|
|
- 2568 ELSE
|
|
|
- 2569 QbeGen.WidenIndex(iq, ql);
|
|
|
- 2570 isOpen :=
|
|
|
- 2571 SymTab.IsOpenArray(t);
|
|
|
- 2572 IF isOpen THEN
|
|
|
- 2573 QbeGen.CopyOp("0", qlo);
|
|
|
- 2574 IF SymTab.IsCharArray(t)
|
|
|
- 2575 OR SymTab.IsUCharArray(t) THEN
|
|
|
- 2576 QbeGen.OpenHiChar(q, qhi)
|
|
|
- 2577 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
- 2578 END
|
|
|
- 2579 ELSE
|
|
|
- 2580 lo := SymTab.ArrayLo(t);
|
|
|
- 2581 hi := SymTab.ArrayHi(t);
|
|
|
- 2582 IF SymTab.IsCharArray(t)
|
|
|
- 2583 OR SymTab.IsUCharArray(t) THEN
|
|
|
- 2584 hi := hi + 1
|
|
|
- 2585 END;
|
|
|
- 2586 QbeGen.IntStr(lo, qlo);
|
|
|
- 2587 QbeGen.IntStr(hi, qhi)
|
|
|
- 2588 END;
|
|
|
- 2589 QbeGen.CheckRange(ql, qlo,
|
|
|
- 2590 qhi);
|
|
|
- 2591 eT := SymTab.ArrayElem(t);
|
|
|
- 2592 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
- 2593 t, qe);
|
|
|
- 2594 IF SymTab.ClassOf(eT) =
|
|
|
- 2595 SymTab.ClArray THEN
|
|
|
- 2596 QbeGen.ElemLoad(qe, eT, q)
|
|
|
- 2597 ELSE QbeGen.CopyOp(qe, q)
|
|
|
- 2598 END;
|
|
|
- 2599 t := eT; sfx := TRUE
|
|
|
- 2600 END; .)
|
|
|
- 2601 "]"
|
|
|
- 2602 | "." GetIdent<fname>
|
|
|
- 2603 (. IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
- 2604 astWrap := AST.MakeNode(
|
|
|
- 2605 AST.NkDesignator);
|
|
|
- 2606 AST.SetChild(astWrap, 0, node);
|
|
|
- 2607 node := astWrap
|
|
|
- 2608 END;
|
|
|
- 2609 AST.SetChild(node, AST.NChild(node),
|
|
|
- 2610 AST.MakeUn(AST.NkSelector,
|
|
|
- 2611 AST.SelField,
|
|
|
- 2612 AST.MakeLeaf(AST.NkIdent,
|
|
|
- 2613 fname))); IF t = SymTab.InvalidType THEN
|
|
|
- 2614 ELSIF (SymTab.ClassOf(t) #
|
|
|
- 2615 SymTab.ClRecord)
|
|
|
- 2616 AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
|
|
|
- 2617 SemError(215);
|
|
|
- 2618 t := SymTab.InvalidType
|
|
|
- 2619 ELSIF NOT SymTab.FieldExists(t,
|
|
|
- 2620 fname) THEN
|
|
|
- 2621 SemError(216);
|
|
|
- 2622 t := SymTab.InvalidType
|
|
|
- 2623 ELSE
|
|
|
- 2624 fo := SymTab.FieldOffset(t,
|
|
|
- 2625 fname);
|
|
|
- 2626 t := SymTab.FieldType(t, fname);
|
|
|
- 2627 QbeGen.FieldAddr(q, fo, qe);
|
|
|
- 2628 QbeGen.CopyOp(qe, q);
|
|
|
- 2629 sfx := TRUE
|
|
|
- 2630 END; .)
|
|
|
- 2631 | "^" (. IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
- 2632 astWrap := AST.MakeNode(
|
|
|
- 2633 AST.NkDesignator);
|
|
|
- 2634 AST.SetChild(astWrap, 0, node);
|
|
|
- 2635 node := astWrap
|
|
|
- 2636 END;
|
|
|
- 2637 astSel := AST.MakeNode(AST.NkSelector);
|
|
|
- 2638 AST.SetOp(astSel, AST.SelDeref);
|
|
|
- 2639 AST.SetChild(node,
|
|
|
- 2640 AST.NChild(node), astSel); IF t = SymTab.InvalidType THEN
|
|
|
- 2641 ELSIF SymTab.ClassOf(t) #
|
|
|
- 2642 SymTab.ClPtr THEN
|
|
|
- 2643 SemError(219);
|
|
|
- 2644 t := SymTab.InvalidType
|
|
|
- 2645 ELSE
|
|
|
- 2646 bt := SymTab.PtrBase(t);
|
|
|
- 2647 IF bt # SymTab.InvalidType THEN
|
|
|
- 2648 IF sfx THEN
|
|
|
- 2649 QbeGen.ElemLoad(q, t, qb);
|
|
|
- 2650 QbeGen.CopyOp(qb, q)
|
|
|
- 2651 END;
|
|
|
- 2652 t := bt; sfx := TRUE
|
|
|
- 2653 END
|
|
|
- 2654 END; .) .
|
|
|
- 2655 Expr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 2656 (. VAR t2: SymTab.TypeIndex;
|
|
|
- 2657 op: INTEGER;
|
|
|
- 2658 q2, qt, wl: QbeGen.QVal;
|
|
|
- 2659 astA, astB: AST.Node;
|
|
|
- 2660 astOp: INTEGER;
|
|
|
- 2661 astMade: BOOLEAN;
|
|
|
- 2662 isR: BOOLEAN; .)
|
|
|
- 2663 = SimExpr<t, q> (. astA := astCur; astMade := FALSE; .)
|
|
|
- 2664 [ Rel<op> SimExpr<t2, q2>
|
|
|
- 2665 (. astB := astCur; astMade := TRUE;
|
|
|
- 2666 astOp := AST.OpEq;
|
|
|
- 2667 IF op = SymTab.OpNeq1 THEN astOp := AST.OpNe
|
|
|
- 2668 ELSIF op = SymTab.OpNeq2 THEN astOp := AST.OpNe
|
|
|
- 2669 ELSIF op = SymTab.OpLt THEN astOp := AST.OpLt
|
|
|
- 2670 ELSIF op = SymTab.OpLe THEN astOp := AST.OpLe
|
|
|
- 2671 ELSIF op = SymTab.OpGt THEN astOp := AST.OpGt
|
|
|
- 2672 ELSIF op = SymTab.OpGe THEN astOp := AST.OpGe
|
|
|
- 2673 ELSIF op = SymTab.OpIn THEN astOp := AST.OpIn
|
|
|
- 2674 END;
|
|
|
- 2675 IF op = SymTab.OpIn THEN
|
|
|
- 2676 IF SymTab.InCheck(t, t2) THEN
|
|
|
- 2677 IF (t = SymTab.InvalidType)
|
|
|
- 2678 OR (t2 = SymTab.InvalidType) THEN
|
|
|
- 2679 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
- 2680 ELSE
|
|
|
- 2681 QbeGen.InSet(q, q2, SymTab.SetBaseLo(t2),
|
|
|
- 2682 SymTab.SetCount(t2), qt);
|
|
|
- 2683 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 2684 END
|
|
|
- 2685 ELSE SemError(222); t := SymTab.InvalidType;
|
|
|
- 2686 QbeGen.CopyOp("0", q)
|
|
|
- 2687 END
|
|
|
- 2688 ELSIF SymTab.RelCheck(t, t2, op) THEN
|
|
|
- 2689 IF (t = SymTab.InvalidType)
|
|
|
- 2690 OR (t2 = SymTab.InvalidType) THEN
|
|
|
- 2691 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
- 2692 ELSIF (SymTab.ClassOf(t) = SymTab.ClPtr)
|
|
|
- 2693 OR (SymTab.ClassOf(t2) = SymTab.ClPtr) THEN
|
|
|
- 2694 IF SymTab.IsFwdVar(t) OR SymTab.IsFwdVar(t2) THEN
|
|
|
- 2695 QbeGen.Cmp(op, q, q2, qt, FALSE);
|
|
|
- 2696 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 2697 ELSIF (op # SymTab.OpEq) AND (op # SymTab.OpNeq1)
|
|
|
- 2698 AND (op # SymTab.OpNeq2) THEN
|
|
|
- 2699 SemError(213); t := SymTab.InvalidType;
|
|
|
- 2700 QbeGen.CopyOp("0", q)
|
|
|
- 2701 ELSE
|
|
|
- 2702 QbeGen.CmpL(op, q, q2, qt);
|
|
|
- 2703 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 2704 END
|
|
|
- 2705 ELSIF (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 2706 OR (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 2707 QbeGen.CmpSet(op, q, q2,
|
|
|
- 2708 SymTab.SetWords(t), SymTab.SetWords(t2), qt);
|
|
|
- 2709 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 2710 ELSIF SymTab.StrCompat(t, t2) THEN
|
|
|
- 2711 QbeGen.StrEq(op, q, q2, qt);
|
|
|
- 2712 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 2713 ELSIF SymTab.IsLongFamily(t)
|
|
|
- 2714 OR SymTab.IsLongFamily(t2) THEN
|
|
|
- 2715 IF SymTab.IsIntFamily(t) THEN
|
|
|
- 2716 QbeGen.WidenLong(q, wl); QbeGen.CopyOp(wl, q)
|
|
|
- 2717 END;
|
|
|
- 2718 IF SymTab.IsIntFamily(t2) THEN
|
|
|
- 2719 QbeGen.WidenLong(q2, wl); QbeGen.CopyOp(wl, q2)
|
|
|
- 2720 END;
|
|
|
- 2721 QbeGen.CmpLong(op, q, q2, qt);
|
|
|
- 2722 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 2723 ELSE
|
|
|
- 2724 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
- 2725 t := SymTab.BoolType();
|
|
|
- 2726 QbeGen.Cmp(op, q, q2, qt, isR);
|
|
|
- 2727 QbeGen.CopyOp(qt, q)
|
|
|
- 2728 END
|
|
|
- 2729 ELSE SemError(213); t := SymTab.InvalidType;
|
|
|
- 2730 QbeGen.CopyOp("0", q)
|
|
|
- 2731 END;
|
|
|
- 2732 astCur := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB); .) ]
|
|
|
- 2733 (. IF NOT astMade THEN astCur := astA END; .) .
|
|
|
- 2734 Rel<VAR op: INTEGER>
|
|
|
- 2735 = "=" (. op := SymTab.OpEq; .)
|
|
|
- 2736 | "#" (. op := SymTab.OpNeq1; .)
|
|
|
- 2737 | "<" (. op := SymTab.OpLt; .)
|
|
|
- 2738 | "<=" (. op := SymTab.OpLe; .)
|
|
|
- 2739 | ">" (. op := SymTab.OpGt; .)
|
|
|
- 2740 | ">=" (. op := SymTab.OpGe; .)
|
|
|
- 2741 | "IN" (. op := SymTab.OpIn; .) .
|
|
|
- 2742 SimExpr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 2743 (. VAR t2, res2, lt, rt:
|
|
|
- 2744 SymTab.TypeIndex;
|
|
|
- 2745 op: INTEGER;
|
|
|
- 2746 q2, qt, wq, qf, q2a, q2b:
|
|
|
- 2747 QbeGen.QVal;
|
|
|
- 2748 neg, isR, isL, folded:
|
|
|
- 2749 BOOLEAN;
|
|
|
- 2750 fok: BOOLEAN;
|
|
|
- 2751 lw, rw, mw: CARDINAL;
|
|
|
- 2752 lTrue, lNext, lDone, qr, qs: QbeGen.QVal;
|
|
|
- 2753 astA, astB: AST.Node;
|
|
|
- 2754 astSign, astOp: INTEGER; .)
|
|
|
- 2755 = (. neg := FALSE; astSign := 0; .)
|
|
|
- 2756 [ "+" (. neg := TRUE; astSign := 1; .)
|
|
|
- 2757 | "-" (. neg := TRUE; astSign := -1; .) ]
|
|
|
- 2758 Term<t, q> (. astA := astCur; IF neg THEN
|
|
|
- 2759 IF QbeGen.IsImm(q) THEN
|
|
|
- 2760 QbeGen.NegFold(q, q)
|
|
|
- 2761 ELSE QbeGen.NewTemp(qt);
|
|
|
- 2762 QbeGen.NegQ(q, qt,
|
|
|
- 2763 SymTab.ClassOf(t)
|
|
|
- 2764 = SymTab.ClReal);
|
|
|
- 2765 QbeGen.CopyOp(qt, q)
|
|
|
- 2766 END
|
|
|
- 2767 END;
|
|
|
- 2768 IF astSign < 0 THEN
|
|
|
- 2769 astCur := AST.MakeUn(
|
|
|
- 2770 AST.NkUnary, AST.OpSub, astA);
|
|
|
- 2771 astA := astCur
|
|
|
- 2772 END; .)
|
|
|
- 2773 { AddOp<op> (. IF op = SymTab.OpOr THEN
|
|
|
- 2774 QbeGen.DelayBegin END; .)
|
|
|
- 2775 Term<t2, q2> (. astB := astCur; IF op = SymTab.OpOr THEN
|
|
|
- 2776 QbeGen.DelayEnd END; .)
|
|
|
- 2777 (. astOp := AST.OpAdd;
|
|
|
- 2778 IF op = SymTab.OpSub THEN astOp := AST.OpSub
|
|
|
- 2779 ELSIF op = SymTab.OpOr THEN astOp := AST.OpOr END;
|
|
|
- 2780 astA := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB);
|
|
|
- 2781 astCur := astA;
|
|
|
- 2782 IF op = SymTab.OpOr THEN
|
|
|
- 2783 (* short-circuit: if q is true the RHS is skipped *)
|
|
|
- 2784 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
- 2785 t := SymTab.BoolType()
|
|
|
- 2786 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
- 2787 IF t # SymTab.InvalidType THEN
|
|
|
- 2788 QbeGen.Slot4(qs);
|
|
|
- 2789 QbeGen.NewLabel(lTrue);
|
|
|
- 2790 QbeGen.NewLabel(lNext);
|
|
|
- 2791 QbeGen.NewLabel(lDone);
|
|
|
- 2792 QbeGen.Jnz(q, lTrue, lNext);
|
|
|
- 2793 QbeGen.EmitLabel(lTrue);
|
|
|
- 2794 QbeGen.StoreW(qs, "1");
|
|
|
- 2795 QbeGen.Jmp(lDone);
|
|
|
- 2796 QbeGen.EmitLabel(lNext);
|
|
|
- 2797 QbeGen.DelayFlush;
|
|
|
- 2798 QbeGen.StoreW(qs, q2);
|
|
|
- 2799 QbeGen.Jmp(lDone);
|
|
|
- 2800 QbeGen.EmitLabel(lDone);
|
|
|
- 2801 QbeGen.LoadW(qs, qr);
|
|
|
- 2802 QbeGen.CopyOp(qr, q)
|
|
|
- 2803 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
- 2804 END
|
|
|
- 2805 ELSIF (op = SymTab.OpAdd)
|
|
|
- 2806 AND (SymTab.UStrCompat(t, t2)
|
|
|
- 2807 OR ((SymTab.ClassOf(t) = SymTab.ClUChar)
|
|
|
- 2808 AND (SymTab.ClassOf(t2) = SymTab.ClUStr))
|
|
|
- 2809 OR ((SymTab.ClassOf(t) = SymTab.ClUStr)
|
|
|
- 2810 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))
|
|
|
- 2811 OR ((SymTab.ClassOf(t) = SymTab.ClUChar)
|
|
|
- 2812 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))) THEN
|
|
|
- 2813 (* UString concatenation: a UCHAR operand becomes a
|
|
|
- 2814 1-codepoint UString; the result is a descriptor in the
|
|
|
- 2815 shim's concat buffer. Work on copies so neither
|
|
|
- 2816 operand is clobbered. *)
|
|
|
- 2817 IF SymTab.ClassOf(t) = SymTab.ClUStr THEN
|
|
|
- 2818 QbeGen.CopyOp(q, q2a)
|
|
|
- 2819 ELSE
|
|
|
- 2820 QbeGen.UStrFrom(q, q2a)
|
|
|
- 2821 END;
|
|
|
- 2822 IF SymTab.ClassOf(t2) = SymTab.ClUStr THEN
|
|
|
- 2823 QbeGen.UStrCat(q2a, q2, qt)
|
|
|
- 2824 ELSE
|
|
|
- 2825 QbeGen.UStrFrom(q2, q2b);
|
|
|
- 2826 QbeGen.UStrCat(q2a, q2b, qt)
|
|
|
- 2827 END;
|
|
|
- 2828 t := SymTab.NewUStr();
|
|
|
- 2829 QbeGen.CopyOp(qt, q)
|
|
|
- 2830 ELSIF (op = SymTab.OpAdd)
|
|
|
- 2831 AND (SymTab.StrCompat(t, t2)
|
|
|
- 2832 OR (SymTab.IsStrType(t)
|
|
|
- 2833 AND (SymTab.ClassOf(t2) = SymTab.ClChar))
|
|
|
- 2834 OR ((SymTab.ClassOf(t) = SymTab.ClChar)
|
|
|
- 2835 AND SymTab.IsStrType(t2))) THEN
|
|
|
- 2836 (* string concatenation; a CHAR operand becomes a
|
|
|
- 2837 1-character string literal. When both operands are
|
|
|
- 2838 constants, fold to a single string literal so a
|
|
|
- 2839 constructor element stays compile-time. *)
|
|
|
- 2840 QbeGen.StrFold(q, q2, SymTab.ClassOf(t), SymTab.ClassOf(t2),
|
|
|
- 2841 qt, fok);
|
|
|
- 2842 IF NOT fok THEN
|
|
|
- 2843 IF SymTab.StrCompat(t, t2) THEN
|
|
|
- 2844 QbeGen.StrCat(q, q2, qt)
|
|
|
- 2845 ELSIF SymTab.IsStrType(t) THEN
|
|
|
- 2846 QbeGen.DeclCharStr(q2, qs);
|
|
|
- 2847 QbeGen.StrCat(q, qs, qt)
|
|
|
- 2848 ELSE
|
|
|
- 2849 QbeGen.DeclCharStr(q, qs);
|
|
|
- 2850 QbeGen.StrCat(qs, q2, qt)
|
|
|
- 2851 END
|
|
|
- 2852 END;
|
|
|
- 2853 t := SymTab.NewStr();
|
|
|
- 2854 QbeGen.CopyOp(qt, q)
|
|
|
- 2855 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
- 2856 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 2857 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 2858 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
- 2859 mw := lw;
|
|
|
- 2860 IF rw > mw THEN mw := rw END;
|
|
|
- 2861 IF op = SymTab.OpAdd THEN
|
|
|
- 2862 QbeGen.SetBinOp(0, q, q2, lw, rw, qt)
|
|
|
- 2863 ELSE
|
|
|
- 2864 QbeGen.SetBinOp(2, q, q2, lw, rw, qt)
|
|
|
- 2865 END;
|
|
|
- 2866 t := SymTab.NewSet(
|
|
|
- 2867 SymTab.NewSubR(0,
|
|
|
- 2868 VAL(INTEGER, mw) * 32 - 1));
|
|
|
+ 2316 = SymTab.ClReal) THEN
|
|
|
+ 2317 QbeGen.LoadVar(n,
|
|
|
+ 2318 cls = SymTab.ClReal, q)
|
|
|
+ 2319 ELSIF (cls = SymTab.ClPtr)
|
|
|
+ 2320 OR (cls = SymTab.ClProc) THEN
|
|
|
+ 2321 QbeGen.LoadPtr(n, q)
|
|
|
+ 2322 ELSIF cls = SymTab.ClLong THEN
|
|
|
+ 2323 QbeGen.LoadLong(n, q)
|
|
|
+ 2324 ELSIF (cls
|
|
|
+ 2325 = SymTab.ClArray)
|
|
|
+ 2326 OR (cls
|
|
|
+ 2327 = SymTab.ClSet)
|
|
|
+ 2328 OR (cls
|
|
|
+ 2329 = SymTab.ClRecord)
|
|
|
+ 2330 OR (cls
|
|
|
+ 2331 = SymTab.ClUStr)
|
|
|
+ 2332 OR (cls
|
|
|
+ 2333 = SymTab.ClClass) THEN
|
|
|
+ 2334 QbeGen.AddrOf(n, q)
|
|
|
+ 2335 ELSE SemError(230);
|
|
|
+ 2336 QbeGen.CopyOp("0", q)
|
|
|
+ 2337 END
|
|
|
+ 2338 ELSE QbeGen.CopyOp("0", q);
|
|
|
+ 2339 IF k = SymTab.KindImport THEN
|
|
|
+ 2340 SemError(230)
|
|
|
+ 2341 ELSIF k =
|
|
|
+ 2342 SymTab.KindProc THEN
|
|
|
+ 2343 (* bare procedure name:
|
|
|
+ 2344 a following ArgList
|
|
|
+ 2345 makes it a call;
|
|
|
+ 2346 otherwise Fact
|
|
|
+ 2347 reports 230 *)
|
|
|
+ 2348 ELSE
|
|
|
+ 2349 IF k = SymTab.KindField THEN
|
|
|
+ 2350 IF QbeGen.TopWith(qb) THEN
|
|
|
+ 2351 fo :=
|
|
|
+ 2352 SymTab.FieldOffset(
|
|
|
+ 2353 SymTab.FieldOwner(n),
|
|
|
+ 2354 n);
|
|
|
+ 2355 QbeGen.FieldAddr(qb,
|
|
|
+ 2356 fo, q);
|
|
|
+ 2357 sfx := TRUE
|
|
|
+ 2358 ELSE SemError(230);
|
|
|
+ 2359 QbeGen.CopyOp("0", q)
|
|
|
+ 2360 END
|
|
|
+ 2361 END
|
|
|
+ 2362 END
|
|
|
+ 2363 END
|
|
|
+ 2364 END; .)
|
|
|
+ 2365 (. astDes := AST.MakeNode(AST.NkDesignator);
|
|
|
+ 2366 AST.SetChild(astDes, AST.NChild(astDes), AST.MakeLeaf(AST.NkIdent, n)); .)
|
|
|
+ 2367 { "[" Expr<it, iq>
|
|
|
+ 2368 (. AST.SetChild(astDes, AST.NChild(astDes),
|
|
|
+ 2369 AST.MakeUn(AST.NkSelector, AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
+ 2370 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 2371 SymTab.ClArray THEN
|
|
|
+ 2372 SemError(217);
|
|
|
+ 2373 t := SymTab.InvalidType
|
|
|
+ 2374 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
+ 2375 AND (SymTab.ClassOf(it) #
|
|
|
+ 2376 SymTab.ClChar)
|
|
|
+ 2377 AND (SymTab.ClassOf(it) #
|
|
|
+ 2378 SymTab.ClEnum) THEN
|
|
|
+ 2379 SemError(218);
|
|
|
+ 2380 t := SymTab.InvalidType
|
|
|
+ 2381 ELSE
|
|
|
+ 2382 QbeGen.WidenIndex(iq, ql);
|
|
|
+ 2383 isOpen :=
|
|
|
+ 2384 SymTab.IsOpenArray(t);
|
|
|
+ 2385 IF isOpen THEN
|
|
|
+ 2386 QbeGen.CopyOp("0", qlo);
|
|
|
+ 2387 IF SymTab.IsCharArray(t)
|
|
|
+ 2388 OR SymTab.IsUCharArray(t) THEN
|
|
|
+ 2389 QbeGen.OpenHiChar(q, qhi)
|
|
|
+ 2390 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
+ 2391 END
|
|
|
+ 2392 ELSE
|
|
|
+ 2393 lo := SymTab.ArrayLo(t);
|
|
|
+ 2394 hi := SymTab.ArrayHi(t);
|
|
|
+ 2395 IF SymTab.IsCharArray(t)
|
|
|
+ 2396 OR SymTab.IsUCharArray(t) THEN
|
|
|
+ 2397 hi := hi + 1
|
|
|
+ 2398 END;
|
|
|
+ 2399 QbeGen.IntStr(lo, qlo);
|
|
|
+ 2400 QbeGen.IntStr(hi, qhi)
|
|
|
+ 2401 END;
|
|
|
+ 2402 QbeGen.CheckRange(ql, qlo,
|
|
|
+ 2403 qhi);
|
|
|
+ 2404 eT := SymTab.ArrayElem(t);
|
|
|
+ 2405 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
+ 2406 t, qe);
|
|
|
+ 2407 IF SymTab.ClassOf(eT) =
|
|
|
+ 2408 SymTab.ClArray THEN
|
|
|
+ 2409 QbeGen.ElemLoad(qe, eT, q)
|
|
|
+ 2410 ELSE QbeGen.CopyOp(qe, q)
|
|
|
+ 2411 END;
|
|
|
+ 2412 t := eT; sfx := TRUE
|
|
|
+ 2413 END; .)
|
|
|
+ 2414 { "," Expr<it, iq>
|
|
|
+ 2415 (. AST.SetChild(astDes, AST.NChild(astDes),
|
|
|
+ 2416 AST.MakeUn(AST.NkSelector, AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
+ 2417 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 2418 SymTab.ClArray THEN
|
|
|
+ 2419 SemError(217);
|
|
|
+ 2420 t := SymTab.InvalidType
|
|
|
+ 2421 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
+ 2422 AND (SymTab.ClassOf(it) #
|
|
|
+ 2423 SymTab.ClChar)
|
|
|
+ 2424 AND (SymTab.ClassOf(it) #
|
|
|
+ 2425 SymTab.ClEnum) THEN
|
|
|
+ 2426 SemError(218);
|
|
|
+ 2427 t := SymTab.InvalidType
|
|
|
+ 2428 ELSE
|
|
|
+ 2429 QbeGen.WidenIndex(iq, ql);
|
|
|
+ 2430 isOpen :=
|
|
|
+ 2431 SymTab.IsOpenArray(t);
|
|
|
+ 2432 IF isOpen THEN
|
|
|
+ 2433 QbeGen.CopyOp("0", qlo);
|
|
|
+ 2434 IF SymTab.IsCharArray(t)
|
|
|
+ 2435 OR SymTab.IsUCharArray(t) THEN
|
|
|
+ 2436 QbeGen.OpenHiChar(q, qhi)
|
|
|
+ 2437 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
+ 2438 END
|
|
|
+ 2439 ELSE
|
|
|
+ 2440 lo := SymTab.ArrayLo(t);
|
|
|
+ 2441 hi := SymTab.ArrayHi(t);
|
|
|
+ 2442 IF SymTab.IsCharArray(t)
|
|
|
+ 2443 OR SymTab.IsUCharArray(t) THEN
|
|
|
+ 2444 hi := hi + 1
|
|
|
+ 2445 END;
|
|
|
+ 2446 QbeGen.IntStr(lo, qlo);
|
|
|
+ 2447 QbeGen.IntStr(hi, qhi)
|
|
|
+ 2448 END;
|
|
|
+ 2449 QbeGen.CheckRange(ql, qlo,
|
|
|
+ 2450 qhi);
|
|
|
+ 2451 eT := SymTab.ArrayElem(t);
|
|
|
+ 2452 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
+ 2453 t, qe);
|
|
|
+ 2454 IF SymTab.ClassOf(eT) =
|
|
|
+ 2455 SymTab.ClArray THEN
|
|
|
+ 2456 QbeGen.ElemLoad(qe, eT, q)
|
|
|
+ 2457 ELSE QbeGen.CopyOp(qe, q)
|
|
|
+ 2458 END;
|
|
|
+ 2459 t := eT; sfx := TRUE
|
|
|
+ 2460 END; .) }
|
|
|
+ 2461 "]"
|
|
|
+ 2462 | "." GetIdent<fn>
|
|
|
+ 2463 (. astSel := AST.MakeNode(AST.NkSelector);
|
|
|
+ 2464 AST.SetOp(astSel, AST.SelField);
|
|
|
+ 2465 AST.SetChild(astSel, 0, AST.MakeLeaf(AST.NkIdent, fn));
|
|
|
+ 2466 AST.SetChild(astDes, AST.NChild(astDes), astSel); IF k = SymTab.KindModule THEN
|
|
|
+ 2467 (* qualified L.x: materialize
|
|
|
+ 2468 the export, then load it *)
|
|
|
+ 2469 IF NOT SymTab.MaterializeAlias(n,
|
|
|
+ 2470 fn, mal) THEN
|
|
|
+ 2471 SemError(201);
|
|
|
+ 2472 t := SymTab.InvalidType;
|
|
|
+ 2473 QbeGen.CopyOp("0", q)
|
|
|
+ 2474 ELSE
|
|
|
+ 2475 QbeGen.CopyOp(mal, qn);
|
|
|
+ 2476 t := SymTab.SymType(mal);
|
|
|
+ 2477 k := SymTab.SymKind(mal);
|
|
|
+ 2478 sfx := FALSE;
|
|
|
+ 2479 IF k = SymTab.KindProc THEN
|
|
|
+ 2480 (* call: ArgList supplies
|
|
|
+ 2481 the value *)
|
|
|
+ 2482 QbeGen.CopyOp("0", q)
|
|
|
+ 2483 ELSIF NOT QbeGen.LoadDesignator(
|
|
|
+ 2484 mal, t, k, q) THEN
|
|
|
+ 2485 SemError(230);
|
|
|
+ 2486 QbeGen.CopyOp("0", q)
|
|
|
+ 2487 END
|
|
|
+ 2488 END
|
|
|
+ 2489 ELSIF t = SymTab.InvalidType THEN
|
|
|
+ 2490 ELSIF (SymTab.ClassOf(t) #
|
|
|
+ 2491 SymTab.ClRecord)
|
|
|
+ 2492 AND (SymTab.ClassOf(t) #
|
|
|
+ 2493 SymTab.ClClass) THEN
|
|
|
+ 2494 SemError(215);
|
|
|
+ 2495 t := SymTab.InvalidType
|
|
|
+ 2496 ELSIF (SymTab.ClassOf(t) =
|
|
|
+ 2497 SymTab.ClClass)
|
|
|
+ 2498 AND SymTab.MethodExists(t, fn) THEN
|
|
|
+ 2499 (* obj.Method: bind the
|
|
|
+ 2500 method and pass obj as
|
|
|
+ 2501 the hidden receiver; q
|
|
|
+ 2502 already holds the
|
|
|
+ 2503 object's address *)
|
|
|
+ 2504 QbeGen.ArmRecv(q);
|
|
|
+ 2505 QbeGen.CopyOp(fn, n);
|
|
|
+ 2506 QbeGen.CopyOp(fn, qn);
|
|
|
+ 2507 methCls := t;
|
|
|
+ 2508 k := SymTab.KindProc;
|
|
|
+ 2509 t := SymTab.InvalidType
|
|
|
+ 2510 ELSIF NOT SymTab.FieldExists(t,
|
|
|
+ 2511 fn) THEN
|
|
|
+ 2512 SemError(216);
|
|
|
+ 2513 t := SymTab.InvalidType
|
|
|
+ 2514 ELSE
|
|
|
+ 2515 fo := SymTab.FieldOffset(t,
|
|
|
+ 2516 fn);
|
|
|
+ 2517 t := SymTab.FieldType(t, fn);
|
|
|
+ 2518 QbeGen.FieldAddr(q, fo, qe);
|
|
|
+ 2519 (* array fields are inline:
|
|
|
+ 2520 the field address is the
|
|
|
+ 2521 descriptor, like records *)
|
|
|
+ 2522 QbeGen.CopyOp(qe, q);
|
|
|
+ 2523 sfx := TRUE
|
|
|
+ 2524 END; .)
|
|
|
+ 2525 | "^"
|
|
|
+ 2526 (. astSel := AST.MakeNode(AST.NkSelector);
|
|
|
+ 2527 AST.SetOp(astSel, AST.SelDeref);
|
|
|
+ 2528 AST.SetChild(astDes, AST.NChild(astDes), astSel); IF t = SymTab.InvalidType THEN
|
|
|
+ 2529 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 2530 SymTab.ClPtr THEN
|
|
|
+ 2531 SemError(219);
|
|
|
+ 2532 t := SymTab.InvalidType
|
|
|
+ 2533 ELSE
|
|
|
+ 2534 bt := SymTab.PtrBase(t);
|
|
|
+ 2535 IF bt = SymTab.InvalidType THEN
|
|
|
+ 2536 ELSE
|
|
|
+ 2537 IF sfx THEN
|
|
|
+ 2538 QbeGen.ElemLoad(q, t,
|
|
|
+ 2539 qb);
|
|
|
+ 2540 QbeGen.CopyOp(qb, q)
|
|
|
+ 2541 END;
|
|
|
+ 2542 t := bt;
|
|
|
+ 2543 (* q holds the pointee
|
|
|
+ 2544 address: Fact loads
|
|
|
+ 2545 scalars/pointers and uses
|
|
|
+ 2546 the address for
|
|
|
+ 2547 aggregates; the VAR-actual
|
|
|
+ 2548 note is q itself. *)
|
|
|
+ 2549 sfx := TRUE
|
|
|
+ 2550 END
|
|
|
+ 2551 END; .) } (. astCur := astDes; .) .
|
|
|
+ 2552 (* Result suffix (ISO component after a function call): `F()^`,
|
|
|
+ 2553 `F()[i]`, `F().field`. The call result is in t/q with sfx FALSE
|
|
|
+ 2554 (a value, or a descriptor address for aggregates); each component
|
|
|
+ 2555 descends one level exactly like the Design components. *)
|
|
|
+ 2556 ResultComp<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal;
|
|
|
+ 2557 VAR sfx: BOOLEAN; VAR node: AST.Node> (. VAR it, eT, bt: SymTab.TypeIndex;
|
|
|
+ 2558 iq, ql, qlo, qhi, qe, qb:
|
|
|
+ 2559 QbeGen.QVal;
|
|
|
+ 2560 lo, hi, fo: INTEGER;
|
|
|
+ 2561 isOpen: BOOLEAN;
|
|
|
+ 2562 fname: SymTab.Name;
|
|
|
+ 2563 astWrap, astSel: AST.Node; .)
|
|
|
+ 2564 = "[" Expr<it, iq>
|
|
|
+ 2565 (. IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
+ 2566 astWrap := AST.MakeNode(
|
|
|
+ 2567 AST.NkDesignator);
|
|
|
+ 2568 AST.SetChild(astWrap, 0, node);
|
|
|
+ 2569 node := astWrap
|
|
|
+ 2570 END;
|
|
|
+ 2571 AST.SetChild(node, AST.NChild(node),
|
|
|
+ 2572 AST.MakeUn(AST.NkSelector,
|
|
|
+ 2573 AST.SelIndex, astCur)); IF t = SymTab.InvalidType THEN
|
|
|
+ 2574 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 2575 SymTab.ClArray THEN
|
|
|
+ 2576 SemError(217);
|
|
|
+ 2577 t := SymTab.InvalidType
|
|
|
+ 2578 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
+ 2579 AND (SymTab.ClassOf(it) # SymTab.ClChar)
|
|
|
+ 2580 AND (SymTab.ClassOf(it) # SymTab.ClEnum) THEN
|
|
|
+ 2581 SemError(218);
|
|
|
+ 2582 t := SymTab.InvalidType
|
|
|
+ 2583 ELSE
|
|
|
+ 2584 QbeGen.WidenIndex(iq, ql);
|
|
|
+ 2585 isOpen :=
|
|
|
+ 2586 SymTab.IsOpenArray(t);
|
|
|
+ 2587 IF isOpen THEN
|
|
|
+ 2588 QbeGen.CopyOp("0", qlo);
|
|
|
+ 2589 IF SymTab.IsCharArray(t)
|
|
|
+ 2590 OR SymTab.IsUCharArray(t) THEN
|
|
|
+ 2591 QbeGen.OpenHiChar(q, qhi)
|
|
|
+ 2592 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
+ 2593 END
|
|
|
+ 2594 ELSE
|
|
|
+ 2595 lo := SymTab.ArrayLo(t);
|
|
|
+ 2596 hi := SymTab.ArrayHi(t);
|
|
|
+ 2597 IF SymTab.IsCharArray(t)
|
|
|
+ 2598 OR SymTab.IsUCharArray(t) THEN
|
|
|
+ 2599 hi := hi + 1
|
|
|
+ 2600 END;
|
|
|
+ 2601 QbeGen.IntStr(lo, qlo);
|
|
|
+ 2602 QbeGen.IntStr(hi, qhi)
|
|
|
+ 2603 END;
|
|
|
+ 2604 QbeGen.CheckRange(ql, qlo,
|
|
|
+ 2605 qhi);
|
|
|
+ 2606 eT := SymTab.ArrayElem(t);
|
|
|
+ 2607 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
+ 2608 t, qe);
|
|
|
+ 2609 IF SymTab.ClassOf(eT) =
|
|
|
+ 2610 SymTab.ClArray THEN
|
|
|
+ 2611 QbeGen.ElemLoad(qe, eT, q)
|
|
|
+ 2612 ELSE QbeGen.CopyOp(qe, q)
|
|
|
+ 2613 END;
|
|
|
+ 2614 t := eT; sfx := TRUE
|
|
|
+ 2615 END; .)
|
|
|
+ 2616 "]"
|
|
|
+ 2617 | "." GetIdent<fname>
|
|
|
+ 2618 (. IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
+ 2619 astWrap := AST.MakeNode(
|
|
|
+ 2620 AST.NkDesignator);
|
|
|
+ 2621 AST.SetChild(astWrap, 0, node);
|
|
|
+ 2622 node := astWrap
|
|
|
+ 2623 END;
|
|
|
+ 2624 AST.SetChild(node, AST.NChild(node),
|
|
|
+ 2625 AST.MakeUn(AST.NkSelector,
|
|
|
+ 2626 AST.SelField,
|
|
|
+ 2627 AST.MakeLeaf(AST.NkIdent,
|
|
|
+ 2628 fname))); IF t = SymTab.InvalidType THEN
|
|
|
+ 2629 ELSIF (SymTab.ClassOf(t) #
|
|
|
+ 2630 SymTab.ClRecord)
|
|
|
+ 2631 AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
|
|
|
+ 2632 SemError(215);
|
|
|
+ 2633 t := SymTab.InvalidType
|
|
|
+ 2634 ELSIF NOT SymTab.FieldExists(t,
|
|
|
+ 2635 fname) THEN
|
|
|
+ 2636 SemError(216);
|
|
|
+ 2637 t := SymTab.InvalidType
|
|
|
+ 2638 ELSE
|
|
|
+ 2639 fo := SymTab.FieldOffset(t,
|
|
|
+ 2640 fname);
|
|
|
+ 2641 t := SymTab.FieldType(t, fname);
|
|
|
+ 2642 QbeGen.FieldAddr(q, fo, qe);
|
|
|
+ 2643 QbeGen.CopyOp(qe, q);
|
|
|
+ 2644 sfx := TRUE
|
|
|
+ 2645 END; .)
|
|
|
+ 2646 | "^" (. IF AST.Kind(node) # AST.NkDesignator THEN
|
|
|
+ 2647 astWrap := AST.MakeNode(
|
|
|
+ 2648 AST.NkDesignator);
|
|
|
+ 2649 AST.SetChild(astWrap, 0, node);
|
|
|
+ 2650 node := astWrap
|
|
|
+ 2651 END;
|
|
|
+ 2652 astSel := AST.MakeNode(AST.NkSelector);
|
|
|
+ 2653 AST.SetOp(astSel, AST.SelDeref);
|
|
|
+ 2654 AST.SetChild(node,
|
|
|
+ 2655 AST.NChild(node), astSel); IF t = SymTab.InvalidType THEN
|
|
|
+ 2656 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 2657 SymTab.ClPtr THEN
|
|
|
+ 2658 SemError(219);
|
|
|
+ 2659 t := SymTab.InvalidType
|
|
|
+ 2660 ELSE
|
|
|
+ 2661 bt := SymTab.PtrBase(t);
|
|
|
+ 2662 IF bt # SymTab.InvalidType THEN
|
|
|
+ 2663 IF sfx THEN
|
|
|
+ 2664 QbeGen.ElemLoad(q, t, qb);
|
|
|
+ 2665 QbeGen.CopyOp(qb, q)
|
|
|
+ 2666 END;
|
|
|
+ 2667 t := bt; sfx := TRUE
|
|
|
+ 2668 END
|
|
|
+ 2669 END; .) .
|
|
|
+ 2670 Expr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 2671 (. VAR t2: SymTab.TypeIndex;
|
|
|
+ 2672 op: INTEGER;
|
|
|
+ 2673 q2, qt, wl: QbeGen.QVal;
|
|
|
+ 2674 astA, astB: AST.Node;
|
|
|
+ 2675 astOp: INTEGER;
|
|
|
+ 2676 astMade: BOOLEAN;
|
|
|
+ 2677 isR: BOOLEAN; .)
|
|
|
+ 2678 = SimExpr<t, q> (. astA := astCur; astMade := FALSE; .)
|
|
|
+ 2679 [ Rel<op> SimExpr<t2, q2>
|
|
|
+ 2680 (. astB := astCur; astMade := TRUE;
|
|
|
+ 2681 astOp := AST.OpEq;
|
|
|
+ 2682 IF op = SymTab.OpNeq1 THEN astOp := AST.OpNe
|
|
|
+ 2683 ELSIF op = SymTab.OpNeq2 THEN astOp := AST.OpNe
|
|
|
+ 2684 ELSIF op = SymTab.OpLt THEN astOp := AST.OpLt
|
|
|
+ 2685 ELSIF op = SymTab.OpLe THEN astOp := AST.OpLe
|
|
|
+ 2686 ELSIF op = SymTab.OpGt THEN astOp := AST.OpGt
|
|
|
+ 2687 ELSIF op = SymTab.OpGe THEN astOp := AST.OpGe
|
|
|
+ 2688 ELSIF op = SymTab.OpIn THEN astOp := AST.OpIn
|
|
|
+ 2689 END;
|
|
|
+ 2690 IF op = SymTab.OpIn THEN
|
|
|
+ 2691 IF SymTab.InCheck(t, t2) THEN
|
|
|
+ 2692 IF (t = SymTab.InvalidType)
|
|
|
+ 2693 OR (t2 = SymTab.InvalidType) THEN
|
|
|
+ 2694 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
+ 2695 ELSE
|
|
|
+ 2696 QbeGen.InSet(q, q2, SymTab.SetBaseLo(t2),
|
|
|
+ 2697 SymTab.SetCount(t2), qt);
|
|
|
+ 2698 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 2699 END
|
|
|
+ 2700 ELSE SemError(222); t := SymTab.InvalidType;
|
|
|
+ 2701 QbeGen.CopyOp("0", q)
|
|
|
+ 2702 END
|
|
|
+ 2703 ELSIF SymTab.RelCheck(t, t2, op) THEN
|
|
|
+ 2704 IF (t = SymTab.InvalidType)
|
|
|
+ 2705 OR (t2 = SymTab.InvalidType) THEN
|
|
|
+ 2706 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
+ 2707 ELSIF (SymTab.ClassOf(t) = SymTab.ClPtr)
|
|
|
+ 2708 OR (SymTab.ClassOf(t2) = SymTab.ClPtr) THEN
|
|
|
+ 2709 IF SymTab.IsFwdVar(t) OR SymTab.IsFwdVar(t2) THEN
|
|
|
+ 2710 QbeGen.Cmp(op, q, q2, qt, FALSE);
|
|
|
+ 2711 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 2712 ELSIF (op # SymTab.OpEq) AND (op # SymTab.OpNeq1)
|
|
|
+ 2713 AND (op # SymTab.OpNeq2) THEN
|
|
|
+ 2714 SemError(213); t := SymTab.InvalidType;
|
|
|
+ 2715 QbeGen.CopyOp("0", q)
|
|
|
+ 2716 ELSE
|
|
|
+ 2717 QbeGen.CmpL(op, q, q2, qt);
|
|
|
+ 2718 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 2719 END
|
|
|
+ 2720 ELSIF (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 2721 OR (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 2722 QbeGen.CmpSet(op, q, q2,
|
|
|
+ 2723 SymTab.SetWords(t), SymTab.SetWords(t2), qt);
|
|
|
+ 2724 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 2725 ELSIF SymTab.StrCompat(t, t2) THEN
|
|
|
+ 2726 QbeGen.StrEq(op, q, q2, qt);
|
|
|
+ 2727 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 2728 ELSIF SymTab.IsLongFamily(t)
|
|
|
+ 2729 OR SymTab.IsLongFamily(t2) THEN
|
|
|
+ 2730 IF SymTab.IsIntFamily(t) THEN
|
|
|
+ 2731 QbeGen.WidenLong(q, wl); QbeGen.CopyOp(wl, q)
|
|
|
+ 2732 END;
|
|
|
+ 2733 IF SymTab.IsIntFamily(t2) THEN
|
|
|
+ 2734 QbeGen.WidenLong(q2, wl); QbeGen.CopyOp(wl, q2)
|
|
|
+ 2735 END;
|
|
|
+ 2736 QbeGen.CmpLong(op, q, q2, qt);
|
|
|
+ 2737 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 2738 ELSE
|
|
|
+ 2739 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
+ 2740 t := SymTab.BoolType();
|
|
|
+ 2741 QbeGen.Cmp(op, q, q2, qt, isR);
|
|
|
+ 2742 QbeGen.CopyOp(qt, q)
|
|
|
+ 2743 END
|
|
|
+ 2744 ELSE SemError(213); t := SymTab.InvalidType;
|
|
|
+ 2745 QbeGen.CopyOp("0", q)
|
|
|
+ 2746 END;
|
|
|
+ 2747 astCur := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB); .) ]
|
|
|
+ 2748 (. IF NOT astMade THEN astCur := astA END; .) .
|
|
|
+ 2749 Rel<VAR op: INTEGER>
|
|
|
+ 2750 = "=" (. op := SymTab.OpEq; .)
|
|
|
+ 2751 | "#" (. op := SymTab.OpNeq1; .)
|
|
|
+ 2752 | "<" (. op := SymTab.OpLt; .)
|
|
|
+ 2753 | "<=" (. op := SymTab.OpLe; .)
|
|
|
+ 2754 | ">" (. op := SymTab.OpGt; .)
|
|
|
+ 2755 | ">=" (. op := SymTab.OpGe; .)
|
|
|
+ 2756 | "IN" (. op := SymTab.OpIn; .) .
|
|
|
+ 2757 SimExpr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 2758 (. VAR t2, res2, lt, rt:
|
|
|
+ 2759 SymTab.TypeIndex;
|
|
|
+ 2760 op: INTEGER;
|
|
|
+ 2761 q2, qt, wq, qf, q2a, q2b:
|
|
|
+ 2762 QbeGen.QVal;
|
|
|
+ 2763 neg, isR, isL, folded:
|
|
|
+ 2764 BOOLEAN;
|
|
|
+ 2765 fok: BOOLEAN;
|
|
|
+ 2766 lw, rw, mw: CARDINAL;
|
|
|
+ 2767 lTrue, lNext, lDone, qr, qs: QbeGen.QVal;
|
|
|
+ 2768 astA, astB: AST.Node;
|
|
|
+ 2769 astSign, astOp: INTEGER; .)
|
|
|
+ 2770 = (. neg := FALSE; astSign := 0; .)
|
|
|
+ 2771 [ "+" (. neg := TRUE; astSign := 1; .)
|
|
|
+ 2772 | "-" (. neg := TRUE; astSign := -1; .) ]
|
|
|
+ 2773 Term<t, q> (. astA := astCur; IF neg THEN
|
|
|
+ 2774 IF QbeGen.IsImm(q) THEN
|
|
|
+ 2775 QbeGen.NegFold(q, q)
|
|
|
+ 2776 ELSE QbeGen.NewTemp(qt);
|
|
|
+ 2777 QbeGen.NegQ(q, qt,
|
|
|
+ 2778 SymTab.ClassOf(t)
|
|
|
+ 2779 = SymTab.ClReal);
|
|
|
+ 2780 QbeGen.CopyOp(qt, q)
|
|
|
+ 2781 END
|
|
|
+ 2782 END;
|
|
|
+ 2783 IF astSign < 0 THEN
|
|
|
+ 2784 astCur := AST.MakeUn(
|
|
|
+ 2785 AST.NkUnary, AST.OpSub, astA);
|
|
|
+ 2786 astA := astCur
|
|
|
+ 2787 END; .)
|
|
|
+ 2788 { AddOp<op> (. IF op = SymTab.OpOr THEN
|
|
|
+ 2789 QbeGen.DelayBegin END; .)
|
|
|
+ 2790 Term<t2, q2> (. astB := astCur; IF op = SymTab.OpOr THEN
|
|
|
+ 2791 QbeGen.DelayEnd END; .)
|
|
|
+ 2792 (. astOp := AST.OpAdd;
|
|
|
+ 2793 IF op = SymTab.OpSub THEN astOp := AST.OpSub
|
|
|
+ 2794 ELSIF op = SymTab.OpOr THEN astOp := AST.OpOr END;
|
|
|
+ 2795 astA := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB);
|
|
|
+ 2796 astCur := astA;
|
|
|
+ 2797 IF op = SymTab.OpOr THEN
|
|
|
+ 2798 (* short-circuit: if q is true the RHS is skipped *)
|
|
|
+ 2799 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
+ 2800 t := SymTab.BoolType()
|
|
|
+ 2801 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
+ 2802 IF t # SymTab.InvalidType THEN
|
|
|
+ 2803 QbeGen.Slot4(qs);
|
|
|
+ 2804 QbeGen.NewLabel(lTrue);
|
|
|
+ 2805 QbeGen.NewLabel(lNext);
|
|
|
+ 2806 QbeGen.NewLabel(lDone);
|
|
|
+ 2807 QbeGen.Jnz(q, lTrue, lNext);
|
|
|
+ 2808 QbeGen.EmitLabel(lTrue);
|
|
|
+ 2809 QbeGen.StoreW(qs, "1");
|
|
|
+ 2810 QbeGen.Jmp(lDone);
|
|
|
+ 2811 QbeGen.EmitLabel(lNext);
|
|
|
+ 2812 QbeGen.DelayFlush;
|
|
|
+ 2813 QbeGen.StoreW(qs, q2);
|
|
|
+ 2814 QbeGen.Jmp(lDone);
|
|
|
+ 2815 QbeGen.EmitLabel(lDone);
|
|
|
+ 2816 QbeGen.LoadW(qs, qr);
|
|
|
+ 2817 QbeGen.CopyOp(qr, q)
|
|
|
+ 2818 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
+ 2819 END
|
|
|
+ 2820 ELSIF (op = SymTab.OpAdd)
|
|
|
+ 2821 AND (SymTab.UStrCompat(t, t2)
|
|
|
+ 2822 OR ((SymTab.ClassOf(t) = SymTab.ClUChar)
|
|
|
+ 2823 AND (SymTab.ClassOf(t2) = SymTab.ClUStr))
|
|
|
+ 2824 OR ((SymTab.ClassOf(t) = SymTab.ClUStr)
|
|
|
+ 2825 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))
|
|
|
+ 2826 OR ((SymTab.ClassOf(t) = SymTab.ClUChar)
|
|
|
+ 2827 AND (SymTab.ClassOf(t2) = SymTab.ClUChar))) THEN
|
|
|
+ 2828 (* UString concatenation: a UCHAR operand becomes a
|
|
|
+ 2829 1-codepoint UString; the result is a descriptor in the
|
|
|
+ 2830 shim's concat buffer. Work on copies so neither
|
|
|
+ 2831 operand is clobbered. *)
|
|
|
+ 2832 IF SymTab.ClassOf(t) = SymTab.ClUStr THEN
|
|
|
+ 2833 QbeGen.CopyOp(q, q2a)
|
|
|
+ 2834 ELSE
|
|
|
+ 2835 QbeGen.UStrFrom(q, q2a)
|
|
|
+ 2836 END;
|
|
|
+ 2837 IF SymTab.ClassOf(t2) = SymTab.ClUStr THEN
|
|
|
+ 2838 QbeGen.UStrCat(q2a, q2, qt)
|
|
|
+ 2839 ELSE
|
|
|
+ 2840 QbeGen.UStrFrom(q2, q2b);
|
|
|
+ 2841 QbeGen.UStrCat(q2a, q2b, qt)
|
|
|
+ 2842 END;
|
|
|
+ 2843 t := SymTab.NewUStr();
|
|
|
+ 2844 QbeGen.CopyOp(qt, q)
|
|
|
+ 2845 ELSIF (op = SymTab.OpAdd)
|
|
|
+ 2846 AND (SymTab.StrCompat(t, t2)
|
|
|
+ 2847 OR (SymTab.IsStrType(t)
|
|
|
+ 2848 AND (SymTab.ClassOf(t2) = SymTab.ClChar))
|
|
|
+ 2849 OR ((SymTab.ClassOf(t) = SymTab.ClChar)
|
|
|
+ 2850 AND SymTab.IsStrType(t2))) THEN
|
|
|
+ 2851 (* string concatenation; a CHAR operand becomes a
|
|
|
+ 2852 1-character string literal. When both operands are
|
|
|
+ 2853 constants, fold to a single string literal so a
|
|
|
+ 2854 constructor element stays compile-time. *)
|
|
|
+ 2855 QbeGen.StrFold(q, q2, SymTab.ClassOf(t), SymTab.ClassOf(t2),
|
|
|
+ 2856 qt, fok);
|
|
|
+ 2857 IF NOT fok THEN
|
|
|
+ 2858 IF SymTab.StrCompat(t, t2) THEN
|
|
|
+ 2859 QbeGen.StrCat(q, q2, qt)
|
|
|
+ 2860 ELSIF SymTab.IsStrType(t) THEN
|
|
|
+ 2861 QbeGen.DeclCharStr(q2, qs);
|
|
|
+ 2862 QbeGen.StrCat(q, qs, qt)
|
|
|
+ 2863 ELSE
|
|
|
+ 2864 QbeGen.DeclCharStr(q, qs);
|
|
|
+ 2865 QbeGen.StrCat(qs, q2, qt)
|
|
|
+ 2866 END
|
|
|
+ 2867 END;
|
|
|
+ 2868 t := SymTab.NewStr();
|
|
|
2869 QbeGen.CopyOp(qt, q)
|
|
|
- 2870 ELSE
|
|
|
- 2871 IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
|
|
|
- 2872 lt := t; rt := t2; t := res2
|
|
|
- 2873 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
- 2874 IF t # SymTab.InvalidType THEN
|
|
|
- 2875 isL := SymTab.IsLongFamily(t);
|
|
|
- 2876 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
- 2877 folded := FALSE;
|
|
|
- 2878 IF (NOT isL) AND (NOT isR)
|
|
|
- 2879 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
- 2880 IF op = SymTab.OpAdd THEN
|
|
|
- 2881 folded := QbeGen.Fold2(0, q, q2, qf)
|
|
|
- 2882 ELSE
|
|
|
- 2883 folded := QbeGen.Fold2(1, q, q2, qf)
|
|
|
- 2884 END
|
|
|
- 2885 END;
|
|
|
- 2886 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
- 2887 ELSE
|
|
|
- 2888 IF isL THEN
|
|
|
- 2889 IF SymTab.IsIntFamily(lt) THEN
|
|
|
- 2890 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
- 2891 END;
|
|
|
- 2892 IF SymTab.IsIntFamily(rt) THEN
|
|
|
- 2893 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
- 2894 END;
|
|
|
- 2895 QbeGen.NewTemp(qt);
|
|
|
- 2896 IF op = SymTab.OpAdd THEN
|
|
|
- 2897 QbeGen.Op3L("add", qt, q, q2)
|
|
|
- 2898 ELSE
|
|
|
- 2899 QbeGen.Op3L("sub", qt, q, q2)
|
|
|
- 2900 END
|
|
|
- 2901 ELSE
|
|
|
- 2902 QbeGen.NewTemp(qt);
|
|
|
- 2903 IF op = SymTab.OpAdd THEN
|
|
|
- 2904 QbeGen.Op3("add", qt, q, q2, isR)
|
|
|
- 2905 ELSE
|
|
|
- 2906 QbeGen.Op3("sub", qt, q, q2, isR)
|
|
|
- 2907 END
|
|
|
- 2908 END;
|
|
|
- 2909 QbeGen.CopyOp(qt, q)
|
|
|
- 2910 END
|
|
|
- 2911 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 2912 END
|
|
|
- 2913 END; .) } .
|
|
|
- 2914 AddOp<VAR op: INTEGER>
|
|
|
- 2915 = "+" (. op := SymTab.OpAdd; .)
|
|
|
- 2916 | "-" (. op := SymTab.OpSub; .)
|
|
|
- 2917 | "OR" (. op := SymTab.OpOr; .) .
|
|
|
- 2918 Term<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 2919 (. VAR t2, res2, lt, rt:
|
|
|
- 2920 SymTab.TypeIndex;
|
|
|
- 2921 op: INTEGER;
|
|
|
- 2922 q2, qt, wq, qf:
|
|
|
- 2923 QbeGen.QVal;
|
|
|
- 2924 isR, isL, folded: BOOLEAN;
|
|
|
- 2925 lw, rw, mw: CARDINAL;
|
|
|
- 2926 lNext, lFalse, lDone, qr, qs: QbeGen.QVal;
|
|
|
- 2927 astA, astB: AST.Node;
|
|
|
- 2928 astOp: INTEGER; .)
|
|
|
- 2929 = Fact<t, q> (. astA := astCur; .) { MulOp<op> (. IF op = SymTab.OpAnd THEN
|
|
|
- 2930 QbeGen.DelayBegin END; .)
|
|
|
- 2931 Fact<t2, q2> (. astB := astCur; IF op = SymTab.OpAnd THEN
|
|
|
- 2932 QbeGen.DelayEnd END; .)
|
|
|
- 2933 (. astOp := AST.OpMul;
|
|
|
- 2934 IF op = SymTab.OpSlash THEN astOp := AST.OpDiv
|
|
|
- 2935 ELSIF op = SymTab.OpDiv THEN astOp := AST.OpDiv
|
|
|
- 2936 ELSIF op = SymTab.OpMod THEN astOp := AST.OpMod
|
|
|
- 2937 ELSIF op = SymTab.OpAnd THEN astOp := AST.OpAnd END;
|
|
|
- 2938 astA := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB);
|
|
|
- 2939 astCur := astA;
|
|
|
- 2940 IF op = SymTab.OpAnd THEN
|
|
|
- 2941 (* short-circuit: if q is false the RHS is skipped *)
|
|
|
- 2942 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
- 2943 t := SymTab.BoolType()
|
|
|
- 2944 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
- 2945 IF t # SymTab.InvalidType THEN
|
|
|
- 2946 QbeGen.Slot4(qs);
|
|
|
- 2947 QbeGen.NewLabel(lNext);
|
|
|
- 2948 QbeGen.NewLabel(lFalse);
|
|
|
- 2949 QbeGen.NewLabel(lDone);
|
|
|
- 2950 QbeGen.Jnz(q, lNext, lFalse);
|
|
|
- 2951 QbeGen.EmitLabel(lNext);
|
|
|
- 2952 QbeGen.DelayFlush;
|
|
|
- 2953 QbeGen.StoreW(qs, q2);
|
|
|
- 2954 QbeGen.Jmp(lDone);
|
|
|
- 2955 QbeGen.EmitLabel(lFalse);
|
|
|
- 2956 QbeGen.StoreW(qs, "0");
|
|
|
- 2957 QbeGen.Jmp(lDone);
|
|
|
- 2958 QbeGen.EmitLabel(lDone);
|
|
|
- 2959 QbeGen.LoadW(qs, qr);
|
|
|
- 2960 QbeGen.CopyOp(qr, q)
|
|
|
- 2961 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
- 2962 END
|
|
|
- 2963 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
- 2964 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 2965 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 2966 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
- 2967 mw := lw;
|
|
|
- 2968 IF rw > mw THEN mw := rw END;
|
|
|
- 2969 IF op = SymTab.OpTimes THEN
|
|
|
- 2970 QbeGen.SetBinOp(1, q, q2, lw, rw, qt)
|
|
|
- 2971 ELSE
|
|
|
- 2972 QbeGen.SetBinOp(3, q, q2, lw, rw, qt)
|
|
|
- 2973 END;
|
|
|
- 2974 t := SymTab.NewSet(
|
|
|
- 2975 SymTab.NewSubR(0,
|
|
|
- 2976 VAL(INTEGER, mw) * 32 - 1));
|
|
|
- 2977 QbeGen.CopyOp(qt, q)
|
|
|
- 2978 ELSE
|
|
|
- 2979 IF SymTab.ArithCheck(t, t2,
|
|
|
- 2980 (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
|
|
|
- 2981 res2) THEN
|
|
|
- 2982 lt := t; rt := t2; t := res2
|
|
|
- 2983 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
- 2984 IF t # SymTab.InvalidType THEN
|
|
|
- 2985 isL := SymTab.IsLongFamily(t);
|
|
|
- 2986 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
- 2987 folded := FALSE;
|
|
|
- 2988 IF (NOT isL) AND (NOT isR)
|
|
|
- 2989 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
- 2990 IF op = SymTab.OpTimes THEN
|
|
|
- 2991 folded := QbeGen.Fold2(2, q, q2, qf)
|
|
|
- 2992 ELSIF op = SymTab.OpDiv THEN
|
|
|
- 2993 folded := QbeGen.Fold2(3, q, q2, qf)
|
|
|
- 2994 ELSIF op = SymTab.OpMod THEN
|
|
|
- 2995 folded := QbeGen.Fold2(4, q, q2, qf)
|
|
|
- 2996 END
|
|
|
- 2997 END;
|
|
|
- 2998 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
- 2999 ELSE
|
|
|
- 3000 IF isL THEN
|
|
|
- 3001 IF SymTab.IsIntFamily(lt) THEN
|
|
|
- 3002 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
- 3003 END;
|
|
|
- 3004 IF SymTab.IsIntFamily(rt) THEN
|
|
|
- 3005 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
- 3006 END;
|
|
|
- 3007 QbeGen.NewTemp(qt);
|
|
|
- 3008 IF op = SymTab.OpTimes THEN
|
|
|
- 3009 QbeGen.Op3L("mul", qt, q, q2)
|
|
|
- 3010 ELSIF (op = SymTab.OpDiv)
|
|
|
- 3011 OR (op = SymTab.OpSlash) THEN
|
|
|
- 3012 QbeGen.Op3L("div", qt, q, q2)
|
|
|
- 3013 ELSE
|
|
|
- 3014 QbeGen.Op3L("rem", qt, q, q2)
|
|
|
- 3015 END
|
|
|
- 3016 ELSE
|
|
|
- 3017 QbeGen.NewTemp(qt);
|
|
|
- 3018 IF op = SymTab.OpTimes THEN
|
|
|
- 3019 QbeGen.Op3("mul", qt, q, q2, isR)
|
|
|
- 3020 ELSIF (op = SymTab.OpDiv)
|
|
|
- 3021 OR (op = SymTab.OpSlash) THEN
|
|
|
- 3022 QbeGen.Op3("div", qt, q, q2, isR)
|
|
|
- 3023 ELSE
|
|
|
- 3024 QbeGen.Op3("rem", qt, q, q2, isR)
|
|
|
- 3025 END
|
|
|
- 3026 END;
|
|
|
- 3027 QbeGen.CopyOp(qt, q)
|
|
|
- 3028 END
|
|
|
- 3029 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 3030 END
|
|
|
- 3031 END; .) } .
|
|
|
- 3032 MulOp<VAR op: INTEGER>
|
|
|
- 3033 = "*" (. op := SymTab.OpTimes; .)
|
|
|
- 3034 | "/" (. op := SymTab.OpSlash; .)
|
|
|
- 3035 | "DIV" (. op := SymTab.OpDiv; .)
|
|
|
- 3036 | "MOD" (. op := SymTab.OpMod; .)
|
|
|
- 3037 | ( "AND" | "&" ) (. op := SymTab.OpAnd; .) .
|
|
|
- 3038 Fact<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 3039 (. VAR s: ARRAY [0 .. 255] OF CHAR;
|
|
|
- 3040 et, dt, t2, st, ct2, et2:
|
|
|
- 3041 SymTab.TypeIndex;
|
|
|
- 3042 dk: INTEGER;
|
|
|
- 3043 qd, q2, sq, qa, qm0, qr, qt:
|
|
|
- 3044 QbeGen.QVal;
|
|
|
- 3045 qn, vn: SymTab.Name;
|
|
|
- 3046 vt: SymTab.TypeIndex;
|
|
|
- 3047 c1, c2: INTEGER;
|
|
|
- 3048 lo, hi: INTEGER;
|
|
|
- 3049 isMax: BOOLEAN;
|
|
|
- 3050 called, isHigh, sfx, isCh,
|
|
|
- 3051 isU, uok, isStr: BOOLEAN;
|
|
|
- 3052 ucp: INTEGER; astIsLit: BOOLEAN;
|
|
|
- 3053 astD: AST.Node;
|
|
|
- 3054 astCall: BOOLEAN;
|
|
|
- 3055 astNode, astNot: AST.Node;
|
|
|
- 3056 j: CARDINAL;
|
|
|
- 3057 astArg2: AST.Node;
|
|
|
- 3058 astBrace: AST.Node;
|
|
|
- 3059 astRes: AST.Node; .)
|
|
|
- 3060 = (. astIsLit := FALSE; .)
|
|
|
- 3061 ( integer (. LexString(s);
|
|
|
- 3062 QbeGen.NormInt(s, q); IF twoPhase THEN astIsLit := TRUE; astCur := AST.MakeLeaf(AST.NkIntLit, s) END;
|
|
|
- 3063 t := SymTab.IntType(); .)
|
|
|
- 3064 | charConst (. LexString(s);
|
|
|
- 3065 QbeGen.NormLit(s, q, isCh);
|
|
|
- 3066 IF twoPhase THEN
|
|
|
- 3067 astIsLit := TRUE;
|
|
|
- 3068 astCur := AST.MakeLeaf(
|
|
|
- 3069 AST.NkCharLit, s)
|
|
|
- 3070 END;
|
|
|
- 3071 t := SymTab.CharType(); .)
|
|
|
- 3072 | real (. LexString(s);
|
|
|
- 3073 QbeGen.NormReal(s, q);
|
|
|
- 3074 IF twoPhase THEN
|
|
|
- 3075 astIsLit := TRUE;
|
|
|
- 3076 astCur := AST.MakeLeaf(
|
|
|
- 3077 AST.NkRealLit, s)
|
|
|
- 3078 END;
|
|
|
- 3079 t := SymTab.RealType(); .)
|
|
|
- 3080 | string (. LexString(s);
|
|
|
+ 2870 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
+ 2871 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 2872 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 2873 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
+ 2874 mw := lw;
|
|
|
+ 2875 IF rw > mw THEN mw := rw END;
|
|
|
+ 2876 IF op = SymTab.OpAdd THEN
|
|
|
+ 2877 QbeGen.SetBinOp(0, q, q2, lw, rw, qt)
|
|
|
+ 2878 ELSE
|
|
|
+ 2879 QbeGen.SetBinOp(2, q, q2, lw, rw, qt)
|
|
|
+ 2880 END;
|
|
|
+ 2881 t := SymTab.NewSet(
|
|
|
+ 2882 SymTab.NewSubR(0,
|
|
|
+ 2883 VAL(INTEGER, mw) * 32 - 1));
|
|
|
+ 2884 QbeGen.CopyOp(qt, q)
|
|
|
+ 2885 ELSE
|
|
|
+ 2886 IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
|
|
|
+ 2887 lt := t; rt := t2; t := res2
|
|
|
+ 2888 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
+ 2889 IF t # SymTab.InvalidType THEN
|
|
|
+ 2890 isL := SymTab.IsLongFamily(t);
|
|
|
+ 2891 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
+ 2892 folded := FALSE;
|
|
|
+ 2893 IF (NOT isL) AND (NOT isR)
|
|
|
+ 2894 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
+ 2895 IF op = SymTab.OpAdd THEN
|
|
|
+ 2896 folded := QbeGen.Fold2(0, q, q2, qf)
|
|
|
+ 2897 ELSE
|
|
|
+ 2898 folded := QbeGen.Fold2(1, q, q2, qf)
|
|
|
+ 2899 END
|
|
|
+ 2900 END;
|
|
|
+ 2901 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
+ 2902 ELSE
|
|
|
+ 2903 IF isL THEN
|
|
|
+ 2904 IF SymTab.IsIntFamily(lt) THEN
|
|
|
+ 2905 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
+ 2906 END;
|
|
|
+ 2907 IF SymTab.IsIntFamily(rt) THEN
|
|
|
+ 2908 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
+ 2909 END;
|
|
|
+ 2910 QbeGen.NewTemp(qt);
|
|
|
+ 2911 IF op = SymTab.OpAdd THEN
|
|
|
+ 2912 QbeGen.Op3L("add", qt, q, q2)
|
|
|
+ 2913 ELSE
|
|
|
+ 2914 QbeGen.Op3L("sub", qt, q, q2)
|
|
|
+ 2915 END
|
|
|
+ 2916 ELSE
|
|
|
+ 2917 QbeGen.NewTemp(qt);
|
|
|
+ 2918 IF op = SymTab.OpAdd THEN
|
|
|
+ 2919 QbeGen.Op3("add", qt, q, q2, isR)
|
|
|
+ 2920 ELSE
|
|
|
+ 2921 QbeGen.Op3("sub", qt, q, q2, isR)
|
|
|
+ 2922 END
|
|
|
+ 2923 END;
|
|
|
+ 2924 QbeGen.CopyOp(qt, q)
|
|
|
+ 2925 END
|
|
|
+ 2926 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 2927 END
|
|
|
+ 2928 END; .) } .
|
|
|
+ 2929 AddOp<VAR op: INTEGER>
|
|
|
+ 2930 = "+" (. op := SymTab.OpAdd; .)
|
|
|
+ 2931 | "-" (. op := SymTab.OpSub; .)
|
|
|
+ 2932 | "OR" (. op := SymTab.OpOr; .) .
|
|
|
+ 2933 Term<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 2934 (. VAR t2, res2, lt, rt:
|
|
|
+ 2935 SymTab.TypeIndex;
|
|
|
+ 2936 op: INTEGER;
|
|
|
+ 2937 q2, qt, wq, qf:
|
|
|
+ 2938 QbeGen.QVal;
|
|
|
+ 2939 isR, isL, folded: BOOLEAN;
|
|
|
+ 2940 lw, rw, mw: CARDINAL;
|
|
|
+ 2941 lNext, lFalse, lDone, qr, qs: QbeGen.QVal;
|
|
|
+ 2942 astA, astB: AST.Node;
|
|
|
+ 2943 astOp: INTEGER; .)
|
|
|
+ 2944 = Fact<t, q> (. astA := astCur; .) { MulOp<op> (. IF op = SymTab.OpAnd THEN
|
|
|
+ 2945 QbeGen.DelayBegin END; .)
|
|
|
+ 2946 Fact<t2, q2> (. astB := astCur; IF op = SymTab.OpAnd THEN
|
|
|
+ 2947 QbeGen.DelayEnd END; .)
|
|
|
+ 2948 (. astOp := AST.OpMul;
|
|
|
+ 2949 IF op = SymTab.OpSlash THEN astOp := AST.OpDiv
|
|
|
+ 2950 ELSIF op = SymTab.OpDiv THEN astOp := AST.OpDiv
|
|
|
+ 2951 ELSIF op = SymTab.OpMod THEN astOp := AST.OpMod
|
|
|
+ 2952 ELSIF op = SymTab.OpAnd THEN astOp := AST.OpAnd END;
|
|
|
+ 2953 astA := AST.MakeBin(AST.NkBinExpr, astOp, astA, astB);
|
|
|
+ 2954 astCur := astA;
|
|
|
+ 2955 IF op = SymTab.OpAnd THEN
|
|
|
+ 2956 (* short-circuit: if q is false the RHS is skipped *)
|
|
|
+ 2957 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
+ 2958 t := SymTab.BoolType()
|
|
|
+ 2959 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
+ 2960 IF t # SymTab.InvalidType THEN
|
|
|
+ 2961 QbeGen.Slot4(qs);
|
|
|
+ 2962 QbeGen.NewLabel(lNext);
|
|
|
+ 2963 QbeGen.NewLabel(lFalse);
|
|
|
+ 2964 QbeGen.NewLabel(lDone);
|
|
|
+ 2965 QbeGen.Jnz(q, lNext, lFalse);
|
|
|
+ 2966 QbeGen.EmitLabel(lNext);
|
|
|
+ 2967 QbeGen.DelayFlush;
|
|
|
+ 2968 QbeGen.StoreW(qs, q2);
|
|
|
+ 2969 QbeGen.Jmp(lDone);
|
|
|
+ 2970 QbeGen.EmitLabel(lFalse);
|
|
|
+ 2971 QbeGen.StoreW(qs, "0");
|
|
|
+ 2972 QbeGen.Jmp(lDone);
|
|
|
+ 2973 QbeGen.EmitLabel(lDone);
|
|
|
+ 2974 QbeGen.LoadW(qs, qr);
|
|
|
+ 2975 QbeGen.CopyOp(qr, q)
|
|
|
+ 2976 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
+ 2977 END
|
|
|
+ 2978 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
+ 2979 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 2980 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 2981 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
+ 2982 mw := lw;
|
|
|
+ 2983 IF rw > mw THEN mw := rw END;
|
|
|
+ 2984 IF op = SymTab.OpTimes THEN
|
|
|
+ 2985 QbeGen.SetBinOp(1, q, q2, lw, rw, qt)
|
|
|
+ 2986 ELSE
|
|
|
+ 2987 QbeGen.SetBinOp(3, q, q2, lw, rw, qt)
|
|
|
+ 2988 END;
|
|
|
+ 2989 t := SymTab.NewSet(
|
|
|
+ 2990 SymTab.NewSubR(0,
|
|
|
+ 2991 VAL(INTEGER, mw) * 32 - 1));
|
|
|
+ 2992 QbeGen.CopyOp(qt, q)
|
|
|
+ 2993 ELSE
|
|
|
+ 2994 IF SymTab.ArithCheck(t, t2,
|
|
|
+ 2995 (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
|
|
|
+ 2996 res2) THEN
|
|
|
+ 2997 lt := t; rt := t2; t := res2
|
|
|
+ 2998 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
+ 2999 IF t # SymTab.InvalidType THEN
|
|
|
+ 3000 isL := SymTab.IsLongFamily(t);
|
|
|
+ 3001 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
+ 3002 folded := FALSE;
|
|
|
+ 3003 IF (NOT isL) AND (NOT isR)
|
|
|
+ 3004 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
+ 3005 IF op = SymTab.OpTimes THEN
|
|
|
+ 3006 folded := QbeGen.Fold2(2, q, q2, qf)
|
|
|
+ 3007 ELSIF op = SymTab.OpDiv THEN
|
|
|
+ 3008 folded := QbeGen.Fold2(3, q, q2, qf)
|
|
|
+ 3009 ELSIF op = SymTab.OpMod THEN
|
|
|
+ 3010 folded := QbeGen.Fold2(4, q, q2, qf)
|
|
|
+ 3011 END
|
|
|
+ 3012 END;
|
|
|
+ 3013 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
+ 3014 ELSE
|
|
|
+ 3015 IF isL THEN
|
|
|
+ 3016 IF SymTab.IsIntFamily(lt) THEN
|
|
|
+ 3017 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
+ 3018 END;
|
|
|
+ 3019 IF SymTab.IsIntFamily(rt) THEN
|
|
|
+ 3020 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
+ 3021 END;
|
|
|
+ 3022 QbeGen.NewTemp(qt);
|
|
|
+ 3023 IF op = SymTab.OpTimes THEN
|
|
|
+ 3024 QbeGen.Op3L("mul", qt, q, q2)
|
|
|
+ 3025 ELSIF (op = SymTab.OpDiv)
|
|
|
+ 3026 OR (op = SymTab.OpSlash) THEN
|
|
|
+ 3027 QbeGen.Op3L("div", qt, q, q2)
|
|
|
+ 3028 ELSE
|
|
|
+ 3029 QbeGen.Op3L("rem", qt, q, q2)
|
|
|
+ 3030 END
|
|
|
+ 3031 ELSE
|
|
|
+ 3032 QbeGen.NewTemp(qt);
|
|
|
+ 3033 IF op = SymTab.OpTimes THEN
|
|
|
+ 3034 QbeGen.Op3("mul", qt, q, q2, isR)
|
|
|
+ 3035 ELSIF (op = SymTab.OpDiv)
|
|
|
+ 3036 OR (op = SymTab.OpSlash) THEN
|
|
|
+ 3037 QbeGen.Op3("div", qt, q, q2, isR)
|
|
|
+ 3038 ELSE
|
|
|
+ 3039 QbeGen.Op3("rem", qt, q, q2, isR)
|
|
|
+ 3040 END
|
|
|
+ 3041 END;
|
|
|
+ 3042 QbeGen.CopyOp(qt, q)
|
|
|
+ 3043 END
|
|
|
+ 3044 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 3045 END
|
|
|
+ 3046 END; .) } .
|
|
|
+ 3047 MulOp<VAR op: INTEGER>
|
|
|
+ 3048 = "*" (. op := SymTab.OpTimes; .)
|
|
|
+ 3049 | "/" (. op := SymTab.OpSlash; .)
|
|
|
+ 3050 | "DIV" (. op := SymTab.OpDiv; .)
|
|
|
+ 3051 | "MOD" (. op := SymTab.OpMod; .)
|
|
|
+ 3052 | ( "AND" | "&" ) (. op := SymTab.OpAnd; .) .
|
|
|
+ 3053 Fact<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 3054 (. VAR s: ARRAY [0 .. 255] OF CHAR;
|
|
|
+ 3055 et, dt, t2, st, ct2, et2:
|
|
|
+ 3056 SymTab.TypeIndex;
|
|
|
+ 3057 dk: INTEGER;
|
|
|
+ 3058 qd, q2, sq, qa, qm0, qr, qt:
|
|
|
+ 3059 QbeGen.QVal;
|
|
|
+ 3060 qn, vn: SymTab.Name;
|
|
|
+ 3061 vt: SymTab.TypeIndex;
|
|
|
+ 3062 c1, c2: INTEGER;
|
|
|
+ 3063 lo, hi: INTEGER;
|
|
|
+ 3064 isMax: BOOLEAN;
|
|
|
+ 3065 called, isHigh, sfx, isCh,
|
|
|
+ 3066 isU, uok, isStr: BOOLEAN;
|
|
|
+ 3067 ucp: INTEGER; astIsLit: BOOLEAN;
|
|
|
+ 3068 astD: AST.Node;
|
|
|
+ 3069 astCall: BOOLEAN;
|
|
|
+ 3070 astNode, astNot: AST.Node;
|
|
|
+ 3071 j: CARDINAL;
|
|
|
+ 3072 astArg2: AST.Node;
|
|
|
+ 3073 astBrace: AST.Node;
|
|
|
+ 3074 astRes: AST.Node; .)
|
|
|
+ 3075 = (. astIsLit := FALSE; .)
|
|
|
+ 3076 ( integer (. LexString(s);
|
|
|
+ 3077 QbeGen.NormInt(s, q); IF twoPhase THEN astIsLit := TRUE; astCur := AST.MakeLeaf(AST.NkIntLit, s) END;
|
|
|
+ 3078 t := SymTab.IntType(); .)
|
|
|
+ 3079 | charConst (. LexString(s);
|
|
|
+ 3080 QbeGen.NormLit(s, q, isCh);
|
|
|
3081 IF twoPhase THEN
|
|
|
3082 astIsLit := TRUE;
|
|
|
3083 astCur := AST.MakeLeaf(
|
|
|
- 3084 AST.NkStrLit, s)
|
|
|
+ 3084 AST.NkCharLit, s)
|
|
|
3085 END;
|
|
|
- 3086 IF SymTab.StrLen(s) = 3 THEN
|
|
|
- 3087 t := SymTab.CharType();
|
|
|
- 3088 QbeGen.IntStr(
|
|
|
- 3089 QbeGen.CharVal(s), q)
|
|
|
- 3090 ELSE t := SymTab.NewStr();
|
|
|
- 3091 QbeGen.DeclStr(s, q);
|
|
|
- 3092 (* a literal's value IS its
|
|
|
- 3093 static descriptor address *)
|
|
|
- 3094 QbeGen.NoteAddr(q, q)
|
|
|
- 3095 END; .)
|
|
|
- 3096 | ustring (. LexString(s);
|
|
|
- 3097 IF twoPhase THEN
|
|
|
- 3098 astIsLit := TRUE;
|
|
|
- 3099 astCur := AST.MakeLeaf(
|
|
|
- 3100 AST.NkStrLit, s)
|
|
|
- 3101 END;
|
|
|
- 3102 QbeGen.DeclUStr(s, q, isU, ucp,
|
|
|
- 3103 uok);
|
|
|
- 3104 IF NOT uok THEN
|
|
|
- 3105 SemError(234);
|
|
|
- 3106 t := SymTab.InvalidType
|
|
|
- 3107 ELSIF isU THEN
|
|
|
- 3108 t := SymTab.UCharType();
|
|
|
- 3109 QbeGen.IntStr(ucp, q)
|
|
|
- 3110 ELSE
|
|
|
- 3111 t := SymTab.NewUStr();
|
|
|
- 3112 QbeGen.NoteAddr(q, q)
|
|
|
- 3113 END; .)
|
|
|
- 3114 | Design<dt, dk, qd, qn, sfx> (. astD := astCur; astCall := FALSE; astBrace := AST.NoNode;
|
|
|
- 3115 astNArgs := 0; called := FALSE;
|
|
|
- 3116 t := dt;
|
|
|
- 3117 IF sfx THEN
|
|
|
- 3118 IF dt =
|
|
|
- 3119 SymTab.InvalidType THEN
|
|
|
- 3120 QbeGen.CopyOp("0", q)
|
|
|
- 3121 ELSIF (SymTab.ClassOf(dt) =
|
|
|
- 3122 SymTab.ClRecord)
|
|
|
- 3123 OR (SymTab.ClassOf(dt) =
|
|
|
- 3124 SymTab.ClSet)
|
|
|
- 3125 OR (SymTab.ClassOf(dt) =
|
|
|
- 3126 SymTab.ClArray)
|
|
|
- 3127 OR (SymTab.ClassOf(dt) =
|
|
|
- 3128 SymTab.ClClass) THEN
|
|
|
- 3129 QbeGen.CopyOp(qd, q)
|
|
|
- 3130 ELSE QbeGen.ElemLoad(qd, dt,
|
|
|
- 3131 q)
|
|
|
- 3132 END
|
|
|
- 3133 ELSE QbeGen.CopyOp(qd, q)
|
|
|
- 3134 END;
|
|
|
- 3135 IF (dk = SymTab.KindVar)
|
|
|
- 3136 OR (dk = SymTab.KindParam)
|
|
|
- 3137 OR (dk =
|
|
|
- 3138 SymTab.KindField) THEN
|
|
|
- 3139 IF sfx THEN
|
|
|
- 3140 QbeGen.NoteAddr(q, qd)
|
|
|
- 3141 ELSE
|
|
|
- 3142 QbeGen.AddrOf(qn, qa);
|
|
|
- 3143 QbeGen.NoteAddr(q, qa)
|
|
|
- 3144 END
|
|
|
- 3145 ELSIF sfx
|
|
|
- 3146 AND (dt #
|
|
|
- 3147 SymTab.InvalidType)
|
|
|
- 3148 AND ((SymTab.ClassOf(dt) =
|
|
|
- 3149 SymTab.ClArray)
|
|
|
- 3150 OR (SymTab.ClassOf(dt) =
|
|
|
- 3151 SymTab.ClSet)
|
|
|
- 3152 OR (SymTab.ClassOf(dt) =
|
|
|
- 3153 SymTab.ClRecord)) THEN
|
|
|
- 3154 QbeGen.NoteAddr(qd, qd)
|
|
|
- 3155 END; .)
|
|
|
- 3156 [ TypedBraceLit<dt, q> (. t := dt; astCall := TRUE;
|
|
|
- 3157 astBrace := astCur; .) ]
|
|
|
- 3158 [ ArgList<qn, dt, qd, TRUE, FALSE, methCls, ct2, q2, called>
|
|
|
- 3159 (. astCall := TRUE;
|
|
|
- 3160 astNode := AstCallNode(astD);
|
|
|
- 3161 astRes := astNode;
|
|
|
- 3162 t := ct2;
|
|
|
- 3163 QbeGen.CopyOp(q2, q);
|
|
|
- 3164 sfx := FALSE; .)
|
|
|
- 3165 { ResultComp<t, q, sfx, astRes> }
|
|
|
- 3166 (. IF sfx THEN
|
|
|
- 3167 IF t = SymTab.InvalidType THEN
|
|
|
- 3168 QbeGen.CopyOp("0", q)
|
|
|
- 3169 ELSIF (SymTab.ClassOf(t) #
|
|
|
- 3170 SymTab.ClRecord)
|
|
|
- 3171 AND (SymTab.ClassOf(t) # SymTab.ClSet)
|
|
|
- 3172 AND (SymTab.ClassOf(t) # SymTab.ClArray)
|
|
|
- 3173 AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
|
|
|
- 3174 QbeGen.ElemLoad(q, t, q2);
|
|
|
- 3175 QbeGen.CopyOp(q2, q)
|
|
|
- 3176 END
|
|
|
- 3177 END; .) ]
|
|
|
- 3178 (. IF called THEN
|
|
|
- 3179 astCur := astRes
|
|
|
- 3180 ELSIF astCall THEN
|
|
|
- 3181 astCur := astBrace
|
|
|
- 3182 ELSE astCur := astD
|
|
|
- 3183 END;
|
|
|
- 3184 astIsLit := TRUE;
|
|
|
- 3185 IF NOT called
|
|
|
- 3186 AND (dk = SymTab.KindProc) THEN
|
|
|
- 3187 (* bare zero-arg function
|
|
|
- 3188 call (parentheses may be
|
|
|
- 3189 omitted); a proper or
|
|
|
- 3190 parameterised proc here
|
|
|
- 3191 is 230 *)
|
|
|
- 3192 IF (SymTab.ProcNPar(qn) = 0)
|
|
|
- 3193 AND (SymTab.ProcRes(qn) #
|
|
|
- 3194 SymTab.InvalidType) THEN
|
|
|
- 3195 QbeGen.Mangled(qn,
|
|
|
- 3196 SymTab.ProcUid(qn), qm0);
|
|
|
- 3197 QbeGen.CallBegin(qm0,
|
|
|
- 3198 SymTab.ProcRes(qn),
|
|
|
- 3199 SymTab.ProcDepthOf(qn),
|
|
|
- 3200 SymTab.IsExternal(qn));
|
|
|
- 3201 QbeGen.CallEnd(TRUE, q);
|
|
|
- 3202 t := SymTab.ProcRes(qn)
|
|
|
- 3203 ELSE
|
|
|
- 3204 (* procedure used as a
|
|
|
- 3205 value (assign to a
|
|
|
- 3206 procedure variable):
|
|
|
- 3207 its code address *)
|
|
|
- 3208 t := SymTab.ProcTypeOf(qn);
|
|
|
- 3209 QbeGen.Mangled(qn,
|
|
|
- 3210 SymTab.ProcUid(qn), qm0);
|
|
|
- 3211 QbeGen.ProcAddr(qm0, q)
|
|
|
- 3212 END
|
|
|
- 3213 END; .)
|
|
|
- 3214 | ( "HIGH" (. isHigh := TRUE; .)
|
|
|
- 3215 | ( "LEN" | "LENGTH" ) (. isHigh := FALSE; .) )
|
|
|
- 3216 "(" ( Design<dt, dk, qd, qn, sfx> (. isStr := FALSE;
|
|
|
- 3217 isU := FALSE; .)
|
|
|
- 3218 | string (. LexString(s); astCur := AST.MakeLeaf(AST.NkStrLit, s);
|
|
|
- 3219 isStr := TRUE;
|
|
|
- 3220 isU := FALSE;
|
|
|
- 3221 IF SymTab.StrLen(s) = 3 THEN
|
|
|
- 3222 dt := SymTab.CharType();
|
|
|
- 3223 QbeGen.IntStr(QbeGen.CharVal(s),
|
|
|
- 3224 qd)
|
|
|
- 3225 ELSE
|
|
|
- 3226 dt := SymTab.NewStr();
|
|
|
- 3227 QbeGen.DeclStr(s, qd);
|
|
|
- 3228 QbeGen.NoteAddr(qd, qd)
|
|
|
- 3229 END;
|
|
|
- 3230 dk := -1;
|
|
|
- 3231 qn[0] := CHR(0); .)
|
|
|
- 3232 | ustring (. LexString(s); astCur := AST.MakeLeaf(AST.NkStrLit, s);
|
|
|
- 3233 QbeGen.DeclUStr(s, qd, isU, ucp,
|
|
|
- 3234 uok);
|
|
|
- 3235 isStr := FALSE;
|
|
|
- 3236 IF NOT uok THEN
|
|
|
- 3237 SemError(234);
|
|
|
- 3238 dt := SymTab.InvalidType
|
|
|
- 3239 ELSIF isU THEN
|
|
|
- 3240 (* one codepoint: a UCHAR;
|
|
|
- 3241 LEN is 1, HIGH is 0 *)
|
|
|
- 3242 dt := SymTab.UCharType();
|
|
|
- 3243 QbeGen.IntStr(ucp, qd)
|
|
|
- 3244 ELSE
|
|
|
- 3245 dt := SymTab.NewUStr();
|
|
|
- 3246 QbeGen.NoteAddr(qd, qd)
|
|
|
- 3247 END;
|
|
|
- 3248 dk := -1;
|
|
|
- 3249 qn[0] := CHR(0); .) )
|
|
|
- 3250 ")"
|
|
|
- 3251 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3252 IF isHigh THEN AST.SetChild(astNode, 0,
|
|
|
- 3253 AST.MakeLeaf(AST.NkIdent, "HIGH"))
|
|
|
- 3254 ELSE AST.SetChild(astNode, 0,
|
|
|
- 3255 AST.MakeLeaf(AST.NkIdent, "LEN")) END;
|
|
|
- 3256 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3257 astCur := astNode; astIsLit := TRUE;
|
|
|
- 3258 IF (dt # SymTab.InvalidType)
|
|
|
- 3259 AND (SymTab.ClassOf(dt) = SymTab.ClUStr) THEN
|
|
|
- 3260 (* UString: the count is
|
|
|
- 3261 the descriptor header *)
|
|
|
- 3262 IF isHigh THEN
|
|
|
- 3263 QbeGen.UStrLen(qd, qr);
|
|
|
- 3264 QbeGen.DecQ(qr)
|
|
|
- 3265 ELSE
|
|
|
- 3266 QbeGen.UStrLen(qd, qr)
|
|
|
- 3267 END;
|
|
|
- 3268 t := SymTab.IntType();
|
|
|
- 3269 QbeGen.CopyOp(qr, q)
|
|
|
- 3270 ELSIF (dt # SymTab.InvalidType)
|
|
|
- 3271 AND (SymTab.ClassOf(dt) = SymTab.ClUChar) THEN
|
|
|
- 3272 (* single UCHAR codepoint *)
|
|
|
- 3273 IF isHigh THEN
|
|
|
- 3274 QbeGen.CopyOp("0", qr)
|
|
|
- 3275 ELSE
|
|
|
- 3276 QbeGen.CopyOp("1", qr)
|
|
|
- 3277 END;
|
|
|
- 3278 t := SymTab.IntType();
|
|
|
- 3279 QbeGen.CopyOp(qr, q)
|
|
|
- 3280 ELSIF isStr THEN
|
|
|
- 3281 (* fold: content length at
|
|
|
- 3282 compile time *)
|
|
|
- 3283 IF SymTab.StrLen(s) = 3 THEN
|
|
|
- 3284 c1 := 1
|
|
|
- 3285 ELSE
|
|
|
- 3286 c1 :=
|
|
|
- 3287 SymTab.StrLen(s) - 2
|
|
|
- 3288 END;
|
|
|
- 3289 IF isHigh THEN
|
|
|
- 3290 DEC(c1)
|
|
|
- 3291 END;
|
|
|
- 3292 QbeGen.IntStr(c1, qr);
|
|
|
+ 3086 t := SymTab.CharType(); .)
|
|
|
+ 3087 | real (. LexString(s);
|
|
|
+ 3088 QbeGen.NormReal(s, q);
|
|
|
+ 3089 IF twoPhase THEN
|
|
|
+ 3090 astIsLit := TRUE;
|
|
|
+ 3091 astCur := AST.MakeLeaf(
|
|
|
+ 3092 AST.NkRealLit, s)
|
|
|
+ 3093 END;
|
|
|
+ 3094 t := SymTab.RealType(); .)
|
|
|
+ 3095 | string (. LexString(s);
|
|
|
+ 3096 IF twoPhase THEN
|
|
|
+ 3097 astIsLit := TRUE;
|
|
|
+ 3098 astCur := AST.MakeLeaf(
|
|
|
+ 3099 AST.NkStrLit, s)
|
|
|
+ 3100 END;
|
|
|
+ 3101 IF SymTab.StrLen(s) = 3 THEN
|
|
|
+ 3102 t := SymTab.CharType();
|
|
|
+ 3103 QbeGen.IntStr(
|
|
|
+ 3104 QbeGen.CharVal(s), q)
|
|
|
+ 3105 ELSE t := SymTab.NewStr();
|
|
|
+ 3106 QbeGen.DeclStr(s, q);
|
|
|
+ 3107 (* a literal's value IS its
|
|
|
+ 3108 static descriptor address *)
|
|
|
+ 3109 QbeGen.NoteAddr(q, q)
|
|
|
+ 3110 END; .)
|
|
|
+ 3111 | ustring (. LexString(s);
|
|
|
+ 3112 IF twoPhase THEN
|
|
|
+ 3113 astIsLit := TRUE;
|
|
|
+ 3114 astCur := AST.MakeLeaf(
|
|
|
+ 3115 AST.NkStrLit, s)
|
|
|
+ 3116 END;
|
|
|
+ 3117 QbeGen.DeclUStr(s, q, isU, ucp,
|
|
|
+ 3118 uok);
|
|
|
+ 3119 IF NOT uok THEN
|
|
|
+ 3120 SemError(234);
|
|
|
+ 3121 t := SymTab.InvalidType
|
|
|
+ 3122 ELSIF isU THEN
|
|
|
+ 3123 t := SymTab.UCharType();
|
|
|
+ 3124 QbeGen.IntStr(ucp, q)
|
|
|
+ 3125 ELSE
|
|
|
+ 3126 t := SymTab.NewUStr();
|
|
|
+ 3127 QbeGen.NoteAddr(q, q)
|
|
|
+ 3128 END; .)
|
|
|
+ 3129 | Design<dt, dk, qd, qn, sfx> (. astD := astCur; astCall := FALSE; astBrace := AST.NoNode;
|
|
|
+ 3130 astNArgs := 0; called := FALSE;
|
|
|
+ 3131 t := dt;
|
|
|
+ 3132 IF sfx THEN
|
|
|
+ 3133 IF dt =
|
|
|
+ 3134 SymTab.InvalidType THEN
|
|
|
+ 3135 QbeGen.CopyOp("0", q)
|
|
|
+ 3136 ELSIF (SymTab.ClassOf(dt) =
|
|
|
+ 3137 SymTab.ClRecord)
|
|
|
+ 3138 OR (SymTab.ClassOf(dt) =
|
|
|
+ 3139 SymTab.ClSet)
|
|
|
+ 3140 OR (SymTab.ClassOf(dt) =
|
|
|
+ 3141 SymTab.ClArray)
|
|
|
+ 3142 OR (SymTab.ClassOf(dt) =
|
|
|
+ 3143 SymTab.ClClass) THEN
|
|
|
+ 3144 QbeGen.CopyOp(qd, q)
|
|
|
+ 3145 ELSE QbeGen.ElemLoad(qd, dt,
|
|
|
+ 3146 q)
|
|
|
+ 3147 END
|
|
|
+ 3148 ELSE QbeGen.CopyOp(qd, q)
|
|
|
+ 3149 END;
|
|
|
+ 3150 IF (dk = SymTab.KindVar)
|
|
|
+ 3151 OR (dk = SymTab.KindParam)
|
|
|
+ 3152 OR (dk =
|
|
|
+ 3153 SymTab.KindField) THEN
|
|
|
+ 3154 IF sfx THEN
|
|
|
+ 3155 QbeGen.NoteAddr(q, qd)
|
|
|
+ 3156 ELSE
|
|
|
+ 3157 QbeGen.AddrOf(qn, qa);
|
|
|
+ 3158 QbeGen.NoteAddr(q, qa)
|
|
|
+ 3159 END
|
|
|
+ 3160 ELSIF sfx
|
|
|
+ 3161 AND (dt #
|
|
|
+ 3162 SymTab.InvalidType)
|
|
|
+ 3163 AND ((SymTab.ClassOf(dt) =
|
|
|
+ 3164 SymTab.ClArray)
|
|
|
+ 3165 OR (SymTab.ClassOf(dt) =
|
|
|
+ 3166 SymTab.ClSet)
|
|
|
+ 3167 OR (SymTab.ClassOf(dt) =
|
|
|
+ 3168 SymTab.ClRecord)) THEN
|
|
|
+ 3169 QbeGen.NoteAddr(qd, qd)
|
|
|
+ 3170 END; .)
|
|
|
+ 3171 [ TypedBraceLit<dt, q> (. t := dt; astCall := TRUE;
|
|
|
+ 3172 astBrace := astCur; .) ]
|
|
|
+ 3173 [ ArgList<qn, dt, qd, TRUE, FALSE, methCls, ct2, q2, called>
|
|
|
+ 3174 (. astCall := TRUE;
|
|
|
+ 3175 astNode := AstCallNode(astD);
|
|
|
+ 3176 astRes := astNode;
|
|
|
+ 3177 t := ct2;
|
|
|
+ 3178 QbeGen.CopyOp(q2, q);
|
|
|
+ 3179 sfx := FALSE; .)
|
|
|
+ 3180 { ResultComp<t, q, sfx, astRes> }
|
|
|
+ 3181 (. IF sfx THEN
|
|
|
+ 3182 IF t = SymTab.InvalidType THEN
|
|
|
+ 3183 QbeGen.CopyOp("0", q)
|
|
|
+ 3184 ELSIF (SymTab.ClassOf(t) #
|
|
|
+ 3185 SymTab.ClRecord)
|
|
|
+ 3186 AND (SymTab.ClassOf(t) # SymTab.ClSet)
|
|
|
+ 3187 AND (SymTab.ClassOf(t) # SymTab.ClArray)
|
|
|
+ 3188 AND (SymTab.ClassOf(t) # SymTab.ClClass) THEN
|
|
|
+ 3189 QbeGen.ElemLoad(q, t, q2);
|
|
|
+ 3190 QbeGen.CopyOp(q2, q)
|
|
|
+ 3191 END
|
|
|
+ 3192 END; .) ]
|
|
|
+ 3193 (. IF called THEN
|
|
|
+ 3194 astCur := astRes
|
|
|
+ 3195 ELSIF astCall THEN
|
|
|
+ 3196 astCur := astBrace
|
|
|
+ 3197 ELSE astCur := astD
|
|
|
+ 3198 END;
|
|
|
+ 3199 astIsLit := TRUE;
|
|
|
+ 3200 IF NOT called
|
|
|
+ 3201 AND (dk = SymTab.KindProc) THEN
|
|
|
+ 3202 (* bare zero-arg function
|
|
|
+ 3203 call (parentheses may be
|
|
|
+ 3204 omitted); a proper or
|
|
|
+ 3205 parameterised proc here
|
|
|
+ 3206 is 230 *)
|
|
|
+ 3207 IF (SymTab.ProcNPar(qn) = 0)
|
|
|
+ 3208 AND (SymTab.ProcRes(qn) #
|
|
|
+ 3209 SymTab.InvalidType) THEN
|
|
|
+ 3210 QbeGen.Mangled(qn,
|
|
|
+ 3211 SymTab.ProcUid(qn), qm0);
|
|
|
+ 3212 QbeGen.CallBegin(qm0,
|
|
|
+ 3213 SymTab.ProcRes(qn),
|
|
|
+ 3214 SymTab.ProcDepthOf(qn),
|
|
|
+ 3215 SymTab.IsExternal(qn));
|
|
|
+ 3216 QbeGen.CallEnd(TRUE, q);
|
|
|
+ 3217 t := SymTab.ProcRes(qn)
|
|
|
+ 3218 ELSE
|
|
|
+ 3219 (* procedure used as a
|
|
|
+ 3220 value (assign to a
|
|
|
+ 3221 procedure variable):
|
|
|
+ 3222 its code address *)
|
|
|
+ 3223 t := SymTab.ProcTypeOf(qn);
|
|
|
+ 3224 QbeGen.Mangled(qn,
|
|
|
+ 3225 SymTab.ProcUid(qn), qm0);
|
|
|
+ 3226 QbeGen.ProcAddr(qm0, q)
|
|
|
+ 3227 END
|
|
|
+ 3228 END; .)
|
|
|
+ 3229 | ( "HIGH" (. isHigh := TRUE; .)
|
|
|
+ 3230 | ( "LEN" | "LENGTH" ) (. isHigh := FALSE; .) )
|
|
|
+ 3231 "(" ( Design<dt, dk, qd, qn, sfx> (. isStr := FALSE;
|
|
|
+ 3232 isU := FALSE; .)
|
|
|
+ 3233 | string (. LexString(s); astCur := AST.MakeLeaf(AST.NkStrLit, s);
|
|
|
+ 3234 isStr := TRUE;
|
|
|
+ 3235 isU := FALSE;
|
|
|
+ 3236 IF SymTab.StrLen(s) = 3 THEN
|
|
|
+ 3237 dt := SymTab.CharType();
|
|
|
+ 3238 QbeGen.IntStr(QbeGen.CharVal(s),
|
|
|
+ 3239 qd)
|
|
|
+ 3240 ELSE
|
|
|
+ 3241 dt := SymTab.NewStr();
|
|
|
+ 3242 QbeGen.DeclStr(s, qd);
|
|
|
+ 3243 QbeGen.NoteAddr(qd, qd)
|
|
|
+ 3244 END;
|
|
|
+ 3245 dk := -1;
|
|
|
+ 3246 qn[0] := CHR(0); .)
|
|
|
+ 3247 | ustring (. LexString(s); astCur := AST.MakeLeaf(AST.NkStrLit, s);
|
|
|
+ 3248 QbeGen.DeclUStr(s, qd, isU, ucp,
|
|
|
+ 3249 uok);
|
|
|
+ 3250 isStr := FALSE;
|
|
|
+ 3251 IF NOT uok THEN
|
|
|
+ 3252 SemError(234);
|
|
|
+ 3253 dt := SymTab.InvalidType
|
|
|
+ 3254 ELSIF isU THEN
|
|
|
+ 3255 (* one codepoint: a UCHAR;
|
|
|
+ 3256 LEN is 1, HIGH is 0 *)
|
|
|
+ 3257 dt := SymTab.UCharType();
|
|
|
+ 3258 QbeGen.IntStr(ucp, qd)
|
|
|
+ 3259 ELSE
|
|
|
+ 3260 dt := SymTab.NewUStr();
|
|
|
+ 3261 QbeGen.NoteAddr(qd, qd)
|
|
|
+ 3262 END;
|
|
|
+ 3263 dk := -1;
|
|
|
+ 3264 qn[0] := CHR(0); .) )
|
|
|
+ 3265 ")"
|
|
|
+ 3266 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3267 IF isHigh THEN AST.SetChild(astNode, 0,
|
|
|
+ 3268 AST.MakeLeaf(AST.NkIdent, "HIGH"))
|
|
|
+ 3269 ELSE AST.SetChild(astNode, 0,
|
|
|
+ 3270 AST.MakeLeaf(AST.NkIdent, "LEN")) END;
|
|
|
+ 3271 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3272 astCur := astNode; astIsLit := TRUE;
|
|
|
+ 3273 IF (dt # SymTab.InvalidType)
|
|
|
+ 3274 AND (SymTab.ClassOf(dt) = SymTab.ClUStr) THEN
|
|
|
+ 3275 (* UString: the count is
|
|
|
+ 3276 the descriptor header *)
|
|
|
+ 3277 IF isHigh THEN
|
|
|
+ 3278 QbeGen.UStrLen(qd, qr);
|
|
|
+ 3279 QbeGen.DecQ(qr)
|
|
|
+ 3280 ELSE
|
|
|
+ 3281 QbeGen.UStrLen(qd, qr)
|
|
|
+ 3282 END;
|
|
|
+ 3283 t := SymTab.IntType();
|
|
|
+ 3284 QbeGen.CopyOp(qr, q)
|
|
|
+ 3285 ELSIF (dt # SymTab.InvalidType)
|
|
|
+ 3286 AND (SymTab.ClassOf(dt) = SymTab.ClUChar) THEN
|
|
|
+ 3287 (* single UCHAR codepoint *)
|
|
|
+ 3288 IF isHigh THEN
|
|
|
+ 3289 QbeGen.CopyOp("0", qr)
|
|
|
+ 3290 ELSE
|
|
|
+ 3291 QbeGen.CopyOp("1", qr)
|
|
|
+ 3292 END;
|
|
|
3293 t := SymTab.IntType();
|
|
|
3294 QbeGen.CopyOp(qr, q)
|
|
|
- 3295 ELSIF dt = SymTab.InvalidType THEN
|
|
|
- 3296 t := SymTab.InvalidType;
|
|
|
- 3297 QbeGen.CopyOp("0", q)
|
|
|
- 3298 ELSIF SymTab.ClassOf(dt) #
|
|
|
- 3299 SymTab.ClArray THEN
|
|
|
- 3300 SemError(217);
|
|
|
- 3301 t := SymTab.InvalidType;
|
|
|
- 3302 QbeGen.CopyOp("0", q)
|
|
|
- 3303 ELSE
|
|
|
+ 3295 ELSIF isStr THEN
|
|
|
+ 3296 (* fold: content length at
|
|
|
+ 3297 compile time *)
|
|
|
+ 3298 IF SymTab.StrLen(s) = 3 THEN
|
|
|
+ 3299 c1 := 1
|
|
|
+ 3300 ELSE
|
|
|
+ 3301 c1 :=
|
|
|
+ 3302 SymTab.StrLen(s) - 2
|
|
|
+ 3303 END;
|
|
|
3304 IF isHigh THEN
|
|
|
- 3305 IF SymTab.IsOpenArray(dt) THEN
|
|
|
- 3306 QbeGen.OpenHi(qd, qr)
|
|
|
- 3307 ELSE
|
|
|
- 3308 QbeGen.IntStr(
|
|
|
- 3309 SymTab.ArrayHi(dt), qr)
|
|
|
- 3310 END
|
|
|
- 3311 ELSE
|
|
|
- 3312 IF SymTab.IsOpenArray(dt) THEN
|
|
|
- 3313 QbeGen.LoadCount(qd, qr)
|
|
|
- 3314 ELSE
|
|
|
- 3315 QbeGen.IntStr(VAL(
|
|
|
- 3316 INTEGER,
|
|
|
- 3317 SymTab.ArrayLen(dt)),
|
|
|
- 3318 qr)
|
|
|
- 3319 END
|
|
|
- 3320 END;
|
|
|
- 3321 t := SymTab.IntType();
|
|
|
- 3322 QbeGen.CopyOp(qr, q)
|
|
|
- 3323 END; .)
|
|
|
- 3324 | ( "SIZE" | "TSIZE" ) "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 3325 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3326 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "SIZE"));
|
|
|
- 3327 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3328 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3329 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 3330 t := SymTab.InvalidType;
|
|
|
- 3331 QbeGen.CopyOp("0", q)
|
|
|
- 3332 ELSE
|
|
|
- 3333 QbeGen.IntStr(VAL(INTEGER,
|
|
|
- 3334 SymTab.ObjectSize(dt)), q);
|
|
|
- 3335 t := SymTab.IntType()
|
|
|
- 3336 END; .)
|
|
|
- 3337 | ( "SHIFT" (. isMax := FALSE; .)
|
|
|
- 3338 | "ROTATE" (. isMax := TRUE; .) )
|
|
|
- 3339 "(" Expr<et, q> (. astArg2 := astCur; .) "," Expr<et2, q2> ")"
|
|
|
- 3340 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3341 IF isMax THEN AST.SetChild(astNode, 0,
|
|
|
- 3342 AST.MakeLeaf(AST.NkIdent, "ROTATE"))
|
|
|
- 3343 ELSE AST.SetChild(astNode, 0,
|
|
|
- 3344 AST.MakeLeaf(AST.NkIdent, "SHIFT")) END;
|
|
|
- 3345 IF astArg2 # AST.NoNode THEN AST.SetChild(astNode, 1, astArg2) END;
|
|
|
- 3346 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
- 3347 astCur := astNode; astIsLit := TRUE;
|
|
|
- 3348 (* set shift/rotate: isMax
|
|
|
- 3349 doubles as "rotate" *)
|
|
|
- 3350 IF (et # SymTab.InvalidType)
|
|
|
- 3351 AND (SymTab.ClassOf(et) =
|
|
|
- 3352 SymTab.ClSet) THEN
|
|
|
- 3353 QbeGen.SetShift(q, q2,
|
|
|
- 3354 SymTab.SetWords(et),
|
|
|
- 3355 SymTab.SetCount(et), isMax,
|
|
|
- 3356 qt);
|
|
|
- 3357 t := et;
|
|
|
- 3358 QbeGen.CopyOp(qt, q)
|
|
|
- 3359 ELSE SemError(230);
|
|
|
- 3360 t := SymTab.InvalidType;
|
|
|
- 3361 QbeGen.CopyOp("0", q)
|
|
|
- 3362 END; .)
|
|
|
- 3363 | ( "MIN" (. isMax := FALSE; .)
|
|
|
- 3364 | "MAX" (. isMax := TRUE; .) )
|
|
|
- 3365 "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 3366 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3367 IF isMax THEN AST.SetChild(astNode, 0,
|
|
|
- 3368 AST.MakeLeaf(AST.NkIdent, "MAX"))
|
|
|
- 3369 ELSE AST.SetChild(astNode, 0,
|
|
|
- 3370 AST.MakeLeaf(AST.NkIdent, "MIN")) END;
|
|
|
- 3371 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3372 astCur := astNode; astIsLit := TRUE;
|
|
|
- 3373 IF (dt # SymTab.InvalidType)
|
|
|
- 3374 AND (SymTab.ClassOf(dt) = SymTab.ClReal) THEN
|
|
|
- 3375 (* REAL/LONGREAL: the
|
|
|
- 3376 implementation bounds *)
|
|
|
- 3377 IF isMax THEN
|
|
|
- 3378 QbeGen.NormReal(
|
|
|
- 3379 "3.402823e38", q)
|
|
|
- 3380 ELSE QbeGen.NormReal(
|
|
|
- 3381 "-3.402823e38", q)
|
|
|
- 3382 END;
|
|
|
- 3383 t := SymTab.RealType()
|
|
|
- 3384 ELSIF (dt #
|
|
|
- 3385 SymTab.InvalidType)
|
|
|
- 3386 AND (SymTab.ClassOf(dt) =
|
|
|
- 3387 SymTab.ClLong) THEN
|
|
|
- 3388 IF isMax THEN
|
|
|
- 3389 QbeGen.CopyOp(
|
|
|
- 3390 "9223372036854775807", q)
|
|
|
- 3391 ELSE QbeGen.CopyOp(
|
|
|
- 3392 "-9223372036854775808", q)
|
|
|
- 3393 END;
|
|
|
- 3394 t := SymTab.LongType()
|
|
|
- 3395 ELSIF SymTab.TypeBounds(dt, lo,
|
|
|
- 3396 hi) THEN
|
|
|
- 3397 IF isMax THEN
|
|
|
- 3398 QbeGen.IntStr(hi, q)
|
|
|
- 3399 ELSE QbeGen.IntStr(lo, q)
|
|
|
- 3400 END;
|
|
|
- 3401 t := SymTab.IntType()
|
|
|
- 3402 ELSE SemError(230);
|
|
|
- 3403 t := SymTab.InvalidType;
|
|
|
- 3404 QbeGen.CopyOp("0", q)
|
|
|
- 3405 END; .)
|
|
|
- 3406 | "ADR" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 3407 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3408 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ADR"));
|
|
|
- 3409 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3410 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3411 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 3412 t := SymTab.InvalidType;
|
|
|
- 3413 QbeGen.CopyOp("0", q)
|
|
|
- 3414 ELSE
|
|
|
- 3415 IF sfx THEN
|
|
|
- 3416 QbeGen.CopyOp(qd, q)
|
|
|
- 3417 ELSIF (dk = SymTab.KindVar)
|
|
|
- 3418 OR (dk = SymTab.KindParam) THEN
|
|
|
- 3419 QbeGen.AddrOf(qn, q)
|
|
|
- 3420 ELSE SemError(230);
|
|
|
- 3421 QbeGen.CopyOp("0", q)
|
|
|
- 3422 END;
|
|
|
- 3423 t := SymTab.AddrType()
|
|
|
- 3424 END; .)
|
|
|
- 3425 | "CHR" "(" Expr<et, q> ")"
|
|
|
- 3426 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3427 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CHR"));
|
|
|
- 3428 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3429 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3430 (. IF (et # SymTab.InvalidType)
|
|
|
- 3431 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
- 3432 SemError(211) END;
|
|
|
- 3433 t := SymTab.CharType(); .)
|
|
|
- 3434 | ( "ORD" | "ORDL" ) "(" Expr<et, q> ")"
|
|
|
- 3435 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3436 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ORD"));
|
|
|
- 3437 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3438 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3439 (. IF et # SymTab.InvalidType THEN
|
|
|
- 3440 IF (SymTab.ClassOf(et) #
|
|
|
- 3441 SymTab.ClChar)
|
|
|
- 3442 AND (SymTab.ClassOf(et) #
|
|
|
- 3443 SymTab.ClBool)
|
|
|
- 3444 AND (SymTab.ClassOf(et) #
|
|
|
- 3445 SymTab.ClEnum)
|
|
|
+ 3305 DEC(c1)
|
|
|
+ 3306 END;
|
|
|
+ 3307 QbeGen.IntStr(c1, qr);
|
|
|
+ 3308 t := SymTab.IntType();
|
|
|
+ 3309 QbeGen.CopyOp(qr, q)
|
|
|
+ 3310 ELSIF dt = SymTab.InvalidType THEN
|
|
|
+ 3311 t := SymTab.InvalidType;
|
|
|
+ 3312 QbeGen.CopyOp("0", q)
|
|
|
+ 3313 ELSIF SymTab.ClassOf(dt) #
|
|
|
+ 3314 SymTab.ClArray THEN
|
|
|
+ 3315 SemError(217);
|
|
|
+ 3316 t := SymTab.InvalidType;
|
|
|
+ 3317 QbeGen.CopyOp("0", q)
|
|
|
+ 3318 ELSE
|
|
|
+ 3319 IF isHigh THEN
|
|
|
+ 3320 IF SymTab.IsOpenArray(dt) THEN
|
|
|
+ 3321 QbeGen.OpenHi(qd, qr)
|
|
|
+ 3322 ELSE
|
|
|
+ 3323 QbeGen.IntStr(
|
|
|
+ 3324 SymTab.ArrayHi(dt), qr)
|
|
|
+ 3325 END
|
|
|
+ 3326 ELSE
|
|
|
+ 3327 IF SymTab.IsOpenArray(dt) THEN
|
|
|
+ 3328 QbeGen.LoadCount(qd, qr)
|
|
|
+ 3329 ELSE
|
|
|
+ 3330 QbeGen.IntStr(VAL(
|
|
|
+ 3331 INTEGER,
|
|
|
+ 3332 SymTab.ArrayLen(dt)),
|
|
|
+ 3333 qr)
|
|
|
+ 3334 END
|
|
|
+ 3335 END;
|
|
|
+ 3336 t := SymTab.IntType();
|
|
|
+ 3337 QbeGen.CopyOp(qr, q)
|
|
|
+ 3338 END; .)
|
|
|
+ 3339 | ( "SIZE" | "TSIZE" ) "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 3340 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3341 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "SIZE"));
|
|
|
+ 3342 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3343 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3344 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 3345 t := SymTab.InvalidType;
|
|
|
+ 3346 QbeGen.CopyOp("0", q)
|
|
|
+ 3347 ELSE
|
|
|
+ 3348 QbeGen.IntStr(VAL(INTEGER,
|
|
|
+ 3349 SymTab.ObjectSize(dt)), q);
|
|
|
+ 3350 t := SymTab.IntType()
|
|
|
+ 3351 END; .)
|
|
|
+ 3352 | ( "SHIFT" (. isMax := FALSE; .)
|
|
|
+ 3353 | "ROTATE" (. isMax := TRUE; .) )
|
|
|
+ 3354 "(" Expr<et, q> (. astArg2 := astCur; .) "," Expr<et2, q2> ")"
|
|
|
+ 3355 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3356 IF isMax THEN AST.SetChild(astNode, 0,
|
|
|
+ 3357 AST.MakeLeaf(AST.NkIdent, "ROTATE"))
|
|
|
+ 3358 ELSE AST.SetChild(astNode, 0,
|
|
|
+ 3359 AST.MakeLeaf(AST.NkIdent, "SHIFT")) END;
|
|
|
+ 3360 IF astArg2 # AST.NoNode THEN AST.SetChild(astNode, 1, astArg2) END;
|
|
|
+ 3361 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
+ 3362 astCur := astNode; astIsLit := TRUE;
|
|
|
+ 3363 (* set shift/rotate: isMax
|
|
|
+ 3364 doubles as "rotate" *)
|
|
|
+ 3365 IF (et # SymTab.InvalidType)
|
|
|
+ 3366 AND (SymTab.ClassOf(et) =
|
|
|
+ 3367 SymTab.ClSet) THEN
|
|
|
+ 3368 QbeGen.SetShift(q, q2,
|
|
|
+ 3369 SymTab.SetWords(et),
|
|
|
+ 3370 SymTab.SetCount(et), isMax,
|
|
|
+ 3371 qt);
|
|
|
+ 3372 t := et;
|
|
|
+ 3373 QbeGen.CopyOp(qt, q)
|
|
|
+ 3374 ELSE SemError(230);
|
|
|
+ 3375 t := SymTab.InvalidType;
|
|
|
+ 3376 QbeGen.CopyOp("0", q)
|
|
|
+ 3377 END; .)
|
|
|
+ 3378 | ( "MIN" (. isMax := FALSE; .)
|
|
|
+ 3379 | "MAX" (. isMax := TRUE; .) )
|
|
|
+ 3380 "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 3381 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3382 IF isMax THEN AST.SetChild(astNode, 0,
|
|
|
+ 3383 AST.MakeLeaf(AST.NkIdent, "MAX"))
|
|
|
+ 3384 ELSE AST.SetChild(astNode, 0,
|
|
|
+ 3385 AST.MakeLeaf(AST.NkIdent, "MIN")) END;
|
|
|
+ 3386 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3387 astCur := astNode; astIsLit := TRUE;
|
|
|
+ 3388 IF (dt # SymTab.InvalidType)
|
|
|
+ 3389 AND (SymTab.ClassOf(dt) = SymTab.ClReal) THEN
|
|
|
+ 3390 (* REAL/LONGREAL: the
|
|
|
+ 3391 implementation bounds *)
|
|
|
+ 3392 IF isMax THEN
|
|
|
+ 3393 QbeGen.NormReal(
|
|
|
+ 3394 "3.402823e38", q)
|
|
|
+ 3395 ELSE QbeGen.NormReal(
|
|
|
+ 3396 "-3.402823e38", q)
|
|
|
+ 3397 END;
|
|
|
+ 3398 t := SymTab.RealType()
|
|
|
+ 3399 ELSIF (dt #
|
|
|
+ 3400 SymTab.InvalidType)
|
|
|
+ 3401 AND (SymTab.ClassOf(dt) =
|
|
|
+ 3402 SymTab.ClLong) THEN
|
|
|
+ 3403 IF isMax THEN
|
|
|
+ 3404 QbeGen.CopyOp(
|
|
|
+ 3405 "9223372036854775807", q)
|
|
|
+ 3406 ELSE QbeGen.CopyOp(
|
|
|
+ 3407 "-9223372036854775808", q)
|
|
|
+ 3408 END;
|
|
|
+ 3409 t := SymTab.LongType()
|
|
|
+ 3410 ELSIF SymTab.TypeBounds(dt, lo,
|
|
|
+ 3411 hi) THEN
|
|
|
+ 3412 IF isMax THEN
|
|
|
+ 3413 QbeGen.IntStr(hi, q)
|
|
|
+ 3414 ELSE QbeGen.IntStr(lo, q)
|
|
|
+ 3415 END;
|
|
|
+ 3416 t := SymTab.IntType()
|
|
|
+ 3417 ELSE SemError(230);
|
|
|
+ 3418 t := SymTab.InvalidType;
|
|
|
+ 3419 QbeGen.CopyOp("0", q)
|
|
|
+ 3420 END; .)
|
|
|
+ 3421 | "ADR" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 3422 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3423 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ADR"));
|
|
|
+ 3424 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3425 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3426 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 3427 t := SymTab.InvalidType;
|
|
|
+ 3428 QbeGen.CopyOp("0", q)
|
|
|
+ 3429 ELSE
|
|
|
+ 3430 IF sfx THEN
|
|
|
+ 3431 QbeGen.CopyOp(qd, q)
|
|
|
+ 3432 ELSIF (dk = SymTab.KindVar)
|
|
|
+ 3433 OR (dk = SymTab.KindParam) THEN
|
|
|
+ 3434 QbeGen.AddrOf(qn, q)
|
|
|
+ 3435 ELSE SemError(230);
|
|
|
+ 3436 QbeGen.CopyOp("0", q)
|
|
|
+ 3437 END;
|
|
|
+ 3438 t := SymTab.AddrType()
|
|
|
+ 3439 END; .)
|
|
|
+ 3440 | "CHR" "(" Expr<et, q> ")"
|
|
|
+ 3441 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3442 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CHR"));
|
|
|
+ 3443 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3444 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3445 (. IF (et # SymTab.InvalidType)
|
|
|
3446 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
- 3447 SemError(211) END
|
|
|
- 3448 END;
|
|
|
- 3449 t := SymTab.IntType(); .)
|
|
|
- 3450 | "CAP" "(" Expr<et, q> ")"
|
|
|
- 3451 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3452 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CAP"));
|
|
|
- 3453 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3454 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3455 (. QbeGen.CapQ(q, qa);
|
|
|
- 3456 QbeGen.CopyOp(qa, q);
|
|
|
- 3457 t := SymTab.CharType(); .)
|
|
|
- 3458 | "UCHR" "(" Expr<et, q> ")"
|
|
|
- 3459 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3460 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "UCHR"));
|
|
|
- 3461 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3462 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3463 (. (* UCHR: the UCHAR constructor.
|
|
|
- 3464 CHAR -> UCHAR (identity);
|
|
|
- 3465 INTEGER familly -> UCHAR
|
|
|
- 3466 (codepoint value). *)
|
|
|
- 3467 IF (et # SymTab.InvalidType)
|
|
|
- 3468 AND (SymTab.ClassOf(et) # SymTab.ClChar)
|
|
|
- 3469 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
- 3470 SemError(211) END;
|
|
|
- 3471 t := SymTab.UCharType(); .)
|
|
|
- 3472 | "CHR8" "(" Expr<et, q> ")"
|
|
|
- 3473 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3474 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CHR8"));
|
|
|
- 3475 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3476 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3477 (. IF (et # SymTab.InvalidType)
|
|
|
- 3478 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
- 3479 SemError(211) END;
|
|
|
- 3480 QbeGen.WidenLong(q, qa);
|
|
|
- 3481 QbeGen.CheckRange(qa, "0", "255");
|
|
|
- 3482 t := SymTab.CharType(); .)
|
|
|
- 3483 | "UORD" "(" Expr<et, q> ")"
|
|
|
- 3484 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3485 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "UORD"));
|
|
|
- 3486 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3487 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3488 (. (* UORD(u): the codepoint as a
|
|
|
- 3489 32-bit ordinal (INTEGER),
|
|
|
- 3490 cf. ORD for CHAR. *)
|
|
|
- 3491 IF (et # SymTab.InvalidType)
|
|
|
- 3492 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
- 3493 SemError(211) END;
|
|
|
- 3494 t := SymTab.IntType(); .)
|
|
|
- 3495 | "ABS" "(" Expr<et, q> ")"
|
|
|
- 3496 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3497 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ABS"));
|
|
|
- 3498 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
- 3499 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3500 (. IF (et # SymTab.InvalidType)
|
|
|
- 3501 AND NOT SymTab.IsIntFamily(et)
|
|
|
- 3502 AND (SymTab.ClassOf(et) #
|
|
|
- 3503 SymTab.ClReal) THEN
|
|
|
- 3504 SemError(211)
|
|
|
- 3505 ELSE QbeGen.AbsQ(q, qa,
|
|
|
- 3506 SymTab.ClassOf(et) =
|
|
|
- 3507 SymTab.ClReal);
|
|
|
- 3508 QbeGen.CopyOp(qa, q)
|
|
|
- 3509 END;
|
|
|
- 3510 t := et; .)
|
|
|
- 3511 | "VAL" "(" GetIdent<vn> (. astArg2 := AST.MakeLeaf(AST.NkIdent, vn); .) "," Expr<et, q> ")"
|
|
|
- 3512 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
- 3513 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "VAL"));
|
|
|
- 3514 IF astArg2 # AST.NoNode THEN AST.SetChild(astNode, 1, astArg2) END;
|
|
|
- 3515 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
- 3516 astCur := astNode; astIsLit := TRUE; .)
|
|
|
- 3517 (. IF NOT SymTab.Lookup(vn) THEN
|
|
|
- 3518 SemError(201);
|
|
|
- 3519 t := SymTab.InvalidType
|
|
|
- 3520 ELSE vt := SymTab.SymType(vn);
|
|
|
- 3521 IF vt = SymTab.InvalidType THEN
|
|
|
- 3522 t := SymTab.InvalidType
|
|
|
- 3523 ELSIF et =
|
|
|
- 3524 SymTab.InvalidType THEN
|
|
|
- 3525 t := vt
|
|
|
- 3526 ELSE
|
|
|
- 3527 c1 := SymTab.ClassOf(et);
|
|
|
- 3528 c2 := SymTab.ClassOf(vt);
|
|
|
- 3529 IF (c1 = SymTab.ClInt)
|
|
|
- 3530 AND (c2 = SymTab.ClLong) THEN
|
|
|
- 3531 QbeGen.WidenLong(q, qa);
|
|
|
- 3532 QbeGen.CopyOp(qa, q);
|
|
|
- 3533 t := vt
|
|
|
- 3534 ELSIF (c1 = SymTab.ClLong)
|
|
|
- 3535 AND (c2 = SymTab.ClInt) THEN
|
|
|
- 3536 QbeGen.NarrowLong(q, qa);
|
|
|
- 3537 QbeGen.CopyOp(qa, q);
|
|
|
- 3538 t := vt
|
|
|
- 3539 ELSIF (c1 = SymTab.ClInt)
|
|
|
- 3540 AND (c2 = SymTab.ClReal) THEN
|
|
|
- 3541 QbeGen.ConvIR(q, qa);
|
|
|
- 3542 QbeGen.CopyOp(qa, q);
|
|
|
- 3543 t := vt
|
|
|
- 3544 ELSIF (c1 = SymTab.ClLong)
|
|
|
- 3545 AND (c2 = SymTab.ClReal) THEN
|
|
|
- 3546 QbeGen.ConvLR(q, qa);
|
|
|
+ 3447 SemError(211) END;
|
|
|
+ 3448 t := SymTab.CharType(); .)
|
|
|
+ 3449 | ( "ORD" | "ORDL" ) "(" Expr<et, q> ")"
|
|
|
+ 3450 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3451 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ORD"));
|
|
|
+ 3452 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3453 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3454 (. IF et # SymTab.InvalidType THEN
|
|
|
+ 3455 IF (SymTab.ClassOf(et) #
|
|
|
+ 3456 SymTab.ClChar)
|
|
|
+ 3457 AND (SymTab.ClassOf(et) #
|
|
|
+ 3458 SymTab.ClBool)
|
|
|
+ 3459 AND (SymTab.ClassOf(et) #
|
|
|
+ 3460 SymTab.ClEnum)
|
|
|
+ 3461 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
+ 3462 SemError(211) END
|
|
|
+ 3463 END;
|
|
|
+ 3464 t := SymTab.IntType(); .)
|
|
|
+ 3465 | "CAP" "(" Expr<et, q> ")"
|
|
|
+ 3466 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3467 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CAP"));
|
|
|
+ 3468 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3469 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3470 (. QbeGen.CapQ(q, qa);
|
|
|
+ 3471 QbeGen.CopyOp(qa, q);
|
|
|
+ 3472 t := SymTab.CharType(); .)
|
|
|
+ 3473 | "UCHR" "(" Expr<et, q> ")"
|
|
|
+ 3474 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3475 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "UCHR"));
|
|
|
+ 3476 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3477 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3478 (. (* UCHR: the UCHAR constructor.
|
|
|
+ 3479 CHAR -> UCHAR (identity);
|
|
|
+ 3480 INTEGER familly -> UCHAR
|
|
|
+ 3481 (codepoint value). *)
|
|
|
+ 3482 IF (et # SymTab.InvalidType)
|
|
|
+ 3483 AND (SymTab.ClassOf(et) # SymTab.ClChar)
|
|
|
+ 3484 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
+ 3485 SemError(211) END;
|
|
|
+ 3486 t := SymTab.UCharType(); .)
|
|
|
+ 3487 | "CHR8" "(" Expr<et, q> ")"
|
|
|
+ 3488 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3489 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "CHR8"));
|
|
|
+ 3490 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3491 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3492 (. IF (et # SymTab.InvalidType)
|
|
|
+ 3493 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
+ 3494 SemError(211) END;
|
|
|
+ 3495 QbeGen.WidenLong(q, qa);
|
|
|
+ 3496 QbeGen.CheckRange(qa, "0", "255");
|
|
|
+ 3497 t := SymTab.CharType(); .)
|
|
|
+ 3498 | "UORD" "(" Expr<et, q> ")"
|
|
|
+ 3499 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3500 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "UORD"));
|
|
|
+ 3501 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3502 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3503 (. (* UORD(u): the codepoint as a
|
|
|
+ 3504 32-bit ordinal (INTEGER),
|
|
|
+ 3505 cf. ORD for CHAR. *)
|
|
|
+ 3506 IF (et # SymTab.InvalidType)
|
|
|
+ 3507 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
+ 3508 SemError(211) END;
|
|
|
+ 3509 t := SymTab.IntType(); .)
|
|
|
+ 3510 | "ABS" "(" Expr<et, q> ")"
|
|
|
+ 3511 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3512 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "ABS"));
|
|
|
+ 3513 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 1, astCur) END;
|
|
|
+ 3514 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3515 (. IF (et # SymTab.InvalidType)
|
|
|
+ 3516 AND NOT SymTab.IsIntFamily(et)
|
|
|
+ 3517 AND (SymTab.ClassOf(et) #
|
|
|
+ 3518 SymTab.ClReal) THEN
|
|
|
+ 3519 SemError(211)
|
|
|
+ 3520 ELSE QbeGen.AbsQ(q, qa,
|
|
|
+ 3521 SymTab.ClassOf(et) =
|
|
|
+ 3522 SymTab.ClReal);
|
|
|
+ 3523 QbeGen.CopyOp(qa, q)
|
|
|
+ 3524 END;
|
|
|
+ 3525 t := et; .)
|
|
|
+ 3526 | "VAL" "(" GetIdent<vn> (. astArg2 := AST.MakeLeaf(AST.NkIdent, vn); .) "," Expr<et, q> ")"
|
|
|
+ 3527 (. astNode := AST.MakeNode(AST.NkCall);
|
|
|
+ 3528 AST.SetChild(astNode, 0, AST.MakeLeaf(AST.NkIdent, "VAL"));
|
|
|
+ 3529 IF astArg2 # AST.NoNode THEN AST.SetChild(astNode, 1, astArg2) END;
|
|
|
+ 3530 IF astCur # AST.NoNode THEN AST.SetChild(astNode, 2, astCur) END;
|
|
|
+ 3531 astCur := astNode; astIsLit := TRUE; .)
|
|
|
+ 3532 (. IF NOT SymTab.Lookup(vn) THEN
|
|
|
+ 3533 SemError(201);
|
|
|
+ 3534 t := SymTab.InvalidType
|
|
|
+ 3535 ELSE vt := SymTab.SymType(vn);
|
|
|
+ 3536 IF vt = SymTab.InvalidType THEN
|
|
|
+ 3537 t := SymTab.InvalidType
|
|
|
+ 3538 ELSIF et =
|
|
|
+ 3539 SymTab.InvalidType THEN
|
|
|
+ 3540 t := vt
|
|
|
+ 3541 ELSE
|
|
|
+ 3542 c1 := SymTab.ClassOf(et);
|
|
|
+ 3543 c2 := SymTab.ClassOf(vt);
|
|
|
+ 3544 IF (c1 = SymTab.ClInt)
|
|
|
+ 3545 AND (c2 = SymTab.ClLong) THEN
|
|
|
+ 3546 QbeGen.WidenLong(q, qa);
|
|
|
3547 QbeGen.CopyOp(qa, q);
|
|
|
3548 t := vt
|
|
|
- 3549 ELSIF (c1 = SymTab.ClReal)
|
|
|
+ 3549 ELSIF (c1 = SymTab.ClLong)
|
|
|
3550 AND (c2 = SymTab.ClInt) THEN
|
|
|
- 3551 QbeGen.ConvRI(q, qa);
|
|
|
+ 3551 QbeGen.NarrowLong(q, qa);
|
|
|
3552 QbeGen.CopyOp(qa, q);
|
|
|
3553 t := vt
|
|
|
- 3554 ELSIF (c1 = SymTab.ClReal)
|
|
|
- 3555 AND (c2 = SymTab.ClLong) THEN
|
|
|
- 3556 QbeGen.ConvRL(q, qa);
|
|
|
+ 3554 ELSIF (c1 = SymTab.ClInt)
|
|
|
+ 3555 AND (c2 = SymTab.ClReal) THEN
|
|
|
+ 3556 QbeGen.ConvIR(q, qa);
|
|
|
3557 QbeGen.CopyOp(qa, q);
|
|
|
3558 t := vt
|
|
|
- 3559 ELSIF ((c1 = SymTab.ClInt)
|
|
|
- 3560 OR (c1 =
|
|
|
- 3561 SymTab.ClChar)
|
|
|
- 3562 OR (c1 =
|
|
|
- 3563 SymTab.ClBool)
|
|
|
- 3564 OR (c1 =
|
|
|
- 3565 SymTab.ClEnum))
|
|
|
- 3566 AND ((c2 = SymTab.ClInt)
|
|
|
- 3567 OR (c2 =
|
|
|
- 3568 SymTab.ClChar)
|
|
|
- 3569 OR (c2 =
|
|
|
- 3570 SymTab.ClBool)
|
|
|
- 3571 OR (c2 =
|
|
|
- 3572 SymTab.ClEnum)) THEN
|
|
|
+ 3559 ELSIF (c1 = SymTab.ClLong)
|
|
|
+ 3560 AND (c2 = SymTab.ClReal) THEN
|
|
|
+ 3561 QbeGen.ConvLR(q, qa);
|
|
|
+ 3562 QbeGen.CopyOp(qa, q);
|
|
|
+ 3563 t := vt
|
|
|
+ 3564 ELSIF (c1 = SymTab.ClReal)
|
|
|
+ 3565 AND (c2 = SymTab.ClInt) THEN
|
|
|
+ 3566 QbeGen.ConvRI(q, qa);
|
|
|
+ 3567 QbeGen.CopyOp(qa, q);
|
|
|
+ 3568 t := vt
|
|
|
+ 3569 ELSIF (c1 = SymTab.ClReal)
|
|
|
+ 3570 AND (c2 = SymTab.ClLong) THEN
|
|
|
+ 3571 QbeGen.ConvRL(q, qa);
|
|
|
+ 3572 QbeGen.CopyOp(qa, q);
|
|
|
3573 t := vt
|
|
|
- 3574 ELSIF (c1 = SymTab.ClPtr)
|
|
|
- 3575 AND (c2 = SymTab.ClPtr) THEN
|
|
|
- 3576 t := vt
|
|
|
- 3577 ELSIF (c1 = SymTab.ClReal)
|
|
|
- 3578 AND (c2 = SymTab.ClReal) THEN
|
|
|
- 3579 t := vt
|
|
|
- 3580 ELSE SemError(230);
|
|
|
- 3581 t := SymTab.InvalidType
|
|
|
- 3582 END
|
|
|
- 3583 END
|
|
|
- 3584 END; .)
|
|
|
- 3585 | "(" Expr<et, q> ")" (. t := et; astIsLit := TRUE; .)
|
|
|
- 3586 | SetLit<st, sq> (. astIsLit := TRUE; t := st;
|
|
|
- 3587 QbeGen.CopyOp(sq, q); .)
|
|
|
- 3588 | ( "NOT" | "~" ) Fact<t2, q2> (. astNot := astCur;
|
|
|
- 3589 IF SymTab.BoolCheck(t2) THEN
|
|
|
- 3590 t := SymTab.BoolType()
|
|
|
- 3591 ELSE SemError(212);
|
|
|
- 3592 t := SymTab.InvalidType END;
|
|
|
- 3593 IF t # SymTab.InvalidType THEN
|
|
|
- 3594 QbeGen.NotQ(q2, q)
|
|
|
- 3595 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 3596 END;
|
|
|
- 3597 astIsLit := TRUE;
|
|
|
- 3598 astCur := AST.MakeUn(
|
|
|
- 3599 AST.NkUnary, AST.OpNot, astNot); .)
|
|
|
- 3600 )
|
|
|
- 3601 (. IF NOT astIsLit THEN astCur := AST.NoNode END; .) .
|
|
|
- 3602 (* Set literals are SET OF [0..255] (8 words); elements validated
|
|
|
- 3603 0..255 statically when foldable (222 otherwise), runtime trap
|
|
|
- 3604 for computed elements. Ranges always lower via SetRange. *)
|
|
|
- 3605 SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 3606 (. VAR astNode: AST.Node; .)
|
|
|
- 3607 = "{" (. t := SymTab.NewSet(
|
|
|
- 3608 SymTab.NewSubR(0, 255));
|
|
|
- 3609 astNode := AST.MakeNode(AST.NkSetLit);
|
|
|
- 3610 QbeGen.NewSetTemp(8, q);
|
|
|
- 3611 QbeGen.SetZero(q, 8); .)
|
|
|
- 3612 [ SetElem<t, q, astNode> { "," SetElem<t, q, astNode> } ]
|
|
|
- 3613 "}" (. astCur := astNode; .) .
|
|
|
- 3614 (* Typed brace constructor: TypeName{ elems } — BITSET{0} (a set)
|
|
|
- 3615 or ArrayName{...} (an array constructor, GNU Modula-2). The
|
|
|
- 3616 declared type sets the width (set) or element type (array). *)
|
|
|
- 3617 TypedBraceLit<vt: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 3618 (. VAR nw: CARDINAL;
|
|
|
- 3619 astNode: AST.Node;
|
|
|
- 3620 savedCls: INTEGER; .)
|
|
|
- 3621 = "{" (. savedCls := braceCls;
|
|
|
- 3622 astNode := AST.MakeNode(AST.NkBraceLit);
|
|
|
- 3623 IF vt = SymTab.InvalidType THEN
|
|
|
- 3624 braceCls := -1
|
|
|
- 3625 ELSE braceCls :=
|
|
|
- 3626 SymTab.ClassOf(vt)
|
|
|
- 3627 END;
|
|
|
- 3628 IF braceCls = SymTab.ClSet THEN
|
|
|
- 3629 IF vt = SymTab.InvalidType THEN
|
|
|
- 3630 nw := 8
|
|
|
- 3631 ELSE nw := SymTab.SetWords(vt);
|
|
|
- 3632 IF nw = 0 THEN nw := 8 END
|
|
|
- 3633 END;
|
|
|
- 3634 QbeGen.NewSetTemp(nw, q);
|
|
|
- 3635 QbeGen.SetZero(q, nw)
|
|
|
- 3636 ELSIF (braceCls =
|
|
|
- 3637 SymTab.ClArray)
|
|
|
- 3638 OR (braceCls =
|
|
|
- 3639 SymTab.ClRecord)
|
|
|
- 3640 OR (braceCls =
|
|
|
- 3641 SymTab.ClClass) THEN
|
|
|
- 3642 QbeGen.CtorBegin(vt)
|
|
|
- 3643 ELSE
|
|
|
- 3644 IF vt # SymTab.InvalidType THEN
|
|
|
- 3645 SemError(230) END;
|
|
|
- 3646 braceCls := -1
|
|
|
- 3647 END; .)
|
|
|
- 3648 [ BraceElem<vt, q, astNode> { "," BraceElem<vt, q, astNode> } ]
|
|
|
- 3649 "}" (. IF (braceCls = SymTab.ClArray)
|
|
|
- 3650 OR (braceCls =
|
|
|
- 3651 SymTab.ClRecord)
|
|
|
- 3652 OR (braceCls =
|
|
|
- 3653 SymTab.ClClass) THEN
|
|
|
- 3654 QbeGen.CtorEnd(q)
|
|
|
- 3655 ELSIF braceCls # SymTab.ClSet THEN
|
|
|
- 3656 QbeGen.CopyOp("0", q)
|
|
|
- 3657 END;
|
|
|
- 3658 braceCls := savedCls; .)
|
|
|
- 3659 (. astCur := astNode; .) .
|
|
|
- 3660 BraceElem<vt: SymTab.TypeIndex; VAR sq: QbeGen.QVal; node: AST.Node>
|
|
|
- 3661 (. VAR et, et2: SymTab.TypeIndex;
|
|
|
- 3662 qe, q2: QbeGen.QVal;
|
|
|
- 3663 v, v2, reps, k: INTEGER;
|
|
|
- 3664 elem: SymTab.TypeIndex;
|
|
|
- 3665 lo: INTEGER;
|
|
|
- 3666 span: CARDINAL;
|
|
|
- 3667 cl, cl2: INTEGER;
|
|
|
- 3668 hasR, hasB: BOOLEAN;
|
|
|
- 3669 astEl: AST.Node; .)
|
|
|
- 3670 = (. hasR := FALSE; hasB := FALSE; .)
|
|
|
- 3671 Expr<et, qe> (. astEl := astCur; .)
|
|
|
- 3672 [ ".." Expr<et2, q2> (. astEl := AST.MakeBin(
|
|
|
- 3673 AST.NkSubrange, 0, astEl, astCur);
|
|
|
- 3674 hasR := TRUE; .) ]
|
|
|
- 3675 [ "BY" Expr<et2, q2> (. hasB := TRUE; .) ]
|
|
|
- 3676 (. IF braceCls = SymTab.ClSet THEN
|
|
|
- 3677 IF hasB THEN SemError(230) END;
|
|
|
- 3678 lo := SymTab.SetBaseLo(vt);
|
|
|
- 3679 span := SymTab.SetCount(vt);
|
|
|
- 3680 IF (et = SymTab.InvalidType)
|
|
|
- 3681 OR (hasR AND (et2 =
|
|
|
- 3682 SymTab.InvalidType)) THEN
|
|
|
- 3683 ELSE cl :=
|
|
|
- 3684 SymTab.ClassOf(et);
|
|
|
- 3685 IF hasR THEN
|
|
|
- 3686 cl2 :=
|
|
|
- 3687 SymTab.ClassOf(et2)
|
|
|
- 3688 ELSE cl2 := SymTab.ClInt
|
|
|
- 3689 END;
|
|
|
- 3690 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
- 3691 OR (hasR AND NOT
|
|
|
- 3692 SymTab.SetElemClassOk(cl2))
|
|
|
- 3693 THEN
|
|
|
- 3694 SemError(222)
|
|
|
- 3695 ELSIF hasR
|
|
|
- 3696 AND SymTab.ConstInt(qe, v)
|
|
|
- 3697 AND SymTab.ConstInt(q2,
|
|
|
- 3698 v2)
|
|
|
- 3699 AND ((v < lo)
|
|
|
- 3700 OR (v2 < lo)
|
|
|
- 3701 OR (v >= lo +
|
|
|
- 3702 VAL(INTEGER, span))
|
|
|
- 3703 OR (v2 >= lo +
|
|
|
- 3704 VAL(INTEGER, span))
|
|
|
- 3705 OR (v > v2)) THEN
|
|
|
- 3706 SemError(222)
|
|
|
- 3707 ELSIF hasR THEN
|
|
|
- 3708 QbeGen.SetRange(sq, qe, q2,
|
|
|
- 3709 lo, span)
|
|
|
- 3710 ELSIF SymTab.ConstInt(qe,
|
|
|
- 3711 v)
|
|
|
- 3712 AND ((v < lo)
|
|
|
- 3713 OR (v >= lo +
|
|
|
- 3714 VAL(INTEGER,
|
|
|
- 3715 span))) THEN
|
|
|
- 3716 SemError(222)
|
|
|
- 3717 ELSE QbeGen.SetBit(sq, qe,
|
|
|
- 3718 lo, span)
|
|
|
- 3719 END
|
|
|
- 3720 END
|
|
|
- 3721 ELSIF (braceCls = SymTab.ClArray)
|
|
|
- 3722 OR (braceCls =
|
|
|
- 3723 SymTab.ClRecord)
|
|
|
- 3724 OR (braceCls =
|
|
|
- 3725 SymTab.ClClass) THEN
|
|
|
- 3726 IF hasR THEN SemError(230) END;
|
|
|
- 3727 reps := 1;
|
|
|
- 3728 IF hasB THEN
|
|
|
- 3729 IF SymTab.ConstInt(q2, v2)
|
|
|
- 3730 AND (v2 >= 1) THEN
|
|
|
- 3731 reps := v2
|
|
|
- 3732 ELSE SemError(230)
|
|
|
- 3733 END
|
|
|
- 3734 END;
|
|
|
- 3735 k := 0;
|
|
|
- 3736 WHILE k < reps DO
|
|
|
- 3737 QbeGen.CtorElem(qe);
|
|
|
- 3738 INC(k)
|
|
|
- 3739 END
|
|
|
- 3740 END; .)
|
|
|
- 3741 (. AST.SetChild(node,
|
|
|
- 3742 AST.NChild(node), astEl); .) .
|
|
|
- 3743 SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal; node: AST.Node> (. VAR et, et2: SymTab.TypeIndex;
|
|
|
- 3744 qe, q2: QbeGen.QVal;
|
|
|
- 3745 v, v2: INTEGER;
|
|
|
- 3746 lo: INTEGER;
|
|
|
- 3747 span: CARDINAL;
|
|
|
- 3748 cl, cl2: INTEGER;
|
|
|
- 3749 hasR: BOOLEAN;
|
|
|
- 3750 astEl: AST.Node; .)
|
|
|
- 3751 = (. hasR := FALSE; .)
|
|
|
- 3752 Expr<et, qe> (. astEl := astCur; .)
|
|
|
- 3753 [ ".." Expr<et2, q2> (. astEl := AST.MakeBin(
|
|
|
- 3754 AST.NkSubrange, 0, astEl, astCur);
|
|
|
- 3755 hasR := TRUE; .) ]
|
|
|
- 3756 (. lo := SymTab.SetBaseLo(st);
|
|
|
- 3757 span := SymTab.SetCount(st);
|
|
|
- 3758 IF (et = SymTab.InvalidType)
|
|
|
- 3759 OR (hasR AND (et2 =
|
|
|
- 3760 SymTab.InvalidType)) THEN
|
|
|
- 3761 ELSE cl :=
|
|
|
- 3762 SymTab.ClassOf(et);
|
|
|
- 3763 IF hasR THEN
|
|
|
- 3764 cl2 :=
|
|
|
- 3765 SymTab.ClassOf(et2)
|
|
|
- 3766 ELSE cl2 := SymTab.ClInt
|
|
|
- 3767 END;
|
|
|
- 3768 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
- 3769 OR (hasR AND NOT
|
|
|
- 3770 SymTab.SetElemClassOk(cl2))
|
|
|
- 3771 THEN
|
|
|
- 3772 SemError(222)
|
|
|
- 3773 ELSIF hasR
|
|
|
- 3774 AND SymTab.ConstInt(qe, v)
|
|
|
- 3775 AND SymTab.ConstInt(q2,
|
|
|
- 3776 v2)
|
|
|
- 3777 AND ((v < lo)
|
|
|
- 3778 OR (v2 < lo)
|
|
|
- 3779 OR (v >= lo +
|
|
|
- 3780 VAL(INTEGER, span))
|
|
|
- 3781 OR (v2 >= lo +
|
|
|
- 3782 VAL(INTEGER, span))
|
|
|
- 3783 OR (v > v2)) THEN
|
|
|
- 3784 SemError(222)
|
|
|
- 3785 ELSIF hasR THEN
|
|
|
- 3786 QbeGen.SetRange(sq, qe, q2,
|
|
|
- 3787 lo, span)
|
|
|
- 3788 ELSIF SymTab.ConstInt(qe,
|
|
|
- 3789 v)
|
|
|
- 3790 AND ((v < lo)
|
|
|
- 3791 OR (v >= lo +
|
|
|
- 3792 VAL(INTEGER,
|
|
|
- 3793 span))) THEN
|
|
|
- 3794 SemError(222)
|
|
|
- 3795 ELSE QbeGen.SetBit(sq, qe,
|
|
|
- 3796 lo, span)
|
|
|
- 3797 END
|
|
|
- 3798 END; .)
|
|
|
- 3799 (. AST.SetChild(node,
|
|
|
- 3800 AST.NChild(node), astEl); .) .
|
|
|
- 3801 GetIdent<VAR n: SymTab.Name>
|
|
|
- 3802 = ident (. LexName(n); .) .
|
|
|
- 3803
|
|
|
- 3804 END M2.
|
|
|
+ 3574 ELSIF ((c1 = SymTab.ClInt)
|
|
|
+ 3575 OR (c1 =
|
|
|
+ 3576 SymTab.ClChar)
|
|
|
+ 3577 OR (c1 =
|
|
|
+ 3578 SymTab.ClBool)
|
|
|
+ 3579 OR (c1 =
|
|
|
+ 3580 SymTab.ClEnum))
|
|
|
+ 3581 AND ((c2 = SymTab.ClInt)
|
|
|
+ 3582 OR (c2 =
|
|
|
+ 3583 SymTab.ClChar)
|
|
|
+ 3584 OR (c2 =
|
|
|
+ 3585 SymTab.ClBool)
|
|
|
+ 3586 OR (c2 =
|
|
|
+ 3587 SymTab.ClEnum)) THEN
|
|
|
+ 3588 t := vt
|
|
|
+ 3589 ELSIF (c1 = SymTab.ClPtr)
|
|
|
+ 3590 AND (c2 = SymTab.ClPtr) THEN
|
|
|
+ 3591 t := vt
|
|
|
+ 3592 ELSIF (c1 = SymTab.ClReal)
|
|
|
+ 3593 AND (c2 = SymTab.ClReal) THEN
|
|
|
+ 3594 t := vt
|
|
|
+ 3595 ELSE SemError(230);
|
|
|
+ 3596 t := SymTab.InvalidType
|
|
|
+ 3597 END
|
|
|
+ 3598 END
|
|
|
+ 3599 END; .)
|
|
|
+ 3600 | "(" Expr<et, q> ")" (. t := et; astIsLit := TRUE; .)
|
|
|
+ 3601 | SetLit<st, sq> (. astIsLit := TRUE; t := st;
|
|
|
+ 3602 QbeGen.CopyOp(sq, q); .)
|
|
|
+ 3603 | ( "NOT" | "~" ) Fact<t2, q2> (. astNot := astCur;
|
|
|
+ 3604 IF SymTab.BoolCheck(t2) THEN
|
|
|
+ 3605 t := SymTab.BoolType()
|
|
|
+ 3606 ELSE SemError(212);
|
|
|
+ 3607 t := SymTab.InvalidType END;
|
|
|
+ 3608 IF t # SymTab.InvalidType THEN
|
|
|
+ 3609 QbeGen.NotQ(q2, q)
|
|
|
+ 3610 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 3611 END;
|
|
|
+ 3612 astIsLit := TRUE;
|
|
|
+ 3613 astCur := AST.MakeUn(
|
|
|
+ 3614 AST.NkUnary, AST.OpNot, astNot); .)
|
|
|
+ 3615 )
|
|
|
+ 3616 (. IF NOT astIsLit THEN astCur := AST.NoNode END; .) .
|
|
|
+ 3617 (* Set literals are SET OF [0..255] (8 words); elements validated
|
|
|
+ 3618 0..255 statically when foldable (222 otherwise), runtime trap
|
|
|
+ 3619 for computed elements. Ranges always lower via SetRange. *)
|
|
|
+ 3620 SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 3621 (. VAR astNode: AST.Node; .)
|
|
|
+ 3622 = "{" (. t := SymTab.NewSet(
|
|
|
+ 3623 SymTab.NewSubR(0, 255));
|
|
|
+ 3624 astNode := AST.MakeNode(AST.NkSetLit);
|
|
|
+ 3625 QbeGen.NewSetTemp(8, q);
|
|
|
+ 3626 QbeGen.SetZero(q, 8); .)
|
|
|
+ 3627 [ SetElem<t, q, astNode> { "," SetElem<t, q, astNode> } ]
|
|
|
+ 3628 "}" (. astCur := astNode; .) .
|
|
|
+ 3629 (* Typed brace constructor: TypeName{ elems } — BITSET{0} (a set)
|
|
|
+ 3630 or ArrayName{...} (an array constructor, GNU Modula-2). The
|
|
|
+ 3631 declared type sets the width (set) or element type (array). *)
|
|
|
+ 3632 TypedBraceLit<vt: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 3633 (. VAR nw: CARDINAL;
|
|
|
+ 3634 astNode: AST.Node;
|
|
|
+ 3635 savedCls: INTEGER; .)
|
|
|
+ 3636 = "{" (. savedCls := braceCls;
|
|
|
+ 3637 astNode := AST.MakeNode(AST.NkBraceLit);
|
|
|
+ 3638 IF vt = SymTab.InvalidType THEN
|
|
|
+ 3639 braceCls := -1
|
|
|
+ 3640 ELSE braceCls :=
|
|
|
+ 3641 SymTab.ClassOf(vt)
|
|
|
+ 3642 END;
|
|
|
+ 3643 IF braceCls = SymTab.ClSet THEN
|
|
|
+ 3644 IF vt = SymTab.InvalidType THEN
|
|
|
+ 3645 nw := 8
|
|
|
+ 3646 ELSE nw := SymTab.SetWords(vt);
|
|
|
+ 3647 IF nw = 0 THEN nw := 8 END
|
|
|
+ 3648 END;
|
|
|
+ 3649 QbeGen.NewSetTemp(nw, q);
|
|
|
+ 3650 QbeGen.SetZero(q, nw)
|
|
|
+ 3651 ELSIF (braceCls =
|
|
|
+ 3652 SymTab.ClArray)
|
|
|
+ 3653 OR (braceCls =
|
|
|
+ 3654 SymTab.ClRecord)
|
|
|
+ 3655 OR (braceCls =
|
|
|
+ 3656 SymTab.ClClass) THEN
|
|
|
+ 3657 QbeGen.CtorBegin(vt)
|
|
|
+ 3658 ELSE
|
|
|
+ 3659 IF vt # SymTab.InvalidType THEN
|
|
|
+ 3660 SemError(230) END;
|
|
|
+ 3661 braceCls := -1
|
|
|
+ 3662 END; .)
|
|
|
+ 3663 [ BraceElem<vt, q, astNode> { "," BraceElem<vt, q, astNode> } ]
|
|
|
+ 3664 "}" (. IF (braceCls = SymTab.ClArray)
|
|
|
+ 3665 OR (braceCls =
|
|
|
+ 3666 SymTab.ClRecord)
|
|
|
+ 3667 OR (braceCls =
|
|
|
+ 3668 SymTab.ClClass) THEN
|
|
|
+ 3669 QbeGen.CtorEnd(q)
|
|
|
+ 3670 ELSIF braceCls # SymTab.ClSet THEN
|
|
|
+ 3671 QbeGen.CopyOp("0", q)
|
|
|
+ 3672 END;
|
|
|
+ 3673 braceCls := savedCls; .)
|
|
|
+ 3674 (. astCur := astNode; .) .
|
|
|
+ 3675 BraceElem<vt: SymTab.TypeIndex; VAR sq: QbeGen.QVal; node: AST.Node>
|
|
|
+ 3676 (. VAR et, et2: SymTab.TypeIndex;
|
|
|
+ 3677 qe, q2: QbeGen.QVal;
|
|
|
+ 3678 v, v2, reps, k: INTEGER;
|
|
|
+ 3679 elem: SymTab.TypeIndex;
|
|
|
+ 3680 lo: INTEGER;
|
|
|
+ 3681 span: CARDINAL;
|
|
|
+ 3682 cl, cl2: INTEGER;
|
|
|
+ 3683 hasR, hasB: BOOLEAN;
|
|
|
+ 3684 astEl: AST.Node; .)
|
|
|
+ 3685 = (. hasR := FALSE; hasB := FALSE; .)
|
|
|
+ 3686 Expr<et, qe> (. astEl := astCur; .)
|
|
|
+ 3687 [ ".." Expr<et2, q2> (. astEl := AST.MakeBin(
|
|
|
+ 3688 AST.NkSubrange, 0, astEl, astCur);
|
|
|
+ 3689 hasR := TRUE; .) ]
|
|
|
+ 3690 [ "BY" Expr<et2, q2> (. hasB := TRUE; .) ]
|
|
|
+ 3691 (. IF braceCls = SymTab.ClSet THEN
|
|
|
+ 3692 IF hasB THEN SemError(230) END;
|
|
|
+ 3693 lo := SymTab.SetBaseLo(vt);
|
|
|
+ 3694 span := SymTab.SetCount(vt);
|
|
|
+ 3695 IF (et = SymTab.InvalidType)
|
|
|
+ 3696 OR (hasR AND (et2 =
|
|
|
+ 3697 SymTab.InvalidType)) THEN
|
|
|
+ 3698 ELSE cl :=
|
|
|
+ 3699 SymTab.ClassOf(et);
|
|
|
+ 3700 IF hasR THEN
|
|
|
+ 3701 cl2 :=
|
|
|
+ 3702 SymTab.ClassOf(et2)
|
|
|
+ 3703 ELSE cl2 := SymTab.ClInt
|
|
|
+ 3704 END;
|
|
|
+ 3705 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
+ 3706 OR (hasR AND NOT
|
|
|
+ 3707 SymTab.SetElemClassOk(cl2))
|
|
|
+ 3708 THEN
|
|
|
+ 3709 SemError(222)
|
|
|
+ 3710 ELSIF hasR
|
|
|
+ 3711 AND SymTab.ConstInt(qe, v)
|
|
|
+ 3712 AND SymTab.ConstInt(q2,
|
|
|
+ 3713 v2)
|
|
|
+ 3714 AND ((v < lo)
|
|
|
+ 3715 OR (v2 < lo)
|
|
|
+ 3716 OR (v >= lo +
|
|
|
+ 3717 VAL(INTEGER, span))
|
|
|
+ 3718 OR (v2 >= lo +
|
|
|
+ 3719 VAL(INTEGER, span))
|
|
|
+ 3720 OR (v > v2)) THEN
|
|
|
+ 3721 SemError(222)
|
|
|
+ 3722 ELSIF hasR THEN
|
|
|
+ 3723 QbeGen.SetRange(sq, qe, q2,
|
|
|
+ 3724 lo, span)
|
|
|
+ 3725 ELSIF SymTab.ConstInt(qe,
|
|
|
+ 3726 v)
|
|
|
+ 3727 AND ((v < lo)
|
|
|
+ 3728 OR (v >= lo +
|
|
|
+ 3729 VAL(INTEGER,
|
|
|
+ 3730 span))) THEN
|
|
|
+ 3731 SemError(222)
|
|
|
+ 3732 ELSE QbeGen.SetBit(sq, qe,
|
|
|
+ 3733 lo, span)
|
|
|
+ 3734 END
|
|
|
+ 3735 END
|
|
|
+ 3736 ELSIF (braceCls = SymTab.ClArray)
|
|
|
+ 3737 OR (braceCls =
|
|
|
+ 3738 SymTab.ClRecord)
|
|
|
+ 3739 OR (braceCls =
|
|
|
+ 3740 SymTab.ClClass) THEN
|
|
|
+ 3741 IF hasR THEN SemError(230) END;
|
|
|
+ 3742 reps := 1;
|
|
|
+ 3743 IF hasB THEN
|
|
|
+ 3744 IF SymTab.ConstInt(q2, v2)
|
|
|
+ 3745 AND (v2 >= 1) THEN
|
|
|
+ 3746 reps := v2
|
|
|
+ 3747 ELSE SemError(230)
|
|
|
+ 3748 END
|
|
|
+ 3749 END;
|
|
|
+ 3750 k := 0;
|
|
|
+ 3751 WHILE k < reps DO
|
|
|
+ 3752 QbeGen.CtorElem(qe);
|
|
|
+ 3753 INC(k)
|
|
|
+ 3754 END
|
|
|
+ 3755 END; .)
|
|
|
+ 3756 (. AST.SetChild(node,
|
|
|
+ 3757 AST.NChild(node), astEl); .) .
|
|
|
+ 3758 SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal; node: AST.Node> (. VAR et, et2: SymTab.TypeIndex;
|
|
|
+ 3759 qe, q2: QbeGen.QVal;
|
|
|
+ 3760 v, v2: INTEGER;
|
|
|
+ 3761 lo: INTEGER;
|
|
|
+ 3762 span: CARDINAL;
|
|
|
+ 3763 cl, cl2: INTEGER;
|
|
|
+ 3764 hasR: BOOLEAN;
|
|
|
+ 3765 astEl: AST.Node; .)
|
|
|
+ 3766 = (. hasR := FALSE; .)
|
|
|
+ 3767 Expr<et, qe> (. astEl := astCur; .)
|
|
|
+ 3768 [ ".." Expr<et2, q2> (. astEl := AST.MakeBin(
|
|
|
+ 3769 AST.NkSubrange, 0, astEl, astCur);
|
|
|
+ 3770 hasR := TRUE; .) ]
|
|
|
+ 3771 (. lo := SymTab.SetBaseLo(st);
|
|
|
+ 3772 span := SymTab.SetCount(st);
|
|
|
+ 3773 IF (et = SymTab.InvalidType)
|
|
|
+ 3774 OR (hasR AND (et2 =
|
|
|
+ 3775 SymTab.InvalidType)) THEN
|
|
|
+ 3776 ELSE cl :=
|
|
|
+ 3777 SymTab.ClassOf(et);
|
|
|
+ 3778 IF hasR THEN
|
|
|
+ 3779 cl2 :=
|
|
|
+ 3780 SymTab.ClassOf(et2)
|
|
|
+ 3781 ELSE cl2 := SymTab.ClInt
|
|
|
+ 3782 END;
|
|
|
+ 3783 IF NOT SymTab.SetElemClassOk(cl)
|
|
|
+ 3784 OR (hasR AND NOT
|
|
|
+ 3785 SymTab.SetElemClassOk(cl2))
|
|
|
+ 3786 THEN
|
|
|
+ 3787 SemError(222)
|
|
|
+ 3788 ELSIF hasR
|
|
|
+ 3789 AND SymTab.ConstInt(qe, v)
|
|
|
+ 3790 AND SymTab.ConstInt(q2,
|
|
|
+ 3791 v2)
|
|
|
+ 3792 AND ((v < lo)
|
|
|
+ 3793 OR (v2 < lo)
|
|
|
+ 3794 OR (v >= lo +
|
|
|
+ 3795 VAL(INTEGER, span))
|
|
|
+ 3796 OR (v2 >= lo +
|
|
|
+ 3797 VAL(INTEGER, span))
|
|
|
+ 3798 OR (v > v2)) THEN
|
|
|
+ 3799 SemError(222)
|
|
|
+ 3800 ELSIF hasR THEN
|
|
|
+ 3801 QbeGen.SetRange(sq, qe, q2,
|
|
|
+ 3802 lo, span)
|
|
|
+ 3803 ELSIF SymTab.ConstInt(qe,
|
|
|
+ 3804 v)
|
|
|
+ 3805 AND ((v < lo)
|
|
|
+ 3806 OR (v >= lo +
|
|
|
+ 3807 VAL(INTEGER,
|
|
|
+ 3808 span))) THEN
|
|
|
+ 3809 SemError(222)
|
|
|
+ 3810 ELSE QbeGen.SetBit(sq, qe,
|
|
|
+ 3811 lo, span)
|
|
|
+ 3812 END
|
|
|
+ 3813 END; .)
|
|
|
+ 3814 (. AST.SetChild(node,
|
|
|
+ 3815 AST.NChild(node), astEl); .) .
|
|
|
+ 3816 GetIdent<VAR n: SymTab.Name>
|
|
|
+ 3817 = ident (. LexName(n); .) .
|
|
|
+ 3818
|
|
|
+ 3819 END M2.
|
|
|
|
|
|
0 errors
|
|
|
|