コード例 #1
0
ファイル: Parser.cs プロジェクト: yoranmandema/Project_Skrypt
        static public node ParseExpression(node branch, List <Token> expression, bool gotSplit = false)
        {
            List <Token> leftBuffer  = new List <Token>();
            List <Token> rightBuffer = new List <Token>();

            int i    = -1;
            int opPC = opPrecedence.Count;

            for (int j = 0; j < opPC; j++)
            {
                OperatorCategory Cat = opPrecedence[j];
                bool             rtl = Cat.rightToLeft;
                byte             cnt = Cat.count;
                int  k    = rtl ? Cat.operators.Length - 1 : 0;
                bool loop = true;
                bool obrk = false;

                while (loop)
                {
                    i = -1;
                    bool brk = false;

                    bool   isPar              = false;
                    int    rParCount          = 0;
                    int    parPairs           = 0;
                    bool   surroundedPar      = false;
                    bool   firstIsPar         = false;
                    bool   firstIsMethod      = false;
                    bool   methodPar          = false;
                    bool   expressionIsMethod = false;
                    Method foundMethod        = null;

                    string op = Tokenizer.processPunctuator(Cat.operators[k]);

                    while (i < expression.Count - 1)
                    {
                        i++;

                        Token token = expression[i];

                        if (MethodHandler.Exists(token.value))
                        {
                            if (i == 0)
                            {
                                firstIsMethod = true;
                                foundMethod   = MethodHandler.Get(token.value);
                            }
                        }

                        // If a left parenthesis is found, increase rParCount so we can keep track of the current pair
                        if (token.value == "lpar")
                        {
                            rParCount++;
                            isPar = true;

                            if (i == 0)
                            {
                                firstIsPar = true;
                            }
                            else if (i == 1 && firstIsMethod)
                            {
                                methodPar = true;
                            }
                        }

                        if (isPar)
                        {
                            // If a right parenthesis is found, decrease rParCount so we can keep track of the current pair
                            if (token.value == "rpar")
                            {
                                rParCount--;

                                // If rParCount == 0, it means that we found a matching pair of parenthesis
                                if (rParCount == 0)
                                {
                                    parPairs++;
                                    isPar = false;

                                    if (i == expression.Count - 1 && firstIsPar && parPairs == 1)
                                    {
                                        surroundedPar = true;
                                        break;
                                    }

                                    if (i == expression.Count - 1 && methodPar)
                                    {
                                        expressionIsMethod = true;
                                        break;
                                    }

                                    continue;
                                }
                            }
                            else
                            {
                                // Skip until we find the matching right parenthesis
                                continue;
                            }
                        }

                        if (op == token.value)
                        {
                            node newNode = new node();
                            node addNode;
                            newNode.depth = branch.depth + 1;
                            newNode.body  = token.value;

                            // All of the tokens on the left
                            leftBuffer = expression.GetRange(0, i);

                            // All of the tokens on the right
                            rightBuffer = expression.GetRange(i + 1, expression.Count - i - 1);

                            if (op == "dec" || op == "inc")
                            {
                                if (leftBuffer.Count > 0 && rightBuffer.Count == 0)
                                {
                                    newNode.body = "p" + Tokenizer.processPunctuator(op);
                                    addNode      = ParseExpression(newNode, leftBuffer, true);
                                }
                                else
                                {
                                    newNode.body = Tokenizer.processPunctuator(op);
                                    addNode      = ParseExpression(newNode, rightBuffer, true);
                                }

                                if (addNode != null)
                                {
                                    newNode.nodes.Add(addNode);
                                }
                            }
                            else
                            {
                                // Parsing a node from the left buffer
                                if (cnt != 1)
                                {
                                    addNode = ParseExpression(newNode, leftBuffer, true);
                                    if (addNode != null)
                                    {
                                        newNode.nodes.Add(addNode);
                                    }
                                }

                                if (op == "return")
                                {
                                    if (rightBuffer.Count > 0)
                                    {
                                        Console.WriteLine(stringList(rightBuffer));

                                        // Parsing a node from the right buffer
                                        addNode = ParseExpression(newNode, rightBuffer, true);

                                        if (addNode != null)
                                        {
                                            newNode.nodes.Add(addNode);
                                        }
                                    }
                                }
                                else
                                {
                                    // Parsing a node from the right buffer
                                    addNode = ParseExpression(newNode, rightBuffer, true);
                                    if (addNode != null)
                                    {
                                        newNode.nodes.Add(addNode);
                                    }
                                }
                            }

                            branch.nodes.Add(newNode);

                            // Break out of all loops
                            brk = true;
                            break;
                        }
                    }

                    // Parse an expression thats between a pair of parenthesis, but ONLY
                    // if it wasn't split up before, and only if the whole block is surrounded by matching parenthesis
                    if (surroundedPar)
                    {
                        expression = expression.GetRange(1, expression.Count - 2);
                        return(ParseExpression(branch, expression));
                    }
                    else if (expressionIsMethod)
                    {
                        node addNode = null;

                        if (expression.Count > 2)
                        {
                            if (expression[0].type == TokenType.Identifier &&
                                expression[1].value == "lpar" &&
                                expression[expression.Count - 1].value == "rpar"
                                )
                            {
                                addNode = ParseMethod(branch, expression, foundMethod);

                                if (addNode != null && !gotSplit)
                                {
                                    branch.nodes.Add(addNode);
                                    return(null);
                                }
                            }
                        }

                        return(addNode);
                    }

                    // Loop direction (0 to length - 1 or length - 1 to 0)
                    if (rtl)
                    {
                        loop = k > 0;
                        k--;
                    }
                    else
                    {
                        loop = k < Cat.operators.Length - 1;
                        k++;
                    }

                    // Break out of all loops
                    if (brk)
                    {
                        obrk = true;
                        break;
                    }
                }

                // Break out of all loops
                if (obrk)
                {
                    break;
                }
            }

            // Return no node if the expression list contains more than 1 token at this point
            if (expression.Count > 1)
            {
                return(null);
            }

            Token  tkn   = expression[0];
            object Value = null;

            switch (tkn.type)
            {
            case TokenType.Numeric:
                Value = double.Parse(tkn.value);
                break;

            case TokenType.String:
                Value = tkn.value.Substring(1, tkn.value.Length - 2);
                break;

            case TokenType.Boolean:
                if (tkn.value == "true")
                {
                    Value = true;
                }
                else
                {
                    Value = false;
                }
                break;

            default:
                break;
            }


            // Return leaf node
            return(new node()
            {
                body = expression[0].value, depth = branch.depth + 1, Value = Value, type = tkn.type
            });
        }
コード例 #2
0
        static public Variable ExecuteMethod(node methodNode, List <Variable> scopeContext)
        {
            if (!MethodHandler.Exists(methodNode.body))
            {
                throw new SkryptMethodDoesNotExistException(methodNode.body);
            }

            Method       method   = MethodHandler.Get(methodNode.body);
            SkryptMethod skmethod = MethodHandler.GetSk(methodNode.body);

            string      type     = methodNode.nodes[0].body;
            List <node> argNodes = null;

            object[]        args       = new object[0];
            List <Variable> scopedVars = new List <Variable>();

            if (method.arguments.Length > 0 && method.arguments != null)
            {
                argNodes = methodNode.nodes[1].nodes;
                args     = new object[argNodes.Count];

                int i = 0;

                foreach (node argNode in argNodes)
                {
                    node     Expr   = argNode.nodes[0];
                    Variable solved = ExecuteExpression(Expr, scopedVars);

                    args[i] = solved.Value;

                    i++;
                }
            }

            Variable returnVariable;

            if (method.predefined)
            {
                returnVariable = method.Run(args);
            }
            else
            {
                if (argNodes != null)
                {
                    int i = 0;

                    foreach (node argNode in argNodes)
                    {
                        node     Expr   = argNode.nodes[0];
                        Variable solved = ExecuteExpression(Expr, scopedVars);
                        solved.Identifier = argNode.body;

                        if (Variables.Exists(x => x.Identifier == argNode.body))
                        {
                            Variables[Variables.IndexOf(Variables.Find(x => x.Identifier == argNode.body))].Value = solved.Value;
                        }

                        scopedVars.Add(solved);

                        i++;
                    }
                }

                returnVariable = skmethod.Run(scopedVars);
                DeleteVariables(scopedVars);
            }

            return(returnVariable);
        }