Implements while loops
This commit is contained in:
parent
fa967383d6
commit
eb1eb81c1b
|
@ -95,6 +95,8 @@ namespace Upsilon.Binder
|
|||
return BindNumericForStatement((NumericForStatementSyntax) s);
|
||||
case SyntaxKind.GenericForStatement:
|
||||
return BindGenericForStatement((GenericForStatementSyntax) s);
|
||||
case SyntaxKind.WhileStatement:
|
||||
return BindWhileStatement((WhileStatementSyntax) s);
|
||||
|
||||
case SyntaxKind.BreakStatement:
|
||||
return new BoundBreakStatement(s.Span);
|
||||
|
@ -860,5 +862,15 @@ namespace Upsilon.Binder
|
|||
|
||||
return new BoundGenericForStatement(array.ToImmutable(), boundEnumerableExpression, block, e.Span);
|
||||
}
|
||||
|
||||
private BoundStatement BindWhileStatement(WhileStatementSyntax e)
|
||||
{
|
||||
Scope = new BoundScope(Scope);
|
||||
var condition = BindExpression(e.Expression);
|
||||
var block = BindBlockStatement((BlockStatementSyntax) e.Block);
|
||||
|
||||
return new BoundWhileStatement(condition, block, e.Span);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -29,6 +29,6 @@ namespace Upsilon.Binder
|
|||
BoundNumericForStatement,
|
||||
BoundGenericForStatement,
|
||||
BoundBreakStatement,
|
||||
|
||||
BoundWhileStatement
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Upsilon.Text;
|
||||
|
||||
namespace Upsilon.Binder
|
||||
{
|
||||
internal class BoundWhileStatement : BoundStatement
|
||||
{
|
||||
public BoundExpression Condition { get; }
|
||||
public BoundStatement Block { get; }
|
||||
|
||||
public BoundWhileStatement(BoundExpression condition, BoundStatement block, TextSpan eSpan)
|
||||
:base(eSpan)
|
||||
{
|
||||
Condition = condition;
|
||||
Block = block;
|
||||
}
|
||||
|
||||
public override BoundKind Kind => BoundKind.BoundWhileStatement;
|
||||
public override IEnumerable<BoundNode> GetNodeAtPosition(int characterPosition)
|
||||
{
|
||||
if (characterPosition >= Condition.Span.Start && characterPosition <= Condition.Span.End)
|
||||
foreach (var boundNode in Condition.GetNodeAtPosition(characterPosition))
|
||||
yield return boundNode;
|
||||
|
||||
if (characterPosition >= Block.Span.Start && characterPosition <= Block.Span.End)
|
||||
foreach (var boundNode in Block.GetNodeAtPosition(characterPosition))
|
||||
yield return boundNode;
|
||||
|
||||
yield return this;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -136,6 +136,7 @@ namespace Upsilon.Evaluator
|
|||
case BoundKind.BoundNumericForStatement:
|
||||
case BoundKind.BoundGenericForStatement:
|
||||
case BoundKind.BoundBreakStatement:
|
||||
case BoundKind.BoundWhileStatement:
|
||||
EvaluateStatement((BoundStatement) b);
|
||||
break;
|
||||
default:
|
||||
|
@ -180,6 +181,9 @@ namespace Upsilon.Evaluator
|
|||
case BoundKind.BoundGenericForStatement:
|
||||
EvaluateGenericForStatement((BoundGenericForStatement) e);
|
||||
break;
|
||||
case BoundKind.BoundWhileStatement:
|
||||
EvaluateWhileStatement((BoundWhileStatement) e);
|
||||
break;
|
||||
default:
|
||||
EvaluateExpressionStatement((BoundExpressionStatement) e);
|
||||
break;
|
||||
|
@ -664,5 +668,16 @@ namespace Upsilon.Evaluator
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void EvaluateWhileStatement(BoundWhileStatement e)
|
||||
{
|
||||
var innerEvaluator = new Evaluator(_diagnostics, Scope, _script);
|
||||
|
||||
var block = (BoundBlockStatement) e.Block;
|
||||
while ((ScriptBoolean)EvaluateExpression(e.Condition))
|
||||
{
|
||||
innerEvaluator.EvaluateBoundBlockStatement(block);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -90,6 +90,10 @@ namespace Upsilon.Parser
|
|||
{
|
||||
return ParseForStatement();
|
||||
}
|
||||
if (Current.Kind == SyntaxKind.WhileKeyword)
|
||||
{
|
||||
return ParseWhileStatement();
|
||||
}
|
||||
if (Current.Kind == SyntaxKind.BreakKeyword)
|
||||
{
|
||||
return new BreakStatementSyntax(NextToken());
|
||||
|
@ -196,6 +200,17 @@ namespace Upsilon.Parser
|
|||
doKeyword, (BlockStatementSyntax) block, endKeyword);
|
||||
}
|
||||
|
||||
private StatementSyntax ParseWhileStatement()
|
||||
{
|
||||
var whileToken = MatchToken(SyntaxKind.WhileKeyword);
|
||||
var expression = ParseExpression();
|
||||
var doToken = MatchToken(SyntaxKind.DoKeyword);
|
||||
var block = ParseBlockStatement(new[] {SyntaxKind.EndKeyword});
|
||||
var endKeyword = MatchToken(SyntaxKind.EndKeyword);
|
||||
return new WhileStatementSyntax(whileToken, expression, doToken, block, endKeyword);
|
||||
}
|
||||
|
||||
|
||||
private ExpressionSyntax ParseFunctionExpression()
|
||||
{
|
||||
var functionToken = MatchToken(SyntaxKind.FunctionKeyword);
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Upsilon.Text;
|
||||
|
||||
namespace Upsilon.Parser
|
||||
{
|
||||
internal class WhileStatementSyntax : StatementSyntax
|
||||
{
|
||||
public SyntaxToken WhileToken { get; }
|
||||
public ExpressionSyntax Expression { get; }
|
||||
public SyntaxToken DoToken { get; }
|
||||
public StatementSyntax Block { get; }
|
||||
public SyntaxToken EndKeyword { get; }
|
||||
|
||||
public WhileStatementSyntax(SyntaxToken whileToken, ExpressionSyntax expression, SyntaxToken doToken,
|
||||
StatementSyntax block, SyntaxToken endKeyword)
|
||||
{
|
||||
WhileToken = whileToken;
|
||||
Expression = expression;
|
||||
DoToken = doToken;
|
||||
Block = block;
|
||||
EndKeyword = endKeyword;
|
||||
|
||||
Span = new TextSpan(whileToken.Span.Start, endKeyword.Span.End);
|
||||
}
|
||||
|
||||
public override SyntaxKind Kind => SyntaxKind.WhileStatement;
|
||||
public override IEnumerable<SyntaxNode> ChildNodes()
|
||||
{
|
||||
yield return WhileToken;
|
||||
yield return Expression;
|
||||
yield return DoToken;
|
||||
yield return Block;
|
||||
yield return EndKeyword;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -36,6 +36,8 @@ namespace Upsilon.Parser
|
|||
return SyntaxKind.ReturnKeyword;
|
||||
case "for":
|
||||
return SyntaxKind.ForKeyword;
|
||||
case "while":
|
||||
return SyntaxKind.WhileKeyword;
|
||||
case "in":
|
||||
return SyntaxKind.InKeyword;
|
||||
case "do":
|
||||
|
|
|
@ -33,6 +33,8 @@ namespace Upsilon.Parser
|
|||
LessEquals,
|
||||
Greater,
|
||||
GreaterEquals,
|
||||
PercentSign,
|
||||
RoofSign,
|
||||
|
||||
// key words
|
||||
TrueKeyword,
|
||||
|
@ -50,6 +52,7 @@ namespace Upsilon.Parser
|
|||
FunctionKeyword,
|
||||
ReturnKeyword,
|
||||
ForKeyword,
|
||||
WhileKeyword,
|
||||
InKeyword,
|
||||
DoKeyword,
|
||||
BreakKeyword,
|
||||
|
@ -87,7 +90,6 @@ namespace Upsilon.Parser
|
|||
NumericForStatement,
|
||||
BreakStatement,
|
||||
GenericForStatement,
|
||||
PercentSign,
|
||||
RoofSign
|
||||
WhileStatement
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue