Reworked handling of getting bottom node. Now uses an iterator to iterate from bottom to top nodes

This commit is contained in:
Deukhoofd 2018-11-27 18:38:28 +01:00
parent dd8569ecb0
commit 8ece53db5b
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
25 changed files with 198 additions and 89 deletions

View File

@ -52,7 +52,7 @@ namespace Upsilon.Binder
Scope = Scope.ParentScope;
}
_unboundFunctions = new Dictionary<string, UnboundFunctionExpression>();
return new BoundScript((BoundBlockStatement) bound, e.Span);
return new BoundScript((BoundBlockStatement) bound, e.Span, Scope);
}
private BoundStatement BindStatement(StatementSyntax s)

View File

@ -1,3 +1,5 @@
using System.Collections;
using System.Collections.Generic;
using Upsilon.BaseTypes;
using Upsilon.Text;
@ -15,14 +17,23 @@ namespace Upsilon.Binder
}
public override BoundKind Kind => BoundKind.BoundBinaryExpression;
public override BoundNode GetNodeAtPosition(int characterPosition)
public override IEnumerable<BoundNode> GetNodeAtPosition(int characterPosition)
{
if (characterPosition >= LeftExpression.Span.Start && characterPosition <= LeftExpression.Span.End)
return LeftExpression.GetNodeAtPosition(characterPosition);
{
foreach (var exp in LeftExpression.GetNodeAtPosition(characterPosition))
{
yield return exp;
}
}
if (characterPosition >= RightExpression.Span.Start && characterPosition <= RightExpression.Span.End)
return RightExpression.GetNodeAtPosition(characterPosition);
return this;
{
foreach (var exp in RightExpression.GetNodeAtPosition(characterPosition))
{
yield return exp;
}
}
yield return this;
}
public override Type Type { get; }

View File

@ -1,3 +1,4 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using Upsilon.BaseTypes;
using Upsilon.Text;
@ -17,17 +18,23 @@ namespace Upsilon.Binder
}
public override BoundKind Kind => BoundKind.BoundFunctionCallExpression;
public override BoundNode GetNodeAtPosition(int characterPosition)
public override IEnumerable<BoundNode> GetNodeAtPosition(int characterPosition)
{
if (characterPosition >= Identifier.Span.Start && characterPosition <= Identifier.Span.End)
return Identifier.GetNodeAtPosition(characterPosition);
{
foreach (var exp in Identifier.GetNodeAtPosition(characterPosition))
{
yield return exp;
}
}
foreach (var parameter in Parameters)
{
if (characterPosition >= parameter.Span.Start && characterPosition <= parameter.Span.End)
return parameter.GetNodeAtPosition(characterPosition);
{
foreach (var boundNode in parameter.GetNodeAtPosition(characterPosition)) yield return boundNode;
}
return this;
}
yield return this;
}
public override Type Type => Type.Unknown;

View File

@ -1,3 +1,4 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using Upsilon.BaseTypes;
using Upsilon.Text;
@ -16,16 +17,18 @@ namespace Upsilon.Binder
}
public override BoundKind Kind => BoundKind.BoundFunctionExpression;
public override BoundNode GetNodeAtPosition(int characterPosition)
public override IEnumerable<BoundNode> GetNodeAtPosition(int characterPosition)
{
foreach (var parameter in Parameters)
{
if (characterPosition >= parameter.Span.Start && characterPosition <= parameter.Span.End)
return parameter.GetNodeAtPosition(characterPosition);
foreach (var boundNode in parameter.GetNodeAtPosition(characterPosition))
yield return boundNode;
}
if (characterPosition >= Block.Span.Start && characterPosition <= Block.Span.End)
return Block.GetNodeAtPosition(characterPosition);
return this;
foreach (var boundNode in Block.GetNodeAtPosition(characterPosition))
yield return boundNode;
yield return this;
}
public override Type Type => Type.Function;

View File

@ -1,3 +1,4 @@
using System.Collections.Generic;
using Upsilon.BaseTypes;
using Upsilon.Parser;
using Upsilon.Text;
@ -17,14 +18,17 @@ namespace Upsilon.Binder
public BoundExpression Index { get; }
public override BoundKind Kind => BoundKind.BoundIndexExpression;
public override BoundNode GetNodeAtPosition(int characterPosition)
public override IEnumerable<BoundNode> GetNodeAtPosition(int characterPosition)
{
if (characterPosition >= Identifier.Span.Start && characterPosition <= Identifier.Span.End)
return Identifier.GetNodeAtPosition(characterPosition);
if (characterPosition >= Index.Span.Start && characterPosition <= Index.Span.End)
return Index.GetNodeAtPosition(characterPosition);
return this;
foreach (var boundNode in Identifier.GetNodeAtPosition(characterPosition))
yield return boundNode;
if (characterPosition >= Index.Span.Start && characterPosition <= Index.Span.End)
foreach (var boundNode in Index.GetNodeAtPosition(characterPosition))
yield return boundNode;
yield return this;
}
public override Type Type { get; }
@ -43,11 +47,13 @@ namespace Upsilon.Binder
}
public override BoundKind Kind => BoundKind.BoundFullstopIndexExpression;
public override BoundNode GetNodeAtPosition(int characterPosition)
public override IEnumerable<BoundNode> GetNodeAtPosition(int characterPosition)
{
if (characterPosition >= Expression.Span.Start && characterPosition <= Expression.Span.End)
return Expression.GetNodeAtPosition(characterPosition);
return this;
foreach (var boundNode in Expression.GetNodeAtPosition(characterPosition))
yield return boundNode;
yield return this;
}
public override Type Type { get; }

View File

@ -1,3 +1,4 @@
using System.Collections.Generic;
using Upsilon.BaseTypes;
using Upsilon.Text;
@ -11,9 +12,9 @@ namespace Upsilon.Binder
}
public override BoundKind Kind => BoundKind.BoundLiteralExpression;
public override BoundNode GetNodeAtPosition(int characterPosition)
public override IEnumerable<BoundNode> GetNodeAtPosition(int characterPosition)
{
return this;
yield return this;
}
public override Type Type => Value.Type;

View File

@ -15,14 +15,15 @@ namespace Upsilon.Binder
}
public override BoundKind Kind => BoundKind.BoundTableExpression;
public override BoundNode GetNodeAtPosition(int characterPosition)
public override IEnumerable<BoundNode> GetNodeAtPosition(int characterPosition)
{
foreach (var statement in Statements)
{
if (characterPosition >= statement.Span.Start && characterPosition <= statement.Span.End)
return statement.GetNodeAtPosition(characterPosition);
foreach (var boundNode in statement.GetNodeAtPosition(characterPosition))
yield return boundNode;
}
return this;
yield return this;
}

View File

@ -1,3 +1,4 @@
using System.Collections.Generic;
using Upsilon.BaseTypes;
using Upsilon.Text;
@ -6,11 +7,13 @@ namespace Upsilon.Binder
public class BoundUnaryExpression : BoundExpression
{
public override BoundKind Kind => BoundKind.BoundUnaryExpression;
public override BoundNode GetNodeAtPosition(int characterPosition)
public override IEnumerable<BoundNode> GetNodeAtPosition(int characterPosition)
{
if (characterPosition >= InExpression.Span.Start && characterPosition <= InExpression.Span.End)
return InExpression.GetNodeAtPosition(characterPosition);
return this;
foreach (var boundNode in InExpression.GetNodeAtPosition(characterPosition))
yield return boundNode;
yield return this;
}
public override Type Type { get; }

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using Upsilon.Text;
using Type = Upsilon.BaseTypes.Type;
@ -13,9 +14,9 @@ namespace Upsilon.Binder
public BoundVariableSymbol Variable { get; }
public override BoundKind Kind => BoundKind.VariableExpression;
public override BoundNode GetNodeAtPosition(int characterPosition)
public override IEnumerable<BoundNode> GetNodeAtPosition(int characterPosition)
{
return Variable;
yield return Variable;
}
public override Type Type => Variable.Type;

View File

@ -1,3 +1,4 @@
using System.Collections.Generic;
using Upsilon.Text;
namespace Upsilon.Binder
@ -12,6 +13,6 @@ namespace Upsilon.Binder
public abstract BoundKind Kind { get; }
public TextSpan Span { get; }
public abstract BoundNode GetNodeAtPosition(int characterPosition);
public abstract IEnumerable<BoundNode> GetNodeAtPosition(int characterPosition);
}
}

View File

@ -1,3 +1,4 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using Upsilon.Text;
@ -12,14 +13,15 @@ namespace Upsilon.Binder
}
public override BoundKind Kind => BoundKind.BoundBlockStatement;
public override BoundNode GetNodeAtPosition(int characterPosition)
public override IEnumerable<BoundNode> GetNodeAtPosition(int characterPosition)
{
yield return this;
foreach (var statement in Statements)
{
if (characterPosition >= statement.Span.Start && characterPosition <= statement.Span.End)
return statement.GetNodeAtPosition(characterPosition);
foreach (var boundNode in statement.GetNodeAtPosition(characterPosition))
yield return boundNode;
}
return this;
}
public ImmutableArray<BoundStatement> Statements { get; }

View File

@ -1,3 +1,4 @@
using System.Collections.Generic;
using Upsilon.Text;
namespace Upsilon.Binder
@ -9,11 +10,11 @@ namespace Upsilon.Binder
}
public override BoundKind Kind => BoundKind.BoundBreakStatement;
public override BoundNode GetNodeAtPosition(int characterPosition)
public override IEnumerable<BoundNode> GetNodeAtPosition(int characterPosition)
{
if (characterPosition >= Span.Start && characterPosition <= Span.End)
return this;
return null;
yield return this;
yield return null;
}
}
}

View File

@ -1,3 +1,4 @@
using System.Collections.Generic;
using Upsilon.Text;
namespace Upsilon.Binder
@ -6,11 +7,13 @@ namespace Upsilon.Binder
{
public BoundExpression Expression { get; }
public override BoundKind Kind => BoundKind.BoundExpressionStatement;
public override BoundNode GetNodeAtPosition(int characterPosition)
public override IEnumerable<BoundNode> GetNodeAtPosition(int characterPosition)
{
if (characterPosition >= Span.Start && characterPosition <= Span.End)
return Expression.GetNodeAtPosition(characterPosition);
return null;
foreach (var boundNode in Expression.GetNodeAtPosition(characterPosition))
yield return boundNode;
yield return null;
}
public BoundExpressionStatement(BoundExpression expression, TextSpan span):base(span)

View File

@ -1,3 +1,4 @@
using System.Collections.Generic;
using Upsilon.Text;
namespace Upsilon.Binder
@ -14,11 +15,13 @@ namespace Upsilon.Binder
}
public override BoundKind Kind => BoundKind.BoundFunctionAssignmentStatement;
public override BoundNode GetNodeAtPosition(int characterPosition)
public override IEnumerable<BoundNode> GetNodeAtPosition(int characterPosition)
{
if (characterPosition >= Func.Span.Start && characterPosition <= Func.Span.End)
return Func.GetNodeAtPosition(characterPosition);
return this;
foreach (var boundNode in Func.GetNodeAtPosition(characterPosition))
yield return boundNode;
yield return this;
}
}
}

View File

@ -1,3 +1,4 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using Upsilon.Text;
@ -18,13 +19,17 @@ namespace Upsilon.Binder
}
public override BoundKind Kind => BoundKind.BoundGenericForStatement;
public override BoundNode GetNodeAtPosition(int characterPosition)
public override IEnumerable<BoundNode> GetNodeAtPosition(int characterPosition)
{
if (characterPosition >= BoundEnumerableExpression.Span.Start && characterPosition <= BoundEnumerableExpression.Span.End)
return BoundEnumerableExpression.GetNodeAtPosition(characterPosition);
foreach (var boundNode in BoundEnumerableExpression.GetNodeAtPosition(characterPosition))
yield return boundNode;
if (characterPosition >= Block.Span.Start && characterPosition <= Block.Span.End)
return Block.GetNodeAtPosition(characterPosition);
return this;
foreach (var boundNode in Block.GetNodeAtPosition(characterPosition))
yield return boundNode;
yield return this;
}
}
}

View File

@ -1,3 +1,4 @@
using System.Collections.Generic;
using Upsilon.Text;
namespace Upsilon.Binder
@ -24,17 +25,25 @@ namespace Upsilon.Binder
}
public override BoundKind Kind => BoundKind.BoundIfStatement;
public override BoundNode GetNodeAtPosition(int characterPosition)
public override IEnumerable<BoundNode> GetNodeAtPosition(int characterPosition)
{
if (characterPosition >= Condition.Span.Start && characterPosition <= Condition.Span.End)
return Condition.GetNodeAtPosition(characterPosition);
foreach (var boundNode in Condition.GetNodeAtPosition(characterPosition))
yield return boundNode;
if (characterPosition >= Block.Span.Start && characterPosition <= Block.Span.End)
return Block.GetNodeAtPosition(characterPosition);
foreach (var boundNode in Block.GetNodeAtPosition(characterPosition))
yield return boundNode;
if (NextElseIf != null && characterPosition >= NextElseIf.Span.Start && characterPosition <= NextElseIf.Span.End)
return NextElseIf.GetNodeAtPosition(characterPosition);
foreach (var boundNode in NextElseIf.GetNodeAtPosition(characterPosition))
yield return boundNode;
if (ElseStatement != null && characterPosition >= ElseStatement.Span.Start && characterPosition <= ElseStatement.Span.End)
return ElseStatement.GetNodeAtPosition(characterPosition);
return this;
foreach (var boundNode in ElseStatement.GetNodeAtPosition(characterPosition))
yield return boundNode;
yield return this;
}
public BoundExpressionStatement Condition { get; }
@ -53,11 +62,13 @@ namespace Upsilon.Binder
}
public override BoundKind Kind => BoundKind.BoundElseStatement;
public override BoundNode GetNodeAtPosition(int characterPosition)
public override IEnumerable<BoundNode> GetNodeAtPosition(int characterPosition)
{
if (Block != null && characterPosition >= Block.Span.Start && characterPosition <= Block.Span.End)
return Block.GetNodeAtPosition(characterPosition);
return this;
foreach (var boundNode in Block.GetNodeAtPosition(characterPosition))
yield return boundNode;
yield return this;
}
}
}

View File

@ -17,11 +17,13 @@ namespace Upsilon.Binder
}
public override BoundKind Kind => BoundKind.BoundMultiAssignmentStatement;
public override BoundNode GetNodeAtPosition(int characterPosition)
public override IEnumerable<BoundNode> GetNodeAtPosition(int characterPosition)
{
if (characterPosition >= Assignment.Span.Start && characterPosition <= Assignment.Span.End)
return Assignment.GetNodeAtPosition(characterPosition);
return this;
foreach (var boundNode in Assignment.GetNodeAtPosition(characterPosition))
yield return boundNode;
yield return this;
}
}

View File

@ -1,3 +1,4 @@
using System.Collections.Generic;
using Upsilon.Text;
namespace Upsilon.Binder
@ -21,17 +22,25 @@ namespace Upsilon.Binder
}
public override BoundKind Kind => BoundKind.BoundNumericForStatement;
public override BoundNode GetNodeAtPosition(int characterPosition)
public override IEnumerable<BoundNode> GetNodeAtPosition(int characterPosition)
{
if (characterPosition >= BoundStart.Span.Start && characterPosition <= BoundStart.Span.End)
return BoundStart.GetNodeAtPosition(characterPosition);
foreach (var boundNode in BoundStart.GetNodeAtPosition(characterPosition))
yield return boundNode;
if (characterPosition >= BoundStop.Span.Start && characterPosition <= BoundStop.Span.End)
return BoundStop.GetNodeAtPosition(characterPosition);
foreach (var boundNode in BoundStop.GetNodeAtPosition(characterPosition))
yield return boundNode;
if (characterPosition >= BoundStep.Span.Start && characterPosition <= BoundStep.Span.End)
return BoundStep.GetNodeAtPosition(characterPosition);
foreach (var boundNode in BoundStep.GetNodeAtPosition(characterPosition))
yield return boundNode;
if (characterPosition >= Block.Span.Start && characterPosition <= Block.Span.End)
return Block.GetNodeAtPosition(characterPosition);
return this;
foreach (var boundNode in Block.GetNodeAtPosition(characterPosition))
yield return boundNode;
yield return this;
}
}

View File

@ -1,3 +1,4 @@
using System.Collections.Generic;
using Upsilon.Text;
namespace Upsilon.Binder
@ -11,11 +12,13 @@ namespace Upsilon.Binder
public BoundExpression Expression { get; }
public override BoundKind Kind => BoundKind.BoundReturnStatement;
public override BoundNode GetNodeAtPosition(int characterPosition)
public override IEnumerable<BoundNode> GetNodeAtPosition(int characterPosition)
{
if (characterPosition >= Expression.Span.Start && characterPosition <= Expression.Span.End)
return Expression.GetNodeAtPosition(characterPosition);
return this;
foreach (var boundNode in Expression.GetNodeAtPosition(characterPosition))
yield return boundNode;
yield return this;
}
}
}

View File

@ -5,17 +5,19 @@ namespace Upsilon.Binder
{
public class BoundScript : BoundStatement
{
public BoundScript(BoundBlockStatement statement, TextSpan span) : base(span)
public BoundScript(BoundBlockStatement statement, TextSpan span, BoundScope scope) : base(span)
{
Statement = statement;
Scope = scope;
}
public override BoundKind Kind => BoundKind.BoundScript;
public override BoundNode GetNodeAtPosition(int characterPosition)
public override IEnumerable<BoundNode> GetNodeAtPosition(int characterPosition)
{
return Statement.GetNodeAtPosition(characterPosition);
foreach (var boundNode in Statement.GetNodeAtPosition(characterPosition)) yield return boundNode;
}
public BoundBlockStatement Statement { get; }
public BoundScope Scope { get; }
}
}

View File

@ -1,3 +1,4 @@
using System.Collections.Generic;
using Upsilon.Text;
namespace Upsilon.Binder
@ -15,13 +16,17 @@ namespace Upsilon.Binder
}
public override BoundKind Kind => BoundKind.BoundTableAssigmentStatement;
public override BoundNode GetNodeAtPosition(int characterPosition)
public override IEnumerable<BoundNode> GetNodeAtPosition(int characterPosition)
{
if (characterPosition >= TableIndexExpression.Span.Start && characterPosition <= TableIndexExpression.Span.End)
return TableIndexExpression.GetNodeAtPosition(characterPosition);
foreach (var boundNode in TableIndexExpression.GetNodeAtPosition(characterPosition))
yield return boundNode;
if (characterPosition >= Value.Span.Start && characterPosition <= Value.Span.End)
return Value.GetNodeAtPosition(characterPosition);
return this;
foreach (var boundNode in Value.GetNodeAtPosition(characterPosition))
yield return boundNode;
yield return this;
}
}

View File

@ -1,3 +1,4 @@
using System.Collections.Generic;
using Upsilon.Text;
namespace Upsilon.Binder
@ -17,13 +18,15 @@ namespace Upsilon.Binder
}
public override BoundKind Kind => BoundKind.BoundAssignmentStatement;
public override BoundNode GetNodeAtPosition(int characterPosition)
public override IEnumerable<BoundNode> GetNodeAtPosition(int characterPosition)
{
if (characterPosition >= Variable.Span.Start && characterPosition <= Variable.Span.End)
return Variable;
yield return Variable;
if (characterPosition >= BoundExpression.Span.Start && characterPosition <= BoundExpression.Span.End)
return BoundExpression.GetNodeAtPosition(characterPosition);
return this;
foreach (var boundNode in BoundExpression.GetNodeAtPosition(characterPosition))
yield return boundNode;
yield return this;
}
}

View File

@ -1,3 +1,4 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using Upsilon.Parser;
using Upsilon.Text;
@ -16,21 +17,22 @@ namespace Upsilon.Binder
public BlockStatementSyntax UnboundBlock { get; }
public override BoundNode GetNodeAtPosition(int characterPosition)
public override IEnumerable<BoundNode> GetNodeAtPosition(int characterPosition)
{
foreach (var parameter in Parameters)
{
if (characterPosition >= parameter.Span.Start && characterPosition <= parameter.Span.End)
return parameter.GetNodeAtPosition(characterPosition);
foreach (var boundNode in parameter.GetNodeAtPosition(characterPosition))
yield return boundNode;
}
if (Block != null)
{
if (characterPosition >= Block.Span.Start && characterPosition <= Block.Span.End)
return Block.GetNodeAtPosition(characterPosition);
foreach (var boundNode in Block.GetNodeAtPosition(characterPosition))
yield return boundNode;
}
return this;
yield return this;
}
}
}

View File

@ -1,3 +1,4 @@
using System.Collections.Generic;
using Upsilon.BaseTypes;
using Upsilon.Text;
@ -13,9 +14,9 @@ namespace Upsilon.Binder
public VariableSymbol VariableSymbol { get; }
public override BoundKind Kind => BoundKind.BoundVariableSymbol;
public override BoundNode GetNodeAtPosition(int characterPosition)
public override IEnumerable<BoundNode> GetNodeAtPosition(int characterPosition)
{
return this;
yield return this;
}
public override Type Type => VariableSymbol.Type;

View File

@ -0,0 +1,23 @@
using System.Linq;
using Upsilon.Binder;
namespace Upsilon.Utilities
{
public static class SearchHelper
{
public static BoundScope GetScopeAt(this BoundScript script, int characterPosition)
{
var scope = script.Scope;
foreach (var node in script.GetNodeAtPosition(characterPosition))
{
}
return scope;
}
public static BoundNode GetBottomNodeAtPosition(this BoundNode node, int characterPosition)
{
return node.GetNodeAtPosition(characterPosition).First();
}
}
}