private List <Token> RemainTokensToArgs(TokenReader reader)
        {
            var result = new List <Token>();

            while (reader.IsRemainToken)
            {
                var current = reader.Get();

                if (current.IsMatchType(TokenType.TargetSelector))
                {
                    if (reader.CheckNext(x => x.IsMatchType(TokenType.OpenSquareBracket)))
                    {
                        reader.Skip(x => x.IsMatchType(TokenType.CloseSquareBracket));
                        reader.MoveNext();
                    }
                }
                else if (current.IsMatchLiteral("minecraft"))
                {
                    if (reader.CheckNext(x => x.IsMatchType(TokenType.Colon)))
                    {
                        reader.MoveNext();
                        if (reader.CheckNext(x => x.IsMatchType(TokenType.Literal)))
                        {
                            current = reader.Get();
                        }
                        else
                        {
                            continue;
                        }
                    }
                }

                result.Add(current);
            }

            return(result);
        }
Esempio n. 2
0
        public static (List <Node> nodes, int variableCount) Parse(string source)
        {
            var Nodes     = new List <Node>();
            var variables = new Dictionary <string, int>();

            bool     inExpression = false;
            NodeType currentMod   = NodeType.NoOperation;

            Stack <Node> BlockLevel = new Stack <Node>();

            using (TokenReader tr = new TokenReader(source))
            {
                do
                {
                    if (string.IsNullOrWhiteSpace(tr.Current()))
                    {
                        continue;
                    }
                    if (tr.EqualTo("if"))
                    {
                        BlockLevel.Push(new Node(NodeType.JumpNotTrue));
                        inExpression = true;
                    }
                    else if (tr.EqualTo("while"))
                    {
                        BlockLevel.Push(new Node(NodeType.JumpNotTrue, Nodes.Count));
                        inExpression = true;
                    }
                    else if (tr.EqualTo("is", "smaller", "then"))
                    {
                        currentMod = NodeType.Smaller;
                        tr.MoveNext(2);
                    }
                    else if (tr.EqualTo("is", "larger", "then"))
                    {
                        currentMod = NodeType.Larger;
                        tr.MoveNext(2);
                    }
                    else if (tr.EqualTo("then") || tr.EqualTo("loop"))
                    {
                        Nodes.Add(BlockLevel.Peek());
                        inExpression = false;
                    }
                    else if (tr.EqualTo("end"))
                    {
                        BlockLevel.Pop().A = Nodes.Count;
                        Nodes.Add(new Node(NodeType.NoOperation));
                    }
                    else if (tr.EqualTo("next"))
                    {
                        var lvl = BlockLevel.Pop();
                        Nodes.Add(new Node(NodeType.GoTo, lvl.A));
                        lvl.A = Nodes.Count;
                        Nodes.Add(new Node(NodeType.NoOperation));
                    }
                    else if (tr.EqualTo("increment"))
                    {
                        if (tr.MoveNext() && !tr.IsNumberLiteral())
                        {
                            Nodes.Add(new Node(NodeType.Increment,
                                               GetVarIndex(tr.Current(), variables)));
                        }
                        else
                        {
                            throw new Exception("Expected a variable after increment");
                        }
                    }
                    else if (tr.EqualTo("decrement"))
                    {
                        if (tr.MoveNext() && !tr.IsNumberLiteral())
                        {
                            Nodes.Add(new Node(NodeType.Decrement,
                                               GetVarIndex(tr.Current(), variables)));
                        }
                        else
                        {
                            throw new Exception("Expected a variable after increment");
                        }
                    }
                    else if (tr.EqualTo("write"))
                    {
                        if (tr.MoveNext())
                        {
                            int     index = -1;
                            decimal value = 0;
                            if (tr.IsNumberLiteral())
                            {
                                value = tr.GetValue();
                            }
                            else
                            {
                                index = GetVarIndex(tr.Current(), variables);
                            }
                            if (tr.MoveNext())
                            {
                                if (tr.EqualTo("to", "the", "console"))
                                {
                                    if (index == -1)
                                    {
                                        Nodes.Add(new Node(NodeType.LoadNumLiteralWriteConsole, value));
                                    }
                                    else
                                    {
                                        Nodes.Add(new Node(NodeType.LoadLocalWriteConsole, index));
                                    }

                                    tr.MoveNext(2);
                                }
                            }
                            else
                            {
                                throw new Exception("Expected what to write to, after value!");
                            }
                        }
                        else
                        {
                            throw new Exception("Expected a value to write");
                        }
                    }
                    else if (tr.EqualTo("is", "not", "equal", "to"))
                    {
                        currentMod = NodeType.NotEqual;
                        tr.MoveNext(3);
                    }
                    else if (tr.EqualTo("is", "equal", "to"))
                    {
                        currentMod = NodeType.Equal;
                        tr.MoveNext(2);
                    }
                    else if (tr.EqualTo("a", "variable", "named"))
                    {
                        if (tr.MoveNext(3))
                        {
                            Nodes.Add(new Node(NodeType.LoadLocal,
                                               GetVarIndex(tr.Current(), variables)));

                            if (currentMod != NodeType.NoOperation)
                            {
                                Nodes.Add(new Node(currentMod));
                                currentMod = NodeType.NoOperation;
                            }
                        }
                        else
                        {
                            throw new Exception("Expected name after a variable named");
                        }
                    }
                    else
                    {
                        if (inExpression)
                        {
                            if (tr.IsNumberLiteral())
                            {
                                Nodes.Add(new Node(NodeType.LoadNumLiteral, tr.GetValue()));
                            }
                            else
                            {
                                Nodes.Add(new Node(NodeType.LoadLocal,
                                                   GetVarIndex(tr.Current(), variables)));
                            }
                            if (currentMod != NodeType.NoOperation)
                            {
                                Nodes.Add(new Node(currentMod));
                                currentMod = NodeType.NoOperation;
                            }
                        }
                        else
                        {
                            int index = GetVarIndex(tr.Current(), variables);
                            if (tr.MoveNext() && tr.EqualTo("equals"))
                            {
                                tr.MoveNext();
                                if (tr.IsNumberLiteral())
                                {
                                    Nodes.Add(new Node(NodeType.LoadNumLiteralAndStoreLocal, index, tr.GetValue()));
                                }
                                else
                                {
                                    Nodes.Add(new Node(NodeType.LoadLocalAndStoreLocal, index,
                                                       GetVarIndex(tr.Current(), variables)));
                                }
                            }
                            else
                            {
                                throw new Exception("Expected something after the variable");
                            }
                        }
                    }
                } while (tr.MoveNext());
            }

            return(Nodes, variables.Count);
        }
Esempio n. 3
0
 protected ParserNode _HandleLevel_Op(Func <ParserNode> HandleLevelNext, string[] Operators, Func <ParserNode, ParserNode, String, ParserNode> HandleOperator)
 {
     return(_HandleLevel_OpBase(HandleLevelNext, Operators, delegate(ParserNode ParserNode, String Operator) {
         Tokens.MoveNext();
         ParserNode RightNode = HandleLevelNext();
         return HandleOperator(ParserNode, RightNode, Operator);
     }));
 }
Esempio n. 4
0
        public static void Main()
        {
            var    Nodes     = new List <Node>();
            var    variables = new Dictionary <string, int>();
            string source    =
                @"
a equals 10
b equals 15

decrement b
decrement b
decrement b
decrement b
decrement b

if a variable named a is not equal to a variable named b then 
    a equals b
end

write a to the console
";

            Console.WriteLine(source);
            bool     inExpression = false;
            NodeType currentMod   = NodeType.NoOperation;

            Queue <Node> BlockLevel = new Queue <Node>();

            using (TokenReader tr = new TokenReader(source))
            {
                do
                {
                    if (string.IsNullOrWhiteSpace(tr.Current()))
                    {
                        continue;
                    }
                    if (tr.EqualTo("if"))
                    {
                        BlockLevel.Enqueue(new Node(NodeType.JumpNotTrue));
                        inExpression = true;
                    }
                    else if (tr.EqualTo("then"))
                    {
                        Nodes.Add(BlockLevel.Peek());
                        inExpression = false;
                    }
                    else if (tr.EqualTo("end"))
                    {
                        BlockLevel.Dequeue().A = Nodes.Count;
                        Nodes.Add(new Node(NodeType.NoOperation));
                    }
                    else if (tr.EqualTo("increment"))
                    {
                        if (tr.MoveNext() && !tr.IsNumberLiteral())
                        {
                            Nodes.Add(new Node(NodeType.Increment,
                                               GetVarIndex(tr.Current(), variables)));
                        }
                        else
                        {
                            throw new Exception("Expected a variable after increment");
                        }
                    }
                    else if (tr.EqualTo("decrement"))
                    {
                        if (tr.MoveNext() && !tr.IsNumberLiteral())
                        {
                            Nodes.Add(new Node(NodeType.Decrement,
                                               GetVarIndex(tr.Current(), variables)));
                        }
                        else
                        {
                            throw new Exception("Expected a variable after increment");
                        }
                    }
                    else if (tr.EqualTo("write"))
                    {
                        if (tr.MoveNext())
                        {
                            int     index = -1;
                            decimal value = 0;
                            if (tr.IsNumberLiteral())
                            {
                                value = tr.GetValue();
                            }
                            else
                            {
                                index = GetVarIndex(tr.Current(), variables);
                            }
                            if (tr.MoveNext())
                            {
                                if (tr.EqualTo("to", "the", "console"))
                                {
                                    if (index == -1)
                                    {
                                        Nodes.Add(new Node(NodeType.LoadNumLiteralWriteConsole, value));
                                    }
                                    else
                                    {
                                        Nodes.Add(new Node(NodeType.LoadLocalWriteConsole, index));
                                    }

                                    tr.MoveNext(2);
                                }
                            }
                            else
                            {
                                throw new Exception("Expected what to write to, after value!");
                            }
                        }
                        else
                        {
                            throw new Exception("Expected a value to write");
                        }
                    }
                    else if (tr.EqualTo("is", "not", "equal", "to"))
                    {
                        //   Nodes.Add(new Node(NodeType.NotEqual));
                        currentMod = NodeType.NotEqual;
                        tr.MoveNext(3);
                    }
                    else if (tr.EqualTo("is", "equal", "to"))
                    {
                        currentMod = NodeType.Equal;
                        //Nodes.Add(new Node(NodeType.Equal));
                        tr.MoveNext(2);
                    }
                    else if (tr.EqualTo("a", "variable", "named"))
                    {
                        if (tr.MoveNext(3))
                        {
                            Nodes.Add(new Node(NodeType.LoadLocal,
                                               GetVarIndex(tr.Current(), variables)));

                            if (currentMod != NodeType.NoOperation)
                            {
                                Nodes.Add(new Node(currentMod));
                                currentMod = NodeType.NoOperation;
                            }
                        }
                        else
                        {
                            throw new Exception("Expected name after a variable named");
                        }
                    }
                    else
                    {
                        if (inExpression)
                        {
                            if (tr.IsNumberLiteral())
                            {
                                Nodes.Add(new Node(NodeType.LoadNumLiteral, tr.GetValue()));
                            }
                            else
                            {
                                Nodes.Add(new Node(NodeType.LoadLocal,
                                                   GetVarIndex(tr.Current(), variables)));
                            }
                            if (currentMod != NodeType.NoOperation)
                            {
                                Nodes.Add(new Node(currentMod));
                                currentMod = NodeType.NoOperation;
                            }
                        }
                        else
                        {
                            int index = GetVarIndex(tr.Current(), variables);
                            if (tr.MoveNext() && tr.EqualTo("equals"))
                            {
                                tr.MoveNext();
                                if (tr.IsNumberLiteral())
                                {
                                    Nodes.Add(new Node(NodeType.LoadNumLiteralAndStoreLocal, index, tr.GetValue()));
                                }
                                else
                                {
                                    Nodes.Add(new Node(NodeType.LoadLocalAndStoreLocal, index,
                                                       GetVarIndex(tr.Current(), variables)));
                                }
                            }
                            else
                            {
                                throw new Exception("Expected something after the variable");
                            }
                        }
                    }
                } while (tr.MoveNext());

                ExecuteNodes(Nodes, variables.Count);
            }
        }
        protected ParserNode _HandleLevel_Op(Func <ParserNode> HandleLevelNext, string[] Operators, Func <ParserNode, ParserNode, String, ParserNode> HandleOperator)
        {
            ParserNode ParserNode = HandleLevelNext();

            while (Tokens.HasMore)
            {
                switch (CurrentTokenType)
                {
                case "OperatorTemplateToken":
                    string Operator = CurrentToken.Text;
                    bool   Found    = false;
                    foreach (var CurrentOperator in Operators)
                    {
                        if (Operator == CurrentOperator)
                        {
                            Tokens.MoveNext();
                            ParserNode RightNode = HandleLevelNext();
                            ParserNode = HandleOperator(ParserNode, RightNode, Operator);
                            Found      = true;
                            break;
                        }
                    }
                    if (!Found)
                    {
                        return(ParserNode);
                    }
                    break;

                default:
                    return(ParserNode);
                }
            }

            return(ParserNode);
        }
        private IEnumerable <CompletionData> GetCompletionData(int index, string input)
        {
            if (!HandleInputStrings.Contains(input))
            {
                return(null);
            }

            var block = this._bracketSearcher.SearchCurrentBlock(this.Document, index - 1);

            var bracket = string.Empty;
            var inBlock = TokenType.StringBlock;

            if (block != null)
            {
                bracket = this.Document.GetCharAt(block.OpenBracketOffset).ToString();

                if (bracket == "{")
                {
                    inBlock = TokenType.TagBlock;
                }
                else if (bracket == "[")
                {
                    inBlock = TokenType.ArrayBlock;
                }
            }

            var tokens = this.Text.Tokenize(TokenizeType.All);

            var next = this.NextChar;
            var prev = (this.CaretOffset > 1)
                ? this.Document.GetCharAt(this.CaretOffset - 2)
                : '\0';

            var before = tokens
                         .TakeWhile(x => x.Index < index)
                         .Where(x => !x.IsMatchType(TokenType.Blank));

            var current   = before.LastOrDefault();
            var prevToken = before.SkipLast(1).LastOrDefault();

            if (before.IsEmpty() ||
                current.IsMatchType(TokenType.String, TokenType.Comment))
            {
                return(null);
            }
            if ("\r\n".Contains(input) &&
                (Keyboard.Modifiers & ModifierKeys.Shift) != ModifierKeys.None)
            {
                return(null);
            }

            before = before.Where(x => !x.IsMatchType(TokenType.Comment));

            using (var reader = new TokenReader(before, true))
            {
                try
                {
                    #region コマンド
                    if (inBlock == TokenType.StringBlock)
                    {
                        switch (input.ToLower())
                        {
                        case "/":
                            return(Minecraft.CommandCompletion);

                        case "@":
                            return(Minecraft.SelectorCompletion);

                        case "_":
                            return((inBlock == TokenType.ArrayBlock && current.IsMatchType(TokenType.Literal))
                                    ? (current.Value.IndexOf("score_") == 0)
                                        ? (current.Value == "score_")
                                            ? this.ExtendedOptions.ScoreNames.ToCompletionData()
                                            : new[] { new CompletionData("min") }
                                        : null
                                    : null);
                        }

                        /*
                         * if (!before.Any(x => x.IsMatchType(TokenType.Command)))
                         * {
                         *  return null;
                         * }
                         */

                        var command = reader.SkipGet(x => x.IsMatchType(TokenType.Command) || x.IsMatchLiteral("detect"));
                        if (command.IsEmpty())
                        {
                            return(null);
                        }

                        switch (input.ToLower())
                        {
                        case ":":
                            if (!command.IsEmpty())
                            {
                                if (reader.CheckAt(1, x => x.IsMatchLiteral("minecraft")))
                                {
                                    goto case " ";
                                }
                            }
                            break;

                        case ",":
                            break;

                        case "\r\n":
                        case "\r":
                        case "\n":
                        case " ":
                            if (!command.IsEmpty() && inBlock == TokenType.StringBlock)
                            {
                                reader.Reverse();
                                var args = this.RemainTokensToArgs(reader);
                                var def  = command.IsMatchLiteral("detect")
                                        ? Minecraft.Document.Root.Element("ExCommands").Elements("Command")
                                           .Where(x => x.Attribute("name").Value == command.Value).SingleOrDefault()
                                        : Minecraft.Document.Root.Element("Commands").Elements("Command")
                                           .Where(x => "/" + x.Attribute("name").Value == command.Value).SingleOrDefault();

                                if (def == null)
                                {
                                    return(null);
                                }

                                var elements = def.Elements("Arg");
                                var element  = null as XElement;

                                foreach (var arg in args)
                                {
                                    if (elements.IsEmpty())
                                    {
                                        return(null);
                                    }
                                    if (elements.Count() > 1)
                                    {
                                        Console.WriteLine(arg.Value);
                                        if (elements.Any(x => x.Attribute("type").Value == "key" && arg.IsMatchLiteral(x.Attribute("key").Value)))
                                        {
                                            elements = elements.Where(x => arg.IsMatchLiteral(x.Attribute("key").Value)).Elements("Arg");
                                        }
                                        else if (elements.Any(x => x.Attributes().Any(a => a.Name == "default" && a.Value == "true")))
                                        {
                                            elements = elements.Where(x => x.Attributes().Any(a => a.Name == "default" && a.Value == "true")).Elements("Arg");
                                        }
                                        else
                                        {
                                            return(null);
                                        }
                                    }
                                    else
                                    {
                                        elements = elements.Elements("Arg");
                                    }
                                }

                                if (elements.Count() > 1)
                                {
                                    if (elements.Any(x => x.Attributes().Any(a => a.Name == "default" && a.Value == "true")))
                                    {
                                        elements = elements.Where(x => x.Attributes().Any(a => a.Name == "default" && a.Value == "true"));
                                    }
                                    else
                                    {
                                        return(elements.Attributes()
                                               .Where(x => x.Name == "key")
                                               .Select(x => new CompletionData(x.Value)));
                                    }
                                }

                                element = elements.SingleOrDefault();
                                if (element == null)
                                {
                                    return(null);
                                }

                                var type = element.Attribute("type").Value;

                                switch (type)
                                {
                                case "key":
                                    return(new[] { new CompletionData(element.Attribute("key").Value) });

                                case "keywords":
                                    return(element.Elements("Word")
                                           .Select(x =>
                                                   new
                                    {
                                        Name = x.Value.Trim(),
                                        Tip = x.Attribute("desc") != null
                                                        ? x.Attribute("desc").Value
                                                        : x.Element("Desc") != null
                                                            ? x.Element("Desc").Value
                                                            : null
                                    })
                                           .Select(x => new CompletionData(x.Name, x.Tip)));

                                case "target":
                                    return(this.ExtendedOptions.PlayerNames.ToCompletionData());

                                case "target_entity":
                                    return(new[] { new CompletionData("@e") });

                                case "score":
                                    return(this.ExtendedOptions.ScoreNames.ToCompletionData());

                                case "team":
                                    return(this.ExtendedOptions.TeamNames.ToCompletionData());

                                case "item":
                                    return(Minecraft.ItemCompletion);

                                case "block":
                                    return(Minecraft.BlockCompletion);

                                case "entity":
                                    return(Minecraft.EntityCompletion);

                                case "effect":
                                    return(prevToken.IsMatchLiteral("minecraft")
                                                ? Minecraft.EffectCompletion
                                                : Minecraft.EffectCompletion
                                           .Concat(new[] { new CompletionData("clear", "すべてのエフェクトを消去します。") }));

                                case "enchant":
                                    return(Minecraft.EnchantCompletion);

                                case "boolean":
                                    return(Minecraft.BooleanCompletion);

                                case "color":
                                    return(Minecraft.ColorCompletion);

                                case "command":
                                    if (command.Value == "/execute" || command.Value == "detect")
                                    {
                                        return(new[] { new CompletionData("detect") }
                                               .Concat(Minecraft.CommandCompletion));
                                    }
                                    return(Minecraft.CommandCompletion);

                                default:
                                    return(null);
                                }
                            }
                            break;
                        }
                    }
                    #endregion
                    #region [ ... ]
                    if (inBlock == TokenType.ArrayBlock)
                    {
                        switch (input)
                        {
                        case "!":
                            if (reader.CheckNext(x => x.IsMatchType(TokenType.Equal)))
                            {
                                reader.MoveNext();
                                goto case "=";
                            }
                            return(null);

                        case "=":
                            if (reader.IsRemainToken)
                            {
                                var selector = before.TakeWhile(x => x.Index < block.OpenBracketOffset).LastOrDefault();
                                if (!selector.IsEmpty() && selector.IsMatchType(TokenType.TargetSelector))
                                {
                                    reader.MoveNext();
                                    if (reader.CheckNext(x => x.IsMatchLiteral("team")))
                                    {
                                        return(this.ExtendedOptions.TeamNames.ToCompletionData());
                                    }
                                    if (reader.CheckNext(x => x.IsMatchLiteral("name")))
                                    {
                                        return(this.ExtendedOptions.PlayerNames.ToCompletionData());
                                    }
                                }
                            }
                            return(null);
                        }
                    }
                    #endregion
                }
                catch
                {
                    return(null);
                }
            }

            return(null);
        }