예제 #1
0
        private static bool CheckMatch(ParameterInfo param, StringIterator inputIterator, StringIterator signatureIterator, out object result)
        {
            //Get the type of the parameter
            Type paramType = param.ParameterType;

            //Check for integer numbers
            if (IsInteger(paramType))
            {
                //Read the integer
                return(ReadInteger(paramType, inputIterator, out result));
            }

            //Check for floating point numbers
            if (IsFloatingPoint(paramType))
            {
                //Read the floating point
                return(ReadFloatingPoint(paramType, inputIterator, out result));
            }

            //Check for string
            if (IsString(paramType))
            {
                //Get the pattern for the regex
                var pattern = param.GetCustomAttribute <RegexParameterAttribute>().Pattern;

                //Check what is expected after our string
                var ch     = signatureIterator.Peek(2);
                int offset = (ch.HasValue) ? inputIterator.Find(ch.Value) : 0;

                //If the input does not have the expected character we
                //continue anyway. The match will fail after this.
                if (offset < 0)
                {
                    offset = 0;
                }

                //Read the string
                return(ReadString(pattern, inputIterator, offset, out result));
            }

            //We do not recognize the type
            throw new Exception($"Unknown type {param.ParameterType.Name}!");
        }
예제 #2
0
        public static List <CommandMatch> ProcessCommand(CommandModuleBase module, string inputString)
        {
            //Prepare a list to hold our candidates
            var candidates = new List <CommandMatch>();

            //Go through each command in the module
            module.Commands.ForEach(cmd =>
            {
                //Grab the signature to match
                var signature = CommandManager.GetCommandSignature(cmd);

                //Prepare our iterators
                var inputIterator     = new StringIterator(inputString);
                var signatureIterator = new StringIterator(signature);

                //Prepare candidate
                var paramInfo = cmd.GetParameters();
                var candidate = new CommandMatch
                {
                    module          = module,
                    cmd             = cmd,
                    inputMatch      = 0,
                    signatureMatch  = 0,
                    signatureLength = signature.Length,
                    extractedParams = new object[paramInfo.Length],
                    count           = 1
                };

                //Iterate through the strings
                while (true)
                {
                    //Check for valid iterators
                    if (!inputIterator.Current().HasValue || !signatureIterator.Current().HasValue)
                    {
                        break;
                    }

                    //Get the next characters
                    var ch1 = inputIterator.Current().Value;
                    var ch2 = signatureIterator.Current().Value;

                    //Check if we hit a whitespace character in the signature
                    if (char.IsWhiteSpace(ch2))
                    {
                        //Check that the input string has at least one whitespace
                        if (char.IsWhiteSpace(ch1))
                        {
                            //Skip the whitespace
                            inputIterator.SkipWhitespace();
                            signatureIterator.SkipWhitespace();

                            //Continue without advancing iterators
                            continue;
                        }
                        else
                        {
                            break;
                        }
                    }

                    //Check if we reached a parameter
                    if ((ch2 == '{') && (signatureIterator.Peek() == '}'))
                    {
                        //Skip any whitespace before our parameter
                        inputIterator.SkipWhitespace();

                        //Try to match the input against our expected parameter
                        if (CheckMatch(paramInfo[candidate.count], inputIterator, signatureIterator, out object result))
                        {
                            //Store the result
                            candidate.extractedParams[candidate.count++] = result;

                            //Skip over the brackets in the signature
                            signatureIterator.Skip();
                            signatureIterator.Skip();

                            //Check if the signature is not explicitly requiring a whitespace
                            var tmp = signatureIterator.Current();
                            if (tmp.HasValue && !char.IsWhiteSpace(tmp.Value))
                            {
                                //Allow optional whitespace which we skip
                                inputIterator.SkipWhitespace();
                            }

                            //Continue without advancing iterators
                            continue;
                        }
                        break;
                    }

                    //Normal case-insensitive string comparison
                    if (char.ToLowerInvariant(ch1) != char.ToLowerInvariant(ch2))
                    {
                        break;
                    }

                    //Advance our iterators
                    inputIterator.Next();
                    signatureIterator.Next();
                }

                //Update how much we matched of the input and signature
                candidate.inputMatch     = inputIterator.Index;
                candidate.signatureMatch = signatureIterator.Index;

                //Push candidate into list
                candidates.Add(candidate);
            });

            //Return the candidates
            return(candidates);
        }