|
|
@@ -975,1493 +975,1505 @@ Listing:
|
|
|
958 OR (dk = SymTab.KindField) THEN
|
|
|
959 IF SymTab.ClassOf(dt) =
|
|
|
960 SymTab.ClArray THEN
|
|
|
- 961 IF SymTab.StrCompat(dt,
|
|
|
- 962 et) THEN
|
|
|
- 963 QbeGen.StrAssign(qd,
|
|
|
- 964 qe)
|
|
|
- 965 ELSE
|
|
|
- 966 QbeGen.CopyArray(qd,
|
|
|
- 967 qe, dt)
|
|
|
- 968 END
|
|
|
- 969 ELSIF SymTab.ClassOf(dt) =
|
|
|
- 970 SymTab.ClSet THEN
|
|
|
- 971 QbeGen.CopySet(qd, qe,
|
|
|
- 972 SymTab.SetWords(dt),
|
|
|
- 973 SymTab.SetWords(et))
|
|
|
- 974 ELSIF SymTab.ClassOf(dt) =
|
|
|
- 975 SymTab.ClRecord THEN
|
|
|
- 976 QbeGen.CopyRecord(qd, qe,
|
|
|
- 977 dt)
|
|
|
- 978 ELSIF SymTab.IsLongFamily(dt) THEN
|
|
|
- 979 IF wconv THEN
|
|
|
- 980 QbeGen.WidenLong(qe, ql);
|
|
|
- 981 QbeGen.ElemStore(qd, ql,
|
|
|
- 982 dt)
|
|
|
- 983 ELSE QbeGen.ElemStore(qd, qe,
|
|
|
- 984 dt)
|
|
|
- 985 END
|
|
|
- 986 ELSIF conv THEN
|
|
|
- 987 QbeGen.ConvIR(qe, qt);
|
|
|
- 988 QbeGen.ElemStore(qd, qt,
|
|
|
- 989 dt)
|
|
|
- 990 ELSE QbeGen.ElemStore(qd, qe,
|
|
|
- 991 dt)
|
|
|
- 992 END
|
|
|
- 993 ELSIF SymTab.ClassOf(dt) =
|
|
|
- 994 SymTab.ClArray THEN
|
|
|
- 995 IF SymTab.StrCompat(dt,
|
|
|
- 996 et) THEN
|
|
|
- 997 QbeGen.StrAssign(qd, qe)
|
|
|
- 998 ELSE
|
|
|
- 999 QbeGen.CopyArray(qd, qe,
|
|
|
- 1000 dt)
|
|
|
- 1001 END
|
|
|
- 1002 ELSIF SymTab.ClassOf(dt) =
|
|
|
- 1003 SymTab.ClSet THEN
|
|
|
- 1004 QbeGen.CopySet(qd, qe,
|
|
|
- 1005 SymTab.SetWords(dt),
|
|
|
- 1006 SymTab.SetWords(et))
|
|
|
- 1007 ELSIF SymTab.ClassOf(dt) =
|
|
|
- 1008 SymTab.ClRecord THEN
|
|
|
- 1009 QbeGen.CopyRecord(qd, qe, dt)
|
|
|
- 1010 ELSIF (SymTab.ClassOf(dt) =
|
|
|
- 1011 SymTab.ClPtr)
|
|
|
- 1012 OR (SymTab.ClassOf(dt) =
|
|
|
- 1013 SymTab.ClProc) THEN
|
|
|
- 1014 QbeGen.StorePtr(qn, qe)
|
|
|
- 1015 ELSIF SymTab.IsLongFamily(dt) THEN
|
|
|
- 1016 IF wconv THEN
|
|
|
- 1017 QbeGen.WidenLong(qe, ql);
|
|
|
- 1018 QbeGen.StoreLong(qn, ql)
|
|
|
- 1019 ELSE QbeGen.StoreLong(qn, qe)
|
|
|
- 1020 END
|
|
|
- 1021 ELSIF conv THEN
|
|
|
- 1022 QbeGen.ConvIR(qe, qt);
|
|
|
- 1023 QbeGen.StoreVar(qn, qt, TRUE)
|
|
|
- 1024 ELSE
|
|
|
- 1025 QbeGen.StoreVar(qn, qe, isR)
|
|
|
- 1026 END
|
|
|
- 1027 END; .)
|
|
|
- 1028 | ArgList<qn, dt, qd, FALSE, ct2, q2, called>
|
|
|
- 1029 | (* bare `P;`: proper parameterless
|
|
|
- 1030 procedure call; anything else
|
|
|
- 1031 here is 233 (was a bare syntax
|
|
|
- 1032 error before 4.2) *)
|
|
|
- 1033 (. IF (dk = SymTab.KindProc)
|
|
|
- 1034 AND NOT sfx THEN
|
|
|
- 1035 res0 := SymTab.ProcRes(qn);
|
|
|
- 1036 IF res0 #
|
|
|
- 1037 SymTab.InvalidType THEN
|
|
|
- 1038 SemError(233)
|
|
|
- 1039 ELSIF SymTab.ProcNPar(qn) #
|
|
|
- 1040 0 THEN
|
|
|
- 1041 SemError(233)
|
|
|
- 1042 ELSE QbeGen.Mangled(qn,
|
|
|
- 1043 SymTab.ProcUid(qn), mg0);
|
|
|
- 1044 QbeGen.CallBegin(mg0,
|
|
|
- 1045 res0,
|
|
|
- 1046 SymTab.ProcDepthOf(qn),
|
|
|
- 1047 SymTab.IsExternal(qn));
|
|
|
- 1048 QbeGen.CallEnd(FALSE, q2)
|
|
|
- 1049 END
|
|
|
- 1050 ELSE SemError(233)
|
|
|
- 1051 END; .) ) .
|
|
|
- 1052 (* Actual-parameter list shared by statement and expression calls.
|
|
|
- 1053 want selects CallEnd's result handling; t/q carry the call
|
|
|
- 1054 value (statement calls discard). Arity/type failures are 233;
|
|
|
- 1055 evaluation code still emits so the .ssa stays assembleable. *)
|
|
|
- 1056 ArgList<pn: SymTab.Name; pt: SymTab.TypeIndex; callee: QbeGen.QVal;
|
|
|
- 1057 want: BOOLEAN;
|
|
|
- 1058 VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal;
|
|
|
- 1059 VAR called: BOOLEAN> (. VAR i: CARDINAL;
|
|
|
- 1060 res: SymTab.TypeIndex;
|
|
|
- 1061 mg: QbeGen.QVal;
|
|
|
- 1062 ok, ind: BOOLEAN; .)
|
|
|
- 1063 = "(" (. called := TRUE;
|
|
|
- 1064 ok := TRUE;
|
|
|
- 1065 ind := FALSE;
|
|
|
- 1066 IF SymTab.SymKind(pn) =
|
|
|
- 1067 SymTab.KindProc THEN
|
|
|
- 1068 res := SymTab.ProcRes(pn);
|
|
|
- 1069 QbeGen.Mangled(pn,
|
|
|
- 1070 SymTab.ProcUid(pn), mg);
|
|
|
- 1071 QbeGen.CallBegin(mg, res,
|
|
|
- 1072 SymTab.ProcDepthOf(pn),
|
|
|
- 1073 SymTab.IsExternal(pn))
|
|
|
- 1074 ELSIF (pt # SymTab.InvalidType)
|
|
|
- 1075 AND (SymTab.ClassOf(pt) = SymTab.ClProc) THEN
|
|
|
- 1076 ind := TRUE;
|
|
|
- 1077 res :=
|
|
|
- 1078 SymTab.ProcTypeRes(pt);
|
|
|
- 1079 QbeGen.CallBeginInd(callee,
|
|
|
- 1080 res, FALSE)
|
|
|
- 1081 ELSE SemError(233);
|
|
|
- 1082 ok := FALSE;
|
|
|
- 1083 res := SymTab.InvalidType
|
|
|
- 1084 END;
|
|
|
- 1085 i := 0; .)
|
|
|
- 1086 [ ActParam<pn, pt, ind, i> (. INC(i); .)
|
|
|
- 1087 { "," ActParam<pn, pt, ind, i> (. INC(i); .) } ]
|
|
|
- 1088 ")" (. IF ok THEN
|
|
|
- 1089 IF ind THEN
|
|
|
- 1090 IF i #
|
|
|
- 1091 SymTab.ProcTypeNPar(pt) THEN
|
|
|
- 1092 SemError(233); ok := FALSE
|
|
|
- 1093 END
|
|
|
- 1094 ELSIF i #
|
|
|
- 1095 SymTab.ProcNPar(pn) THEN
|
|
|
- 1096 SemError(233); ok := FALSE
|
|
|
- 1097 END
|
|
|
- 1098 END;
|
|
|
- 1099 IF NOT ok THEN
|
|
|
- 1100 t := SymTab.InvalidType;
|
|
|
- 1101 QbeGen.CopyOp("0", q)
|
|
|
- 1102 ELSIF want THEN
|
|
|
- 1103 IF res =
|
|
|
- 1104 SymTab.InvalidType THEN
|
|
|
- 1105 SemError(233);
|
|
|
- 1106 t := SymTab.InvalidType;
|
|
|
- 1107 QbeGen.CopyOp("0", q)
|
|
|
- 1108 ELSE t := res;
|
|
|
- 1109 QbeGen.CallEnd(TRUE, q)
|
|
|
- 1110 END
|
|
|
- 1111 ELSE
|
|
|
- 1112 IF res #
|
|
|
- 1113 SymTab.InvalidType THEN
|
|
|
- 1114 SemError(233)
|
|
|
- 1115 END;
|
|
|
- 1116 t := SymTab.InvalidType;
|
|
|
- 1117 QbeGen.CopyOp("0", q);
|
|
|
- 1118 QbeGen.CallEnd(FALSE, q)
|
|
|
- 1119 END; .) .
|
|
|
- 1120 (* One actual: VAR formals take recorded designator addresses
|
|
|
- 1121 (233 otherwise); value formals take converted expressions. *)
|
|
|
- 1122 ActParam<pn: SymTab.Name; pt: SymTab.TypeIndex; ind: BOOLEAN;
|
|
|
- 1123 i: CARDINAL> (. VAR at, ft: SymTab.TypeIndex;
|
|
|
- 1124 qe, qa, qt: QbeGen.QVal;
|
|
|
- 1125 isV, conv: BOOLEAN; .)
|
|
|
- 1126 = Expr<at, qe> (. IF ind THEN
|
|
|
- 1127 ft :=
|
|
|
- 1128 SymTab.ProcTypeParamType(pt,
|
|
|
- 1129 i);
|
|
|
- 1130 isV :=
|
|
|
- 1131 SymTab.ProcTypeParamIsVar(pt,
|
|
|
- 1132 i)
|
|
|
- 1133 ELSE
|
|
|
- 1134 ft := SymTab.ParamType(pn, i);
|
|
|
- 1135 isV := SymTab.ParamIsVar(pn, i)
|
|
|
- 1136 END;
|
|
|
- 1137 IF (at = SymTab.InvalidType)
|
|
|
- 1138 OR (ft =
|
|
|
- 1139 SymTab.InvalidType) THEN
|
|
|
- 1140 ELSIF isV THEN
|
|
|
- 1141 IF (SymTab.ClassOf(at)
|
|
|
- 1142 = SymTab.ClChar)
|
|
|
- 1143 AND (SymTab.ClassOf(ft) = SymTab.ClArray)
|
|
|
- 1144 AND (SymTab.ClassOf(SymTab.ArrayElem(ft))
|
|
|
- 1145 = SymTab.ClChar)
|
|
|
- 1146 AND QbeGen.IsImm(qe) THEN
|
|
|
- 1147 (* 1-char string
|
|
|
- 1148 literal passed to
|
|
|
- 1149 a VAR ARRAY OF CHAR *)
|
|
|
- 1150 QbeGen.DeclCharStr(qe,
|
|
|
- 1151 qa);
|
|
|
- 1152 IF NOT QbeGen.CallArg(qa,
|
|
|
- 1153 "l") THEN
|
|
|
- 1154 SemError(233)
|
|
|
- 1155 END
|
|
|
- 1156 ELSIF NOT QbeGen.AddrOfVal(qe,
|
|
|
- 1157 qa) THEN
|
|
|
- 1158 SemError(233)
|
|
|
- 1159 ELSIF NOT SymTab.VarParamOk(at,
|
|
|
- 1160 ft) THEN
|
|
|
- 1161 SemError(233)
|
|
|
- 1162 ELSIF NOT QbeGen.CallArg(qa,
|
|
|
- 1163 "l") THEN
|
|
|
- 1164 SemError(233)
|
|
|
- 1165 END
|
|
|
- 1166 ELSE
|
|
|
- 1167 IF (SymTab.ClassOf(at)
|
|
|
- 1168 = SymTab.ClChar)
|
|
|
- 1169 AND (SymTab.ClassOf(ft) = SymTab.ClArray)
|
|
|
- 1170 AND (SymTab.ClassOf(SymTab.ArrayElem(ft))
|
|
|
- 1171 = SymTab.ClChar)
|
|
|
- 1172 AND QbeGen.IsImm(qe) THEN
|
|
|
- 1173 (* 1-char string
|
|
|
- 1174 literal passed to
|
|
|
- 1175 ARRAY OF CHAR *)
|
|
|
- 1176 QbeGen.DeclCharStr(qe,
|
|
|
- 1177 qa);
|
|
|
- 1178 IF NOT QbeGen.CallArg(qa,
|
|
|
- 1179 "l") THEN
|
|
|
- 1180 SemError(233)
|
|
|
- 1181 END
|
|
|
- 1182 ELSIF NOT SymTab.Assignable(at,
|
|
|
- 1183 ft) THEN
|
|
|
- 1184 SemError(233)
|
|
|
- 1185 ELSE
|
|
|
- 1186 conv := (SymTab.ClassOf(
|
|
|
- 1187 ft) = SymTab.ClReal)
|
|
|
- 1188 AND SymTab.IsIntFamily(at);
|
|
|
- 1189 IF conv THEN
|
|
|
- 1190 QbeGen.ConvIR(qe, qt);
|
|
|
- 1191 IF NOT QbeGen.CallArg(qt,
|
|
|
- 1192 "d") THEN
|
|
|
- 1193 SemError(233)
|
|
|
- 1194 END
|
|
|
- 1195 ELSIF NOT QbeGen.CallArg(qe,
|
|
|
- 1196 QbeGen.ArgClass(ft)) THEN
|
|
|
- 1197 SemError(233)
|
|
|
- 1198 END
|
|
|
- 1199 END
|
|
|
- 1200 END; .) .
|
|
|
- 1201 IfStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 1202 q, lThen, lElse, lEnd:
|
|
|
- 1203 QbeGen.QVal;
|
|
|
- 1204 hasElse: BOOLEAN; .)
|
|
|
- 1205 = "IF" (. hasElse := FALSE; .)
|
|
|
- 1206 Expr<t, q> (. IF NOT SymTab.BoolCheck(t) THEN
|
|
|
- 1207 SemError(214) END;
|
|
|
- 1208 QbeGen.NewLabel(lThen);
|
|
|
- 1209 QbeGen.NewLabel(lElse);
|
|
|
- 1210 QbeGen.NewLabel(lEnd);
|
|
|
- 1211 QbeGen.Jnz(q, lThen, lElse);
|
|
|
- 1212 QbeGen.EmitLabel(lThen); .)
|
|
|
- 1213 "THEN" [ StatSeq ] (. QbeGen.Jmp(lEnd); .)
|
|
|
- 1214 { "ELSIF" (. QbeGen.EmitLabel(lElse);
|
|
|
- 1215 QbeGen.NewLabel(lElse); .)
|
|
|
- 1216 Expr<t, q> (. IF NOT SymTab.BoolCheck(t) THEN
|
|
|
- 1217 SemError(214) END;
|
|
|
- 1218 QbeGen.NewLabel(lThen);
|
|
|
+ 961 IF (et # SymTab.InvalidType)
|
|
|
+ 962 AND (SymTab.ClassOf(et) = SymTab.ClUStr)
|
|
|
+ 963 AND SymTab.IsUCharArray(dt) THEN
|
|
|
+ 964 QbeGen.UAssign(qd, qe)
|
|
|
+ 965 ELSIF SymTab.StrCompat(dt,
|
|
|
+ 966 et) THEN
|
|
|
+ 967 QbeGen.StrAssign(qd,
|
|
|
+ 968 qe)
|
|
|
+ 969 ELSE
|
|
|
+ 970 QbeGen.CopyArray(qd,
|
|
|
+ 971 qe, dt)
|
|
|
+ 972 END
|
|
|
+ 973 ELSIF SymTab.ClassOf(dt) =
|
|
|
+ 974 SymTab.ClSet THEN
|
|
|
+ 975 QbeGen.CopySet(qd, qe,
|
|
|
+ 976 SymTab.SetWords(dt),
|
|
|
+ 977 SymTab.SetWords(et))
|
|
|
+ 978 ELSIF SymTab.ClassOf(dt) =
|
|
|
+ 979 SymTab.ClRecord THEN
|
|
|
+ 980 QbeGen.CopyRecord(qd, qe,
|
|
|
+ 981 dt)
|
|
|
+ 982 ELSIF SymTab.IsLongFamily(dt) THEN
|
|
|
+ 983 IF wconv THEN
|
|
|
+ 984 QbeGen.WidenLong(qe, ql);
|
|
|
+ 985 QbeGen.ElemStore(qd, ql,
|
|
|
+ 986 dt)
|
|
|
+ 987 ELSE QbeGen.ElemStore(qd, qe,
|
|
|
+ 988 dt)
|
|
|
+ 989 END
|
|
|
+ 990 ELSIF conv THEN
|
|
|
+ 991 QbeGen.ConvIR(qe, qt);
|
|
|
+ 992 QbeGen.ElemStore(qd, qt,
|
|
|
+ 993 dt)
|
|
|
+ 994 ELSE QbeGen.ElemStore(qd, qe,
|
|
|
+ 995 dt)
|
|
|
+ 996 END
|
|
|
+ 997 ELSIF SymTab.ClassOf(dt) =
|
|
|
+ 998 SymTab.ClArray THEN
|
|
|
+ 999 IF (et # SymTab.InvalidType)
|
|
|
+ 1000 AND (SymTab.ClassOf(et) = SymTab.ClUStr)
|
|
|
+ 1001 AND SymTab.IsUCharArray(dt) THEN
|
|
|
+ 1002 QbeGen.UAssign(qd, qe)
|
|
|
+ 1003 ELSIF SymTab.StrCompat(dt,
|
|
|
+ 1004 et) THEN
|
|
|
+ 1005 QbeGen.StrAssign(qd, qe)
|
|
|
+ 1006 ELSE
|
|
|
+ 1007 QbeGen.CopyArray(qd, qe,
|
|
|
+ 1008 dt)
|
|
|
+ 1009 END
|
|
|
+ 1010 ELSIF SymTab.ClassOf(dt) =
|
|
|
+ 1011 SymTab.ClSet THEN
|
|
|
+ 1012 QbeGen.CopySet(qd, qe,
|
|
|
+ 1013 SymTab.SetWords(dt),
|
|
|
+ 1014 SymTab.SetWords(et))
|
|
|
+ 1015 ELSIF SymTab.ClassOf(dt) =
|
|
|
+ 1016 SymTab.ClRecord THEN
|
|
|
+ 1017 QbeGen.CopyRecord(qd, qe, dt)
|
|
|
+ 1018 ELSIF (SymTab.ClassOf(dt) =
|
|
|
+ 1019 SymTab.ClPtr)
|
|
|
+ 1020 OR (SymTab.ClassOf(dt) =
|
|
|
+ 1021 SymTab.ClProc) THEN
|
|
|
+ 1022 QbeGen.StorePtr(qn, qe)
|
|
|
+ 1023 ELSIF SymTab.IsLongFamily(dt) THEN
|
|
|
+ 1024 IF wconv THEN
|
|
|
+ 1025 QbeGen.WidenLong(qe, ql);
|
|
|
+ 1026 QbeGen.StoreLong(qn, ql)
|
|
|
+ 1027 ELSE QbeGen.StoreLong(qn, qe)
|
|
|
+ 1028 END
|
|
|
+ 1029 ELSIF conv THEN
|
|
|
+ 1030 QbeGen.ConvIR(qe, qt);
|
|
|
+ 1031 QbeGen.StoreVar(qn, qt, TRUE)
|
|
|
+ 1032 ELSE
|
|
|
+ 1033 QbeGen.StoreVar(qn, qe, isR)
|
|
|
+ 1034 END
|
|
|
+ 1035 END; .)
|
|
|
+ 1036 | ArgList<qn, dt, qd, FALSE, ct2, q2, called>
|
|
|
+ 1037 | (* bare `P;`: proper parameterless
|
|
|
+ 1038 procedure call; anything else
|
|
|
+ 1039 here is 233 (was a bare syntax
|
|
|
+ 1040 error before 4.2) *)
|
|
|
+ 1041 (. IF (dk = SymTab.KindProc)
|
|
|
+ 1042 AND NOT sfx THEN
|
|
|
+ 1043 res0 := SymTab.ProcRes(qn);
|
|
|
+ 1044 IF res0 #
|
|
|
+ 1045 SymTab.InvalidType THEN
|
|
|
+ 1046 SemError(233)
|
|
|
+ 1047 ELSIF SymTab.ProcNPar(qn) #
|
|
|
+ 1048 0 THEN
|
|
|
+ 1049 SemError(233)
|
|
|
+ 1050 ELSE QbeGen.Mangled(qn,
|
|
|
+ 1051 SymTab.ProcUid(qn), mg0);
|
|
|
+ 1052 QbeGen.CallBegin(mg0,
|
|
|
+ 1053 res0,
|
|
|
+ 1054 SymTab.ProcDepthOf(qn),
|
|
|
+ 1055 SymTab.IsExternal(qn));
|
|
|
+ 1056 QbeGen.CallEnd(FALSE, q2)
|
|
|
+ 1057 END
|
|
|
+ 1058 ELSE SemError(233)
|
|
|
+ 1059 END; .) ) .
|
|
|
+ 1060 (* Actual-parameter list shared by statement and expression calls.
|
|
|
+ 1061 want selects CallEnd's result handling; t/q carry the call
|
|
|
+ 1062 value (statement calls discard). Arity/type failures are 233;
|
|
|
+ 1063 evaluation code still emits so the .ssa stays assembleable. *)
|
|
|
+ 1064 ArgList<pn: SymTab.Name; pt: SymTab.TypeIndex; callee: QbeGen.QVal;
|
|
|
+ 1065 want: BOOLEAN;
|
|
|
+ 1066 VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal;
|
|
|
+ 1067 VAR called: BOOLEAN> (. VAR i: CARDINAL;
|
|
|
+ 1068 res: SymTab.TypeIndex;
|
|
|
+ 1069 mg: QbeGen.QVal;
|
|
|
+ 1070 ok, ind: BOOLEAN; .)
|
|
|
+ 1071 = "(" (. called := TRUE;
|
|
|
+ 1072 ok := TRUE;
|
|
|
+ 1073 ind := FALSE;
|
|
|
+ 1074 IF SymTab.SymKind(pn) =
|
|
|
+ 1075 SymTab.KindProc THEN
|
|
|
+ 1076 res := SymTab.ProcRes(pn);
|
|
|
+ 1077 QbeGen.Mangled(pn,
|
|
|
+ 1078 SymTab.ProcUid(pn), mg);
|
|
|
+ 1079 QbeGen.CallBegin(mg, res,
|
|
|
+ 1080 SymTab.ProcDepthOf(pn),
|
|
|
+ 1081 SymTab.IsExternal(pn))
|
|
|
+ 1082 ELSIF (pt # SymTab.InvalidType)
|
|
|
+ 1083 AND (SymTab.ClassOf(pt) = SymTab.ClProc) THEN
|
|
|
+ 1084 ind := TRUE;
|
|
|
+ 1085 res :=
|
|
|
+ 1086 SymTab.ProcTypeRes(pt);
|
|
|
+ 1087 QbeGen.CallBeginInd(callee,
|
|
|
+ 1088 res, FALSE)
|
|
|
+ 1089 ELSE SemError(233);
|
|
|
+ 1090 ok := FALSE;
|
|
|
+ 1091 res := SymTab.InvalidType
|
|
|
+ 1092 END;
|
|
|
+ 1093 i := 0; .)
|
|
|
+ 1094 [ ActParam<pn, pt, ind, i> (. INC(i); .)
|
|
|
+ 1095 { "," ActParam<pn, pt, ind, i> (. INC(i); .) } ]
|
|
|
+ 1096 ")" (. IF ok THEN
|
|
|
+ 1097 IF ind THEN
|
|
|
+ 1098 IF i #
|
|
|
+ 1099 SymTab.ProcTypeNPar(pt) THEN
|
|
|
+ 1100 SemError(233); ok := FALSE
|
|
|
+ 1101 END
|
|
|
+ 1102 ELSIF i #
|
|
|
+ 1103 SymTab.ProcNPar(pn) THEN
|
|
|
+ 1104 SemError(233); ok := FALSE
|
|
|
+ 1105 END
|
|
|
+ 1106 END;
|
|
|
+ 1107 IF NOT ok THEN
|
|
|
+ 1108 t := SymTab.InvalidType;
|
|
|
+ 1109 QbeGen.CopyOp("0", q)
|
|
|
+ 1110 ELSIF want THEN
|
|
|
+ 1111 IF res =
|
|
|
+ 1112 SymTab.InvalidType THEN
|
|
|
+ 1113 SemError(233);
|
|
|
+ 1114 t := SymTab.InvalidType;
|
|
|
+ 1115 QbeGen.CopyOp("0", q)
|
|
|
+ 1116 ELSE t := res;
|
|
|
+ 1117 QbeGen.CallEnd(TRUE, q)
|
|
|
+ 1118 END
|
|
|
+ 1119 ELSE
|
|
|
+ 1120 IF res #
|
|
|
+ 1121 SymTab.InvalidType THEN
|
|
|
+ 1122 SemError(233)
|
|
|
+ 1123 END;
|
|
|
+ 1124 t := SymTab.InvalidType;
|
|
|
+ 1125 QbeGen.CopyOp("0", q);
|
|
|
+ 1126 QbeGen.CallEnd(FALSE, q)
|
|
|
+ 1127 END; .) .
|
|
|
+ 1128 (* One actual: VAR formals take recorded designator addresses
|
|
|
+ 1129 (233 otherwise); value formals take converted expressions. *)
|
|
|
+ 1130 ActParam<pn: SymTab.Name; pt: SymTab.TypeIndex; ind: BOOLEAN;
|
|
|
+ 1131 i: CARDINAL> (. VAR at, ft: SymTab.TypeIndex;
|
|
|
+ 1132 qe, qa, qt: QbeGen.QVal;
|
|
|
+ 1133 isV, conv: BOOLEAN; .)
|
|
|
+ 1134 = Expr<at, qe> (. IF ind THEN
|
|
|
+ 1135 ft :=
|
|
|
+ 1136 SymTab.ProcTypeParamType(pt,
|
|
|
+ 1137 i);
|
|
|
+ 1138 isV :=
|
|
|
+ 1139 SymTab.ProcTypeParamIsVar(pt,
|
|
|
+ 1140 i)
|
|
|
+ 1141 ELSE
|
|
|
+ 1142 ft := SymTab.ParamType(pn, i);
|
|
|
+ 1143 isV := SymTab.ParamIsVar(pn, i)
|
|
|
+ 1144 END;
|
|
|
+ 1145 IF (at = SymTab.InvalidType)
|
|
|
+ 1146 OR (ft =
|
|
|
+ 1147 SymTab.InvalidType) THEN
|
|
|
+ 1148 ELSIF isV THEN
|
|
|
+ 1149 IF (SymTab.ClassOf(at)
|
|
|
+ 1150 = SymTab.ClChar)
|
|
|
+ 1151 AND (SymTab.ClassOf(ft) = SymTab.ClArray)
|
|
|
+ 1152 AND (SymTab.ClassOf(SymTab.ArrayElem(ft))
|
|
|
+ 1153 = SymTab.ClChar)
|
|
|
+ 1154 AND QbeGen.IsImm(qe) THEN
|
|
|
+ 1155 (* 1-char string
|
|
|
+ 1156 literal passed to
|
|
|
+ 1157 a VAR ARRAY OF CHAR *)
|
|
|
+ 1158 QbeGen.DeclCharStr(qe,
|
|
|
+ 1159 qa);
|
|
|
+ 1160 IF NOT QbeGen.CallArg(qa,
|
|
|
+ 1161 "l") THEN
|
|
|
+ 1162 SemError(233)
|
|
|
+ 1163 END
|
|
|
+ 1164 ELSIF NOT QbeGen.AddrOfVal(qe,
|
|
|
+ 1165 qa) THEN
|
|
|
+ 1166 SemError(233)
|
|
|
+ 1167 ELSIF NOT SymTab.VarParamOk(at,
|
|
|
+ 1168 ft) THEN
|
|
|
+ 1169 SemError(233)
|
|
|
+ 1170 ELSIF NOT QbeGen.CallArg(qa,
|
|
|
+ 1171 "l") THEN
|
|
|
+ 1172 SemError(233)
|
|
|
+ 1173 END
|
|
|
+ 1174 ELSE
|
|
|
+ 1175 IF (SymTab.ClassOf(at)
|
|
|
+ 1176 = SymTab.ClChar)
|
|
|
+ 1177 AND (SymTab.ClassOf(ft) = SymTab.ClArray)
|
|
|
+ 1178 AND (SymTab.ClassOf(SymTab.ArrayElem(ft))
|
|
|
+ 1179 = SymTab.ClChar)
|
|
|
+ 1180 AND QbeGen.IsImm(qe) THEN
|
|
|
+ 1181 (* 1-char string
|
|
|
+ 1182 literal passed to
|
|
|
+ 1183 ARRAY OF CHAR *)
|
|
|
+ 1184 QbeGen.DeclCharStr(qe,
|
|
|
+ 1185 qa);
|
|
|
+ 1186 IF NOT QbeGen.CallArg(qa,
|
|
|
+ 1187 "l") THEN
|
|
|
+ 1188 SemError(233)
|
|
|
+ 1189 END
|
|
|
+ 1190 ELSIF NOT SymTab.Assignable(at,
|
|
|
+ 1191 ft) THEN
|
|
|
+ 1192 SemError(233)
|
|
|
+ 1193 ELSE
|
|
|
+ 1194 conv := (SymTab.ClassOf(
|
|
|
+ 1195 ft) = SymTab.ClReal)
|
|
|
+ 1196 AND SymTab.IsIntFamily(at);
|
|
|
+ 1197 IF conv THEN
|
|
|
+ 1198 QbeGen.ConvIR(qe, qt);
|
|
|
+ 1199 IF NOT QbeGen.CallArg(qt,
|
|
|
+ 1200 "d") THEN
|
|
|
+ 1201 SemError(233)
|
|
|
+ 1202 END
|
|
|
+ 1203 ELSIF NOT QbeGen.CallArg(qe,
|
|
|
+ 1204 QbeGen.ArgClass(ft)) THEN
|
|
|
+ 1205 SemError(233)
|
|
|
+ 1206 END
|
|
|
+ 1207 END
|
|
|
+ 1208 END; .) .
|
|
|
+ 1209 IfStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 1210 q, lThen, lElse, lEnd:
|
|
|
+ 1211 QbeGen.QVal;
|
|
|
+ 1212 hasElse: BOOLEAN; .)
|
|
|
+ 1213 = "IF" (. hasElse := FALSE; .)
|
|
|
+ 1214 Expr<t, q> (. IF NOT SymTab.BoolCheck(t) THEN
|
|
|
+ 1215 SemError(214) END;
|
|
|
+ 1216 QbeGen.NewLabel(lThen);
|
|
|
+ 1217 QbeGen.NewLabel(lElse);
|
|
|
+ 1218 QbeGen.NewLabel(lEnd);
|
|
|
1219 QbeGen.Jnz(q, lThen, lElse);
|
|
|
1220 QbeGen.EmitLabel(lThen); .)
|
|
|
- 1221 "THEN" [ StatSeq ] (. QbeGen.Jmp(lEnd); .) }
|
|
|
- 1222 [ "ELSE" (. QbeGen.EmitLabel(lElse);
|
|
|
- 1223 hasElse := TRUE; .)
|
|
|
- 1224 [ StatSeq ] ]
|
|
|
- 1225 "END" (. IF hasElse THEN
|
|
|
- 1226 QbeGen.EmitLabel(lEnd)
|
|
|
- 1227 ELSE QbeGen.EmitLabel(lElse);
|
|
|
- 1228 QbeGen.EmitLabel(lEnd)
|
|
|
- 1229 END; .) .
|
|
|
- 1230 WhileStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 1231 q, lTop, lBody, lEnd:
|
|
|
- 1232 QbeGen.QVal; .)
|
|
|
- 1233 = "WHILE" (. QbeGen.NewLabel(lTop);
|
|
|
- 1234 QbeGen.NewLabel(lBody);
|
|
|
- 1235 QbeGen.NewLabel(lEnd);
|
|
|
- 1236 QbeGen.EmitLabel(lTop); .)
|
|
|
- 1237 Expr<t, q> (. IF NOT SymTab.BoolCheck(t) THEN
|
|
|
- 1238 SemError(214) END;
|
|
|
- 1239 QbeGen.Jnz(q, lBody, lEnd);
|
|
|
- 1240 QbeGen.EmitLabel(lBody); .)
|
|
|
- 1241 "DO" [ StatSeq ] (. QbeGen.Jmp(lTop); .)
|
|
|
- 1242 "END" (. QbeGen.EmitLabel(lEnd); .) .
|
|
|
- 1243 RepeatStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 1244 q, lTop, lEnd: QbeGen.QVal; .)
|
|
|
- 1245 = "REPEAT" (. QbeGen.NewLabel(lTop);
|
|
|
- 1246 QbeGen.NewLabel(lEnd);
|
|
|
- 1247 QbeGen.EmitLabel(lTop); .)
|
|
|
- 1248 [ StatSeq ]
|
|
|
- 1249 "UNTIL" Expr<t, q> (. IF NOT SymTab.BoolCheck(t) THEN
|
|
|
- 1250 SemError(214) END;
|
|
|
- 1251 QbeGen.Jnz(q, lEnd, lTop);
|
|
|
- 1252 QbeGen.EmitLabel(lEnd); .) .
|
|
|
- 1253 LoopStat (. VAR lTop, lEnd: QbeGen.QVal; .)
|
|
|
- 1254 = "LOOP" (. QbeGen.NewLabel(lTop);
|
|
|
- 1255 QbeGen.NewLabel(lEnd);
|
|
|
- 1256 QbeGen.PushLoop(lEnd);
|
|
|
- 1257 QbeGen.EmitLabel(lTop); .)
|
|
|
- 1258 [ StatSeq ]
|
|
|
- 1259 "END" (. QbeGen.Jmp(lTop);
|
|
|
- 1260 QbeGen.PopLoop;
|
|
|
- 1261 QbeGen.EmitLabel(lEnd); .) .
|
|
|
- 1262 (* FOR with static-sign BY (literal, non-zero; 220 otherwise).
|
|
|
- 1263 Runtime direction would need a compare-select; the literal
|
|
|
- 1264 sign picks cslew/csegew at "DO" time. *)
|
|
|
- 1265 ForStat (. VAR lv: SymTab.Name;
|
|
|
- 1266 tlo, thi, tby:
|
|
|
- 1267 SymTab.TypeIndex;
|
|
|
- 1268 qlo, qhi, qby, qt, qk, qb:
|
|
|
- 1269 QbeGen.QVal;
|
|
|
- 1270 lTop, lBody, lEnd:
|
|
|
- 1271 QbeGen.QVal;
|
|
|
- 1272 by: INTEGER;
|
|
|
- 1273 ok: BOOLEAN; .)
|
|
|
- 1274 = "FOR" (. by := 1; .)
|
|
|
- 1275 GetIdent<lv> (. ok := SymTab.Lookup(lv);
|
|
|
- 1276 IF NOT ok THEN
|
|
|
- 1277 SemError(201)
|
|
|
- 1278 ELSIF (SymTab.SymKind(lv) #
|
|
|
- 1279 SymTab.KindVar)
|
|
|
- 1280 AND (SymTab.SymKind(lv) #
|
|
|
- 1281 SymTab.KindParam) THEN
|
|
|
- 1282 SemError(220); ok := FALSE
|
|
|
- 1283 ELSIF NOT SymTab.IsIntFamily(
|
|
|
- 1284 SymTab.SymType(lv)) THEN
|
|
|
- 1285 SemError(220); ok := FALSE
|
|
|
- 1286 END; .)
|
|
|
- 1287 ":=" Expr<tlo, qlo> (. IF NOT SymTab.IsIntFamily(tlo) THEN
|
|
|
- 1288 SemError(220); ok := FALSE
|
|
|
- 1289 END; .)
|
|
|
- 1290 "TO" Expr<thi, qhi> (. IF NOT SymTab.IsIntFamily(thi) THEN
|
|
|
- 1291 SemError(220); ok := FALSE
|
|
|
- 1292 END; .)
|
|
|
- 1293 [ "BY" Expr<tby, qby> (. IF (tby #
|
|
|
- 1294 SymTab.InvalidType)
|
|
|
- 1295 AND NOT SymTab.IsIntFamily(tby) THEN
|
|
|
+ 1221 "THEN" [ StatSeq ] (. QbeGen.Jmp(lEnd); .)
|
|
|
+ 1222 { "ELSIF" (. QbeGen.EmitLabel(lElse);
|
|
|
+ 1223 QbeGen.NewLabel(lElse); .)
|
|
|
+ 1224 Expr<t, q> (. IF NOT SymTab.BoolCheck(t) THEN
|
|
|
+ 1225 SemError(214) END;
|
|
|
+ 1226 QbeGen.NewLabel(lThen);
|
|
|
+ 1227 QbeGen.Jnz(q, lThen, lElse);
|
|
|
+ 1228 QbeGen.EmitLabel(lThen); .)
|
|
|
+ 1229 "THEN" [ StatSeq ] (. QbeGen.Jmp(lEnd); .) }
|
|
|
+ 1230 [ "ELSE" (. QbeGen.EmitLabel(lElse);
|
|
|
+ 1231 hasElse := TRUE; .)
|
|
|
+ 1232 [ StatSeq ] ]
|
|
|
+ 1233 "END" (. IF hasElse THEN
|
|
|
+ 1234 QbeGen.EmitLabel(lEnd)
|
|
|
+ 1235 ELSE QbeGen.EmitLabel(lElse);
|
|
|
+ 1236 QbeGen.EmitLabel(lEnd)
|
|
|
+ 1237 END; .) .
|
|
|
+ 1238 WhileStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 1239 q, lTop, lBody, lEnd:
|
|
|
+ 1240 QbeGen.QVal; .)
|
|
|
+ 1241 = "WHILE" (. QbeGen.NewLabel(lTop);
|
|
|
+ 1242 QbeGen.NewLabel(lBody);
|
|
|
+ 1243 QbeGen.NewLabel(lEnd);
|
|
|
+ 1244 QbeGen.EmitLabel(lTop); .)
|
|
|
+ 1245 Expr<t, q> (. IF NOT SymTab.BoolCheck(t) THEN
|
|
|
+ 1246 SemError(214) END;
|
|
|
+ 1247 QbeGen.Jnz(q, lBody, lEnd);
|
|
|
+ 1248 QbeGen.EmitLabel(lBody); .)
|
|
|
+ 1249 "DO" [ StatSeq ] (. QbeGen.Jmp(lTop); .)
|
|
|
+ 1250 "END" (. QbeGen.EmitLabel(lEnd); .) .
|
|
|
+ 1251 RepeatStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 1252 q, lTop, lEnd: QbeGen.QVal; .)
|
|
|
+ 1253 = "REPEAT" (. QbeGen.NewLabel(lTop);
|
|
|
+ 1254 QbeGen.NewLabel(lEnd);
|
|
|
+ 1255 QbeGen.EmitLabel(lTop); .)
|
|
|
+ 1256 [ StatSeq ]
|
|
|
+ 1257 "UNTIL" Expr<t, q> (. IF NOT SymTab.BoolCheck(t) THEN
|
|
|
+ 1258 SemError(214) END;
|
|
|
+ 1259 QbeGen.Jnz(q, lEnd, lTop);
|
|
|
+ 1260 QbeGen.EmitLabel(lEnd); .) .
|
|
|
+ 1261 LoopStat (. VAR lTop, lEnd: QbeGen.QVal; .)
|
|
|
+ 1262 = "LOOP" (. QbeGen.NewLabel(lTop);
|
|
|
+ 1263 QbeGen.NewLabel(lEnd);
|
|
|
+ 1264 QbeGen.PushLoop(lEnd);
|
|
|
+ 1265 QbeGen.EmitLabel(lTop); .)
|
|
|
+ 1266 [ StatSeq ]
|
|
|
+ 1267 "END" (. QbeGen.Jmp(lTop);
|
|
|
+ 1268 QbeGen.PopLoop;
|
|
|
+ 1269 QbeGen.EmitLabel(lEnd); .) .
|
|
|
+ 1270 (* FOR with static-sign BY (literal, non-zero; 220 otherwise).
|
|
|
+ 1271 Runtime direction would need a compare-select; the literal
|
|
|
+ 1272 sign picks cslew/csegew at "DO" time. *)
|
|
|
+ 1273 ForStat (. VAR lv: SymTab.Name;
|
|
|
+ 1274 tlo, thi, tby:
|
|
|
+ 1275 SymTab.TypeIndex;
|
|
|
+ 1276 qlo, qhi, qby, qt, qk, qb:
|
|
|
+ 1277 QbeGen.QVal;
|
|
|
+ 1278 lTop, lBody, lEnd:
|
|
|
+ 1279 QbeGen.QVal;
|
|
|
+ 1280 by: INTEGER;
|
|
|
+ 1281 ok: BOOLEAN; .)
|
|
|
+ 1282 = "FOR" (. by := 1; .)
|
|
|
+ 1283 GetIdent<lv> (. ok := SymTab.Lookup(lv);
|
|
|
+ 1284 IF NOT ok THEN
|
|
|
+ 1285 SemError(201)
|
|
|
+ 1286 ELSIF (SymTab.SymKind(lv) #
|
|
|
+ 1287 SymTab.KindVar)
|
|
|
+ 1288 AND (SymTab.SymKind(lv) #
|
|
|
+ 1289 SymTab.KindParam) THEN
|
|
|
+ 1290 SemError(220); ok := FALSE
|
|
|
+ 1291 ELSIF NOT SymTab.IsIntFamily(
|
|
|
+ 1292 SymTab.SymType(lv)) THEN
|
|
|
+ 1293 SemError(220); ok := FALSE
|
|
|
+ 1294 END; .)
|
|
|
+ 1295 ":=" Expr<tlo, qlo> (. IF NOT SymTab.IsIntFamily(tlo) THEN
|
|
|
1296 SemError(220); ok := FALSE
|
|
|
- 1297 END;
|
|
|
- 1298 IF NOT SymTab.ConstInt(qby, by) THEN
|
|
|
- 1299 SemError(230); by := 1
|
|
|
- 1300 ELSIF by = 0 THEN
|
|
|
- 1301 SemError(220); by := 1
|
|
|
- 1302 END; .) ]
|
|
|
- 1303 "DO" (. IF ok THEN
|
|
|
- 1304 QbeGen.StoreVar(lv, qlo,
|
|
|
- 1305 FALSE) END;
|
|
|
- 1306 QbeGen.NewLabel(lTop);
|
|
|
- 1307 QbeGen.NewLabel(lBody);
|
|
|
- 1308 QbeGen.NewLabel(lEnd);
|
|
|
- 1309 QbeGen.EmitLabel(lTop);
|
|
|
- 1310 QbeGen.LoadVar(lv, FALSE, qt);
|
|
|
- 1311 QbeGen.NewTemp(qk);
|
|
|
- 1312 IF by > 0 THEN
|
|
|
- 1313 QbeGen.Op3("cslew", qk,
|
|
|
- 1314 qt, qhi, FALSE)
|
|
|
- 1315 ELSE QbeGen.Op3("csgew", qk,
|
|
|
- 1316 qt, qhi, FALSE)
|
|
|
- 1317 END;
|
|
|
- 1318 QbeGen.Jnz(qk, lBody, lEnd);
|
|
|
- 1319 QbeGen.EmitLabel(lBody); .)
|
|
|
- 1320 [ StatSeq ]
|
|
|
- 1321 "END" (. IF ok THEN
|
|
|
- 1322 QbeGen.LoadVar(lv, FALSE,
|
|
|
- 1323 qt);
|
|
|
- 1324 QbeGen.IntStr(by, qb);
|
|
|
- 1325 QbeGen.NewTemp(qk);
|
|
|
- 1326 QbeGen.Op3("add", qk,
|
|
|
- 1327 qt, qb, FALSE);
|
|
|
- 1328 QbeGen.StoreVar(lv, qk,
|
|
|
- 1329 FALSE) END;
|
|
|
- 1330 QbeGen.Jmp(lTop);
|
|
|
- 1331 QbeGen.EmitLabel(lEnd); .) .
|
|
|
- 1332 CaseStat (. VAR tsel: SymTab.TypeIndex;
|
|
|
- 1333 qsel, lEnd: QbeGen.QVal; .)
|
|
|
- 1334 = "CASE" Expr<tsel, qsel> (. QbeGen.NewLabel(lEnd); .)
|
|
|
- 1335 "OF" CaseAlt<tsel, qsel, lEnd>
|
|
|
- 1336 { "|" CaseAlt<tsel, qsel, lEnd> }
|
|
|
- 1337 [ "ELSE" [ StatSeq ] ]
|
|
|
- 1338 "END" (. QbeGen.EmitLabel(lEnd); .) .
|
|
|
- 1339 (* Compare-chain lowering: each alternative ends its match-tests
|
|
|
- 1340 with "jmp lAfter", so the no-match fallthrough skips the body:
|
|
|
- 1341 "cmp; jnz(lBody,lF); lF: ... ; jmp lAfter; lBody: S; jmp lEnd;
|
|
|
- 1342 lAfter:". Falls into the next alternative, ELSE, or END. *)
|
|
|
- 1343 CaseAlt<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
- 1344 lEnd: QbeGen.QVal> (. VAR lBody, lAfter: QbeGen.QVal; .)
|
|
|
- 1345 = (. QbeGen.NewLabel(lBody);
|
|
|
- 1346 QbeGen.NewLabel(lAfter); .)
|
|
|
- 1347 CaseLabel<tsel, qsel, lBody>
|
|
|
- 1348 { "," CaseLabel<tsel, qsel, lBody> }
|
|
|
- 1349 ":" (. QbeGen.Jmp(lAfter);
|
|
|
- 1350 QbeGen.EmitLabel(lBody); .)
|
|
|
- 1351 [ StatSeq ] (. QbeGen.Jmp(lEnd);
|
|
|
- 1352 QbeGen.EmitLabel(lAfter); .) .
|
|
|
- 1353 CaseLabel<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
- 1354 lBody: QbeGen.QVal> (. VAR t2, t3: SymTab.TypeIndex;
|
|
|
- 1355 q2, q3, qc, qd, qe:
|
|
|
- 1356 QbeGen.QVal;
|
|
|
- 1357 lNext: QbeGen.QVal; .)
|
|
|
- 1358 = Expr<t2, q2> (. IF (t2 #
|
|
|
- 1359 SymTab.InvalidType)
|
|
|
- 1360 AND (tsel #
|
|
|
- 1361 SymTab.InvalidType)
|
|
|
- 1362 AND ((SymTab.ClassOf(t2) =
|
|
|
- 1363 SymTab.ClSet)
|
|
|
- 1364 OR (SymTab.ClassOf(tsel) =
|
|
|
- 1365 SymTab.ClSet)) THEN
|
|
|
- 1366 SemError(230)
|
|
|
- 1367 ELSIF (t2 #
|
|
|
- 1368 SymTab.InvalidType)
|
|
|
- 1369 AND (tsel #
|
|
|
- 1370 SymTab.InvalidType)
|
|
|
- 1371 AND NOT SymTab.EqCheck(t2,
|
|
|
- 1372 tsel) THEN
|
|
|
- 1373 SemError(213) END;
|
|
|
- 1374 IF NOT QbeGen.IsImm(q2) THEN
|
|
|
- 1375 SemError(230);
|
|
|
- 1376 QbeGen.CopyOp("0", q2)
|
|
|
- 1377 END;
|
|
|
- 1378 QbeGen.NewLabel(lNext);
|
|
|
- 1379 QbeGen.Cmp(SymTab.OpEq,
|
|
|
- 1380 qsel, q2, qc, FALSE);
|
|
|
- 1381 QbeGen.Jnz(qc, lBody, lNext);
|
|
|
- 1382 QbeGen.EmitLabel(lNext); .)
|
|
|
- 1383 [ ".." Expr<t3, q3> (. IF (t3 #
|
|
|
- 1384 SymTab.InvalidType)
|
|
|
- 1385 AND (tsel #
|
|
|
- 1386 SymTab.InvalidType)
|
|
|
- 1387 AND NOT SymTab.EqCheck(t3,
|
|
|
- 1388 tsel) THEN
|
|
|
- 1389 SemError(213) END;
|
|
|
- 1390 IF NOT QbeGen.IsImm(q3) THEN
|
|
|
- 1391 SemError(230);
|
|
|
- 1392 QbeGen.CopyOp("0", q3)
|
|
|
- 1393 END;
|
|
|
- 1394 QbeGen.Cmp(SymTab.OpGe,
|
|
|
- 1395 qsel, q2, qc, FALSE);
|
|
|
- 1396 QbeGen.Cmp(SymTab.OpLe,
|
|
|
- 1397 qsel, q3, qd, FALSE);
|
|
|
- 1398 QbeGen.NewTemp(qe);
|
|
|
- 1399 QbeGen.Op3("and", qe, qc, qd,
|
|
|
- 1400 FALSE);
|
|
|
- 1401 QbeGen.NewLabel(lNext);
|
|
|
- 1402 QbeGen.Jnz(qe, lBody, lNext);
|
|
|
- 1403 QbeGen.EmitLabel(lNext); .) ] .
|
|
|
- 1404 ReturnStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 1405 q, qt: QbeGen.QVal;
|
|
|
- 1406 res: SymTab.TypeIndex;
|
|
|
- 1407 hadE, conv: BOOLEAN; .)
|
|
|
- 1408 = "RETURN" (. hadE := FALSE; .)
|
|
|
- 1409 [ Expr<t, q> (. hadE := TRUE; .) ]
|
|
|
- 1410 (. conv := FALSE;
|
|
|
- 1411 IF NOT SymTab.InProc() THEN
|
|
|
- 1412 SemError(232)
|
|
|
- 1413 ELSE res := SymTab.CurRes();
|
|
|
- 1414 IF NOT hadE THEN
|
|
|
- 1415 IF res #
|
|
|
- 1416 SymTab.InvalidType THEN
|
|
|
- 1417 SemError(232)
|
|
|
- 1418 ELSE QbeGen.EmitRet(q,
|
|
|
- 1419 FALSE)
|
|
|
- 1420 END
|
|
|
- 1421 ELSIF (res =
|
|
|
- 1422 SymTab.InvalidType)
|
|
|
- 1423 OR (t #
|
|
|
- 1424 SymTab.InvalidType)
|
|
|
- 1425 AND NOT SymTab.Assignable(t,
|
|
|
- 1426 res) THEN
|
|
|
- 1427 SemError(232)
|
|
|
- 1428 ELSE
|
|
|
- 1429 conv := (SymTab.ClassOf(
|
|
|
- 1430 res) = SymTab.ClReal)
|
|
|
- 1431 AND SymTab.IsIntFamily(t);
|
|
|
- 1432 IF conv THEN
|
|
|
- 1433 QbeGen.ConvIR(q, qt);
|
|
|
- 1434 QbeGen.EmitRet(qt, TRUE)
|
|
|
- 1435 ELSE QbeGen.EmitRet(q, TRUE)
|
|
|
- 1436 END
|
|
|
- 1437 END
|
|
|
- 1438 END; .) .
|
|
|
- 1439 HaltStat (. VAR t: SymTab.TypeIndex;
|
|
|
- 1440 q: QbeGen.QVal; .)
|
|
|
- 1441 = "HALT" [ "(" Expr<t, q> ")" ] (. QbeGen.HaltQ; .) .
|
|
|
- 1442 (* Designator: scalar loads, array addresses, and index suffixes.
|
|
|
- 1443 Each index descends one level (bounds-checked, trap on breach);
|
|
|
- 1444 nested levels reload the inner descriptor address. q ends as the
|
|
|
- 1445 value (scalars), the descriptor address (plain arrays), or the
|
|
|
- 1446 element address (indexed); sfx marks the indexed form. *)
|
|
|
- 1447 Design<VAR t: SymTab.TypeIndex; VAR k: INTEGER;
|
|
|
- 1448 VAR q: QbeGen.QVal; VAR qn: SymTab.Name; VAR sfx: BOOLEAN>
|
|
|
- 1449 (. VAR n, fn, mal: SymTab.Name;
|
|
|
- 1450 cls: INTEGER;
|
|
|
- 1451 curT, it, eT, bt:
|
|
|
- 1452 SymTab.TypeIndex;
|
|
|
- 1453 iq, ql, qlo, qhi, qe:
|
|
|
- 1454 QbeGen.QVal;
|
|
|
- 1455 lo, hi: INTEGER;
|
|
|
- 1456 fo: INTEGER;
|
|
|
- 1457 isOpen: BOOLEAN;
|
|
|
- 1458 qb, cv: QbeGen.QVal; .)
|
|
|
- 1459 = GetIdent<n> (. QbeGen.CopyOp(n, qn);
|
|
|
- 1460 sfx := FALSE;
|
|
|
- 1461 IF NOT SymTab.Lookup(n) THEN
|
|
|
- 1462 SemError(201);
|
|
|
- 1463 t := SymTab.InvalidType;
|
|
|
- 1464 k := -1;
|
|
|
- 1465 QbeGen.CopyOp("0", q)
|
|
|
- 1466 ELSE
|
|
|
- 1467 t := SymTab.SymType(n);
|
|
|
- 1468 k := SymTab.SymKind(n);
|
|
|
- 1469 IF k = SymTab.KindConst THEN
|
|
|
- 1470 IF SymTab.Equal(n,
|
|
|
- 1471 "TRUE") THEN
|
|
|
- 1472 t := SymTab.BoolType();
|
|
|
- 1473 QbeGen.CopyOp("1", q)
|
|
|
- 1474 ELSIF SymTab.Equal(n,
|
|
|
- 1475 "FALSE") THEN
|
|
|
- 1476 t := SymTab.BoolType();
|
|
|
- 1477 QbeGen.CopyOp("0", q)
|
|
|
- 1478 ELSIF SymTab.Equal(n,
|
|
|
- 1479 "NIL") THEN
|
|
|
- 1480 QbeGen.CopyOp("0", q)
|
|
|
- 1481 ELSE
|
|
|
- 1482 cls :=
|
|
|
- 1483 SymTab.ClassOf(t);
|
|
|
- 1484 IF (t #
|
|
|
- 1485 SymTab.InvalidType)
|
|
|
- 1486 AND ((cls = SymTab.ClInt)
|
|
|
- 1487 OR (cls
|
|
|
- 1488 = SymTab.ClChar)
|
|
|
- 1489 OR (cls
|
|
|
- 1490 = SymTab.ClEnum)
|
|
|
- 1491 OR (cls
|
|
|
- 1492 = SymTab.ClReal)
|
|
|
- 1493 OR (cls
|
|
|
- 1494 = SymTab.ClNil)) THEN
|
|
|
- 1495 IF cls = SymTab.ClNil THEN
|
|
|
- 1496 QbeGen.CopyOp("0", q)
|
|
|
- 1497 ELSIF ((cls
|
|
|
- 1498 = SymTab.ClInt)
|
|
|
- 1499 OR (cls
|
|
|
- 1500 = SymTab.ClChar)
|
|
|
- 1501 OR (cls
|
|
|
- 1502 = SymTab.ClEnum))
|
|
|
- 1503 AND SymTab.GetSymVal(n, cv)
|
|
|
- 1504 AND QbeGen.IsImm(cv) THEN
|
|
|
- 1505 QbeGen.CopyOp(cv, q)
|
|
|
- 1506 ELSE
|
|
|
- 1507 QbeGen.LoadVar(n,
|
|
|
- 1508 cls = SymTab.ClReal,
|
|
|
- 1509 q)
|
|
|
- 1510 END
|
|
|
- 1511 ELSE
|
|
|
- 1512 IF t #
|
|
|
- 1513 SymTab.InvalidType THEN
|
|
|
- 1514 SemError(230)
|
|
|
- 1515 END;
|
|
|
- 1516 QbeGen.CopyOp("0", q)
|
|
|
- 1517 END
|
|
|
- 1518 END
|
|
|
- 1519 ELSIF (k = SymTab.KindVar)
|
|
|
- 1520 OR (k = SymTab.KindParam) THEN
|
|
|
- 1521 cls :=
|
|
|
- 1522 SymTab.ClassOf(t);
|
|
|
- 1523 IF (cls = SymTab.ClInt)
|
|
|
- 1524 OR (cls = SymTab.ClBool)
|
|
|
- 1525 OR (cls = SymTab.ClChar)
|
|
|
- 1526 OR (cls = SymTab.ClUChar)
|
|
|
- 1527 OR (cls = SymTab.ClEnum)
|
|
|
- 1528 OR (cls
|
|
|
- 1529 = SymTab.ClReal) THEN
|
|
|
- 1530 QbeGen.LoadVar(n,
|
|
|
- 1531 cls = SymTab.ClReal, q)
|
|
|
- 1532 ELSIF (cls = SymTab.ClPtr)
|
|
|
- 1533 OR (cls = SymTab.ClProc) THEN
|
|
|
- 1534 QbeGen.LoadPtr(n, q)
|
|
|
- 1535 ELSIF cls = SymTab.ClLong THEN
|
|
|
- 1536 QbeGen.LoadLong(n, q)
|
|
|
- 1537 ELSIF (cls
|
|
|
- 1538 = SymTab.ClArray)
|
|
|
- 1539 OR (cls
|
|
|
- 1540 = SymTab.ClSet)
|
|
|
- 1541 OR (cls
|
|
|
- 1542 = SymTab.ClRecord)
|
|
|
- 1543 OR (cls
|
|
|
- 1544 = SymTab.ClUStr)
|
|
|
- 1545 OR (cls
|
|
|
- 1546 = SymTab.ClClass) THEN
|
|
|
- 1547 QbeGen.AddrOf(n, q)
|
|
|
- 1548 ELSE SemError(230);
|
|
|
- 1549 QbeGen.CopyOp("0", q)
|
|
|
- 1550 END
|
|
|
- 1551 ELSE QbeGen.CopyOp("0", q);
|
|
|
- 1552 IF k = SymTab.KindImport THEN
|
|
|
- 1553 SemError(230)
|
|
|
- 1554 ELSIF k =
|
|
|
- 1555 SymTab.KindProc THEN
|
|
|
- 1556 (* bare procedure name:
|
|
|
- 1557 a following ArgList
|
|
|
- 1558 makes it a call;
|
|
|
- 1559 otherwise Fact
|
|
|
- 1560 reports 230 *)
|
|
|
- 1561 ELSE
|
|
|
- 1562 IF k = SymTab.KindField THEN
|
|
|
- 1563 IF QbeGen.TopWith(qb) THEN
|
|
|
- 1564 fo :=
|
|
|
- 1565 SymTab.FieldOffset(
|
|
|
- 1566 SymTab.FieldOwner(n),
|
|
|
- 1567 n);
|
|
|
- 1568 QbeGen.FieldAddr(qb,
|
|
|
- 1569 fo, q);
|
|
|
- 1570 sfx := TRUE
|
|
|
- 1571 ELSE SemError(230);
|
|
|
- 1572 QbeGen.CopyOp("0", q)
|
|
|
- 1573 END
|
|
|
- 1574 END
|
|
|
- 1575 END
|
|
|
- 1576 END
|
|
|
- 1577 END; .)
|
|
|
- 1578 { "[" Expr<it, iq>
|
|
|
- 1579 (. IF t = SymTab.InvalidType THEN
|
|
|
- 1580 ELSIF SymTab.ClassOf(t) #
|
|
|
- 1581 SymTab.ClArray THEN
|
|
|
- 1582 SemError(217);
|
|
|
- 1583 t := SymTab.InvalidType
|
|
|
- 1584 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
- 1585 AND (SymTab.ClassOf(it) #
|
|
|
- 1586 SymTab.ClChar) THEN
|
|
|
- 1587 SemError(218);
|
|
|
- 1588 t := SymTab.InvalidType
|
|
|
- 1589 ELSE
|
|
|
- 1590 QbeGen.WidenIndex(iq, ql);
|
|
|
- 1591 isOpen :=
|
|
|
- 1592 SymTab.IsOpenArray(t);
|
|
|
- 1593 IF isOpen THEN
|
|
|
- 1594 QbeGen.CopyOp("0", qlo);
|
|
|
- 1595 IF SymTab.IsCharArray(t) THEN
|
|
|
- 1596 QbeGen.OpenHiChar(q, qhi)
|
|
|
- 1597 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
- 1598 END
|
|
|
- 1599 ELSE
|
|
|
- 1600 lo := SymTab.ArrayLo(t);
|
|
|
- 1601 hi := SymTab.ArrayHi(t);
|
|
|
- 1602 IF SymTab.IsCharArray(t) THEN
|
|
|
- 1603 hi := hi + 1
|
|
|
- 1604 END;
|
|
|
- 1605 QbeGen.IntStr(lo, qlo);
|
|
|
- 1606 QbeGen.IntStr(hi, qhi)
|
|
|
- 1607 END;
|
|
|
- 1608 QbeGen.CheckRange(ql, qlo,
|
|
|
- 1609 qhi);
|
|
|
- 1610 eT := SymTab.ArrayElem(t);
|
|
|
- 1611 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
- 1612 t, qe);
|
|
|
- 1613 IF SymTab.ClassOf(eT) =
|
|
|
- 1614 SymTab.ClArray THEN
|
|
|
- 1615 QbeGen.ElemLoad(qe, eT, q)
|
|
|
- 1616 ELSE QbeGen.CopyOp(qe, q)
|
|
|
+ 1297 END; .)
|
|
|
+ 1298 "TO" Expr<thi, qhi> (. IF NOT SymTab.IsIntFamily(thi) THEN
|
|
|
+ 1299 SemError(220); ok := FALSE
|
|
|
+ 1300 END; .)
|
|
|
+ 1301 [ "BY" Expr<tby, qby> (. IF (tby #
|
|
|
+ 1302 SymTab.InvalidType)
|
|
|
+ 1303 AND NOT SymTab.IsIntFamily(tby) THEN
|
|
|
+ 1304 SemError(220); ok := FALSE
|
|
|
+ 1305 END;
|
|
|
+ 1306 IF NOT SymTab.ConstInt(qby, by) THEN
|
|
|
+ 1307 SemError(230); by := 1
|
|
|
+ 1308 ELSIF by = 0 THEN
|
|
|
+ 1309 SemError(220); by := 1
|
|
|
+ 1310 END; .) ]
|
|
|
+ 1311 "DO" (. IF ok THEN
|
|
|
+ 1312 QbeGen.StoreVar(lv, qlo,
|
|
|
+ 1313 FALSE) END;
|
|
|
+ 1314 QbeGen.NewLabel(lTop);
|
|
|
+ 1315 QbeGen.NewLabel(lBody);
|
|
|
+ 1316 QbeGen.NewLabel(lEnd);
|
|
|
+ 1317 QbeGen.EmitLabel(lTop);
|
|
|
+ 1318 QbeGen.LoadVar(lv, FALSE, qt);
|
|
|
+ 1319 QbeGen.NewTemp(qk);
|
|
|
+ 1320 IF by > 0 THEN
|
|
|
+ 1321 QbeGen.Op3("cslew", qk,
|
|
|
+ 1322 qt, qhi, FALSE)
|
|
|
+ 1323 ELSE QbeGen.Op3("csgew", qk,
|
|
|
+ 1324 qt, qhi, FALSE)
|
|
|
+ 1325 END;
|
|
|
+ 1326 QbeGen.Jnz(qk, lBody, lEnd);
|
|
|
+ 1327 QbeGen.EmitLabel(lBody); .)
|
|
|
+ 1328 [ StatSeq ]
|
|
|
+ 1329 "END" (. IF ok THEN
|
|
|
+ 1330 QbeGen.LoadVar(lv, FALSE,
|
|
|
+ 1331 qt);
|
|
|
+ 1332 QbeGen.IntStr(by, qb);
|
|
|
+ 1333 QbeGen.NewTemp(qk);
|
|
|
+ 1334 QbeGen.Op3("add", qk,
|
|
|
+ 1335 qt, qb, FALSE);
|
|
|
+ 1336 QbeGen.StoreVar(lv, qk,
|
|
|
+ 1337 FALSE) END;
|
|
|
+ 1338 QbeGen.Jmp(lTop);
|
|
|
+ 1339 QbeGen.EmitLabel(lEnd); .) .
|
|
|
+ 1340 CaseStat (. VAR tsel: SymTab.TypeIndex;
|
|
|
+ 1341 qsel, lEnd: QbeGen.QVal; .)
|
|
|
+ 1342 = "CASE" Expr<tsel, qsel> (. QbeGen.NewLabel(lEnd); .)
|
|
|
+ 1343 "OF" CaseAlt<tsel, qsel, lEnd>
|
|
|
+ 1344 { "|" CaseAlt<tsel, qsel, lEnd> }
|
|
|
+ 1345 [ "ELSE" [ StatSeq ] ]
|
|
|
+ 1346 "END" (. QbeGen.EmitLabel(lEnd); .) .
|
|
|
+ 1347 (* Compare-chain lowering: each alternative ends its match-tests
|
|
|
+ 1348 with "jmp lAfter", so the no-match fallthrough skips the body:
|
|
|
+ 1349 "cmp; jnz(lBody,lF); lF: ... ; jmp lAfter; lBody: S; jmp lEnd;
|
|
|
+ 1350 lAfter:". Falls into the next alternative, ELSE, or END. *)
|
|
|
+ 1351 CaseAlt<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
+ 1352 lEnd: QbeGen.QVal> (. VAR lBody, lAfter: QbeGen.QVal; .)
|
|
|
+ 1353 = (. QbeGen.NewLabel(lBody);
|
|
|
+ 1354 QbeGen.NewLabel(lAfter); .)
|
|
|
+ 1355 CaseLabel<tsel, qsel, lBody>
|
|
|
+ 1356 { "," CaseLabel<tsel, qsel, lBody> }
|
|
|
+ 1357 ":" (. QbeGen.Jmp(lAfter);
|
|
|
+ 1358 QbeGen.EmitLabel(lBody); .)
|
|
|
+ 1359 [ StatSeq ] (. QbeGen.Jmp(lEnd);
|
|
|
+ 1360 QbeGen.EmitLabel(lAfter); .) .
|
|
|
+ 1361 CaseLabel<tsel: SymTab.TypeIndex; qsel: QbeGen.QVal;
|
|
|
+ 1362 lBody: QbeGen.QVal> (. VAR t2, t3: SymTab.TypeIndex;
|
|
|
+ 1363 q2, q3, qc, qd, qe:
|
|
|
+ 1364 QbeGen.QVal;
|
|
|
+ 1365 lNext: QbeGen.QVal; .)
|
|
|
+ 1366 = Expr<t2, q2> (. IF (t2 #
|
|
|
+ 1367 SymTab.InvalidType)
|
|
|
+ 1368 AND (tsel #
|
|
|
+ 1369 SymTab.InvalidType)
|
|
|
+ 1370 AND ((SymTab.ClassOf(t2) =
|
|
|
+ 1371 SymTab.ClSet)
|
|
|
+ 1372 OR (SymTab.ClassOf(tsel) =
|
|
|
+ 1373 SymTab.ClSet)) THEN
|
|
|
+ 1374 SemError(230)
|
|
|
+ 1375 ELSIF (t2 #
|
|
|
+ 1376 SymTab.InvalidType)
|
|
|
+ 1377 AND (tsel #
|
|
|
+ 1378 SymTab.InvalidType)
|
|
|
+ 1379 AND NOT SymTab.EqCheck(t2,
|
|
|
+ 1380 tsel) THEN
|
|
|
+ 1381 SemError(213) END;
|
|
|
+ 1382 IF NOT QbeGen.IsImm(q2) THEN
|
|
|
+ 1383 SemError(230);
|
|
|
+ 1384 QbeGen.CopyOp("0", q2)
|
|
|
+ 1385 END;
|
|
|
+ 1386 QbeGen.NewLabel(lNext);
|
|
|
+ 1387 QbeGen.Cmp(SymTab.OpEq,
|
|
|
+ 1388 qsel, q2, qc, FALSE);
|
|
|
+ 1389 QbeGen.Jnz(qc, lBody, lNext);
|
|
|
+ 1390 QbeGen.EmitLabel(lNext); .)
|
|
|
+ 1391 [ ".." Expr<t3, q3> (. IF (t3 #
|
|
|
+ 1392 SymTab.InvalidType)
|
|
|
+ 1393 AND (tsel #
|
|
|
+ 1394 SymTab.InvalidType)
|
|
|
+ 1395 AND NOT SymTab.EqCheck(t3,
|
|
|
+ 1396 tsel) THEN
|
|
|
+ 1397 SemError(213) END;
|
|
|
+ 1398 IF NOT QbeGen.IsImm(q3) THEN
|
|
|
+ 1399 SemError(230);
|
|
|
+ 1400 QbeGen.CopyOp("0", q3)
|
|
|
+ 1401 END;
|
|
|
+ 1402 QbeGen.Cmp(SymTab.OpGe,
|
|
|
+ 1403 qsel, q2, qc, FALSE);
|
|
|
+ 1404 QbeGen.Cmp(SymTab.OpLe,
|
|
|
+ 1405 qsel, q3, qd, FALSE);
|
|
|
+ 1406 QbeGen.NewTemp(qe);
|
|
|
+ 1407 QbeGen.Op3("and", qe, qc, qd,
|
|
|
+ 1408 FALSE);
|
|
|
+ 1409 QbeGen.NewLabel(lNext);
|
|
|
+ 1410 QbeGen.Jnz(qe, lBody, lNext);
|
|
|
+ 1411 QbeGen.EmitLabel(lNext); .) ] .
|
|
|
+ 1412 ReturnStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 1413 q, qt: QbeGen.QVal;
|
|
|
+ 1414 res: SymTab.TypeIndex;
|
|
|
+ 1415 hadE, conv: BOOLEAN; .)
|
|
|
+ 1416 = "RETURN" (. hadE := FALSE; .)
|
|
|
+ 1417 [ Expr<t, q> (. hadE := TRUE; .) ]
|
|
|
+ 1418 (. conv := FALSE;
|
|
|
+ 1419 IF NOT SymTab.InProc() THEN
|
|
|
+ 1420 SemError(232)
|
|
|
+ 1421 ELSE res := SymTab.CurRes();
|
|
|
+ 1422 IF NOT hadE THEN
|
|
|
+ 1423 IF res #
|
|
|
+ 1424 SymTab.InvalidType THEN
|
|
|
+ 1425 SemError(232)
|
|
|
+ 1426 ELSE QbeGen.EmitRet(q,
|
|
|
+ 1427 FALSE)
|
|
|
+ 1428 END
|
|
|
+ 1429 ELSIF (res =
|
|
|
+ 1430 SymTab.InvalidType)
|
|
|
+ 1431 OR (t #
|
|
|
+ 1432 SymTab.InvalidType)
|
|
|
+ 1433 AND NOT SymTab.Assignable(t,
|
|
|
+ 1434 res) THEN
|
|
|
+ 1435 SemError(232)
|
|
|
+ 1436 ELSE
|
|
|
+ 1437 conv := (SymTab.ClassOf(
|
|
|
+ 1438 res) = SymTab.ClReal)
|
|
|
+ 1439 AND SymTab.IsIntFamily(t);
|
|
|
+ 1440 IF conv THEN
|
|
|
+ 1441 QbeGen.ConvIR(q, qt);
|
|
|
+ 1442 QbeGen.EmitRet(qt, TRUE)
|
|
|
+ 1443 ELSE QbeGen.EmitRet(q, TRUE)
|
|
|
+ 1444 END
|
|
|
+ 1445 END
|
|
|
+ 1446 END; .) .
|
|
|
+ 1447 HaltStat (. VAR t: SymTab.TypeIndex;
|
|
|
+ 1448 q: QbeGen.QVal; .)
|
|
|
+ 1449 = "HALT" [ "(" Expr<t, q> ")" ] (. QbeGen.HaltQ; .) .
|
|
|
+ 1450 (* Designator: scalar loads, array addresses, and index suffixes.
|
|
|
+ 1451 Each index descends one level (bounds-checked, trap on breach);
|
|
|
+ 1452 nested levels reload the inner descriptor address. q ends as the
|
|
|
+ 1453 value (scalars), the descriptor address (plain arrays), or the
|
|
|
+ 1454 element address (indexed); sfx marks the indexed form. *)
|
|
|
+ 1455 Design<VAR t: SymTab.TypeIndex; VAR k: INTEGER;
|
|
|
+ 1456 VAR q: QbeGen.QVal; VAR qn: SymTab.Name; VAR sfx: BOOLEAN>
|
|
|
+ 1457 (. VAR n, fn, mal: SymTab.Name;
|
|
|
+ 1458 cls: INTEGER;
|
|
|
+ 1459 curT, it, eT, bt:
|
|
|
+ 1460 SymTab.TypeIndex;
|
|
|
+ 1461 iq, ql, qlo, qhi, qe:
|
|
|
+ 1462 QbeGen.QVal;
|
|
|
+ 1463 lo, hi: INTEGER;
|
|
|
+ 1464 fo: INTEGER;
|
|
|
+ 1465 isOpen: BOOLEAN;
|
|
|
+ 1466 qb, cv: QbeGen.QVal; .)
|
|
|
+ 1467 = GetIdent<n> (. QbeGen.CopyOp(n, qn);
|
|
|
+ 1468 sfx := FALSE;
|
|
|
+ 1469 IF NOT SymTab.Lookup(n) THEN
|
|
|
+ 1470 SemError(201);
|
|
|
+ 1471 t := SymTab.InvalidType;
|
|
|
+ 1472 k := -1;
|
|
|
+ 1473 QbeGen.CopyOp("0", q)
|
|
|
+ 1474 ELSE
|
|
|
+ 1475 t := SymTab.SymType(n);
|
|
|
+ 1476 k := SymTab.SymKind(n);
|
|
|
+ 1477 IF k = SymTab.KindConst THEN
|
|
|
+ 1478 IF SymTab.Equal(n,
|
|
|
+ 1479 "TRUE") THEN
|
|
|
+ 1480 t := SymTab.BoolType();
|
|
|
+ 1481 QbeGen.CopyOp("1", q)
|
|
|
+ 1482 ELSIF SymTab.Equal(n,
|
|
|
+ 1483 "FALSE") THEN
|
|
|
+ 1484 t := SymTab.BoolType();
|
|
|
+ 1485 QbeGen.CopyOp("0", q)
|
|
|
+ 1486 ELSIF SymTab.Equal(n,
|
|
|
+ 1487 "NIL") THEN
|
|
|
+ 1488 QbeGen.CopyOp("0", q)
|
|
|
+ 1489 ELSE
|
|
|
+ 1490 cls :=
|
|
|
+ 1491 SymTab.ClassOf(t);
|
|
|
+ 1492 IF (t #
|
|
|
+ 1493 SymTab.InvalidType)
|
|
|
+ 1494 AND ((cls = SymTab.ClInt)
|
|
|
+ 1495 OR (cls
|
|
|
+ 1496 = SymTab.ClChar)
|
|
|
+ 1497 OR (cls
|
|
|
+ 1498 = SymTab.ClEnum)
|
|
|
+ 1499 OR (cls
|
|
|
+ 1500 = SymTab.ClReal)
|
|
|
+ 1501 OR (cls
|
|
|
+ 1502 = SymTab.ClNil)) THEN
|
|
|
+ 1503 IF cls = SymTab.ClNil THEN
|
|
|
+ 1504 QbeGen.CopyOp("0", q)
|
|
|
+ 1505 ELSIF ((cls
|
|
|
+ 1506 = SymTab.ClInt)
|
|
|
+ 1507 OR (cls
|
|
|
+ 1508 = SymTab.ClChar)
|
|
|
+ 1509 OR (cls
|
|
|
+ 1510 = SymTab.ClEnum))
|
|
|
+ 1511 AND SymTab.GetSymVal(n, cv)
|
|
|
+ 1512 AND QbeGen.IsImm(cv) THEN
|
|
|
+ 1513 QbeGen.CopyOp(cv, q)
|
|
|
+ 1514 ELSE
|
|
|
+ 1515 QbeGen.LoadVar(n,
|
|
|
+ 1516 cls = SymTab.ClReal,
|
|
|
+ 1517 q)
|
|
|
+ 1518 END
|
|
|
+ 1519 ELSE
|
|
|
+ 1520 IF t #
|
|
|
+ 1521 SymTab.InvalidType THEN
|
|
|
+ 1522 SemError(230)
|
|
|
+ 1523 END;
|
|
|
+ 1524 QbeGen.CopyOp("0", q)
|
|
|
+ 1525 END
|
|
|
+ 1526 END
|
|
|
+ 1527 ELSIF (k = SymTab.KindVar)
|
|
|
+ 1528 OR (k = SymTab.KindParam) THEN
|
|
|
+ 1529 cls :=
|
|
|
+ 1530 SymTab.ClassOf(t);
|
|
|
+ 1531 IF (cls = SymTab.ClInt)
|
|
|
+ 1532 OR (cls = SymTab.ClBool)
|
|
|
+ 1533 OR (cls = SymTab.ClChar)
|
|
|
+ 1534 OR (cls = SymTab.ClUChar)
|
|
|
+ 1535 OR (cls = SymTab.ClEnum)
|
|
|
+ 1536 OR (cls
|
|
|
+ 1537 = SymTab.ClReal) THEN
|
|
|
+ 1538 QbeGen.LoadVar(n,
|
|
|
+ 1539 cls = SymTab.ClReal, q)
|
|
|
+ 1540 ELSIF (cls = SymTab.ClPtr)
|
|
|
+ 1541 OR (cls = SymTab.ClProc) THEN
|
|
|
+ 1542 QbeGen.LoadPtr(n, q)
|
|
|
+ 1543 ELSIF cls = SymTab.ClLong THEN
|
|
|
+ 1544 QbeGen.LoadLong(n, q)
|
|
|
+ 1545 ELSIF (cls
|
|
|
+ 1546 = SymTab.ClArray)
|
|
|
+ 1547 OR (cls
|
|
|
+ 1548 = SymTab.ClSet)
|
|
|
+ 1549 OR (cls
|
|
|
+ 1550 = SymTab.ClRecord)
|
|
|
+ 1551 OR (cls
|
|
|
+ 1552 = SymTab.ClUStr)
|
|
|
+ 1553 OR (cls
|
|
|
+ 1554 = SymTab.ClClass) THEN
|
|
|
+ 1555 QbeGen.AddrOf(n, q)
|
|
|
+ 1556 ELSE SemError(230);
|
|
|
+ 1557 QbeGen.CopyOp("0", q)
|
|
|
+ 1558 END
|
|
|
+ 1559 ELSE QbeGen.CopyOp("0", q);
|
|
|
+ 1560 IF k = SymTab.KindImport THEN
|
|
|
+ 1561 SemError(230)
|
|
|
+ 1562 ELSIF k =
|
|
|
+ 1563 SymTab.KindProc THEN
|
|
|
+ 1564 (* bare procedure name:
|
|
|
+ 1565 a following ArgList
|
|
|
+ 1566 makes it a call;
|
|
|
+ 1567 otherwise Fact
|
|
|
+ 1568 reports 230 *)
|
|
|
+ 1569 ELSE
|
|
|
+ 1570 IF k = SymTab.KindField THEN
|
|
|
+ 1571 IF QbeGen.TopWith(qb) THEN
|
|
|
+ 1572 fo :=
|
|
|
+ 1573 SymTab.FieldOffset(
|
|
|
+ 1574 SymTab.FieldOwner(n),
|
|
|
+ 1575 n);
|
|
|
+ 1576 QbeGen.FieldAddr(qb,
|
|
|
+ 1577 fo, q);
|
|
|
+ 1578 sfx := TRUE
|
|
|
+ 1579 ELSE SemError(230);
|
|
|
+ 1580 QbeGen.CopyOp("0", q)
|
|
|
+ 1581 END
|
|
|
+ 1582 END
|
|
|
+ 1583 END
|
|
|
+ 1584 END
|
|
|
+ 1585 END; .)
|
|
|
+ 1586 { "[" Expr<it, iq>
|
|
|
+ 1587 (. IF t = SymTab.InvalidType THEN
|
|
|
+ 1588 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 1589 SymTab.ClArray THEN
|
|
|
+ 1590 SemError(217);
|
|
|
+ 1591 t := SymTab.InvalidType
|
|
|
+ 1592 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
+ 1593 AND (SymTab.ClassOf(it) #
|
|
|
+ 1594 SymTab.ClChar) THEN
|
|
|
+ 1595 SemError(218);
|
|
|
+ 1596 t := SymTab.InvalidType
|
|
|
+ 1597 ELSE
|
|
|
+ 1598 QbeGen.WidenIndex(iq, ql);
|
|
|
+ 1599 isOpen :=
|
|
|
+ 1600 SymTab.IsOpenArray(t);
|
|
|
+ 1601 IF isOpen THEN
|
|
|
+ 1602 QbeGen.CopyOp("0", qlo);
|
|
|
+ 1603 IF SymTab.IsCharArray(t)
|
|
|
+ 1604 OR SymTab.IsUCharArray(t) THEN
|
|
|
+ 1605 QbeGen.OpenHiChar(q, qhi)
|
|
|
+ 1606 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
+ 1607 END
|
|
|
+ 1608 ELSE
|
|
|
+ 1609 lo := SymTab.ArrayLo(t);
|
|
|
+ 1610 hi := SymTab.ArrayHi(t);
|
|
|
+ 1611 IF SymTab.IsCharArray(t)
|
|
|
+ 1612 OR SymTab.IsUCharArray(t) THEN
|
|
|
+ 1613 hi := hi + 1
|
|
|
+ 1614 END;
|
|
|
+ 1615 QbeGen.IntStr(lo, qlo);
|
|
|
+ 1616 QbeGen.IntStr(hi, qhi)
|
|
|
1617 END;
|
|
|
- 1618 t := eT; sfx := TRUE
|
|
|
- 1619 END; .)
|
|
|
- 1620 { "," Expr<it, iq>
|
|
|
- 1621 (. IF t = SymTab.InvalidType THEN
|
|
|
- 1622 ELSIF SymTab.ClassOf(t) #
|
|
|
- 1623 SymTab.ClArray THEN
|
|
|
- 1624 SemError(217);
|
|
|
- 1625 t := SymTab.InvalidType
|
|
|
- 1626 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
- 1627 AND (SymTab.ClassOf(it) #
|
|
|
- 1628 SymTab.ClChar) THEN
|
|
|
- 1629 SemError(218);
|
|
|
- 1630 t := SymTab.InvalidType
|
|
|
- 1631 ELSE
|
|
|
- 1632 QbeGen.WidenIndex(iq, ql);
|
|
|
- 1633 isOpen :=
|
|
|
- 1634 SymTab.IsOpenArray(t);
|
|
|
- 1635 IF isOpen THEN
|
|
|
- 1636 QbeGen.CopyOp("0", qlo);
|
|
|
- 1637 IF SymTab.IsCharArray(t) THEN
|
|
|
- 1638 QbeGen.OpenHiChar(q, qhi)
|
|
|
- 1639 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
- 1640 END
|
|
|
- 1641 ELSE
|
|
|
- 1642 lo := SymTab.ArrayLo(t);
|
|
|
- 1643 hi := SymTab.ArrayHi(t);
|
|
|
- 1644 IF SymTab.IsCharArray(t) THEN
|
|
|
- 1645 hi := hi + 1
|
|
|
- 1646 END;
|
|
|
- 1647 QbeGen.IntStr(lo, qlo);
|
|
|
- 1648 QbeGen.IntStr(hi, qhi)
|
|
|
- 1649 END;
|
|
|
- 1650 QbeGen.CheckRange(ql, qlo,
|
|
|
- 1651 qhi);
|
|
|
- 1652 eT := SymTab.ArrayElem(t);
|
|
|
- 1653 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
- 1654 t, qe);
|
|
|
- 1655 IF SymTab.ClassOf(eT) =
|
|
|
- 1656 SymTab.ClArray THEN
|
|
|
- 1657 QbeGen.ElemLoad(qe, eT, q)
|
|
|
- 1658 ELSE QbeGen.CopyOp(qe, q)
|
|
|
- 1659 END;
|
|
|
- 1660 t := eT; sfx := TRUE
|
|
|
- 1661 END; .) }
|
|
|
- 1662 "]"
|
|
|
- 1663 | "." GetIdent<fn>
|
|
|
- 1664 (. IF k = SymTab.KindModule THEN
|
|
|
- 1665 (* qualified L.x: materialize
|
|
|
- 1666 the export, then load it *)
|
|
|
- 1667 IF NOT SymTab.MaterializeAlias(n,
|
|
|
- 1668 fn, mal) THEN
|
|
|
- 1669 SemError(201);
|
|
|
- 1670 t := SymTab.InvalidType;
|
|
|
- 1671 QbeGen.CopyOp("0", q)
|
|
|
- 1672 ELSE
|
|
|
- 1673 QbeGen.CopyOp(mal, qn);
|
|
|
- 1674 t := SymTab.SymType(mal);
|
|
|
- 1675 k := SymTab.SymKind(mal);
|
|
|
- 1676 sfx := FALSE;
|
|
|
- 1677 IF k = SymTab.KindProc THEN
|
|
|
- 1678 (* call: ArgList supplies
|
|
|
- 1679 the value *)
|
|
|
- 1680 QbeGen.CopyOp("0", q)
|
|
|
- 1681 ELSIF NOT QbeGen.LoadDesignator(
|
|
|
- 1682 mal, t, k, q) THEN
|
|
|
- 1683 SemError(230);
|
|
|
- 1684 QbeGen.CopyOp("0", q)
|
|
|
- 1685 END
|
|
|
- 1686 END
|
|
|
- 1687 ELSIF t = SymTab.InvalidType THEN
|
|
|
- 1688 ELSIF (SymTab.ClassOf(t) #
|
|
|
- 1689 SymTab.ClRecord)
|
|
|
- 1690 AND (SymTab.ClassOf(t) #
|
|
|
- 1691 SymTab.ClClass) THEN
|
|
|
- 1692 SemError(215);
|
|
|
- 1693 t := SymTab.InvalidType
|
|
|
- 1694 ELSIF NOT SymTab.FieldExists(t,
|
|
|
- 1695 fn) THEN
|
|
|
- 1696 SemError(216);
|
|
|
- 1697 t := SymTab.InvalidType
|
|
|
- 1698 ELSE
|
|
|
- 1699 fo := SymTab.FieldOffset(t,
|
|
|
- 1700 fn);
|
|
|
- 1701 t := SymTab.FieldType(t, fn);
|
|
|
- 1702 QbeGen.FieldAddr(q, fo, qe);
|
|
|
- 1703 (* array fields are inline:
|
|
|
- 1704 the field address is the
|
|
|
- 1705 descriptor, like records *)
|
|
|
- 1706 QbeGen.CopyOp(qe, q);
|
|
|
- 1707 sfx := TRUE
|
|
|
- 1708 END; .)
|
|
|
- 1709 | "^"
|
|
|
- 1710 (. IF t = SymTab.InvalidType THEN
|
|
|
- 1711 ELSIF SymTab.ClassOf(t) #
|
|
|
- 1712 SymTab.ClPtr THEN
|
|
|
- 1713 SemError(219);
|
|
|
- 1714 t := SymTab.InvalidType
|
|
|
- 1715 ELSE
|
|
|
- 1716 bt := SymTab.PtrBase(t);
|
|
|
- 1717 IF bt = SymTab.InvalidType THEN
|
|
|
- 1718 ELSE
|
|
|
- 1719 IF sfx THEN
|
|
|
- 1720 QbeGen.ElemLoad(q, t,
|
|
|
- 1721 qb);
|
|
|
- 1722 QbeGen.CopyOp(qb, q)
|
|
|
- 1723 END;
|
|
|
- 1724 t := bt;
|
|
|
- 1725 (* q holds the pointee
|
|
|
- 1726 address: Fact loads
|
|
|
- 1727 scalars/pointers and uses
|
|
|
- 1728 the address for
|
|
|
- 1729 aggregates; the VAR-actual
|
|
|
- 1730 note is q itself. *)
|
|
|
- 1731 sfx := TRUE
|
|
|
- 1732 END
|
|
|
- 1733 END; .) } .
|
|
|
- 1734 Expr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 1735 (. VAR t2: SymTab.TypeIndex;
|
|
|
- 1736 op: INTEGER;
|
|
|
- 1737 q2, qt, wl: QbeGen.QVal;
|
|
|
- 1738 isR: BOOLEAN; .)
|
|
|
- 1739 = SimExpr<t, q>
|
|
|
- 1740 [ Rel<op> SimExpr<t2, q2>
|
|
|
- 1741 (. IF op = SymTab.OpIn THEN
|
|
|
- 1742 IF SymTab.InCheck(t, t2) THEN
|
|
|
- 1743 IF (t = SymTab.InvalidType)
|
|
|
- 1744 OR (t2 = SymTab.InvalidType) THEN
|
|
|
- 1745 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
- 1746 ELSE
|
|
|
- 1747 QbeGen.InSet(q, q2, SymTab.SetBaseLo(t2),
|
|
|
- 1748 SymTab.SetCount(t2), qt);
|
|
|
- 1749 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 1750 END
|
|
|
- 1751 ELSE SemError(222); t := SymTab.InvalidType;
|
|
|
- 1752 QbeGen.CopyOp("0", q)
|
|
|
- 1753 END
|
|
|
- 1754 ELSIF SymTab.RelCheck(t, t2, op) THEN
|
|
|
- 1755 IF (t = SymTab.InvalidType)
|
|
|
- 1756 OR (t2 = SymTab.InvalidType) THEN
|
|
|
- 1757 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
- 1758 ELSIF (SymTab.ClassOf(t) = SymTab.ClPtr)
|
|
|
- 1759 OR (SymTab.ClassOf(t2) = SymTab.ClPtr) THEN
|
|
|
- 1760 IF (op # SymTab.OpEq) AND (op # SymTab.OpNeq1)
|
|
|
- 1761 AND (op # SymTab.OpNeq2) THEN
|
|
|
- 1762 SemError(213); t := SymTab.InvalidType;
|
|
|
- 1763 QbeGen.CopyOp("0", q)
|
|
|
- 1764 ELSE
|
|
|
- 1765 QbeGen.CmpL(op, q, q2, qt);
|
|
|
- 1766 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 1767 END
|
|
|
- 1768 ELSIF (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 1769 OR (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 1770 QbeGen.CmpSet(op, q, q2,
|
|
|
- 1771 SymTab.SetWords(t), SymTab.SetWords(t2), qt);
|
|
|
- 1772 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 1773 ELSIF SymTab.StrCompat(t, t2) THEN
|
|
|
- 1774 QbeGen.StrEq(op, q, q2, qt);
|
|
|
- 1775 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 1776 ELSIF SymTab.IsLongFamily(t)
|
|
|
- 1777 OR SymTab.IsLongFamily(t2) THEN
|
|
|
- 1778 IF SymTab.IsIntFamily(t) THEN
|
|
|
- 1779 QbeGen.WidenLong(q, wl); QbeGen.CopyOp(wl, q)
|
|
|
- 1780 END;
|
|
|
- 1781 IF SymTab.IsIntFamily(t2) THEN
|
|
|
- 1782 QbeGen.WidenLong(q2, wl); QbeGen.CopyOp(wl, q2)
|
|
|
- 1783 END;
|
|
|
- 1784 QbeGen.CmpLong(op, q, q2, qt);
|
|
|
- 1785 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
- 1786 ELSE
|
|
|
- 1787 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
- 1788 t := SymTab.BoolType();
|
|
|
- 1789 QbeGen.Cmp(op, q, q2, qt, isR);
|
|
|
- 1790 QbeGen.CopyOp(qt, q)
|
|
|
- 1791 END
|
|
|
- 1792 ELSE SemError(213); t := SymTab.InvalidType;
|
|
|
- 1793 QbeGen.CopyOp("0", q)
|
|
|
- 1794 END; .) ] .
|
|
|
- 1795 Rel<VAR op: INTEGER>
|
|
|
- 1796 = "=" (. op := SymTab.OpEq; .)
|
|
|
- 1797 | "#" (. op := SymTab.OpNeq1; .)
|
|
|
- 1798 | "<" (. op := SymTab.OpLt; .)
|
|
|
- 1799 | "<=" (. op := SymTab.OpLe; .)
|
|
|
- 1800 | ">" (. op := SymTab.OpGt; .)
|
|
|
- 1801 | ">=" (. op := SymTab.OpGe; .)
|
|
|
- 1802 | "IN" (. op := SymTab.OpIn; .) .
|
|
|
- 1803 SimExpr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 1804 (. VAR t2, res2, lt, rt:
|
|
|
- 1805 SymTab.TypeIndex;
|
|
|
- 1806 op: INTEGER;
|
|
|
- 1807 q2, qt, wq, qf:
|
|
|
- 1808 QbeGen.QVal;
|
|
|
- 1809 neg, isR, isL, folded:
|
|
|
- 1810 BOOLEAN;
|
|
|
- 1811 lw, rw, mw: CARDINAL;
|
|
|
- 1812 lTrue, lNext, lDone, qr, qs:
|
|
|
- 1813 QbeGen.QVal; .)
|
|
|
- 1814 = (. neg := FALSE; .)
|
|
|
- 1815 [ "+" | "-" (. neg := TRUE; .) ]
|
|
|
- 1816 Term<t, q> (. IF neg THEN
|
|
|
- 1817 IF QbeGen.IsImm(q) THEN
|
|
|
- 1818 QbeGen.NegFold(q, q)
|
|
|
- 1819 ELSE QbeGen.NewTemp(qt);
|
|
|
- 1820 QbeGen.NegQ(q, qt,
|
|
|
- 1821 SymTab.ClassOf(t)
|
|
|
- 1822 = SymTab.ClReal);
|
|
|
- 1823 QbeGen.CopyOp(qt, q)
|
|
|
- 1824 END
|
|
|
- 1825 END; .)
|
|
|
- 1826 { AddOp<op> (. IF op = SymTab.OpOr THEN
|
|
|
- 1827 QbeGen.DelayBegin END; .)
|
|
|
- 1828 Term<t2, q2> (. IF op = SymTab.OpOr THEN
|
|
|
- 1829 QbeGen.DelayEnd END; .)
|
|
|
- 1830 (. IF op = SymTab.OpOr THEN
|
|
|
- 1831 (* short-circuit: if q is true the RHS is skipped *)
|
|
|
- 1832 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
- 1833 t := SymTab.BoolType()
|
|
|
- 1834 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
- 1835 IF t # SymTab.InvalidType THEN
|
|
|
- 1836 QbeGen.Slot4(qs);
|
|
|
- 1837 QbeGen.NewLabel(lTrue);
|
|
|
- 1838 QbeGen.NewLabel(lNext);
|
|
|
- 1839 QbeGen.NewLabel(lDone);
|
|
|
- 1840 QbeGen.Jnz(q, lTrue, lNext);
|
|
|
- 1841 QbeGen.EmitLabel(lTrue);
|
|
|
- 1842 QbeGen.StoreW(qs, "1");
|
|
|
- 1843 QbeGen.Jmp(lDone);
|
|
|
- 1844 QbeGen.EmitLabel(lNext);
|
|
|
- 1845 QbeGen.DelayFlush;
|
|
|
- 1846 QbeGen.StoreW(qs, q2);
|
|
|
- 1847 QbeGen.Jmp(lDone);
|
|
|
- 1848 QbeGen.EmitLabel(lDone);
|
|
|
- 1849 QbeGen.LoadW(qs, qr);
|
|
|
- 1850 QbeGen.CopyOp(qr, q)
|
|
|
- 1851 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
- 1852 END
|
|
|
- 1853 ELSIF (op = SymTab.OpAdd)
|
|
|
- 1854 AND (SymTab.StrCompat(t, t2)
|
|
|
- 1855 OR (SymTab.IsStrType(t)
|
|
|
- 1856 AND (SymTab.ClassOf(t2) = SymTab.ClChar))
|
|
|
- 1857 OR ((SymTab.ClassOf(t) = SymTab.ClChar)
|
|
|
- 1858 AND SymTab.IsStrType(t2))) THEN
|
|
|
- 1859 (* string concatenation; a CHAR operand becomes a
|
|
|
- 1860 1-character string literal *)
|
|
|
- 1861 IF SymTab.StrCompat(t, t2) THEN
|
|
|
- 1862 QbeGen.StrCat(q, q2, qt)
|
|
|
- 1863 ELSIF SymTab.IsStrType(t) THEN
|
|
|
- 1864 QbeGen.DeclCharStr(q2, qs);
|
|
|
- 1865 QbeGen.StrCat(q, qs, qt)
|
|
|
- 1866 ELSE
|
|
|
- 1867 QbeGen.DeclCharStr(q, qs);
|
|
|
- 1868 QbeGen.StrCat(qs, q2, qt)
|
|
|
- 1869 END;
|
|
|
- 1870 t := SymTab.NewStr();
|
|
|
- 1871 QbeGen.CopyOp(qt, q)
|
|
|
- 1872 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
- 1873 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 1874 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 1875 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
- 1876 mw := lw;
|
|
|
- 1877 IF rw > mw THEN mw := rw END;
|
|
|
- 1878 IF op = SymTab.OpAdd THEN
|
|
|
- 1879 QbeGen.SetBinOp(0, q, q2, lw, rw, qt)
|
|
|
- 1880 ELSE
|
|
|
- 1881 QbeGen.SetBinOp(2, q, q2, lw, rw, qt)
|
|
|
- 1882 END;
|
|
|
- 1883 t := SymTab.NewSet(
|
|
|
- 1884 SymTab.NewSubR(0,
|
|
|
- 1885 VAL(INTEGER, mw) * 32 - 1));
|
|
|
- 1886 QbeGen.CopyOp(qt, q)
|
|
|
- 1887 ELSE
|
|
|
- 1888 IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
|
|
|
- 1889 lt := t; rt := t2; t := res2
|
|
|
- 1890 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
- 1891 IF t # SymTab.InvalidType THEN
|
|
|
- 1892 isL := SymTab.IsLongFamily(t);
|
|
|
- 1893 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
- 1894 folded := FALSE;
|
|
|
- 1895 IF (NOT isL) AND (NOT isR)
|
|
|
- 1896 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
- 1897 IF op = SymTab.OpAdd THEN
|
|
|
- 1898 folded := QbeGen.Fold2(0, q, q2, qf)
|
|
|
- 1899 ELSE
|
|
|
- 1900 folded := QbeGen.Fold2(1, q, q2, qf)
|
|
|
- 1901 END
|
|
|
- 1902 END;
|
|
|
- 1903 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
- 1904 ELSE
|
|
|
- 1905 IF isL THEN
|
|
|
- 1906 IF SymTab.IsIntFamily(lt) THEN
|
|
|
- 1907 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
- 1908 END;
|
|
|
- 1909 IF SymTab.IsIntFamily(rt) THEN
|
|
|
- 1910 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
- 1911 END;
|
|
|
- 1912 QbeGen.NewTemp(qt);
|
|
|
- 1913 IF op = SymTab.OpAdd THEN
|
|
|
- 1914 QbeGen.Op3L("add", qt, q, q2)
|
|
|
- 1915 ELSE
|
|
|
- 1916 QbeGen.Op3L("sub", qt, q, q2)
|
|
|
- 1917 END
|
|
|
- 1918 ELSE
|
|
|
- 1919 QbeGen.NewTemp(qt);
|
|
|
- 1920 IF op = SymTab.OpAdd THEN
|
|
|
- 1921 QbeGen.Op3("add", qt, q, q2, isR)
|
|
|
- 1922 ELSE
|
|
|
- 1923 QbeGen.Op3("sub", qt, q, q2, isR)
|
|
|
- 1924 END
|
|
|
- 1925 END;
|
|
|
- 1926 QbeGen.CopyOp(qt, q)
|
|
|
- 1927 END
|
|
|
- 1928 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 1929 END
|
|
|
- 1930 END; .) } .
|
|
|
- 1931 AddOp<VAR op: INTEGER>
|
|
|
- 1932 = "+" (. op := SymTab.OpAdd; .)
|
|
|
- 1933 | "-" (. op := SymTab.OpSub; .)
|
|
|
- 1934 | "OR" (. op := SymTab.OpOr; .) .
|
|
|
- 1935 Term<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 1936 (. VAR t2, res2, lt, rt:
|
|
|
- 1937 SymTab.TypeIndex;
|
|
|
- 1938 op: INTEGER;
|
|
|
- 1939 q2, qt, wq, qf:
|
|
|
- 1940 QbeGen.QVal;
|
|
|
- 1941 isR, isL, folded: BOOLEAN;
|
|
|
- 1942 lw, rw, mw: CARDINAL;
|
|
|
- 1943 lNext, lFalse, lDone, qr, qs:
|
|
|
- 1944 QbeGen.QVal; .)
|
|
|
- 1945 = Fact<t, q> { MulOp<op> (. IF op = SymTab.OpAnd THEN
|
|
|
- 1946 QbeGen.DelayBegin END; .)
|
|
|
- 1947 Fact<t2, q2> (. IF op = SymTab.OpAnd THEN
|
|
|
- 1948 QbeGen.DelayEnd END; .)
|
|
|
- 1949 (. IF op = SymTab.OpAnd THEN
|
|
|
- 1950 (* short-circuit: if q is false the RHS is skipped *)
|
|
|
- 1951 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
- 1952 t := SymTab.BoolType()
|
|
|
- 1953 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
- 1954 IF t # SymTab.InvalidType THEN
|
|
|
- 1955 QbeGen.Slot4(qs);
|
|
|
- 1956 QbeGen.NewLabel(lNext);
|
|
|
- 1957 QbeGen.NewLabel(lFalse);
|
|
|
- 1958 QbeGen.NewLabel(lDone);
|
|
|
- 1959 QbeGen.Jnz(q, lNext, lFalse);
|
|
|
- 1960 QbeGen.EmitLabel(lNext);
|
|
|
- 1961 QbeGen.DelayFlush;
|
|
|
- 1962 QbeGen.StoreW(qs, q2);
|
|
|
- 1963 QbeGen.Jmp(lDone);
|
|
|
- 1964 QbeGen.EmitLabel(lFalse);
|
|
|
- 1965 QbeGen.StoreW(qs, "0");
|
|
|
- 1966 QbeGen.Jmp(lDone);
|
|
|
- 1967 QbeGen.EmitLabel(lDone);
|
|
|
- 1968 QbeGen.LoadW(qs, qr);
|
|
|
- 1969 QbeGen.CopyOp(qr, q)
|
|
|
- 1970 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
- 1971 END
|
|
|
- 1972 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
- 1973 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
- 1974 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
- 1975 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
- 1976 mw := lw;
|
|
|
- 1977 IF rw > mw THEN mw := rw END;
|
|
|
- 1978 IF op = SymTab.OpTimes THEN
|
|
|
- 1979 QbeGen.SetBinOp(1, q, q2, lw, rw, qt)
|
|
|
- 1980 ELSE
|
|
|
- 1981 QbeGen.SetBinOp(3, q, q2, lw, rw, qt)
|
|
|
- 1982 END;
|
|
|
- 1983 t := SymTab.NewSet(
|
|
|
- 1984 SymTab.NewSubR(0,
|
|
|
- 1985 VAL(INTEGER, mw) * 32 - 1));
|
|
|
- 1986 QbeGen.CopyOp(qt, q)
|
|
|
- 1987 ELSE
|
|
|
- 1988 IF SymTab.ArithCheck(t, t2,
|
|
|
- 1989 (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
|
|
|
- 1990 res2) THEN
|
|
|
- 1991 lt := t; rt := t2; t := res2
|
|
|
- 1992 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
- 1993 IF t # SymTab.InvalidType THEN
|
|
|
- 1994 isL := SymTab.IsLongFamily(t);
|
|
|
- 1995 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
- 1996 folded := FALSE;
|
|
|
- 1997 IF (NOT isL) AND (NOT isR)
|
|
|
- 1998 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
- 1999 IF op = SymTab.OpTimes THEN
|
|
|
- 2000 folded := QbeGen.Fold2(2, q, q2, qf)
|
|
|
- 2001 ELSIF op = SymTab.OpDiv THEN
|
|
|
- 2002 folded := QbeGen.Fold2(3, q, q2, qf)
|
|
|
- 2003 ELSIF op = SymTab.OpMod THEN
|
|
|
- 2004 folded := QbeGen.Fold2(4, q, q2, qf)
|
|
|
- 2005 END
|
|
|
- 2006 END;
|
|
|
- 2007 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
- 2008 ELSE
|
|
|
- 2009 IF isL THEN
|
|
|
- 2010 IF SymTab.IsIntFamily(lt) THEN
|
|
|
- 2011 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
- 2012 END;
|
|
|
- 2013 IF SymTab.IsIntFamily(rt) THEN
|
|
|
- 2014 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
- 2015 END;
|
|
|
- 2016 QbeGen.NewTemp(qt);
|
|
|
- 2017 IF op = SymTab.OpTimes THEN
|
|
|
- 2018 QbeGen.Op3L("mul", qt, q, q2)
|
|
|
- 2019 ELSIF (op = SymTab.OpDiv)
|
|
|
- 2020 OR (op = SymTab.OpSlash) THEN
|
|
|
- 2021 QbeGen.Op3L("div", qt, q, q2)
|
|
|
- 2022 ELSE
|
|
|
- 2023 QbeGen.Op3L("rem", qt, q, q2)
|
|
|
- 2024 END
|
|
|
- 2025 ELSE
|
|
|
- 2026 QbeGen.NewTemp(qt);
|
|
|
- 2027 IF op = SymTab.OpTimes THEN
|
|
|
- 2028 QbeGen.Op3("mul", qt, q, q2, isR)
|
|
|
- 2029 ELSIF (op = SymTab.OpDiv)
|
|
|
- 2030 OR (op = SymTab.OpSlash) THEN
|
|
|
- 2031 QbeGen.Op3("div", qt, q, q2, isR)
|
|
|
- 2032 ELSE
|
|
|
- 2033 QbeGen.Op3("rem", qt, q, q2, isR)
|
|
|
- 2034 END
|
|
|
- 2035 END;
|
|
|
- 2036 QbeGen.CopyOp(qt, q)
|
|
|
- 2037 END
|
|
|
- 2038 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 2039 END
|
|
|
- 2040 END; .) } .
|
|
|
- 2041 MulOp<VAR op: INTEGER>
|
|
|
- 2042 = "*" (. op := SymTab.OpTimes; .)
|
|
|
- 2043 | "/" (. op := SymTab.OpSlash; .)
|
|
|
- 2044 | "DIV" (. op := SymTab.OpDiv; .)
|
|
|
- 2045 | "MOD" (. op := SymTab.OpMod; .)
|
|
|
- 2046 | ( "AND" | "&" ) (. op := SymTab.OpAnd; .) .
|
|
|
- 2047 Fact<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 2048 (. VAR s: ARRAY [0 .. 255] OF CHAR;
|
|
|
- 2049 et, dt, t2, st, ct2:
|
|
|
- 2050 SymTab.TypeIndex;
|
|
|
- 2051 dk: INTEGER;
|
|
|
- 2052 qd, q2, sq, qa, qm0, qr:
|
|
|
- 2053 QbeGen.QVal;
|
|
|
- 2054 qn, vn: SymTab.Name;
|
|
|
- 2055 vt: SymTab.TypeIndex;
|
|
|
- 2056 c1, c2: INTEGER;
|
|
|
- 2057 called, isHigh, sfx, isCh,
|
|
|
- 2058 isU, uok, isStr: BOOLEAN;
|
|
|
- 2059 ucp: INTEGER; .)
|
|
|
- 2060 = integer (. LexString(s);
|
|
|
- 2061 QbeGen.NormInt(s, q);
|
|
|
- 2062 t := SymTab.IntType(); .)
|
|
|
- 2063 | charConst (. LexString(s);
|
|
|
- 2064 QbeGen.NormLit(s, q, isCh);
|
|
|
- 2065 t := SymTab.CharType(); .)
|
|
|
- 2066 | real (. LexString(s);
|
|
|
- 2067 QbeGen.NormReal(s, q);
|
|
|
- 2068 t := SymTab.RealType(); .)
|
|
|
- 2069 | string (. LexString(s);
|
|
|
- 2070 IF SymTab.StrLen(s) = 3 THEN
|
|
|
- 2071 t := SymTab.CharType();
|
|
|
- 2072 QbeGen.IntStr(
|
|
|
- 2073 QbeGen.CharVal(s), q)
|
|
|
- 2074 ELSE t := SymTab.NewStr();
|
|
|
- 2075 QbeGen.DeclStr(s, q);
|
|
|
- 2076 (* a literal's value IS its
|
|
|
- 2077 static descriptor address *)
|
|
|
- 2078 QbeGen.NoteAddr(q, q)
|
|
|
- 2079 END; .)
|
|
|
- 2080 | ustring (. LexString(s);
|
|
|
- 2081 QbeGen.DeclUStr(s, q, isU, ucp,
|
|
|
- 2082 uok);
|
|
|
- 2083 IF NOT uok THEN
|
|
|
- 2084 SemError(234);
|
|
|
- 2085 t := SymTab.InvalidType
|
|
|
- 2086 ELSIF isU THEN
|
|
|
- 2087 t := SymTab.UCharType();
|
|
|
- 2088 QbeGen.IntStr(ucp, q)
|
|
|
- 2089 ELSE
|
|
|
- 2090 t := SymTab.NewUStr();
|
|
|
- 2091 QbeGen.NoteAddr(q, q)
|
|
|
- 2092 END; .)
|
|
|
- 2093 | Design<dt, dk, qd, qn, sfx> (. called := FALSE;
|
|
|
- 2094 t := dt;
|
|
|
- 2095 IF sfx THEN
|
|
|
- 2096 IF dt =
|
|
|
- 2097 SymTab.InvalidType THEN
|
|
|
- 2098 QbeGen.CopyOp("0", q)
|
|
|
- 2099 ELSIF (SymTab.ClassOf(dt) =
|
|
|
- 2100 SymTab.ClRecord)
|
|
|
- 2101 OR (SymTab.ClassOf(dt) =
|
|
|
- 2102 SymTab.ClSet)
|
|
|
- 2103 OR (SymTab.ClassOf(dt) =
|
|
|
- 2104 SymTab.ClArray)
|
|
|
- 2105 OR (SymTab.ClassOf(dt) =
|
|
|
- 2106 SymTab.ClClass) THEN
|
|
|
- 2107 QbeGen.CopyOp(qd, q)
|
|
|
- 2108 ELSE QbeGen.ElemLoad(qd, dt,
|
|
|
- 2109 q)
|
|
|
- 2110 END
|
|
|
- 2111 ELSE QbeGen.CopyOp(qd, q)
|
|
|
- 2112 END;
|
|
|
- 2113 IF (dk = SymTab.KindVar)
|
|
|
- 2114 OR (dk = SymTab.KindParam)
|
|
|
- 2115 OR (dk =
|
|
|
- 2116 SymTab.KindField) THEN
|
|
|
- 2117 IF sfx THEN
|
|
|
- 2118 QbeGen.NoteAddr(q, qd)
|
|
|
- 2119 ELSE
|
|
|
- 2120 QbeGen.AddrOf(qn, qa);
|
|
|
- 2121 QbeGen.NoteAddr(q, qa)
|
|
|
+ 1618 QbeGen.CheckRange(ql, qlo,
|
|
|
+ 1619 qhi);
|
|
|
+ 1620 eT := SymTab.ArrayElem(t);
|
|
|
+ 1621 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
+ 1622 t, qe);
|
|
|
+ 1623 IF SymTab.ClassOf(eT) =
|
|
|
+ 1624 SymTab.ClArray THEN
|
|
|
+ 1625 QbeGen.ElemLoad(qe, eT, q)
|
|
|
+ 1626 ELSE QbeGen.CopyOp(qe, q)
|
|
|
+ 1627 END;
|
|
|
+ 1628 t := eT; sfx := TRUE
|
|
|
+ 1629 END; .)
|
|
|
+ 1630 { "," Expr<it, iq>
|
|
|
+ 1631 (. IF t = SymTab.InvalidType THEN
|
|
|
+ 1632 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 1633 SymTab.ClArray THEN
|
|
|
+ 1634 SemError(217);
|
|
|
+ 1635 t := SymTab.InvalidType
|
|
|
+ 1636 ELSIF NOT SymTab.IsIntFamily(it)
|
|
|
+ 1637 AND (SymTab.ClassOf(it) #
|
|
|
+ 1638 SymTab.ClChar) THEN
|
|
|
+ 1639 SemError(218);
|
|
|
+ 1640 t := SymTab.InvalidType
|
|
|
+ 1641 ELSE
|
|
|
+ 1642 QbeGen.WidenIndex(iq, ql);
|
|
|
+ 1643 isOpen :=
|
|
|
+ 1644 SymTab.IsOpenArray(t);
|
|
|
+ 1645 IF isOpen THEN
|
|
|
+ 1646 QbeGen.CopyOp("0", qlo);
|
|
|
+ 1647 IF SymTab.IsCharArray(t)
|
|
|
+ 1648 OR SymTab.IsUCharArray(t) THEN
|
|
|
+ 1649 QbeGen.OpenHiChar(q, qhi)
|
|
|
+ 1650 ELSE QbeGen.OpenHi(q, qhi)
|
|
|
+ 1651 END
|
|
|
+ 1652 ELSE
|
|
|
+ 1653 lo := SymTab.ArrayLo(t);
|
|
|
+ 1654 hi := SymTab.ArrayHi(t);
|
|
|
+ 1655 IF SymTab.IsCharArray(t)
|
|
|
+ 1656 OR SymTab.IsUCharArray(t) THEN
|
|
|
+ 1657 hi := hi + 1
|
|
|
+ 1658 END;
|
|
|
+ 1659 QbeGen.IntStr(lo, qlo);
|
|
|
+ 1660 QbeGen.IntStr(hi, qhi)
|
|
|
+ 1661 END;
|
|
|
+ 1662 QbeGen.CheckRange(ql, qlo,
|
|
|
+ 1663 qhi);
|
|
|
+ 1664 eT := SymTab.ArrayElem(t);
|
|
|
+ 1665 QbeGen.ElemAddr(q, ql, qlo,
|
|
|
+ 1666 t, qe);
|
|
|
+ 1667 IF SymTab.ClassOf(eT) =
|
|
|
+ 1668 SymTab.ClArray THEN
|
|
|
+ 1669 QbeGen.ElemLoad(qe, eT, q)
|
|
|
+ 1670 ELSE QbeGen.CopyOp(qe, q)
|
|
|
+ 1671 END;
|
|
|
+ 1672 t := eT; sfx := TRUE
|
|
|
+ 1673 END; .) }
|
|
|
+ 1674 "]"
|
|
|
+ 1675 | "." GetIdent<fn>
|
|
|
+ 1676 (. IF k = SymTab.KindModule THEN
|
|
|
+ 1677 (* qualified L.x: materialize
|
|
|
+ 1678 the export, then load it *)
|
|
|
+ 1679 IF NOT SymTab.MaterializeAlias(n,
|
|
|
+ 1680 fn, mal) THEN
|
|
|
+ 1681 SemError(201);
|
|
|
+ 1682 t := SymTab.InvalidType;
|
|
|
+ 1683 QbeGen.CopyOp("0", q)
|
|
|
+ 1684 ELSE
|
|
|
+ 1685 QbeGen.CopyOp(mal, qn);
|
|
|
+ 1686 t := SymTab.SymType(mal);
|
|
|
+ 1687 k := SymTab.SymKind(mal);
|
|
|
+ 1688 sfx := FALSE;
|
|
|
+ 1689 IF k = SymTab.KindProc THEN
|
|
|
+ 1690 (* call: ArgList supplies
|
|
|
+ 1691 the value *)
|
|
|
+ 1692 QbeGen.CopyOp("0", q)
|
|
|
+ 1693 ELSIF NOT QbeGen.LoadDesignator(
|
|
|
+ 1694 mal, t, k, q) THEN
|
|
|
+ 1695 SemError(230);
|
|
|
+ 1696 QbeGen.CopyOp("0", q)
|
|
|
+ 1697 END
|
|
|
+ 1698 END
|
|
|
+ 1699 ELSIF t = SymTab.InvalidType THEN
|
|
|
+ 1700 ELSIF (SymTab.ClassOf(t) #
|
|
|
+ 1701 SymTab.ClRecord)
|
|
|
+ 1702 AND (SymTab.ClassOf(t) #
|
|
|
+ 1703 SymTab.ClClass) THEN
|
|
|
+ 1704 SemError(215);
|
|
|
+ 1705 t := SymTab.InvalidType
|
|
|
+ 1706 ELSIF NOT SymTab.FieldExists(t,
|
|
|
+ 1707 fn) THEN
|
|
|
+ 1708 SemError(216);
|
|
|
+ 1709 t := SymTab.InvalidType
|
|
|
+ 1710 ELSE
|
|
|
+ 1711 fo := SymTab.FieldOffset(t,
|
|
|
+ 1712 fn);
|
|
|
+ 1713 t := SymTab.FieldType(t, fn);
|
|
|
+ 1714 QbeGen.FieldAddr(q, fo, qe);
|
|
|
+ 1715 (* array fields are inline:
|
|
|
+ 1716 the field address is the
|
|
|
+ 1717 descriptor, like records *)
|
|
|
+ 1718 QbeGen.CopyOp(qe, q);
|
|
|
+ 1719 sfx := TRUE
|
|
|
+ 1720 END; .)
|
|
|
+ 1721 | "^"
|
|
|
+ 1722 (. IF t = SymTab.InvalidType THEN
|
|
|
+ 1723 ELSIF SymTab.ClassOf(t) #
|
|
|
+ 1724 SymTab.ClPtr THEN
|
|
|
+ 1725 SemError(219);
|
|
|
+ 1726 t := SymTab.InvalidType
|
|
|
+ 1727 ELSE
|
|
|
+ 1728 bt := SymTab.PtrBase(t);
|
|
|
+ 1729 IF bt = SymTab.InvalidType THEN
|
|
|
+ 1730 ELSE
|
|
|
+ 1731 IF sfx THEN
|
|
|
+ 1732 QbeGen.ElemLoad(q, t,
|
|
|
+ 1733 qb);
|
|
|
+ 1734 QbeGen.CopyOp(qb, q)
|
|
|
+ 1735 END;
|
|
|
+ 1736 t := bt;
|
|
|
+ 1737 (* q holds the pointee
|
|
|
+ 1738 address: Fact loads
|
|
|
+ 1739 scalars/pointers and uses
|
|
|
+ 1740 the address for
|
|
|
+ 1741 aggregates; the VAR-actual
|
|
|
+ 1742 note is q itself. *)
|
|
|
+ 1743 sfx := TRUE
|
|
|
+ 1744 END
|
|
|
+ 1745 END; .) } .
|
|
|
+ 1746 Expr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 1747 (. VAR t2: SymTab.TypeIndex;
|
|
|
+ 1748 op: INTEGER;
|
|
|
+ 1749 q2, qt, wl: QbeGen.QVal;
|
|
|
+ 1750 isR: BOOLEAN; .)
|
|
|
+ 1751 = SimExpr<t, q>
|
|
|
+ 1752 [ Rel<op> SimExpr<t2, q2>
|
|
|
+ 1753 (. IF op = SymTab.OpIn THEN
|
|
|
+ 1754 IF SymTab.InCheck(t, t2) THEN
|
|
|
+ 1755 IF (t = SymTab.InvalidType)
|
|
|
+ 1756 OR (t2 = SymTab.InvalidType) THEN
|
|
|
+ 1757 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
+ 1758 ELSE
|
|
|
+ 1759 QbeGen.InSet(q, q2, SymTab.SetBaseLo(t2),
|
|
|
+ 1760 SymTab.SetCount(t2), qt);
|
|
|
+ 1761 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 1762 END
|
|
|
+ 1763 ELSE SemError(222); t := SymTab.InvalidType;
|
|
|
+ 1764 QbeGen.CopyOp("0", q)
|
|
|
+ 1765 END
|
|
|
+ 1766 ELSIF SymTab.RelCheck(t, t2, op) THEN
|
|
|
+ 1767 IF (t = SymTab.InvalidType)
|
|
|
+ 1768 OR (t2 = SymTab.InvalidType) THEN
|
|
|
+ 1769 t := SymTab.BoolType(); QbeGen.CopyOp("0", q)
|
|
|
+ 1770 ELSIF (SymTab.ClassOf(t) = SymTab.ClPtr)
|
|
|
+ 1771 OR (SymTab.ClassOf(t2) = SymTab.ClPtr) THEN
|
|
|
+ 1772 IF (op # SymTab.OpEq) AND (op # SymTab.OpNeq1)
|
|
|
+ 1773 AND (op # SymTab.OpNeq2) THEN
|
|
|
+ 1774 SemError(213); t := SymTab.InvalidType;
|
|
|
+ 1775 QbeGen.CopyOp("0", q)
|
|
|
+ 1776 ELSE
|
|
|
+ 1777 QbeGen.CmpL(op, q, q2, qt);
|
|
|
+ 1778 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 1779 END
|
|
|
+ 1780 ELSIF (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 1781 OR (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 1782 QbeGen.CmpSet(op, q, q2,
|
|
|
+ 1783 SymTab.SetWords(t), SymTab.SetWords(t2), qt);
|
|
|
+ 1784 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 1785 ELSIF SymTab.StrCompat(t, t2) THEN
|
|
|
+ 1786 QbeGen.StrEq(op, q, q2, qt);
|
|
|
+ 1787 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 1788 ELSIF SymTab.IsLongFamily(t)
|
|
|
+ 1789 OR SymTab.IsLongFamily(t2) THEN
|
|
|
+ 1790 IF SymTab.IsIntFamily(t) THEN
|
|
|
+ 1791 QbeGen.WidenLong(q, wl); QbeGen.CopyOp(wl, q)
|
|
|
+ 1792 END;
|
|
|
+ 1793 IF SymTab.IsIntFamily(t2) THEN
|
|
|
+ 1794 QbeGen.WidenLong(q2, wl); QbeGen.CopyOp(wl, q2)
|
|
|
+ 1795 END;
|
|
|
+ 1796 QbeGen.CmpLong(op, q, q2, qt);
|
|
|
+ 1797 t := SymTab.BoolType(); QbeGen.CopyOp(qt, q)
|
|
|
+ 1798 ELSE
|
|
|
+ 1799 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
+ 1800 t := SymTab.BoolType();
|
|
|
+ 1801 QbeGen.Cmp(op, q, q2, qt, isR);
|
|
|
+ 1802 QbeGen.CopyOp(qt, q)
|
|
|
+ 1803 END
|
|
|
+ 1804 ELSE SemError(213); t := SymTab.InvalidType;
|
|
|
+ 1805 QbeGen.CopyOp("0", q)
|
|
|
+ 1806 END; .) ] .
|
|
|
+ 1807 Rel<VAR op: INTEGER>
|
|
|
+ 1808 = "=" (. op := SymTab.OpEq; .)
|
|
|
+ 1809 | "#" (. op := SymTab.OpNeq1; .)
|
|
|
+ 1810 | "<" (. op := SymTab.OpLt; .)
|
|
|
+ 1811 | "<=" (. op := SymTab.OpLe; .)
|
|
|
+ 1812 | ">" (. op := SymTab.OpGt; .)
|
|
|
+ 1813 | ">=" (. op := SymTab.OpGe; .)
|
|
|
+ 1814 | "IN" (. op := SymTab.OpIn; .) .
|
|
|
+ 1815 SimExpr<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 1816 (. VAR t2, res2, lt, rt:
|
|
|
+ 1817 SymTab.TypeIndex;
|
|
|
+ 1818 op: INTEGER;
|
|
|
+ 1819 q2, qt, wq, qf:
|
|
|
+ 1820 QbeGen.QVal;
|
|
|
+ 1821 neg, isR, isL, folded:
|
|
|
+ 1822 BOOLEAN;
|
|
|
+ 1823 lw, rw, mw: CARDINAL;
|
|
|
+ 1824 lTrue, lNext, lDone, qr, qs:
|
|
|
+ 1825 QbeGen.QVal; .)
|
|
|
+ 1826 = (. neg := FALSE; .)
|
|
|
+ 1827 [ "+" | "-" (. neg := TRUE; .) ]
|
|
|
+ 1828 Term<t, q> (. IF neg THEN
|
|
|
+ 1829 IF QbeGen.IsImm(q) THEN
|
|
|
+ 1830 QbeGen.NegFold(q, q)
|
|
|
+ 1831 ELSE QbeGen.NewTemp(qt);
|
|
|
+ 1832 QbeGen.NegQ(q, qt,
|
|
|
+ 1833 SymTab.ClassOf(t)
|
|
|
+ 1834 = SymTab.ClReal);
|
|
|
+ 1835 QbeGen.CopyOp(qt, q)
|
|
|
+ 1836 END
|
|
|
+ 1837 END; .)
|
|
|
+ 1838 { AddOp<op> (. IF op = SymTab.OpOr THEN
|
|
|
+ 1839 QbeGen.DelayBegin END; .)
|
|
|
+ 1840 Term<t2, q2> (. IF op = SymTab.OpOr THEN
|
|
|
+ 1841 QbeGen.DelayEnd END; .)
|
|
|
+ 1842 (. IF op = SymTab.OpOr THEN
|
|
|
+ 1843 (* short-circuit: if q is true the RHS is skipped *)
|
|
|
+ 1844 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
+ 1845 t := SymTab.BoolType()
|
|
|
+ 1846 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
+ 1847 IF t # SymTab.InvalidType THEN
|
|
|
+ 1848 QbeGen.Slot4(qs);
|
|
|
+ 1849 QbeGen.NewLabel(lTrue);
|
|
|
+ 1850 QbeGen.NewLabel(lNext);
|
|
|
+ 1851 QbeGen.NewLabel(lDone);
|
|
|
+ 1852 QbeGen.Jnz(q, lTrue, lNext);
|
|
|
+ 1853 QbeGen.EmitLabel(lTrue);
|
|
|
+ 1854 QbeGen.StoreW(qs, "1");
|
|
|
+ 1855 QbeGen.Jmp(lDone);
|
|
|
+ 1856 QbeGen.EmitLabel(lNext);
|
|
|
+ 1857 QbeGen.DelayFlush;
|
|
|
+ 1858 QbeGen.StoreW(qs, q2);
|
|
|
+ 1859 QbeGen.Jmp(lDone);
|
|
|
+ 1860 QbeGen.EmitLabel(lDone);
|
|
|
+ 1861 QbeGen.LoadW(qs, qr);
|
|
|
+ 1862 QbeGen.CopyOp(qr, q)
|
|
|
+ 1863 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
+ 1864 END
|
|
|
+ 1865 ELSIF (op = SymTab.OpAdd)
|
|
|
+ 1866 AND (SymTab.StrCompat(t, t2)
|
|
|
+ 1867 OR (SymTab.IsStrType(t)
|
|
|
+ 1868 AND (SymTab.ClassOf(t2) = SymTab.ClChar))
|
|
|
+ 1869 OR ((SymTab.ClassOf(t) = SymTab.ClChar)
|
|
|
+ 1870 AND SymTab.IsStrType(t2))) THEN
|
|
|
+ 1871 (* string concatenation; a CHAR operand becomes a
|
|
|
+ 1872 1-character string literal *)
|
|
|
+ 1873 IF SymTab.StrCompat(t, t2) THEN
|
|
|
+ 1874 QbeGen.StrCat(q, q2, qt)
|
|
|
+ 1875 ELSIF SymTab.IsStrType(t) THEN
|
|
|
+ 1876 QbeGen.DeclCharStr(q2, qs);
|
|
|
+ 1877 QbeGen.StrCat(q, qs, qt)
|
|
|
+ 1878 ELSE
|
|
|
+ 1879 QbeGen.DeclCharStr(q, qs);
|
|
|
+ 1880 QbeGen.StrCat(qs, q2, qt)
|
|
|
+ 1881 END;
|
|
|
+ 1882 t := SymTab.NewStr();
|
|
|
+ 1883 QbeGen.CopyOp(qt, q)
|
|
|
+ 1884 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
+ 1885 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 1886 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 1887 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
+ 1888 mw := lw;
|
|
|
+ 1889 IF rw > mw THEN mw := rw END;
|
|
|
+ 1890 IF op = SymTab.OpAdd THEN
|
|
|
+ 1891 QbeGen.SetBinOp(0, q, q2, lw, rw, qt)
|
|
|
+ 1892 ELSE
|
|
|
+ 1893 QbeGen.SetBinOp(2, q, q2, lw, rw, qt)
|
|
|
+ 1894 END;
|
|
|
+ 1895 t := SymTab.NewSet(
|
|
|
+ 1896 SymTab.NewSubR(0,
|
|
|
+ 1897 VAL(INTEGER, mw) * 32 - 1));
|
|
|
+ 1898 QbeGen.CopyOp(qt, q)
|
|
|
+ 1899 ELSE
|
|
|
+ 1900 IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
|
|
|
+ 1901 lt := t; rt := t2; t := res2
|
|
|
+ 1902 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
+ 1903 IF t # SymTab.InvalidType THEN
|
|
|
+ 1904 isL := SymTab.IsLongFamily(t);
|
|
|
+ 1905 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
+ 1906 folded := FALSE;
|
|
|
+ 1907 IF (NOT isL) AND (NOT isR)
|
|
|
+ 1908 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
+ 1909 IF op = SymTab.OpAdd THEN
|
|
|
+ 1910 folded := QbeGen.Fold2(0, q, q2, qf)
|
|
|
+ 1911 ELSE
|
|
|
+ 1912 folded := QbeGen.Fold2(1, q, q2, qf)
|
|
|
+ 1913 END
|
|
|
+ 1914 END;
|
|
|
+ 1915 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
+ 1916 ELSE
|
|
|
+ 1917 IF isL THEN
|
|
|
+ 1918 IF SymTab.IsIntFamily(lt) THEN
|
|
|
+ 1919 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
+ 1920 END;
|
|
|
+ 1921 IF SymTab.IsIntFamily(rt) THEN
|
|
|
+ 1922 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
+ 1923 END;
|
|
|
+ 1924 QbeGen.NewTemp(qt);
|
|
|
+ 1925 IF op = SymTab.OpAdd THEN
|
|
|
+ 1926 QbeGen.Op3L("add", qt, q, q2)
|
|
|
+ 1927 ELSE
|
|
|
+ 1928 QbeGen.Op3L("sub", qt, q, q2)
|
|
|
+ 1929 END
|
|
|
+ 1930 ELSE
|
|
|
+ 1931 QbeGen.NewTemp(qt);
|
|
|
+ 1932 IF op = SymTab.OpAdd THEN
|
|
|
+ 1933 QbeGen.Op3("add", qt, q, q2, isR)
|
|
|
+ 1934 ELSE
|
|
|
+ 1935 QbeGen.Op3("sub", qt, q, q2, isR)
|
|
|
+ 1936 END
|
|
|
+ 1937 END;
|
|
|
+ 1938 QbeGen.CopyOp(qt, q)
|
|
|
+ 1939 END
|
|
|
+ 1940 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 1941 END
|
|
|
+ 1942 END; .) } .
|
|
|
+ 1943 AddOp<VAR op: INTEGER>
|
|
|
+ 1944 = "+" (. op := SymTab.OpAdd; .)
|
|
|
+ 1945 | "-" (. op := SymTab.OpSub; .)
|
|
|
+ 1946 | "OR" (. op := SymTab.OpOr; .) .
|
|
|
+ 1947 Term<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 1948 (. VAR t2, res2, lt, rt:
|
|
|
+ 1949 SymTab.TypeIndex;
|
|
|
+ 1950 op: INTEGER;
|
|
|
+ 1951 q2, qt, wq, qf:
|
|
|
+ 1952 QbeGen.QVal;
|
|
|
+ 1953 isR, isL, folded: BOOLEAN;
|
|
|
+ 1954 lw, rw, mw: CARDINAL;
|
|
|
+ 1955 lNext, lFalse, lDone, qr, qs:
|
|
|
+ 1956 QbeGen.QVal; .)
|
|
|
+ 1957 = Fact<t, q> { MulOp<op> (. IF op = SymTab.OpAnd THEN
|
|
|
+ 1958 QbeGen.DelayBegin END; .)
|
|
|
+ 1959 Fact<t2, q2> (. IF op = SymTab.OpAnd THEN
|
|
|
+ 1960 QbeGen.DelayEnd END; .)
|
|
|
+ 1961 (. IF op = SymTab.OpAnd THEN
|
|
|
+ 1962 (* short-circuit: if q is false the RHS is skipped *)
|
|
|
+ 1963 IF SymTab.BoolCheck(t) AND SymTab.BoolCheck(t2) THEN
|
|
|
+ 1964 t := SymTab.BoolType()
|
|
|
+ 1965 ELSE SemError(212); t := SymTab.InvalidType END;
|
|
|
+ 1966 IF t # SymTab.InvalidType THEN
|
|
|
+ 1967 QbeGen.Slot4(qs);
|
|
|
+ 1968 QbeGen.NewLabel(lNext);
|
|
|
+ 1969 QbeGen.NewLabel(lFalse);
|
|
|
+ 1970 QbeGen.NewLabel(lDone);
|
|
|
+ 1971 QbeGen.Jnz(q, lNext, lFalse);
|
|
|
+ 1972 QbeGen.EmitLabel(lNext);
|
|
|
+ 1973 QbeGen.DelayFlush;
|
|
|
+ 1974 QbeGen.StoreW(qs, q2);
|
|
|
+ 1975 QbeGen.Jmp(lDone);
|
|
|
+ 1976 QbeGen.EmitLabel(lFalse);
|
|
|
+ 1977 QbeGen.StoreW(qs, "0");
|
|
|
+ 1978 QbeGen.Jmp(lDone);
|
|
|
+ 1979 QbeGen.EmitLabel(lDone);
|
|
|
+ 1980 QbeGen.LoadW(qs, qr);
|
|
|
+ 1981 QbeGen.CopyOp(qr, q)
|
|
|
+ 1982 ELSE QbeGen.DelayFlush; QbeGen.CopyOp("0", q)
|
|
|
+ 1983 END
|
|
|
+ 1984 ELSIF (t # SymTab.InvalidType) AND (t2 # SymTab.InvalidType)
|
|
|
+ 1985 AND (SymTab.ClassOf(t) = SymTab.ClSet)
|
|
|
+ 1986 AND (SymTab.ClassOf(t2) = SymTab.ClSet) THEN
|
|
|
+ 1987 lw := SymTab.SetWords(t); rw := SymTab.SetWords(t2);
|
|
|
+ 1988 mw := lw;
|
|
|
+ 1989 IF rw > mw THEN mw := rw END;
|
|
|
+ 1990 IF op = SymTab.OpTimes THEN
|
|
|
+ 1991 QbeGen.SetBinOp(1, q, q2, lw, rw, qt)
|
|
|
+ 1992 ELSE
|
|
|
+ 1993 QbeGen.SetBinOp(3, q, q2, lw, rw, qt)
|
|
|
+ 1994 END;
|
|
|
+ 1995 t := SymTab.NewSet(
|
|
|
+ 1996 SymTab.NewSubR(0,
|
|
|
+ 1997 VAL(INTEGER, mw) * 32 - 1));
|
|
|
+ 1998 QbeGen.CopyOp(qt, q)
|
|
|
+ 1999 ELSE
|
|
|
+ 2000 IF SymTab.ArithCheck(t, t2,
|
|
|
+ 2001 (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
|
|
|
+ 2002 res2) THEN
|
|
|
+ 2003 lt := t; rt := t2; t := res2
|
|
|
+ 2004 ELSE SemError(211); t := SymTab.InvalidType END;
|
|
|
+ 2005 IF t # SymTab.InvalidType THEN
|
|
|
+ 2006 isL := SymTab.IsLongFamily(t);
|
|
|
+ 2007 isR := SymTab.ClassOf(t) = SymTab.ClReal;
|
|
|
+ 2008 folded := FALSE;
|
|
|
+ 2009 IF (NOT isL) AND (NOT isR)
|
|
|
+ 2010 AND QbeGen.IsImm(q) AND QbeGen.IsImm(q2) THEN
|
|
|
+ 2011 IF op = SymTab.OpTimes THEN
|
|
|
+ 2012 folded := QbeGen.Fold2(2, q, q2, qf)
|
|
|
+ 2013 ELSIF op = SymTab.OpDiv THEN
|
|
|
+ 2014 folded := QbeGen.Fold2(3, q, q2, qf)
|
|
|
+ 2015 ELSIF op = SymTab.OpMod THEN
|
|
|
+ 2016 folded := QbeGen.Fold2(4, q, q2, qf)
|
|
|
+ 2017 END
|
|
|
+ 2018 END;
|
|
|
+ 2019 IF folded THEN QbeGen.CopyOp(qf, q)
|
|
|
+ 2020 ELSE
|
|
|
+ 2021 IF isL THEN
|
|
|
+ 2022 IF SymTab.IsIntFamily(lt) THEN
|
|
|
+ 2023 QbeGen.WidenLong(q, wq); QbeGen.CopyOp(wq, q)
|
|
|
+ 2024 END;
|
|
|
+ 2025 IF SymTab.IsIntFamily(rt) THEN
|
|
|
+ 2026 QbeGen.WidenLong(q2, wq); QbeGen.CopyOp(wq, q2)
|
|
|
+ 2027 END;
|
|
|
+ 2028 QbeGen.NewTemp(qt);
|
|
|
+ 2029 IF op = SymTab.OpTimes THEN
|
|
|
+ 2030 QbeGen.Op3L("mul", qt, q, q2)
|
|
|
+ 2031 ELSIF (op = SymTab.OpDiv)
|
|
|
+ 2032 OR (op = SymTab.OpSlash) THEN
|
|
|
+ 2033 QbeGen.Op3L("div", qt, q, q2)
|
|
|
+ 2034 ELSE
|
|
|
+ 2035 QbeGen.Op3L("rem", qt, q, q2)
|
|
|
+ 2036 END
|
|
|
+ 2037 ELSE
|
|
|
+ 2038 QbeGen.NewTemp(qt);
|
|
|
+ 2039 IF op = SymTab.OpTimes THEN
|
|
|
+ 2040 QbeGen.Op3("mul", qt, q, q2, isR)
|
|
|
+ 2041 ELSIF (op = SymTab.OpDiv)
|
|
|
+ 2042 OR (op = SymTab.OpSlash) THEN
|
|
|
+ 2043 QbeGen.Op3("div", qt, q, q2, isR)
|
|
|
+ 2044 ELSE
|
|
|
+ 2045 QbeGen.Op3("rem", qt, q, q2, isR)
|
|
|
+ 2046 END
|
|
|
+ 2047 END;
|
|
|
+ 2048 QbeGen.CopyOp(qt, q)
|
|
|
+ 2049 END
|
|
|
+ 2050 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 2051 END
|
|
|
+ 2052 END; .) } .
|
|
|
+ 2053 MulOp<VAR op: INTEGER>
|
|
|
+ 2054 = "*" (. op := SymTab.OpTimes; .)
|
|
|
+ 2055 | "/" (. op := SymTab.OpSlash; .)
|
|
|
+ 2056 | "DIV" (. op := SymTab.OpDiv; .)
|
|
|
+ 2057 | "MOD" (. op := SymTab.OpMod; .)
|
|
|
+ 2058 | ( "AND" | "&" ) (. op := SymTab.OpAnd; .) .
|
|
|
+ 2059 Fact<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 2060 (. VAR s: ARRAY [0 .. 255] OF CHAR;
|
|
|
+ 2061 et, dt, t2, st, ct2:
|
|
|
+ 2062 SymTab.TypeIndex;
|
|
|
+ 2063 dk: INTEGER;
|
|
|
+ 2064 qd, q2, sq, qa, qm0, qr:
|
|
|
+ 2065 QbeGen.QVal;
|
|
|
+ 2066 qn, vn: SymTab.Name;
|
|
|
+ 2067 vt: SymTab.TypeIndex;
|
|
|
+ 2068 c1, c2: INTEGER;
|
|
|
+ 2069 called, isHigh, sfx, isCh,
|
|
|
+ 2070 isU, uok, isStr: BOOLEAN;
|
|
|
+ 2071 ucp: INTEGER; .)
|
|
|
+ 2072 = integer (. LexString(s);
|
|
|
+ 2073 QbeGen.NormInt(s, q);
|
|
|
+ 2074 t := SymTab.IntType(); .)
|
|
|
+ 2075 | charConst (. LexString(s);
|
|
|
+ 2076 QbeGen.NormLit(s, q, isCh);
|
|
|
+ 2077 t := SymTab.CharType(); .)
|
|
|
+ 2078 | real (. LexString(s);
|
|
|
+ 2079 QbeGen.NormReal(s, q);
|
|
|
+ 2080 t := SymTab.RealType(); .)
|
|
|
+ 2081 | string (. LexString(s);
|
|
|
+ 2082 IF SymTab.StrLen(s) = 3 THEN
|
|
|
+ 2083 t := SymTab.CharType();
|
|
|
+ 2084 QbeGen.IntStr(
|
|
|
+ 2085 QbeGen.CharVal(s), q)
|
|
|
+ 2086 ELSE t := SymTab.NewStr();
|
|
|
+ 2087 QbeGen.DeclStr(s, q);
|
|
|
+ 2088 (* a literal's value IS its
|
|
|
+ 2089 static descriptor address *)
|
|
|
+ 2090 QbeGen.NoteAddr(q, q)
|
|
|
+ 2091 END; .)
|
|
|
+ 2092 | ustring (. LexString(s);
|
|
|
+ 2093 QbeGen.DeclUStr(s, q, isU, ucp,
|
|
|
+ 2094 uok);
|
|
|
+ 2095 IF NOT uok THEN
|
|
|
+ 2096 SemError(234);
|
|
|
+ 2097 t := SymTab.InvalidType
|
|
|
+ 2098 ELSIF isU THEN
|
|
|
+ 2099 t := SymTab.UCharType();
|
|
|
+ 2100 QbeGen.IntStr(ucp, q)
|
|
|
+ 2101 ELSE
|
|
|
+ 2102 t := SymTab.NewUStr();
|
|
|
+ 2103 QbeGen.NoteAddr(q, q)
|
|
|
+ 2104 END; .)
|
|
|
+ 2105 | Design<dt, dk, qd, qn, sfx> (. called := FALSE;
|
|
|
+ 2106 t := dt;
|
|
|
+ 2107 IF sfx THEN
|
|
|
+ 2108 IF dt =
|
|
|
+ 2109 SymTab.InvalidType THEN
|
|
|
+ 2110 QbeGen.CopyOp("0", q)
|
|
|
+ 2111 ELSIF (SymTab.ClassOf(dt) =
|
|
|
+ 2112 SymTab.ClRecord)
|
|
|
+ 2113 OR (SymTab.ClassOf(dt) =
|
|
|
+ 2114 SymTab.ClSet)
|
|
|
+ 2115 OR (SymTab.ClassOf(dt) =
|
|
|
+ 2116 SymTab.ClArray)
|
|
|
+ 2117 OR (SymTab.ClassOf(dt) =
|
|
|
+ 2118 SymTab.ClClass) THEN
|
|
|
+ 2119 QbeGen.CopyOp(qd, q)
|
|
|
+ 2120 ELSE QbeGen.ElemLoad(qd, dt,
|
|
|
+ 2121 q)
|
|
|
2122 END
|
|
|
- 2123 ELSIF sfx
|
|
|
- 2124 AND (dt #
|
|
|
- 2125 SymTab.InvalidType)
|
|
|
- 2126 AND ((SymTab.ClassOf(dt) =
|
|
|
- 2127 SymTab.ClArray)
|
|
|
- 2128 OR (SymTab.ClassOf(dt) =
|
|
|
- 2129 SymTab.ClSet)
|
|
|
- 2130 OR (SymTab.ClassOf(dt) =
|
|
|
- 2131 SymTab.ClRecord)) THEN
|
|
|
- 2132 QbeGen.NoteAddr(qd, qd)
|
|
|
- 2133 END; .)
|
|
|
- 2134 [ TypedSetLit<dt, q> (. t := dt; .) ]
|
|
|
- 2135 [ ArgList<qn, dt, qd, TRUE, ct2, q2, called>
|
|
|
- 2136 (. t := ct2;
|
|
|
- 2137 QbeGen.CopyOp(q2, q); .) ]
|
|
|
- 2138 (. IF NOT called
|
|
|
- 2139 AND (dk = SymTab.KindProc) THEN
|
|
|
- 2140 (* bare zero-arg function
|
|
|
- 2141 call (parentheses may be
|
|
|
- 2142 omitted); a proper or
|
|
|
- 2143 parameterised proc here
|
|
|
- 2144 is 230 *)
|
|
|
- 2145 IF (SymTab.ProcNPar(qn) = 0)
|
|
|
- 2146 AND (SymTab.ProcRes(qn) #
|
|
|
- 2147 SymTab.InvalidType) THEN
|
|
|
- 2148 QbeGen.Mangled(qn,
|
|
|
- 2149 SymTab.ProcUid(qn), qm0);
|
|
|
- 2150 QbeGen.CallBegin(qm0,
|
|
|
- 2151 SymTab.ProcRes(qn),
|
|
|
- 2152 SymTab.ProcDepthOf(qn),
|
|
|
- 2153 SymTab.IsExternal(qn));
|
|
|
- 2154 QbeGen.CallEnd(TRUE, q);
|
|
|
- 2155 t := SymTab.ProcRes(qn)
|
|
|
- 2156 ELSE
|
|
|
- 2157 (* procedure used as a
|
|
|
- 2158 value (assign to a
|
|
|
- 2159 procedure variable):
|
|
|
- 2160 its code address *)
|
|
|
- 2161 t := SymTab.ProcTypeOf(qn);
|
|
|
- 2162 QbeGen.Mangled(qn,
|
|
|
- 2163 SymTab.ProcUid(qn), qm0);
|
|
|
- 2164 QbeGen.ProcAddr(qm0, q)
|
|
|
- 2165 END
|
|
|
- 2166 END; .)
|
|
|
- 2167 | ( "HIGH" (. isHigh := TRUE; .)
|
|
|
- 2168 | ( "LEN" | "LENGTH" ) (. isHigh := FALSE; .) )
|
|
|
- 2169 "(" ( Design<dt, dk, qd, qn, sfx> (. isStr := FALSE; .)
|
|
|
- 2170 | string (. LexString(s);
|
|
|
- 2171 isStr := TRUE;
|
|
|
- 2172 IF SymTab.StrLen(s) = 3 THEN
|
|
|
- 2173 dt := SymTab.CharType();
|
|
|
- 2174 QbeGen.IntStr(QbeGen.CharVal(s),
|
|
|
- 2175 qd)
|
|
|
- 2176 ELSE
|
|
|
- 2177 dt := SymTab.NewStr();
|
|
|
- 2178 QbeGen.DeclStr(s, qd);
|
|
|
- 2179 QbeGen.NoteAddr(qd, qd)
|
|
|
- 2180 END;
|
|
|
- 2181 dk := -1;
|
|
|
- 2182 qn[0] := CHR(0); .) )
|
|
|
- 2183 ")"
|
|
|
- 2184 (. IF isStr THEN
|
|
|
- 2185 (* fold: content length at
|
|
|
- 2186 compile time *)
|
|
|
- 2187 IF SymTab.StrLen(s) = 3 THEN
|
|
|
- 2188 c1 := 1
|
|
|
- 2189 ELSE
|
|
|
- 2190 c1 :=
|
|
|
- 2191 SymTab.StrLen(s) - 2
|
|
|
- 2192 END;
|
|
|
- 2193 IF isHigh THEN
|
|
|
- 2194 DEC(c1)
|
|
|
- 2195 END;
|
|
|
- 2196 QbeGen.IntStr(c1, qr);
|
|
|
- 2197 t := SymTab.IntType();
|
|
|
- 2198 QbeGen.CopyOp(qr, q)
|
|
|
- 2199 ELSIF dt = SymTab.InvalidType THEN
|
|
|
- 2200 t := SymTab.InvalidType;
|
|
|
- 2201 QbeGen.CopyOp("0", q)
|
|
|
- 2202 ELSIF SymTab.ClassOf(dt) #
|
|
|
- 2203 SymTab.ClArray THEN
|
|
|
- 2204 SemError(217);
|
|
|
- 2205 t := SymTab.InvalidType;
|
|
|
- 2206 QbeGen.CopyOp("0", q)
|
|
|
- 2207 ELSE
|
|
|
- 2208 IF isHigh THEN
|
|
|
- 2209 IF SymTab.IsOpenArray(dt) THEN
|
|
|
- 2210 QbeGen.OpenHi(qd, qr)
|
|
|
- 2211 ELSE
|
|
|
- 2212 QbeGen.IntStr(
|
|
|
- 2213 SymTab.ArrayHi(dt), qr)
|
|
|
- 2214 END
|
|
|
- 2215 ELSE
|
|
|
- 2216 IF SymTab.IsOpenArray(dt) THEN
|
|
|
- 2217 QbeGen.LoadCount(qd, qr)
|
|
|
- 2218 ELSE
|
|
|
- 2219 QbeGen.IntStr(VAL(
|
|
|
- 2220 INTEGER,
|
|
|
- 2221 SymTab.ArrayLen(dt)),
|
|
|
- 2222 qr)
|
|
|
- 2223 END
|
|
|
- 2224 END;
|
|
|
- 2225 t := SymTab.IntType();
|
|
|
- 2226 QbeGen.CopyOp(qr, q)
|
|
|
- 2227 END; .)
|
|
|
- 2228 | ( "SIZE" | "TSIZE" ) "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 2229 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 2230 t := SymTab.InvalidType;
|
|
|
- 2231 QbeGen.CopyOp("0", q)
|
|
|
- 2232 ELSE
|
|
|
- 2233 QbeGen.IntStr(VAL(INTEGER,
|
|
|
- 2234 SymTab.ObjectSize(dt)), q);
|
|
|
- 2235 t := SymTab.IntType()
|
|
|
- 2236 END; .)
|
|
|
- 2237 | "ADR" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
- 2238 (. IF dt = SymTab.InvalidType THEN
|
|
|
- 2239 t := SymTab.InvalidType;
|
|
|
- 2240 QbeGen.CopyOp("0", q)
|
|
|
- 2241 ELSE
|
|
|
- 2242 IF sfx THEN
|
|
|
- 2243 QbeGen.CopyOp(qd, q)
|
|
|
- 2244 ELSIF (dk = SymTab.KindVar)
|
|
|
- 2245 OR (dk = SymTab.KindParam) THEN
|
|
|
- 2246 QbeGen.AddrOf(qn, q)
|
|
|
- 2247 ELSE SemError(230);
|
|
|
- 2248 QbeGen.CopyOp("0", q)
|
|
|
- 2249 END;
|
|
|
- 2250 t := SymTab.AddrType()
|
|
|
- 2251 END; .)
|
|
|
- 2252 | "CHR" "(" Expr<et, q> ")"
|
|
|
- 2253 (. IF (et # SymTab.InvalidType)
|
|
|
- 2254 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
- 2255 SemError(211) END;
|
|
|
- 2256 t := SymTab.CharType(); .)
|
|
|
- 2257 | ( "ORD" | "ORDL" ) "(" Expr<et, q> ")"
|
|
|
- 2258 (. IF et # SymTab.InvalidType THEN
|
|
|
- 2259 IF (SymTab.ClassOf(et) #
|
|
|
- 2260 SymTab.ClChar)
|
|
|
- 2261 AND (SymTab.ClassOf(et) #
|
|
|
- 2262 SymTab.ClBool)
|
|
|
- 2263 AND (SymTab.ClassOf(et) #
|
|
|
- 2264 SymTab.ClEnum)
|
|
|
- 2265 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
- 2266 SemError(211) END
|
|
|
- 2267 END;
|
|
|
- 2268 t := SymTab.IntType(); .)
|
|
|
- 2269 | "CAP" "(" Expr<et, q> ")"
|
|
|
- 2270 (. QbeGen.CapQ(q, qa);
|
|
|
- 2271 QbeGen.CopyOp(qa, q);
|
|
|
- 2272 t := SymTab.CharType(); .)
|
|
|
- 2273 | "UCHR" "(" Expr<et, q> ")"
|
|
|
- 2274 (. (* UCHR: the UCHAR constructor.
|
|
|
- 2275 CHAR -> UCHAR (identity);
|
|
|
- 2276 INTEGER familly -> UCHAR
|
|
|
- 2277 (codepoint value). *)
|
|
|
- 2278 IF (et # SymTab.InvalidType)
|
|
|
- 2279 AND (SymTab.ClassOf(et) # SymTab.ClChar)
|
|
|
- 2280 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
- 2281 SemError(211) END;
|
|
|
- 2282 t := SymTab.UCharType(); .)
|
|
|
- 2283 | "CHR8" "(" Expr<et, q> ")"
|
|
|
- 2284 (. IF (et # SymTab.InvalidType)
|
|
|
- 2285 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
- 2286 SemError(211) END;
|
|
|
- 2287 QbeGen.WidenLong(q, qa);
|
|
|
- 2288 QbeGen.CheckRange(qa, "0", "255");
|
|
|
- 2289 t := SymTab.CharType(); .)
|
|
|
- 2290 | "UORD" "(" Expr<et, q> ")"
|
|
|
- 2291 (. (* UORD(u): the codepoint as a
|
|
|
- 2292 32-bit ordinal (INTEGER),
|
|
|
- 2293 cf. ORD for CHAR. *)
|
|
|
- 2294 IF (et # SymTab.InvalidType)
|
|
|
- 2295 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
- 2296 SemError(211) END;
|
|
|
- 2297 t := SymTab.IntType(); .)
|
|
|
- 2298 | "ABS" "(" Expr<et, q> ")"
|
|
|
- 2299 (. IF (et # SymTab.InvalidType)
|
|
|
- 2300 AND NOT SymTab.IsIntFamily(et)
|
|
|
- 2301 AND (SymTab.ClassOf(et) #
|
|
|
- 2302 SymTab.ClReal) THEN
|
|
|
- 2303 SemError(211)
|
|
|
- 2304 ELSE QbeGen.AbsQ(q, qa,
|
|
|
- 2305 SymTab.ClassOf(et) =
|
|
|
- 2306 SymTab.ClReal);
|
|
|
- 2307 QbeGen.CopyOp(qa, q)
|
|
|
- 2308 END;
|
|
|
- 2309 t := et; .)
|
|
|
- 2310 | "VAL" "(" GetIdent<vn> "," Expr<et, q> ")"
|
|
|
- 2311 (. IF NOT SymTab.Lookup(vn) THEN
|
|
|
- 2312 SemError(201);
|
|
|
- 2313 t := SymTab.InvalidType
|
|
|
- 2314 ELSE vt := SymTab.SymType(vn);
|
|
|
- 2315 IF vt = SymTab.InvalidType THEN
|
|
|
- 2316 t := SymTab.InvalidType
|
|
|
- 2317 ELSIF et =
|
|
|
- 2318 SymTab.InvalidType THEN
|
|
|
- 2319 t := vt
|
|
|
- 2320 ELSE
|
|
|
- 2321 c1 := SymTab.ClassOf(et);
|
|
|
- 2322 c2 := SymTab.ClassOf(vt);
|
|
|
- 2323 IF ((c1 = SymTab.ClInt)
|
|
|
- 2324 OR (c1 =
|
|
|
- 2325 SymTab.ClChar)
|
|
|
- 2326 OR (c1 =
|
|
|
- 2327 SymTab.ClBool)
|
|
|
- 2328 OR (c1 =
|
|
|
- 2329 SymTab.ClEnum))
|
|
|
- 2330 AND ((c2 = SymTab.ClInt)
|
|
|
- 2331 OR (c2 =
|
|
|
- 2332 SymTab.ClChar)
|
|
|
- 2333 OR (c2 =
|
|
|
- 2334 SymTab.ClBool)
|
|
|
- 2335 OR (c2 =
|
|
|
- 2336 SymTab.ClEnum)) THEN
|
|
|
- 2337 t := vt
|
|
|
- 2338 ELSIF (c1 = SymTab.ClPtr)
|
|
|
- 2339 AND (c2 = SymTab.ClPtr) THEN
|
|
|
- 2340 t := vt
|
|
|
- 2341 ELSIF (c1 = SymTab.ClReal)
|
|
|
- 2342 AND (c2 = SymTab.ClReal) THEN
|
|
|
- 2343 t := vt
|
|
|
- 2344 ELSE SemError(230);
|
|
|
- 2345 t := SymTab.InvalidType
|
|
|
- 2346 END
|
|
|
- 2347 END
|
|
|
- 2348 END; .)
|
|
|
- 2349 | "(" Expr<et, q> ")" (. t := et; .)
|
|
|
- 2350 | SetLit<st, sq> (. t := st;
|
|
|
- 2351 QbeGen.CopyOp(sq, q); .)
|
|
|
- 2352 | ( "NOT" | "~" ) Fact<t2, q2> (. IF SymTab.BoolCheck(t2) THEN
|
|
|
- 2353 t := SymTab.BoolType()
|
|
|
- 2354 ELSE SemError(212);
|
|
|
- 2355 t := SymTab.InvalidType END;
|
|
|
- 2356 IF t # SymTab.InvalidType THEN
|
|
|
- 2357 QbeGen.NotQ(q2, q)
|
|
|
- 2358 ELSE QbeGen.CopyOp("0", q)
|
|
|
- 2359 END; .) .
|
|
|
- 2360 (* Set literals are SET OF [0..255] (8 words); elements validated
|
|
|
- 2361 0..255 statically when foldable (222 otherwise), runtime trap
|
|
|
- 2362 for computed elements. Ranges always lower via SetRange. *)
|
|
|
- 2363 SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 2364 = "{" (. t := SymTab.NewSet(
|
|
|
- 2365 SymTab.NewSubR(0, 255));
|
|
|
- 2366 QbeGen.NewSetTemp(8, q);
|
|
|
- 2367 QbeGen.SetZero(q, 8); .)
|
|
|
- 2368 [ SetElem<t, q> { "," SetElem<t, q> } ]
|
|
|
- 2369 "}" .
|
|
|
- 2370 (* Typed set constructor: TypeName{ elems } — e.g. BITSET{0},
|
|
|
- 2371 BITSET{}. The declared type (not SET OF [0..255]) sets the
|
|
|
- 2372 width and element span. *)
|
|
|
- 2373 TypedSetLit<vt: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
- 2374 (. VAR nw: CARDINAL; .)
|
|
|
- 2375 = "{" (. IF SymTab.ClassOf(vt) #
|
|
|
- 2376 SymTab.ClSet THEN
|
|
|
- 2377 SemError(230); nw := 8
|
|
|
- 2378 ELSE nw := SymTab.SetWords(vt);
|
|
|
- 2379 IF nw = 0 THEN nw := 8 END
|
|
|
- 2380 END;
|
|
|
- 2381 QbeGen.NewSetTemp(nw, q);
|
|
|
- 2382 QbeGen.SetZero(q, nw); .)
|
|
|
- 2383 [ SetElem<vt, q> { "," SetElem<vt, q> } ]
|
|
|
- 2384 "}" .
|
|
|
- 2385 SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal> (. VAR et, et2: SymTab.TypeIndex;
|
|
|
- 2386 qe, q2: QbeGen.QVal;
|
|
|
- 2387 v, v2: INTEGER;
|
|
|
- 2388 lo: INTEGER;
|
|
|
- 2389 span: CARDINAL;
|
|
|
- 2390 cl, cl2: INTEGER;
|
|
|
- 2391 hasR: BOOLEAN; .)
|
|
|
- 2392 = (. hasR := FALSE; .)
|
|
|
- 2393 Expr<et, qe>
|
|
|
- 2394 [ ".." Expr<et2, q2> (. hasR := TRUE; .) ]
|
|
|
- 2395 (. lo := SymTab.SetBaseLo(st);
|
|
|
- 2396 span := SymTab.SetCount(st);
|
|
|
- 2397 IF (et = SymTab.InvalidType)
|
|
|
- 2398 OR (hasR AND (et2 =
|
|
|
- 2399 SymTab.InvalidType)) THEN
|
|
|
- 2400 ELSE cl :=
|
|
|
- 2401 SymTab.ClassOf(et);
|
|
|
- 2402 IF hasR THEN
|
|
|
- 2403 cl2 :=
|
|
|
- 2404 SymTab.ClassOf(et2)
|
|
|
- 2405 ELSE cl2 := SymTab.ClInt
|
|
|
- 2406 END;
|
|
|
- 2407 IF ((cl # SymTab.ClInt)
|
|
|
- 2408 AND (cl # SymTab.ClChar)
|
|
|
- 2409 AND (cl # SymTab.ClBool))
|
|
|
- 2410 OR (hasR AND
|
|
|
- 2411 ((cl2
|
|
|
- 2412 # SymTab.ClInt)
|
|
|
- 2413 AND (cl2
|
|
|
- 2414 # SymTab.ClChar)
|
|
|
- 2415 AND (cl2
|
|
|
- 2416 # SymTab.ClBool))) THEN
|
|
|
- 2417 SemError(222)
|
|
|
- 2418 ELSIF hasR
|
|
|
- 2419 AND SymTab.ConstInt(qe, v)
|
|
|
- 2420 AND SymTab.ConstInt(q2,
|
|
|
- 2421 v2)
|
|
|
- 2422 AND ((v < lo)
|
|
|
- 2423 OR (v2 < lo)
|
|
|
- 2424 OR (v >= lo +
|
|
|
- 2425 VAL(INTEGER, span))
|
|
|
- 2426 OR (v2 >= lo +
|
|
|
- 2427 VAL(INTEGER, span))
|
|
|
- 2428 OR (v > v2)) THEN
|
|
|
+ 2123 ELSE QbeGen.CopyOp(qd, q)
|
|
|
+ 2124 END;
|
|
|
+ 2125 IF (dk = SymTab.KindVar)
|
|
|
+ 2126 OR (dk = SymTab.KindParam)
|
|
|
+ 2127 OR (dk =
|
|
|
+ 2128 SymTab.KindField) THEN
|
|
|
+ 2129 IF sfx THEN
|
|
|
+ 2130 QbeGen.NoteAddr(q, qd)
|
|
|
+ 2131 ELSE
|
|
|
+ 2132 QbeGen.AddrOf(qn, qa);
|
|
|
+ 2133 QbeGen.NoteAddr(q, qa)
|
|
|
+ 2134 END
|
|
|
+ 2135 ELSIF sfx
|
|
|
+ 2136 AND (dt #
|
|
|
+ 2137 SymTab.InvalidType)
|
|
|
+ 2138 AND ((SymTab.ClassOf(dt) =
|
|
|
+ 2139 SymTab.ClArray)
|
|
|
+ 2140 OR (SymTab.ClassOf(dt) =
|
|
|
+ 2141 SymTab.ClSet)
|
|
|
+ 2142 OR (SymTab.ClassOf(dt) =
|
|
|
+ 2143 SymTab.ClRecord)) THEN
|
|
|
+ 2144 QbeGen.NoteAddr(qd, qd)
|
|
|
+ 2145 END; .)
|
|
|
+ 2146 [ TypedSetLit<dt, q> (. t := dt; .) ]
|
|
|
+ 2147 [ ArgList<qn, dt, qd, TRUE, ct2, q2, called>
|
|
|
+ 2148 (. t := ct2;
|
|
|
+ 2149 QbeGen.CopyOp(q2, q); .) ]
|
|
|
+ 2150 (. IF NOT called
|
|
|
+ 2151 AND (dk = SymTab.KindProc) THEN
|
|
|
+ 2152 (* bare zero-arg function
|
|
|
+ 2153 call (parentheses may be
|
|
|
+ 2154 omitted); a proper or
|
|
|
+ 2155 parameterised proc here
|
|
|
+ 2156 is 230 *)
|
|
|
+ 2157 IF (SymTab.ProcNPar(qn) = 0)
|
|
|
+ 2158 AND (SymTab.ProcRes(qn) #
|
|
|
+ 2159 SymTab.InvalidType) THEN
|
|
|
+ 2160 QbeGen.Mangled(qn,
|
|
|
+ 2161 SymTab.ProcUid(qn), qm0);
|
|
|
+ 2162 QbeGen.CallBegin(qm0,
|
|
|
+ 2163 SymTab.ProcRes(qn),
|
|
|
+ 2164 SymTab.ProcDepthOf(qn),
|
|
|
+ 2165 SymTab.IsExternal(qn));
|
|
|
+ 2166 QbeGen.CallEnd(TRUE, q);
|
|
|
+ 2167 t := SymTab.ProcRes(qn)
|
|
|
+ 2168 ELSE
|
|
|
+ 2169 (* procedure used as a
|
|
|
+ 2170 value (assign to a
|
|
|
+ 2171 procedure variable):
|
|
|
+ 2172 its code address *)
|
|
|
+ 2173 t := SymTab.ProcTypeOf(qn);
|
|
|
+ 2174 QbeGen.Mangled(qn,
|
|
|
+ 2175 SymTab.ProcUid(qn), qm0);
|
|
|
+ 2176 QbeGen.ProcAddr(qm0, q)
|
|
|
+ 2177 END
|
|
|
+ 2178 END; .)
|
|
|
+ 2179 | ( "HIGH" (. isHigh := TRUE; .)
|
|
|
+ 2180 | ( "LEN" | "LENGTH" ) (. isHigh := FALSE; .) )
|
|
|
+ 2181 "(" ( Design<dt, dk, qd, qn, sfx> (. isStr := FALSE; .)
|
|
|
+ 2182 | string (. LexString(s);
|
|
|
+ 2183 isStr := TRUE;
|
|
|
+ 2184 IF SymTab.StrLen(s) = 3 THEN
|
|
|
+ 2185 dt := SymTab.CharType();
|
|
|
+ 2186 QbeGen.IntStr(QbeGen.CharVal(s),
|
|
|
+ 2187 qd)
|
|
|
+ 2188 ELSE
|
|
|
+ 2189 dt := SymTab.NewStr();
|
|
|
+ 2190 QbeGen.DeclStr(s, qd);
|
|
|
+ 2191 QbeGen.NoteAddr(qd, qd)
|
|
|
+ 2192 END;
|
|
|
+ 2193 dk := -1;
|
|
|
+ 2194 qn[0] := CHR(0); .) )
|
|
|
+ 2195 ")"
|
|
|
+ 2196 (. IF isStr THEN
|
|
|
+ 2197 (* fold: content length at
|
|
|
+ 2198 compile time *)
|
|
|
+ 2199 IF SymTab.StrLen(s) = 3 THEN
|
|
|
+ 2200 c1 := 1
|
|
|
+ 2201 ELSE
|
|
|
+ 2202 c1 :=
|
|
|
+ 2203 SymTab.StrLen(s) - 2
|
|
|
+ 2204 END;
|
|
|
+ 2205 IF isHigh THEN
|
|
|
+ 2206 DEC(c1)
|
|
|
+ 2207 END;
|
|
|
+ 2208 QbeGen.IntStr(c1, qr);
|
|
|
+ 2209 t := SymTab.IntType();
|
|
|
+ 2210 QbeGen.CopyOp(qr, q)
|
|
|
+ 2211 ELSIF dt = SymTab.InvalidType THEN
|
|
|
+ 2212 t := SymTab.InvalidType;
|
|
|
+ 2213 QbeGen.CopyOp("0", q)
|
|
|
+ 2214 ELSIF SymTab.ClassOf(dt) #
|
|
|
+ 2215 SymTab.ClArray THEN
|
|
|
+ 2216 SemError(217);
|
|
|
+ 2217 t := SymTab.InvalidType;
|
|
|
+ 2218 QbeGen.CopyOp("0", q)
|
|
|
+ 2219 ELSE
|
|
|
+ 2220 IF isHigh THEN
|
|
|
+ 2221 IF SymTab.IsOpenArray(dt) THEN
|
|
|
+ 2222 QbeGen.OpenHi(qd, qr)
|
|
|
+ 2223 ELSE
|
|
|
+ 2224 QbeGen.IntStr(
|
|
|
+ 2225 SymTab.ArrayHi(dt), qr)
|
|
|
+ 2226 END
|
|
|
+ 2227 ELSE
|
|
|
+ 2228 IF SymTab.IsOpenArray(dt) THEN
|
|
|
+ 2229 QbeGen.LoadCount(qd, qr)
|
|
|
+ 2230 ELSE
|
|
|
+ 2231 QbeGen.IntStr(VAL(
|
|
|
+ 2232 INTEGER,
|
|
|
+ 2233 SymTab.ArrayLen(dt)),
|
|
|
+ 2234 qr)
|
|
|
+ 2235 END
|
|
|
+ 2236 END;
|
|
|
+ 2237 t := SymTab.IntType();
|
|
|
+ 2238 QbeGen.CopyOp(qr, q)
|
|
|
+ 2239 END; .)
|
|
|
+ 2240 | ( "SIZE" | "TSIZE" ) "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 2241 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 2242 t := SymTab.InvalidType;
|
|
|
+ 2243 QbeGen.CopyOp("0", q)
|
|
|
+ 2244 ELSE
|
|
|
+ 2245 QbeGen.IntStr(VAL(INTEGER,
|
|
|
+ 2246 SymTab.ObjectSize(dt)), q);
|
|
|
+ 2247 t := SymTab.IntType()
|
|
|
+ 2248 END; .)
|
|
|
+ 2249 | "ADR" "(" Design<dt, dk, qd, qn, sfx> ")"
|
|
|
+ 2250 (. IF dt = SymTab.InvalidType THEN
|
|
|
+ 2251 t := SymTab.InvalidType;
|
|
|
+ 2252 QbeGen.CopyOp("0", q)
|
|
|
+ 2253 ELSE
|
|
|
+ 2254 IF sfx THEN
|
|
|
+ 2255 QbeGen.CopyOp(qd, q)
|
|
|
+ 2256 ELSIF (dk = SymTab.KindVar)
|
|
|
+ 2257 OR (dk = SymTab.KindParam) THEN
|
|
|
+ 2258 QbeGen.AddrOf(qn, q)
|
|
|
+ 2259 ELSE SemError(230);
|
|
|
+ 2260 QbeGen.CopyOp("0", q)
|
|
|
+ 2261 END;
|
|
|
+ 2262 t := SymTab.AddrType()
|
|
|
+ 2263 END; .)
|
|
|
+ 2264 | "CHR" "(" Expr<et, q> ")"
|
|
|
+ 2265 (. IF (et # SymTab.InvalidType)
|
|
|
+ 2266 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
+ 2267 SemError(211) END;
|
|
|
+ 2268 t := SymTab.CharType(); .)
|
|
|
+ 2269 | ( "ORD" | "ORDL" ) "(" Expr<et, q> ")"
|
|
|
+ 2270 (. IF et # SymTab.InvalidType THEN
|
|
|
+ 2271 IF (SymTab.ClassOf(et) #
|
|
|
+ 2272 SymTab.ClChar)
|
|
|
+ 2273 AND (SymTab.ClassOf(et) #
|
|
|
+ 2274 SymTab.ClBool)
|
|
|
+ 2275 AND (SymTab.ClassOf(et) #
|
|
|
+ 2276 SymTab.ClEnum)
|
|
|
+ 2277 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
+ 2278 SemError(211) END
|
|
|
+ 2279 END;
|
|
|
+ 2280 t := SymTab.IntType(); .)
|
|
|
+ 2281 | "CAP" "(" Expr<et, q> ")"
|
|
|
+ 2282 (. QbeGen.CapQ(q, qa);
|
|
|
+ 2283 QbeGen.CopyOp(qa, q);
|
|
|
+ 2284 t := SymTab.CharType(); .)
|
|
|
+ 2285 | "UCHR" "(" Expr<et, q> ")"
|
|
|
+ 2286 (. (* UCHR: the UCHAR constructor.
|
|
|
+ 2287 CHAR -> UCHAR (identity);
|
|
|
+ 2288 INTEGER familly -> UCHAR
|
|
|
+ 2289 (codepoint value). *)
|
|
|
+ 2290 IF (et # SymTab.InvalidType)
|
|
|
+ 2291 AND (SymTab.ClassOf(et) # SymTab.ClChar)
|
|
|
+ 2292 AND NOT SymTab.IsIntFamily(et) THEN
|
|
|
+ 2293 SemError(211) END;
|
|
|
+ 2294 t := SymTab.UCharType(); .)
|
|
|
+ 2295 | "CHR8" "(" Expr<et, q> ")"
|
|
|
+ 2296 (. IF (et # SymTab.InvalidType)
|
|
|
+ 2297 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
+ 2298 SemError(211) END;
|
|
|
+ 2299 QbeGen.WidenLong(q, qa);
|
|
|
+ 2300 QbeGen.CheckRange(qa, "0", "255");
|
|
|
+ 2301 t := SymTab.CharType(); .)
|
|
|
+ 2302 | "UORD" "(" Expr<et, q> ")"
|
|
|
+ 2303 (. (* UORD(u): the codepoint as a
|
|
|
+ 2304 32-bit ordinal (INTEGER),
|
|
|
+ 2305 cf. ORD for CHAR. *)
|
|
|
+ 2306 IF (et # SymTab.InvalidType)
|
|
|
+ 2307 AND (SymTab.ClassOf(et) # SymTab.ClUChar) THEN
|
|
|
+ 2308 SemError(211) END;
|
|
|
+ 2309 t := SymTab.IntType(); .)
|
|
|
+ 2310 | "ABS" "(" Expr<et, q> ")"
|
|
|
+ 2311 (. IF (et # SymTab.InvalidType)
|
|
|
+ 2312 AND NOT SymTab.IsIntFamily(et)
|
|
|
+ 2313 AND (SymTab.ClassOf(et) #
|
|
|
+ 2314 SymTab.ClReal) THEN
|
|
|
+ 2315 SemError(211)
|
|
|
+ 2316 ELSE QbeGen.AbsQ(q, qa,
|
|
|
+ 2317 SymTab.ClassOf(et) =
|
|
|
+ 2318 SymTab.ClReal);
|
|
|
+ 2319 QbeGen.CopyOp(qa, q)
|
|
|
+ 2320 END;
|
|
|
+ 2321 t := et; .)
|
|
|
+ 2322 | "VAL" "(" GetIdent<vn> "," Expr<et, q> ")"
|
|
|
+ 2323 (. IF NOT SymTab.Lookup(vn) THEN
|
|
|
+ 2324 SemError(201);
|
|
|
+ 2325 t := SymTab.InvalidType
|
|
|
+ 2326 ELSE vt := SymTab.SymType(vn);
|
|
|
+ 2327 IF vt = SymTab.InvalidType THEN
|
|
|
+ 2328 t := SymTab.InvalidType
|
|
|
+ 2329 ELSIF et =
|
|
|
+ 2330 SymTab.InvalidType THEN
|
|
|
+ 2331 t := vt
|
|
|
+ 2332 ELSE
|
|
|
+ 2333 c1 := SymTab.ClassOf(et);
|
|
|
+ 2334 c2 := SymTab.ClassOf(vt);
|
|
|
+ 2335 IF ((c1 = SymTab.ClInt)
|
|
|
+ 2336 OR (c1 =
|
|
|
+ 2337 SymTab.ClChar)
|
|
|
+ 2338 OR (c1 =
|
|
|
+ 2339 SymTab.ClBool)
|
|
|
+ 2340 OR (c1 =
|
|
|
+ 2341 SymTab.ClEnum))
|
|
|
+ 2342 AND ((c2 = SymTab.ClInt)
|
|
|
+ 2343 OR (c2 =
|
|
|
+ 2344 SymTab.ClChar)
|
|
|
+ 2345 OR (c2 =
|
|
|
+ 2346 SymTab.ClBool)
|
|
|
+ 2347 OR (c2 =
|
|
|
+ 2348 SymTab.ClEnum)) THEN
|
|
|
+ 2349 t := vt
|
|
|
+ 2350 ELSIF (c1 = SymTab.ClPtr)
|
|
|
+ 2351 AND (c2 = SymTab.ClPtr) THEN
|
|
|
+ 2352 t := vt
|
|
|
+ 2353 ELSIF (c1 = SymTab.ClReal)
|
|
|
+ 2354 AND (c2 = SymTab.ClReal) THEN
|
|
|
+ 2355 t := vt
|
|
|
+ 2356 ELSE SemError(230);
|
|
|
+ 2357 t := SymTab.InvalidType
|
|
|
+ 2358 END
|
|
|
+ 2359 END
|
|
|
+ 2360 END; .)
|
|
|
+ 2361 | "(" Expr<et, q> ")" (. t := et; .)
|
|
|
+ 2362 | SetLit<st, sq> (. t := st;
|
|
|
+ 2363 QbeGen.CopyOp(sq, q); .)
|
|
|
+ 2364 | ( "NOT" | "~" ) Fact<t2, q2> (. IF SymTab.BoolCheck(t2) THEN
|
|
|
+ 2365 t := SymTab.BoolType()
|
|
|
+ 2366 ELSE SemError(212);
|
|
|
+ 2367 t := SymTab.InvalidType END;
|
|
|
+ 2368 IF t # SymTab.InvalidType THEN
|
|
|
+ 2369 QbeGen.NotQ(q2, q)
|
|
|
+ 2370 ELSE QbeGen.CopyOp("0", q)
|
|
|
+ 2371 END; .) .
|
|
|
+ 2372 (* Set literals are SET OF [0..255] (8 words); elements validated
|
|
|
+ 2373 0..255 statically when foldable (222 otherwise), runtime trap
|
|
|
+ 2374 for computed elements. Ranges always lower via SetRange. *)
|
|
|
+ 2375 SetLit<VAR t: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 2376 = "{" (. t := SymTab.NewSet(
|
|
|
+ 2377 SymTab.NewSubR(0, 255));
|
|
|
+ 2378 QbeGen.NewSetTemp(8, q);
|
|
|
+ 2379 QbeGen.SetZero(q, 8); .)
|
|
|
+ 2380 [ SetElem<t, q> { "," SetElem<t, q> } ]
|
|
|
+ 2381 "}" .
|
|
|
+ 2382 (* Typed set constructor: TypeName{ elems } — e.g. BITSET{0},
|
|
|
+ 2383 BITSET{}. The declared type (not SET OF [0..255]) sets the
|
|
|
+ 2384 width and element span. *)
|
|
|
+ 2385 TypedSetLit<vt: SymTab.TypeIndex; VAR q: QbeGen.QVal>
|
|
|
+ 2386 (. VAR nw: CARDINAL; .)
|
|
|
+ 2387 = "{" (. IF SymTab.ClassOf(vt) #
|
|
|
+ 2388 SymTab.ClSet THEN
|
|
|
+ 2389 SemError(230); nw := 8
|
|
|
+ 2390 ELSE nw := SymTab.SetWords(vt);
|
|
|
+ 2391 IF nw = 0 THEN nw := 8 END
|
|
|
+ 2392 END;
|
|
|
+ 2393 QbeGen.NewSetTemp(nw, q);
|
|
|
+ 2394 QbeGen.SetZero(q, nw); .)
|
|
|
+ 2395 [ SetElem<vt, q> { "," SetElem<vt, q> } ]
|
|
|
+ 2396 "}" .
|
|
|
+ 2397 SetElem<st: SymTab.TypeIndex; sq: QbeGen.QVal> (. VAR et, et2: SymTab.TypeIndex;
|
|
|
+ 2398 qe, q2: QbeGen.QVal;
|
|
|
+ 2399 v, v2: INTEGER;
|
|
|
+ 2400 lo: INTEGER;
|
|
|
+ 2401 span: CARDINAL;
|
|
|
+ 2402 cl, cl2: INTEGER;
|
|
|
+ 2403 hasR: BOOLEAN; .)
|
|
|
+ 2404 = (. hasR := FALSE; .)
|
|
|
+ 2405 Expr<et, qe>
|
|
|
+ 2406 [ ".." Expr<et2, q2> (. hasR := TRUE; .) ]
|
|
|
+ 2407 (. lo := SymTab.SetBaseLo(st);
|
|
|
+ 2408 span := SymTab.SetCount(st);
|
|
|
+ 2409 IF (et = SymTab.InvalidType)
|
|
|
+ 2410 OR (hasR AND (et2 =
|
|
|
+ 2411 SymTab.InvalidType)) THEN
|
|
|
+ 2412 ELSE cl :=
|
|
|
+ 2413 SymTab.ClassOf(et);
|
|
|
+ 2414 IF hasR THEN
|
|
|
+ 2415 cl2 :=
|
|
|
+ 2416 SymTab.ClassOf(et2)
|
|
|
+ 2417 ELSE cl2 := SymTab.ClInt
|
|
|
+ 2418 END;
|
|
|
+ 2419 IF ((cl # SymTab.ClInt)
|
|
|
+ 2420 AND (cl # SymTab.ClChar)
|
|
|
+ 2421 AND (cl # SymTab.ClBool))
|
|
|
+ 2422 OR (hasR AND
|
|
|
+ 2423 ((cl2
|
|
|
+ 2424 # SymTab.ClInt)
|
|
|
+ 2425 AND (cl2
|
|
|
+ 2426 # SymTab.ClChar)
|
|
|
+ 2427 AND (cl2
|
|
|
+ 2428 # SymTab.ClBool))) THEN
|
|
|
2429 SemError(222)
|
|
|
- 2430 ELSIF hasR THEN
|
|
|
- 2431 QbeGen.SetRange(sq, qe, q2,
|
|
|
- 2432 lo, span)
|
|
|
- 2433 ELSIF SymTab.ConstInt(qe,
|
|
|
- 2434 v)
|
|
|
- 2435 AND ((v < lo)
|
|
|
- 2436 OR (v >= lo +
|
|
|
- 2437 VAL(INTEGER,
|
|
|
- 2438 span))) THEN
|
|
|
- 2439 SemError(222)
|
|
|
- 2440 ELSE QbeGen.SetBit(sq, qe,
|
|
|
- 2441 lo, span)
|
|
|
- 2442 END
|
|
|
- 2443 END; .) .
|
|
|
- 2444 GetIdent<VAR n: SymTab.Name>
|
|
|
- 2445 = ident (. LexName(n); .) .
|
|
|
- 2446
|
|
|
- 2447 END M2.
|
|
|
+ 2430 ELSIF hasR
|
|
|
+ 2431 AND SymTab.ConstInt(qe, v)
|
|
|
+ 2432 AND SymTab.ConstInt(q2,
|
|
|
+ 2433 v2)
|
|
|
+ 2434 AND ((v < lo)
|
|
|
+ 2435 OR (v2 < lo)
|
|
|
+ 2436 OR (v >= lo +
|
|
|
+ 2437 VAL(INTEGER, span))
|
|
|
+ 2438 OR (v2 >= lo +
|
|
|
+ 2439 VAL(INTEGER, span))
|
|
|
+ 2440 OR (v > v2)) THEN
|
|
|
+ 2441 SemError(222)
|
|
|
+ 2442 ELSIF hasR THEN
|
|
|
+ 2443 QbeGen.SetRange(sq, qe, q2,
|
|
|
+ 2444 lo, span)
|
|
|
+ 2445 ELSIF SymTab.ConstInt(qe,
|
|
|
+ 2446 v)
|
|
|
+ 2447 AND ((v < lo)
|
|
|
+ 2448 OR (v >= lo +
|
|
|
+ 2449 VAL(INTEGER,
|
|
|
+ 2450 span))) THEN
|
|
|
+ 2451 SemError(222)
|
|
|
+ 2452 ELSE QbeGen.SetBit(sq, qe,
|
|
|
+ 2453 lo, span)
|
|
|
+ 2454 END
|
|
|
+ 2455 END; .) .
|
|
|
+ 2456 GetIdent<VAR n: SymTab.Name>
|
|
|
+ 2457 = ident (. LexName(n); .) .
|
|
|
+ 2458
|
|
|
+ 2459 END M2.
|
|
|
|
|
|
0 errors
|
|
|
|