public int IndexOf(string name, List <ProtoCore.Type> argTypeList, ProtoCore.DSASM.ClassTable classtable, bool isStaticOrConstructor = false) { #if STATIC_TYPE_CHECKING int distance = (int)ProcedureDistance.kMaxDistance; #endif int currentProcedure = ProtoCore.DSASM.Constants.kInvalidIndex; bool functionPointerCheck = argTypeList == null; if (functionPointerCheck) // check for function pointer { for (int n = 0; n < procList.Count; ++n) { if (name == procList[n].name) { currentProcedure = n; break; } } return(currentProcedure); } // For every procedure in this table for (int n = 0; n < procList.Count; ++n) { int defaultArgNum = procList[n].argInfoList.Count(X => X.isDefault); if (name == procList[n].name && procList[n].argTypeList.Count >= argTypeList.Count && (procList[n].argTypeList.Count - argTypeList.Count <= defaultArgNum)) { #if STATIC_TYPE_CHECKING int currentDist = procList[n].GetDistance(name, argTypeList, classtable); if (currentDist < distance && procList[n].argTypeList.Count > argTypeList.Count) { //Fuqiang: to differentiate a function with all the arguments provided and a function with default arguments not provided. currentDist += (int)ProcedureDistance.kHasOmittedDefaultArgDistance; } if (currentDist < distance) { distance = currentDist; currentProcedure = n; if ((int)ProcedureDistance.kExactMatchDistance == distance) { // The procedure is an exact match // There is nothing more to check break; } } #else if (!isStaticOrConstructor || (isStaticOrConstructor && (procList[n].isStatic || procList[n].isConstructor))) { currentProcedure = n; break; } #endif } } return(currentProcedure); }
/* * // Check the expected type * switch (rcvdType) * { * case (int)PrimitiveType.kTypeVar: * { * score = (int)ProcedureDistance.kCoerceScore; * break; * } * case (int)PrimitiveType.kTypeDouble: * { * score = (int)ProcedureDistance.kCoerceScore; * break; * } * case (int)PrimitiveType.kTypeInt: * { * score = (int)ProcedureDistance.kCoerceIntToDoubleScore; * break; * } * case (int)PrimitiveType.kTypeNull: * { * score = (int)ProcedureDistance.kCoerceScore; * break; * } * case (int)PrimitiveType.kTypeArray: * { * score = (int)ProcedureDistance.kCoerceScore; * break; * } * default: * { * // Procedure expects a user-defined type * break; * } * } * */ public int GetDistance(string name, List <ProtoCore.Type> args, ProtoCore.DSASM.ClassTable classtable) { Debug.Assert(null != classtable); int defaultArgNum = argInfoList.Count(X => X.isDefault); Debug.Assert(argTypeList.Count - args.Count <= defaultArgNum); int distance = (int)ProcedureDistance.kMaxDistance; if (0 == args.Count) { distance = (int)ProcedureDistance.kExactMatchDistance; } else { isThisCallReplication = false; // Check if all the types match the current function at 'n' for (int i = 0; i < args.Count; ++i) { int rcvdType = args[i].UID; int expectedType = argTypeList[i].UID; int currentScore = (int)ProcedureDistance.kNotMatchScore; //check whether it is replication call if (argTypeList[i].rank != -1 && args[i].rank > argTypeList[i].rank) { isThisCallReplication = true; } //Fuqiang: For now disable rank check //if function is expecting array, but non-array or array of lower rank is passed, break. //if (args[i].rank != -1 && args[i].UID != (int)PrimitiveType.kTypeVar && args[i].rank < argTypeList[i].rank) //Only enable type check, and array and non-array check if (args[i].rank != -1 && args[i].UID != (int)PrimitiveType.kTypeVar && !args[i].IsIndexable && argTypeList[i].IsIndexable) { distance = (int)ProcedureDistance.kMaxDistance; break; } else if (expectedType == rcvdType) { currentScore = (int)ProcedureDistance.kExactMatchScore; } else { currentScore = classtable.ClassNodes[rcvdType].GetCoercionScore(expectedType); if (currentScore == (int)ProcedureDistance.kNotMatchScore) { distance = (int)ProcedureDistance.kMaxDistance; break; } } distance -= currentScore; } } return(distance); }