CommandArg EatArgument(ref string s)
        {
            var arg = new CommandArg();

            int  endIndex  = -1;
            bool mutliWord = false;

            if (argumentGroupMarkers.TryGetValue(s[0], out char endChar))
            {
                endIndex  = s.IndexOf(endChar, 1);
                mutliWord = true;
            }
            else
            {
                endIndex = s.IndexOf(' ');
            }

            if (endIndex >= 0)
            {
                arg.String = s.Substring(mutliWord ? 1 : 0, mutliWord ? endIndex - 1 : endIndex);
                s          = s.Substring(endIndex + 1); // Remaining
            }
            else
            {
                arg.String = s;
                s          = "";
            }

            return(arg);
        }
        CommandArg EatArgument(ref string s)
        {
            var arg         = new CommandArg();
            int space_index = s.IndexOf(' ');

            if (space_index >= 0)
            {
                arg.String = s.Substring(0, space_index);
                s          = s.Substring(space_index + 1); // Remaining
            }
            else
            {
                arg.String = s;
                s          = "";
            }

            return(arg);
        }
        public void SetVariable(string name, CommandArg arg)
        {
            name = name.ToUpper();

            if (!variables.ContainsKey(name))
            {
                throw new Exception($"no variable registered with name {name}");
            }

            object value = null;

            var propertyType = variables[name].PropertyType;

            if (propertyType == typeof(string))
            {
                value = arg.String;
            }
            else if (propertyType == typeof(int))
            {
                value = arg.Int;
            }
            else if (propertyType == typeof(float))
            {
                value = arg.Float;
            }
            else if (propertyType == typeof(bool))
            {
                value = arg.Bool;
            }
            else if (propertyType.IsEnum)
            {
                value = Enum.Parse(propertyType, arg.String);
            }

            variables[name].SetMethod.Invoke(null, new object[] { value });
        }