Implements while loops
This commit is contained in:
parent
fa967383d6
commit
eb1eb81c1b
|
@ -95,6 +95,8 @@ namespace Upsilon.Binder
|
||||||
return BindNumericForStatement((NumericForStatementSyntax) s);
|
return BindNumericForStatement((NumericForStatementSyntax) s);
|
||||||
case SyntaxKind.GenericForStatement:
|
case SyntaxKind.GenericForStatement:
|
||||||
return BindGenericForStatement((GenericForStatementSyntax) s);
|
return BindGenericForStatement((GenericForStatementSyntax) s);
|
||||||
|
case SyntaxKind.WhileStatement:
|
||||||
|
return BindWhileStatement((WhileStatementSyntax) s);
|
||||||
|
|
||||||
case SyntaxKind.BreakStatement:
|
case SyntaxKind.BreakStatement:
|
||||||
return new BoundBreakStatement(s.Span);
|
return new BoundBreakStatement(s.Span);
|
||||||
|
@ -860,5 +862,15 @@ namespace Upsilon.Binder
|
||||||
|
|
||||||
return new BoundGenericForStatement(array.ToImmutable(), boundEnumerableExpression, block, e.Span);
|
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,
|
BoundNumericForStatement,
|
||||||
BoundGenericForStatement,
|
BoundGenericForStatement,
|
||||||
BoundBreakStatement,
|
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.BoundNumericForStatement:
|
||||||
case BoundKind.BoundGenericForStatement:
|
case BoundKind.BoundGenericForStatement:
|
||||||
case BoundKind.BoundBreakStatement:
|
case BoundKind.BoundBreakStatement:
|
||||||
|
case BoundKind.BoundWhileStatement:
|
||||||
EvaluateStatement((BoundStatement) b);
|
EvaluateStatement((BoundStatement) b);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -180,6 +181,9 @@ namespace Upsilon.Evaluator
|
||||||
case BoundKind.BoundGenericForStatement:
|
case BoundKind.BoundGenericForStatement:
|
||||||
EvaluateGenericForStatement((BoundGenericForStatement) e);
|
EvaluateGenericForStatement((BoundGenericForStatement) e);
|
||||||
break;
|
break;
|
||||||
|
case BoundKind.BoundWhileStatement:
|
||||||
|
EvaluateWhileStatement((BoundWhileStatement) e);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
EvaluateExpressionStatement((BoundExpressionStatement) e);
|
EvaluateExpressionStatement((BoundExpressionStatement) e);
|
||||||
break;
|
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();
|
return ParseForStatement();
|
||||||
}
|
}
|
||||||
|
if (Current.Kind == SyntaxKind.WhileKeyword)
|
||||||
|
{
|
||||||
|
return ParseWhileStatement();
|
||||||
|
}
|
||||||
if (Current.Kind == SyntaxKind.BreakKeyword)
|
if (Current.Kind == SyntaxKind.BreakKeyword)
|
||||||
{
|
{
|
||||||
return new BreakStatementSyntax(NextToken());
|
return new BreakStatementSyntax(NextToken());
|
||||||
|
@ -196,6 +200,17 @@ namespace Upsilon.Parser
|
||||||
doKeyword, (BlockStatementSyntax) block, endKeyword);
|
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()
|
private ExpressionSyntax ParseFunctionExpression()
|
||||||
{
|
{
|
||||||
var functionToken = MatchToken(SyntaxKind.FunctionKeyword);
|
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;
|
return SyntaxKind.ReturnKeyword;
|
||||||
case "for":
|
case "for":
|
||||||
return SyntaxKind.ForKeyword;
|
return SyntaxKind.ForKeyword;
|
||||||
|
case "while":
|
||||||
|
return SyntaxKind.WhileKeyword;
|
||||||
case "in":
|
case "in":
|
||||||
return SyntaxKind.InKeyword;
|
return SyntaxKind.InKeyword;
|
||||||
case "do":
|
case "do":
|
||||||
|
|
|
@ -33,6 +33,8 @@ namespace Upsilon.Parser
|
||||||
LessEquals,
|
LessEquals,
|
||||||
Greater,
|
Greater,
|
||||||
GreaterEquals,
|
GreaterEquals,
|
||||||
|
PercentSign,
|
||||||
|
RoofSign,
|
||||||
|
|
||||||
// key words
|
// key words
|
||||||
TrueKeyword,
|
TrueKeyword,
|
||||||
|
@ -50,6 +52,7 @@ namespace Upsilon.Parser
|
||||||
FunctionKeyword,
|
FunctionKeyword,
|
||||||
ReturnKeyword,
|
ReturnKeyword,
|
||||||
ForKeyword,
|
ForKeyword,
|
||||||
|
WhileKeyword,
|
||||||
InKeyword,
|
InKeyword,
|
||||||
DoKeyword,
|
DoKeyword,
|
||||||
BreakKeyword,
|
BreakKeyword,
|
||||||
|
@ -87,7 +90,6 @@ namespace Upsilon.Parser
|
||||||
NumericForStatement,
|
NumericForStatement,
|
||||||
BreakStatement,
|
BreakStatement,
|
||||||
GenericForStatement,
|
GenericForStatement,
|
||||||
PercentSign,
|
WhileStatement
|
||||||
RoofSign
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue