public override CheckTypesResult CheckExprTypeBounds() { CheckTypesResult result = new CheckTypesResult(); result.AddMinTypeExprent(value, VarType.Vartype_Bytechar); result.AddMaxTypeExprent(value, VarType.Vartype_Int); VarType valType = value.GetExprType(); foreach (List <Exprent> lst in caseValues) { foreach (Exprent expr in lst) { if (expr != null) { VarType caseType = expr.GetExprType(); if (!caseType.Equals(valType)) { valType = VarType.GetCommonSupertype(caseType, valType); result.AddMinTypeExprent(value, valType); } } } } return(result); }
public override CheckTypesResult CheckExprTypeBounds() { CheckTypesResult result = new CheckTypesResult(); VarType typeLeft = left.GetExprType(); VarType typeRight = right.GetExprType(); if (typeLeft.typeFamily > typeRight.typeFamily) { result.AddMinTypeExprent(right, VarType.GetMinTypeInFamily(typeLeft.typeFamily)); } else if (typeLeft.typeFamily < typeRight.typeFamily) { result.AddMinTypeExprent(left, typeRight); } else { result.AddMinTypeExprent(left, VarType.GetCommonSupertype(typeLeft, typeRight)); } return(result); }
private bool ChangeExprentType(Exprent exprent, VarType newType, int minMax) { bool res = true; switch (exprent.type) { case Exprent.Exprent_Const: { ConstExprent constExpr = (ConstExprent)exprent; VarType constType = constExpr.GetConstType(); if (newType.typeFamily > ICodeConstants.Type_Family_Integer || constType.typeFamily > ICodeConstants.Type_Family_Integer) { return(true); } else if (newType.typeFamily == ICodeConstants.Type_Family_Integer) { VarType minInteger = new ConstExprent((int)constExpr.GetValue(), false, null).GetConstType (); if (minInteger.IsStrictSuperset(newType)) { newType = minInteger; } } goto case Exprent.Exprent_Var; } case Exprent.Exprent_Var: { VarVersionPair pair = null; if (exprent.type == Exprent.Exprent_Const) { pair = new VarVersionPair(((ConstExprent)exprent).id, -1); } else if (exprent.type == Exprent.Exprent_Var) { pair = new VarVersionPair((VarExprent)exprent); } if (minMax == 0) { // min VarType currentMinType = mapExprentMinTypes.GetOrNull(pair); VarType newMinType; if (currentMinType == null || newType.typeFamily > currentMinType.typeFamily) { newMinType = newType; } else if (newType.typeFamily < currentMinType.typeFamily) { return(true); } else { newMinType = VarType.GetCommonSupertype(currentMinType, newType); } Sharpen.Collections.Put(mapExprentMinTypes, pair, newMinType); if (exprent.type == Exprent.Exprent_Const) { ((ConstExprent)exprent).SetConstType(newMinType); } if (currentMinType != null && (newMinType.typeFamily > currentMinType.typeFamily || newMinType.IsStrictSuperset(currentMinType))) { return(false); } } else { // max VarType currentMaxType = mapExprentMaxTypes.GetOrNull(pair); VarType newMaxType; if (currentMaxType == null || newType.typeFamily < currentMaxType.typeFamily) { newMaxType = newType; } else if (newType.typeFamily > currentMaxType.typeFamily) { return(true); } else { newMaxType = VarType.GetCommonMinType(currentMaxType, newType); } Sharpen.Collections.Put(mapExprentMaxTypes, pair, newMaxType); } break; } case Exprent.Exprent_Assignment: { return(ChangeExprentType(((AssignmentExprent)exprent).GetRight(), newType, minMax )); } case Exprent.Exprent_Function: { FunctionExprent func = (FunctionExprent)exprent; switch (func.GetFuncType()) { case FunctionExprent.Function_Iif: { // FIXME: res = ChangeExprentType(func.GetLstOperands()[1], newType, minMax) & ChangeExprentType (func.GetLstOperands()[2], newType, minMax); break; } case FunctionExprent.Function_And: case FunctionExprent.Function_Or: case FunctionExprent.Function_Xor: { res = ChangeExprentType(func.GetLstOperands()[0], newType, minMax) & ChangeExprentType (func.GetLstOperands()[1], newType, minMax); break; } } break; } } return(res); }
public override VarType GetExprType() { VarType exprType = null; if (funcType <= Function_Neg || funcType == Function_Ipp || funcType == Function_Ppi || funcType == Function_Imm || funcType == Function_Mmi) { VarType type1 = lstOperands[0].GetExprType(); VarType type2 = null; if (lstOperands.Count > 1) { type2 = lstOperands[1].GetExprType(); } switch (funcType) { case Function_Imm: case Function_Mmi: case Function_Ipp: case Function_Ppi: { exprType = implicitType; break; } case Function_Bool_Not: { exprType = VarType.Vartype_Boolean; break; } case Function_Shl: case Function_Shr: case Function_Ushr: case Function_Bit_Not: case Function_Neg: { exprType = GetMaxVarType(new VarType[] { type1 }); break; } case Function_Add: case Function_Sub: case Function_Mul: case Function_Div: case Function_Rem: { exprType = GetMaxVarType(new VarType[] { type1, type2 }); break; } case Function_And: case Function_Or: case Function_Xor: { if (type1.type == ICodeConstants.Type_Boolean & type2.type == ICodeConstants.Type_Boolean) { exprType = VarType.Vartype_Boolean; } else { exprType = GetMaxVarType(new VarType[] { type1, type2 }); } break; } } } else if (funcType == Function_Cast) { exprType = lstOperands[1].GetExprType(); } else if (funcType == Function_Iif) { Exprent param1 = lstOperands[1]; Exprent param2 = lstOperands[2]; VarType supertype = VarType.GetCommonSupertype(param1.GetExprType(), param2.GetExprType ()); if (param1.type == Exprent.Exprent_Const && param2.type == Exprent.Exprent_Const && supertype.type != ICodeConstants.Type_Boolean && VarType.Vartype_Int.IsSuperset (supertype)) { exprType = VarType.Vartype_Int; } else { exprType = supertype; } } else if (funcType == Function_Str_Concat) { exprType = VarType.Vartype_String; } else if (funcType >= Function_Eq || funcType == Function_Instanceof) { exprType = VarType.Vartype_Boolean; } else if (funcType >= Function_Array_Length) { exprType = VarType.Vartype_Int; } else { exprType = Types[funcType - Function_I2l]; } return(exprType); }