public override DynValue Visit(WhileLoopNode whileLoopNode)
        {
            try
            {
                LoopStack.Push(new LoopStackItem());

                while (Visit(whileLoopNode.Expression).Number != 0)
                {
                    ExecuteStatementList(whileLoopNode.StatementList).GetAwaiter().GetResult();

                    var stackTop = LoopStack.Peek();

                    if (stackTop.BreakLoop)
                    {
                        break;
                    }

                    if (stackTop.SkipThisIteration)
                    {
                        stackTop.SkipThisIteration = false;
                        continue;
                    }
                }
            }
            catch
            {
                throw;
            }
            finally
            {
                LoopStack.Pop();
            }

            return(DynValue.Zero);
        }
 public override void Visit(WhileLoopNode node)
 {
     SymbolTable.SetCurrentNode(node);
     node.BoolCompare.Accept(this);
     SymbolTable.OpenScope(BlockType.WhileLoop);
     VisitChildren(node);
     SymbolTable.CloseScope();
 }
Пример #3
0
        /// <summary>
        /// while语句
        /// </summary>
        /// <param name="node"></param>
        public void Visit(WhileLoopNode node)
        {
            var builder = new StringBuilder();

            builder.Append("while条件语句:");
            builder.Append("  条件:");
            Visit((Object)node.Condition);
            builder.AppendLine("条件语句块:");
            Console.WriteLine(builder.ToString());
            foreach (var item in node.SubNodes)
            {
                Visit((Object)item);
            }
        }
Пример #4
0
        public override DynValue Visit(WhileLoopNode whileLoopNode)
        {
            Environment.EnterScope();
            {
                try
                {
                    Environment.LoopStack.Push(new LoopFrame());

                    while (Visit(whileLoopNode.Expression).IsTruth)
                    {
                        Environment.EnterScope();
                        {
                            ExecuteStatementList(whileLoopNode.StatementList);
                        }
                        Environment.ExitScope();
                        var stackTop = Environment.LoopStackTop;

                        if (stackTop.BreakLoop)
                        {
                            break;
                        }

                        if (stackTop.SkipThisIteration)
                        {
                            stackTop.SkipThisIteration = false;
                        }
                    }
                }
                finally
                {
                    Environment.LoopStack.Pop();
                }
            }
            Environment.ExitScope();

            return(DynValue.Zero);
        }
Пример #5
0
 public virtual XzaarExpression Visit(WhileLoopNode loop)
 {
     return(null);
 }
Пример #6
0
 public virtual T VisitWhileLoop(WhileLoopNode whileLoop)
 {
     throw new NotImplementedException();
 }
Пример #7
0
 public abstract DynValue Visit(WhileLoopNode whileLoopNode);
Пример #8
0
        public ProgramNode ParseToAst()
        {
            _scopes.Push(new ProgramNode());

            while (!EndOfProgram)
            {
                var upcomingToken = PeekNextToken();
                if (upcomingToken is KeywordToken)
                {
                    var keyword     = (KeywordToken)NextToken();
                    var globalScope = _scopes.Count == 1; // There are constraints to what is available on the global scope
                    if (keyword.IsTypeKeyword)
                    {
                        var varType = keyword.ToVariableType();
                        //it must be followed by a identifier:
                        var name = ReadNextToken <IdentifierToken>();
                        //so see what it is (function or variable):
                        Token lookahead = PeekNextToken();
                        if (lookahead is OperatorToken && (((OperatorToken)lookahead).OperatorType == OperatorType.Assignment) || lookahead is StatementSeparatorToken) //variable declaration
                        {
                            if (lookahead is OperatorToken)
                            {
                                NextToken(); //skip the "="
                            }
                            _currentScope.AddStatement(new VariableDeclarationNode(varType, name.Content, ExpressionNode.CreateFromTokens(ReadUntilStatementSeparator())));
                        }
                        else if (lookahead is OpenBraceToken)
                        {
                            var lookaheadOpenBrace = lookahead as OpenBraceToken;
                            if (lookaheadOpenBrace.BraceType == BraceType.Square) //It is a list type declaration
                            {
                                //Ensure that the next token is the close square brace
                                NextToken(); //Go past the opening token
                                var secondLookahead = PeekNextToken();
                                if (secondLookahead is CloseBraceToken && ((CloseBraceToken)secondLookahead).BraceType == BraceType.Square)
                                {
                                    NextToken(); //Good, it matched, now skip that too
                                    //Add a list declaration node
                                    _currentScope.AddStatement(new ListDeclarationNode(varType, name.Content, ExpressionNode.CreateFromTokens(ReadUntilStatementSeparator())));
                                }
                                else
                                {
                                    throw new UnexpectedTokenException("Missing close square bracket in array declaration");
                                }
                            }
                            //If in the global scope, it can also be a function declaration
                            else if (globalScope && lookaheadOpenBrace.BraceType == BraceType.Round) //function definition
                            {
                                var func = new FunctionDeclarationNode(name.Content);
                                _currentScope.AddStatement(func);                                                                                //add the function to the old (root) scope...
                                _scopes.Push(func);                                                                                              //...and set it a the new scope!
                                                                                                                                                 //Read the argument list
                                NextToken();                                                                                                     //skip the opening brace
                                while (!(PeekNextToken() is CloseBraceToken && ((CloseBraceToken)PeekNextToken()).BraceType == BraceType.Round)) //TODO: Refactor using readUntilClosingBrace?
                                {
                                    var argType = ReadNextToken <KeywordToken>();
                                    if (!argType.IsTypeKeyword)
                                    {
                                        throw new ParsingException("Expected type keyword!");
                                    }
                                    var argName = ReadNextToken <IdentifierToken>();
                                    func.AddParameter(new ParameterDeclarationNode(argType.ToVariableType(), argName.Content));
                                    if (PeekNextToken() is ArgSeperatorToken) //TODO: Does this allow (int a int b)-style functions? (No arg-seperator!)
                                    {
                                        NextToken();                          //skip the sperator
                                    }
                                }
                                NextToken(); //skip the closing brace
                                var curlyBrace = ReadNextToken <OpenBraceToken>();
                                if (curlyBrace.BraceType != BraceType.Curly)
                                {
                                    throw new ParsingException("Wrong brace type found!");
                                }
                            }
                        }
                        else
                        {
                            throw new Exception("The parser encountered an unexpected token.");
                        }
                        //We can't have anything other than what's listed above on the global scope
                    }
                    //Not a type keyword. If on a local scope, it may be other keywords
                    else if (!globalScope)
                    {
                        switch (keyword.KeywordType)
                        {
                        case KeywordType.Return:
                            _currentScope.AddStatement(new ReturnStatementNode(ExpressionNode.CreateFromTokens(ReadUntilStatementSeparator())));
                            break;

                        case KeywordType.If:
                            var @if = new IfStatementNode(ExpressionNode.CreateFromTokens(ReadUntilClosingBrace(true)));
                            _currentScope.AddStatement(@if); //Add if statement to previous scope
                            _scopes.Push(@if);               //...and set it a the new scope!
                            NextToken();                     //skip the opening curly brace
                            break;

                        case KeywordType.While:
                            var @while = new WhileLoopNode(ExpressionNode.CreateFromTokens(ReadUntilClosingBrace(true)));
                            _currentScope.AddStatement(@while);
                            _scopes.Push(@while);
                            NextToken();     //skip the opening curly brace
                            break;

                        default:
                            throw new ParsingException("Unexpected keyword type.");
                        }
                    }
                    else //It was not a keyword, and it was a global scope
                    {
                        throw new ParsingException("Found non-type keyword on global scope.");
                    }
                }
                else if (upcomingToken is IdentifierToken && _scopes.Count > 1) //in a nested scope
                {
                    var identifierToken = upcomingToken as IdentifierToken;
                    NextToken();                                                                                          //Step past the identifier token
                    var nextToken = PeekNextToken();                                                                      //Read the next token
                    if (nextToken is OperatorToken && ((OperatorToken)nextToken).OperatorType == OperatorType.Assignment) //variable assignment
                    {
                        NextToken();                                                                                      //skip the "="
                        _currentScope.AddStatement(new VariableAssignmentNode(identifierToken.Content, ExpressionNode.CreateFromTokens(ReadUntilStatementSeparator())));
                    }
                    else if (nextToken is MemberAccessToken)
                    {
                        List <MemberAccessToken> memberAccessTokens = new List <MemberAccessToken>();
                        Token currentTestToken;
                        while ((currentTestToken = PeekNextToken()) is MemberAccessToken) //They can be stacked
                        {
                            NextToken();                                                  //Advance
                            memberAccessTokens.Add(currentTestToken as MemberAccessToken);
                        }
                        if (currentTestToken is OperatorToken && ((OperatorToken)currentTestToken).OperatorType == OperatorType.Assignment) //table member assignment
                        {
                            NextToken();                                                                                                    //skip the "="
                                                                                                                                            //Tokens until statement end have to be preloaded as a 'temporary workaround' to allow looking forward
                            var expressionTokens = ReadUntilStatementSeparator().ToList();
                            _currentScope.AddStatement(new TableAssignmentNode(TableQualifier.Create(identifierToken, memberAccessTokens), ExpressionNode.CreateFromTokens(expressionTokens)));
                        }
                        else if (currentTestToken is OpenBraceToken && ((OpenBraceToken)currentTestToken).BraceType == BraceType.Round)
                        {
                            //Member invocation
                            var fakeIdentifierToken = new IdentifierToken(identifierToken.Content); //So it will be parsed as a function call
                            var memberInvocationInternalFunctionCall = ExpressionNode.CreateFromTokens(new[] { fakeIdentifierToken }.Concat(ReadUntilStatementSeparator())) as FunctionCallExpressionNode;
                            _currentScope.AddStatement(new TableMemberInvocationNode(TableQualifier.Create(identifierToken, memberAccessTokens), memberInvocationInternalFunctionCall.Arguments));
                        }
                    }
                    else //lone expression (incl. function calls!)
                    {
                        _currentScope.AddStatement(ExpressionNode.CreateFromTokens(new[] { identifierToken }.Concat(ReadUntilStatementSeparator()))); //don't forget the name here!
                    }
                }
                else if (upcomingToken is CloseBraceToken)
                {
                    //Closing a scope
                    var brace = ReadNextToken <CloseBraceToken>();
                    if (brace.BraceType != BraceType.Curly)
                    {
                        throw new ParsingException("Wrong brace type found!");
                    }
                    _scopes.Pop(); //Scope has been closed!
                }
                else
                {
                    throw new UnexpectedTokenException("The parser ran into an unexpected token", upcomingToken);
                }
            }

            if (_scopes.Count != 1)
            {
                throw new ParsingException("The scopes are not correctly nested.");
            }

            return((ProgramNode)_scopes.Pop());
        }
Пример #9
0
        public ProgramNode ParseToAst()
        {
            scopes.Push(new ProgramNode());

            while (!eof())
            {
                if (peek() is KeywordToken)
                {
                    var keyword = (KeywordToken)next();

                    if (scopes.Count == 1) //we are a top level, the only valid keywords are variable types, starting a variable or function definition
                    {
                        if (keyword.IsTypeKeyword)
                        {
                            var varType = keyword.ToVariableType();
                            //it must be followed by a identifier:
                            var name = readToken <IdentifierToken>();
                            //so see what it is (function or variable):
                            Token lookahead = peek();
                            if (lookahead is OperatorToken && (((OperatorToken)lookahead).OperatorType == OperatorType.Assignment) || lookahead is StatementSperatorToken) //variable declaration
                            {
                                if (lookahead is OperatorToken)
                                {
                                    next(); //skip the "="
                                }
                                scopes.Peek().AddStatement(new VariableDeclarationNode(varType, name.Content, ExpressionNode.CreateFromTokens(readUntilStatementSeperator())));
                            }
                            else if (lookahead is OpenBraceToken && (((OpenBraceToken)lookahead).BraceType == BraceType.Round)) //function definition
                            {
                                var func = new FunctionDeclarationNode(name.Content);
                                scopes.Peek().AddStatement(func);                                                              //add the function to the old (root) scope...
                                scopes.Push(func);                                                                             //...and set it a the new scope!
                                //Read the argument list
                                next();                                                                                        //skip the opening brace
                                while (!(peek() is CloseBraceToken && ((CloseBraceToken)peek()).BraceType == BraceType.Round)) //TODO: Refactor using readUntilClosingBrace?
                                {
                                    var argType = readToken <KeywordToken>();
                                    if (!argType.IsTypeKeyword)
                                    {
                                        throw new ParsingException("Expected type keyword!");
                                    }
                                    var argName = readToken <IdentifierToken>();
                                    func.AddParameter(new ParameterDeclarationNode(argType.ToVariableType(), argName.Content));
                                    if (peek() is ArgSeperatorToken) //TODO: Does this allow (int a int b)-style functions? (No arg-seperator!)
                                    {
                                        next();                      //skip the sperator
                                    }
                                }
                                next(); //skip the closing brace
                                var curlyBrace = readToken <OpenBraceToken>();
                                if (curlyBrace.BraceType != BraceType.Curly)
                                {
                                    throw new ParsingException("Wrong brace type found!");
                                }
                            }
                            else
                            {
                                throw new Exception("The parser encountered an unexpected token.");
                            }
                        }
                        else
                        {
                            throw new ParsingException("Found non-type keyword on top level.");
                        }
                    }
                    else //we are in a nested scope
                    {
                        //TODO: Can we avoid the code duplication from above?
                        if (keyword.IsTypeKeyword) //local variable declaration!
                        {
                            var varType = keyword.ToVariableType();
                            //it must be followed by a identifier:
                            var name = readToken <IdentifierToken>();
                            //so see what it is (function or variable):
                            Token lookahead = peek();
                            if (lookahead is OperatorToken && (((OperatorToken)lookahead).OperatorType == OperatorType.Assignment) || lookahead is StatementSperatorToken) //variable declaration
                            {
                                if (lookahead is OperatorToken)
                                {
                                    next(); //skip the "="
                                }
                                scopes.Peek().AddStatement(new VariableDeclarationNode(varType, name.Content, ExpressionNode.CreateFromTokens(readUntilStatementSeperator())));
                            }
                        }
                        else
                        {
                            switch (keyword.KeywordType)
                            {
                            case KeywordType.Return:
                                scopes.Peek().AddStatement(new ReturnStatementNode(ExpressionNode.CreateFromTokens(readUntilStatementSeperator())));
                                break;

                            case KeywordType.If:
                                var @if = new IfStatementNode(ExpressionNode.CreateFromTokens(readUntilClosingBrace()));
                                scopes.Peek().AddStatement(@if);
                                scopes.Push(@if);
                                break;

                            case KeywordType.While:
                                var @while = new WhileLoopNode(ExpressionNode.CreateFromTokens(readUntilClosingBrace()));
                                scopes.Peek().AddStatement(@while);
                                scopes.Push(@while);
                                break;

                            default:
                                throw new ParsingException("Unexpected keyword type.");
                            }
                        }
                    }
                }
                else if (peek() is IdentifierToken && scopes.Count > 1) //in nested scope
                {
                    var name = readToken <IdentifierToken>();
                    if (peek() is OperatorToken && ((OperatorToken)peek()).OperatorType == OperatorType.Assignment) //variable assignment
                    {
                        next();                                                                                     //skip the "="
                        scopes.Peek().AddStatement(new VariableAssingmentNode(name.Content, ExpressionNode.CreateFromTokens(readUntilStatementSeperator())));
                    }
                    else //lone expression (incl. function calls!)
                    {
                        scopes.Peek().AddStatement(ExpressionNode.CreateFromTokens(new[] { name }.Concat(readUntilStatementSeperator()))); //don't forget the name here!
                    }
                }
                else if (peek() is CloseBraceToken)
                {
                    var brace = readToken <CloseBraceToken>();
                    if (brace.BraceType != BraceType.Curly)
                    {
                        throw new ParsingException("Wrong brace type found!");
                    }
                    scopes.Pop(); //Scope has been closed!
                }
                else
                {
                    throw new ParsingException("The parser ran into an unexpeted token.");
                }
            }

            if (scopes.Count != 1)
            {
                throw new ParsingException("The scopes are not correctly nested.");
            }

            return((ProgramNode)scopes.Pop());
        }
 public string VisitWhileLoop(WhileLoopNode whileLoop)
 {
     throw new NotImplementedException();
 }
Пример #11
0
 public AddressNode VisitWhileLoop(WhileLoopNode whileLoop)
 {
     throw new System.NotImplementedException();
 }
Пример #12
0
        /// <summary>
        /// 解析成抽象语法树
        /// </summary>
        /// <returns></returns>
        public ProgramNode ParseToAst()
        {
            if (scopes.Count == 0)
            {
                scopes.Push(new ProgramNode());
            }
            while (!Eof())
            {
                if (Peek() is KeywordToken)
                {
                    var keyword = (KeywordToken)Next();

                    if (scopes.Count == 1)
                    {
                        if (keyword.IsTypeKeyword)
                        {
                            var varType = keyword.ToVariableType();

                            var name = ReadToken <IdentifierToken>();
                            //超前搜索
                            Token lookahead = Peek();
                            if (lookahead is OperatorToken && (((OperatorToken)lookahead).OperatorType == OperatorType.Assignment) || lookahead is StatementSperatorToken)
                            {
                                if (lookahead is OperatorToken)
                                {
                                    Next();
                                }
                                scopes.Peek().AddStatement(new VariableDeclarationNode(varType, name.Content, ExpressionNode.CreateFromTokens(ReadUntilStatementSeperator())));
                            }
                            else if (lookahead is OpenBraceToken && (((OpenBraceToken)lookahead).BraceType == BraceType.Round))
                            {
                                var func = new FunctionDeclarationNode(name.Content);
                                scopes.Peek().AddStatement(func);
                                scopes.Push(func);
                                Next();
                                while (!(Peek() is CloseBraceToken && ((CloseBraceToken)Peek()).BraceType == BraceType.Round))
                                {
                                    var argType = ReadToken <KeywordToken>();
                                    if (!argType.IsTypeKeyword)
                                    {
                                        throw new ParsingException("Expected type keyword!");
                                    }
                                    var argName = ReadToken <IdentifierToken>();
                                    func.AddParameter(new ParameterDeclarationNode(argType.ToVariableType(), argName.Content));
                                    if (Peek() is ArgSeperatorToken)
                                    {
                                        Next();
                                    }
                                }

                                Next();
                                var curlyBrace = ReadToken <OpenBraceToken>();
                                if (curlyBrace.BraceType != BraceType.Curly)
                                {
                                    throw new ParsingException("Wrong brace type found!");
                                }
                            }
                            else
                            {
                                throw new Exception("The parser encountered an unexpected token.");
                            }
                        }
                        else
                        {
                            throw new ParsingException("Found non-type keyword on top level.");
                        }
                    }
                    else
                    {
                        if (keyword.IsTypeKeyword)
                        {
                            var varType = keyword.ToVariableType();

                            var name = ReadToken <IdentifierToken>();

                            Token lookahead = Peek();
                            if (lookahead is OperatorToken && (((OperatorToken)lookahead).OperatorType == OperatorType.Assignment) || lookahead is StatementSperatorToken) //variable declaration
                            {
                                if (lookahead is OperatorToken)
                                {
                                    Next();
                                }
                                scopes.Peek().AddStatement(new VariableDeclarationNode(varType, name.Content, ExpressionNode.CreateFromTokens(ReadUntilStatementSeperator())));
                            }
                        }
                        else
                        {
                            switch (keyword.KeywordType)
                            {
                            case KeywordType.Return:
                                scopes.Peek().AddStatement(new ReturnStatementNode(ExpressionNode.CreateFromTokens(ReadUntilStatementSeperator())));
                                break;

                            case KeywordType.If:
                                var @if = new IfStatementNode(ExpressionNode.CreateFromTokens(ReadUntilClosingBrace()));
                                scopes.Peek().AddStatement(@if);
                                scopes.Push(@if);
                                if (Peek() is OpenBraceToken && ((OpenBraceToken)Peek()).BraceType == BraceType.Curly)
                                {
                                    Next();
                                }
                                break;

                            case KeywordType.While:
                                var @while = new WhileLoopNode(ExpressionNode.CreateFromTokens(ReadUntilClosingBrace()));
                                scopes.Peek().AddStatement(@while);
                                scopes.Push(@while);
                                if (Peek() is OpenBraceToken && ((OpenBraceToken)Peek()).BraceType == BraceType.Curly)
                                {
                                    Next();
                                }
                                break;

                            default:
                                throw new ParsingException("Unexpected keyword type.");
                            }
                        }
                    }
                }
                else if (Peek() is IdentifierToken && scopes.Count > 1)
                {
                    var name = ReadToken <IdentifierToken>();
                    if (Peek() is OperatorToken && ((OperatorToken)Peek()).OperatorType == OperatorType.Assignment)
                    {
                        Next();
                        scopes.Peek().AddStatement(new VariableAssingmentNode(name.Content, ExpressionNode.CreateFromTokens(ReadUntilStatementSeperator())));
                    }
                    else
                    {
                        scopes.Peek().AddStatement(ExpressionNode.CreateFromTokens(new[] { name }.Concat(ReadUntilStatementSeperator())));
                    }
                }
                else if (Peek() is CloseBraceToken)
                {
                    var brace = ReadToken <CloseBraceToken>();
                    if (brace.BraceType != BraceType.Curly)
                    {
                        throw new ParsingException("Wrong brace type found!");
                    }
                    scopes.Pop();
                }
                else
                {
                    throw new ParsingException("The parser ran into an unexpeted token.");
                }
            }

            if (scopes.Count != 1)
            {
                throw new ParsingException("The scopes are not correctly nested.");
            }

            return((ProgramNode)scopes.Pop());
        }
Пример #13
0
 public virtual WhileLoopNode Visit(WhileLoopNode loop)
 {
     return(loop);
 }