예제 #1
0
        /* Resolve using a fixed type                               */
        /* Generally main reducing factor of remaining overloads    */
        public void Resolve(int index, GamaValueRef fixedValue)
        {
            if (index < 0)
            {
                return;
            }

            FixedArgs[index] = fixedValue;

            Remaining.RemoveAll((fnref) =>
            {
                if (fnref.IsMethod)
                {
                    index++;                 // skip first for object reference
                }
                var ty = fnref.Type as GamaFunction;
                if (fnref.Parameters.Count == 0)
                {
                    return(true);
                }
                if (index >= fnref.Parameters.Count)
                {
                    if (ty.IsVarArg)
                    {
                        return(false);
                    }
                    return(true);
                }
                return(!fnref.Parameters[index].Type.Compatible(fixedValue.Type));
            });
        }
예제 #2
0
        /* Returns resolved parameters for the function call            */
        /* If remaining number of functions is not one reuturns a null  */
        // TODO: maybe change GamaValueRef to LLVMValueRef to gain some performance
        public (ArgResolveStatus, GamaValueRef[]) ResolveArgs()
        {
            if (Remaining.Count != 1)
            {
                return(ArgResolveStatus.ErrorAmbiguous, null);
            }
            var fnref = Remaining[0];
            var ty    = fnref.Type as GamaFunction;

            var argcount        = FixedArgs.Count + AmbiguousArgs.Count;
            var fnrefparmscount = fnref.Parameters.Count;

            if (ty.IsVarArg)
            {
                if (argcount < fnrefparmscount)
                {
                    return(ArgResolveStatus.ErrorNotEnoughArgs, null);
                }
                var start = fnref.IsMethod ? 1 : 0; // clever hack to let compiler decide first argument
                var args  = new GamaValueRef[argcount + start];
                for (int i = start; i < args.Length; i++)
                {
                    if (i >= fnrefparmscount) // vararg
                    {
                        if (FixedArgs.TryGetValue(i, out GamaValueRef fixedval))
                        {
                            args[i] = fixedval;
                        }
                        else
                        {
                            return(ArgResolveStatus.ErrorFunctionInVararg, null);
                        }
                    }
                    else
                    {
                        var param = fnref.Parameters[i];
                        if (FixedArgs.TryGetValue(i, out GamaValueRef fixedval))
                        {
                            args[i] = fixedval;
                        }
                        else
                        {
                            var list = AmbiguousArgs[i];
                            var fnty = param.Type as GamaFunction;
                            args[i] = list.FindFunction(fnty.ReturnType, fnty.ParameterTypes);
                        }
                    }
                }

                return(ArgResolveStatus.Success, args);
            }
            else
            {
                var start = fnref.IsMethod ? 1 : 0;
                if (argcount + start != fnrefparmscount)
                {
                    return(ArgResolveStatus.ErrorArgCountMismatch, null);
                }
                var args = new GamaValueRef[fnrefparmscount];
                for (int i = start; i < fnrefparmscount; i++)
                {
                    var param = fnref.Parameters[i];
                    if (FixedArgs.TryGetValue(i - start, out GamaValueRef fixedval))
                    {
                        args[i] = fixedval;
                    }
                    else
                    {
                        var list = AmbiguousArgs[i - start];
                        var fnty = param.Type as GamaFunction;
                        args[i] = list.FindFunction(fnty.ReturnType, fnty.ParameterTypes);
                    }
                }

                return(ArgResolveStatus.Success, args);
            }
        }