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(); }
/// <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); } }
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); }
public virtual XzaarExpression Visit(WhileLoopNode loop) { return(null); }
public virtual T VisitWhileLoop(WhileLoopNode whileLoop) { throw new NotImplementedException(); }
public abstract DynValue Visit(WhileLoopNode whileLoopNode);
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()); }
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(); }
public AddressNode VisitWhileLoop(WhileLoopNode whileLoop) { throw new System.NotImplementedException(); }
/// <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()); }
public virtual WhileLoopNode Visit(WhileLoopNode loop) { return(loop); }