コード例 #1
0
        public VariableTBase Invoke(string name, VariableTBase[] args)
        {
            List <Invokable> invs;

            lock (functions) {
                if (!functions.ContainsKey(name))
                {
                    access.WriteText(ConsoleErrorMessages.FunctionNotFound);
                    throw new Exceptions.ShellFunctionNotFound();
                }
                else
                {
                    invs = functions[name];
                }
            }
            foreach (Invokable ivb in invs)
            {
                ArgResult rs = CheckPopulateArgs(args, ivb);
                if (!rs.IsCorrect)
                {
                    continue;
                }
                MethodInfo    minf = ivb.CallStd.generic ? rs.genCr : ivb.MInfo;
                object        o    = minf.Invoke(null, rs.arguments);
                VariableTBase vb   = (VariableTBase)o;
                return(vb);
            }
            throw new Exceptions.ShellFunctionNotFound();
            return(null);
        }
コード例 #2
0
        /// <summary>
        /// Checks for correct arguments and populates the argument array.
        /// </summary>
        /// <param name="args">Given arguments.</param>
        /// <param name="inv">Invokable to test.</param>
        ArgResult CheckPopulateArgs(VariableTBase[] args, Invokable inv)
        {
            if (inv.CallStd == null)
            {
                FindCallStd(inv);
            }
            var Arguments = inv.MInfo.GetParameters();
            int usesCFunc;

            /* Check whether it uses the ConsoleAccess structure and also check it has at least as many arguments as the function inputs */
            if (inv.CallStd.cfunc)
            {
                if (Arguments.Length > args.Length + 1)
                {
                    return new ArgResult()
                           {
                               IsCorrect = false, ex = new Exceptions.ShellArgumentMismatch(ConsoleErrorMessages.TooFewArguments)
                           }
                }
                ;
                else
                {
                    usesCFunc = 1;
                }
            }
            else
            {
                if (Arguments.Length > args.Length)
                {
                    return new ArgResult()
                           {
                               IsCorrect = false, ex = new Exceptions.ShellArgumentMismatch(ConsoleErrorMessages.TooFewArguments)
                           }
                }
                ;
                else
                {
                    usesCFunc = 0;
                }
            }

            /* Get rid of the case where there are no function inputs */
            if (Arguments.Length == usesCFunc)
            {
                if (args.Length != 0)
                {
                    return new ArgResult()
                           {
                               IsCorrect = false, ex = new Exceptions.ShellArgumentMismatch(ConsoleErrorMessages.NonemptyArguments)
                           }
                }
                ;
                else
                {
                    return new ArgResult()
                           {
                               IsCorrect = true, arguments = new object[0]
                           }
                };
            }

            /* Check if it uses a variable number of arguments */
            int hasparams = inv.CallStd.hp1 | inv.CallStd.hp2 ? 1 : 0;

            if (hasparams == 0 & (args.Length + usesCFunc > Arguments.Length))
            {
                return new ArgResult()
                       {
                           IsCorrect = false, ex = new Exceptions.ShellArgumentMismatch(ConsoleErrorMessages.TooManyArgsNotVarargs)
                       }
            }
            ;

            /* Prepare ArgResult */
            ArgResult lg = new ArgResult();

            lg.Extracted = new List <Tuple <int, object> > ();
            lg.arguments = new object[Arguments.Length];

            if (inv.CallStd.generic)
            {
                try {
                    lg.genCr = CreateGenericMethod(args, inv);
                } catch (Exceptions.ShellArgumentMismatch e) {
                    return(new ArgResult()
                    {
                        IsCorrect = false, ex = e
                    });
                }
                Arguments = lg.genCr.GetParameters();
            }

            int i;

            /* Check if the arguments match the function */
            for (i = 0; i + hasparams + usesCFunc < Arguments.Length; i++)
            {
                if (!Arguments[i].ParameterType.IsInstanceOfType(args[i]))
                {
                    var z = GetVar(args[i], Arguments[i].ParameterType);
                    if (z == null)
                    {
                        return new ArgResult()
                               {
                                   IsCorrect = false, ex = new Exceptions.ShellArgumentMismatch(ConsoleErrorMessages.ArgumentTypeMismatch)
                               }
                    }
                    ;
                    lg.Extracted.Add(new Tuple <int, object> (i, z.Item2));
                    lg.arguments[i] = z.Item2;
                }
                else
                {
                    lg.arguments[i] = args[i];
                }
            }

            /* Check for the 2 possible params cases */
            if (inv.CallStd.hp1)
            {
                List <VariableTBase> vb = new List <VariableTBase> ();
                Type       z            = Arguments[Arguments.Length - 1 - usesCFunc].ParameterType.GetElementType();
                Type       tz           = this.GetType();
                MethodInfo eim          = tz.GetMethod("MakeArrayT", BindingFlags.NonPublic | BindingFlags.Static);
                MethodInfo im           = eim.MakeGenericMethod(z);
                for (; i < args.Length; i++)
                {
                    vb.Add(args[i]);
                }
                lg.arguments[Arguments.Length - 1 - usesCFunc] = im.Invoke(null, new object[] { vb });
            }
            if (inv.CallStd.hp2)
            {
                List <object> sobj = new List <object> ();
                for (; i + usesCFunc < Arguments.Length; i++)
                {
                    object[] o2;
                    var      z = GetVar(args[i], Arguments[i].ParameterType);
                    if (z != null)
                    {
                        sobj.Add(z.Item2);
                    }
                    else
                    {
                        z = GetVar(args[i], Arguments[i].ParameterType.GetElementType());
                        if (z == null)
                        {
                            return new ArgResult()
                                   {
                                       IsCorrect = false, ex = new Exceptions.ShellArgumentMismatch(ConsoleErrorMessages.ArgumentTypeMismatch)
                                   }
                        }
                        ;
                        o2 = (object[])z.Item2; sobj.AddRange(o2);
                    }
                    lg.Extracted.Add(new Tuple <int, object> (i, z.Item2));
                }
                lg.arguments[Arguments.Length - 1 - usesCFunc] = sobj.ToArray();
            }
            lg.IsCorrect = true;
            return(lg);
        }

        /// <summary>
        /// Gets the variable type and embedded object.
        /// </summary>
        /// <param name="vb">The input variable.</param>
        /// <param name="tp">The expected argument type.</param>
        Tuple <Type, object> GetVar(VariableTBase vb, Type tp)
        {
            Type tc = tp;

            while (tc != null && tc != typeof(object))
            {
                var cur = tc.IsGenericType ? tc.GetGenericTypeDefinition() : tc;
                if (typeof(Variable <>) == cur)
                {
                    return(new Tuple <Type, object> (tc.GetGenericArguments()[0], tc.GetField("obj").GetValue(vb)));
                }
                tc = tc.BaseType;
            }
            return(null);
        }