Ejemplo n.º 1
0
        private Tree ParseStatement()
        {
            if (curToken.type == TokenType.Keyword)
            {
                Token keyword = curToken;
                nextToken();

                if (keyword.value == "var" || keyword.value == "global")
                {
                    bool isLocal = keyword.value == "var";

                    string varName = curToken.value;

                    nextToken();

                    Tree expression = null;

                    if (accept(equals).valid)
                    {
                        expression = ParseExpression();
                    }

                    Scope last = scopes[scopes.Count - 1];

                    if (isLocal)
                    {
                        last.localVariables.Add(varName, last.localCount);

                        last.localCount++;
                        last.maxLocalCount = Math.Max(last.localCount, last.maxLocalCount);

                        return(new LocalAssignmentTree(last.localCount - 1, expression));
                    }
                    else
                    {
                        last.globalVariables.Add(varName, true);

                        return(new GlobalAssignmentTree(varName, expression));
                    }
                }
                else if (keyword.value == "function")
                {
                    string name = expect(Token.Identifier).value;

                    scopes[scopes.Count - 1].globalVariables.Add(name, true);

                    CreateClosureTree funcTree = ParseFunctionDeclaration();

                    GlobalAssignmentTree tree = new GlobalAssignmentTree(name, funcTree);

                    return(tree);
                }
                else if (keyword.value == "if")
                {
                    IfTree tree = new IfTree();

                    expect(lParen);

                    tree.condition = ParseExpression();

                    expect(rParen);

                    tree.ifBody = ParseBlockOrStatement(ScopeType.If);

                    if (accept(kElse).valid)
                    {
                        tree.hasElse  = true;
                        tree.elseBody = ParseBlockOrStatement(ScopeType.If);
                    }

                    return(tree);
                }
                else if (keyword.value == "while")
                {
                    WhileTree tree = new WhileTree();

                    expect(lParen);

                    tree.condition = ParseExpression();

                    expect(rParen);

                    tree.body = ParseBlockOrStatement(ScopeType.While);

                    return(tree);
                }
                else if (keyword.value == "return")
                {
                    ReturnTree tree = new ReturnTree();

                    if (curToken.type != TokenType.Punctuation)
                    {
                        tree.value = ParseExpression();
                    }

                    return(tree);
                }
            }
            else if (curToken.type == TokenType.Identifier || curToken.compare(lParen))
            {
                Tree thing = ParseIndexOrCall();

                if (thing.type == TreeType.FunctionCall)
                {
                    return(thing);
                }
                else
                {
                    // assignment

                    if (thing.type == TreeType.GlobalValue)
                    {
                        expect(equals);

                        Tree value = ParseExpression();

                        return(new GlobalAssignmentTree((thing as GlobalValueTree).name, value));
                    }
                    else if (thing.type == TreeType.LocalValue)
                    {
                        expect(equals);

                        Tree value = ParseExpression();

                        return(new LocalAssignmentTree((thing as LocalValueTree).index, value));
                    }
                    else if (thing.type == TreeType.ObjectIndexValue)
                    {
                        expect(equals);

                        Tree value = ParseExpression();

                        ObjectIndexValueTree OIVTree = thing as ObjectIndexValueTree;

                        return(new ObjectIndexAssignmentTree(OIVTree.Object, OIVTree.Index, value));
                    }
                }
            }
            throw new SyntaxErrorException(curToken.line, "Did not expect " + curToken + " here");
        }
Ejemplo n.º 2
0
        //==========

        private Tree ParseIndexOrCall(Tree theObject = null)
        {
            if (theObject == null)
            {
                if (curToken.type == TokenType.Identifier)
                {
                    theObject = GetVariableFromName(curToken.value);

                    if (theObject == null)
                    {
                        throw new ReferenceErrorException(curToken.line, $"'{curToken.value}' is not defined");
                    }

                    if (theObject.type == TreeType.LocalValue)
                    {
                        if ((theObject as LocalValueTree).functionId != scopes[scopes.Count - 1].functionId)
                        {
                            throw new SyntaxErrorException(curToken.line, "upvalues are not supported");
                        }
                    }
                    nextToken();
                }
                else if (accept(lParen).valid)
                {
                    theObject = ParseExpression();
                    expect(rParen);
                }
                else
                {
                    throw new SyntaxErrorException(curToken.line, "Did not expect " + curToken + " here");
                }
            }

            if (theObject.type == TreeType.FunctionCall)
            {
                (theObject as FunctionCallTree).isExpression = true;
            }

            if (accept(dot).valid)
            {
                //index using identifier

                theObject = new ObjectIndexValueTree(theObject, new StringTree(expect(Token.Identifier).value));

                return(ParseIndexOrCall(theObject));
            }
            else if (accept(lSquare).valid)
            {
                //index using expression

                Tree index = ParseExpression();

                expect(rSquare);

                theObject = new ObjectIndexValueTree(theObject, index);

                return(ParseIndexOrCall(theObject));
            }
            else if (accept(lParen).valid)
            {
                //function call

                FunctionCallTree tree = new FunctionCallTree(theObject);

                if (!accept(rParen).valid)
                {
                    do
                    {
                        tree.AddArgument(ParseExpression());
                    } while (accept(comma).valid);
                    expect(rParen);
                }

                return(ParseIndexOrCall(tree));
            }

            if (theObject.type == TreeType.FunctionCall)
            {
                (theObject as FunctionCallTree).isExpression = false;
            }

            return(theObject);
        }