Type typeAddO(Type t1, Type t2) { if (auto t = eval_const(t1, t2, cellAddO)) return *t; if (t1.subtypeOf(TInt) && t2.subtypeOf(TInt)) return TNum; if (auto t = usual_arith_conversions(t1, t2)) return *t; if (t1.subtypeOf(TArr) && t2.subtypeOf(TArr)) return TArr; return TInitCell; }
Type typeAdd(Type t1, Type t2) { if (auto t = eval_const(t1, t2, cellAdd)) return *t; if (auto t = usual_arith_conversions(t1, t2)) return *t; if (t1.subtypeOf(TArr) && t2.subtypeOf(TArr)) return TArr; if (t1.subtypeOf(TVec) && t2.subtypeOf(TVec)) return TVec; if (t1.subtypeOf(TDict) && t2.subtypeOf(TDict)) return TDict; if (t1.subtypeOf(TKeyset) && t2.subtypeOf(TKeyset)) return TKeyset; return TInitCell; }
Type typePow(Type t1, Type t2) { if (auto t = eval_const(t1, t2, cellPow)) return *t; return TNum; }
Type typeSubMulImplO(Type t1, Type t2, CellOp op) { if (auto t = eval_const(t1, t2, op)) return *t; if (t1.subtypeOf(TInt) && t2.subtypeOf(TInt)) return TNum; if (auto t = usual_arith_conversions(t1, t2)) return *t; return TInitPrim; }
Type typeSubMulImpl(Type t1, Type t2, CellOp op) { if (auto t = eval_const(t1, t2, op)) return *t; if (auto t = usual_arith_conversions(t1, t2)) return *t; return TInitPrim; }
Type typeBitXor(Type t1, Type t2) { if (auto t = eval_const(t1, t2, cellBitXor)) return *t; return TInitCell; }
Type typeMod(Type t1, Type t2) { if (auto t = eval_const(t1, t2, cellMod)) return *t; return TInitPrim; }
Type typeDiv(Type t1, Type t2) { if (auto t = eval_const(t1, t2, cellDiv)) return *t; return TInitPrim; }
Type typeBitXor(Type t1, Type t2) { if (auto t = eval_const(t1, t2, cellBitXor)) return *t; return bitwise_arith(t1, t2); }
Type typeMul(Type t1, Type t2) { if (auto t = eval_const(t1, t2, cellMul)) return *t; if (auto t = usual_arith_conversions(t1, t2)) return *t; return TInitCell; }