From 8ece53db5bc0e6e641a26ca34518583e6d9767c2 Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Tue, 27 Nov 2018 18:38:28 +0100 Subject: [PATCH] Reworked handling of getting bottom node. Now uses an iterator to iterate from bottom to top nodes --- Upsilon/Binder/Binder.cs | 2 +- .../BoundExpressions/BoundBinaryExpression.cs | 21 ++++++++++---- .../BoundFunctionCallExpression.cs | 17 +++++++---- .../BoundFunctionExpression.cs | 11 ++++--- .../BoundExpressions/BoundIndexExpression.cs | 22 +++++++++----- .../BoundLiteralExpression.cs | 5 ++-- .../BoundExpressions/BoundTableExpression.cs | 7 +++-- .../BoundExpressions/BoundUnaryExpression.cs | 9 ++++-- .../BoundVariableExpression.cs | 5 ++-- Upsilon/Binder/BoundNode.cs | 3 +- .../BoundStatements/BoundBlockStatement.cs | 8 +++-- .../BoundStatements/BoundBreakStatement.cs | 7 +++-- .../BoundExpressionStatement.cs | 9 ++++-- .../BoundFunctionAssignmentStatement.cs | 9 ++++-- .../BoundGenericForStatement.cs | 13 ++++++--- .../BoundStatements/BoundIfStatement.cs | 29 +++++++++++++------ .../BoundMultiAssignmentStatement.cs | 8 +++-- .../BoundNumericForStatement.cs | 21 ++++++++++---- .../BoundStatements/BoundReturnStatement.cs | 9 ++++-- Upsilon/Binder/BoundStatements/BoundScript.cs | 8 +++-- .../BoundTableAssigmentStatement.cs | 13 ++++++--- .../BoundVariableAssignment.cs | 11 ++++--- .../UnboundFunctionExpression.cs | 12 ++++---- Upsilon/Binder/BoundVariableSymbol.cs | 5 ++-- Upsilon/Utilities/SearchHelper.cs | 23 +++++++++++++++ 25 files changed, 198 insertions(+), 89 deletions(-) create mode 100644 Upsilon/Utilities/SearchHelper.cs diff --git a/Upsilon/Binder/Binder.cs b/Upsilon/Binder/Binder.cs index e76da57..7af1f08 100644 --- a/Upsilon/Binder/Binder.cs +++ b/Upsilon/Binder/Binder.cs @@ -52,7 +52,7 @@ namespace Upsilon.Binder Scope = Scope.ParentScope; } _unboundFunctions = new Dictionary(); - return new BoundScript((BoundBlockStatement) bound, e.Span); + return new BoundScript((BoundBlockStatement) bound, e.Span, Scope); } private BoundStatement BindStatement(StatementSyntax s) diff --git a/Upsilon/Binder/BoundExpressions/BoundBinaryExpression.cs b/Upsilon/Binder/BoundExpressions/BoundBinaryExpression.cs index 00035d1..b0f1e8b 100644 --- a/Upsilon/Binder/BoundExpressions/BoundBinaryExpression.cs +++ b/Upsilon/Binder/BoundExpressions/BoundBinaryExpression.cs @@ -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 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; } diff --git a/Upsilon/Binder/BoundExpressions/BoundFunctionCallExpression.cs b/Upsilon/Binder/BoundExpressions/BoundFunctionCallExpression.cs index d155418..6302772 100644 --- a/Upsilon/Binder/BoundExpressions/BoundFunctionCallExpression.cs +++ b/Upsilon/Binder/BoundExpressions/BoundFunctionCallExpression.cs @@ -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 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; diff --git a/Upsilon/Binder/BoundExpressions/BoundFunctionExpression.cs b/Upsilon/Binder/BoundExpressions/BoundFunctionExpression.cs index 24716be..4f2c1d7 100644 --- a/Upsilon/Binder/BoundExpressions/BoundFunctionExpression.cs +++ b/Upsilon/Binder/BoundExpressions/BoundFunctionExpression.cs @@ -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 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; diff --git a/Upsilon/Binder/BoundExpressions/BoundIndexExpression.cs b/Upsilon/Binder/BoundExpressions/BoundIndexExpression.cs index cd781eb..335781b 100644 --- a/Upsilon/Binder/BoundExpressions/BoundIndexExpression.cs +++ b/Upsilon/Binder/BoundExpressions/BoundIndexExpression.cs @@ -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 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 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; } diff --git a/Upsilon/Binder/BoundExpressions/BoundLiteralExpression.cs b/Upsilon/Binder/BoundExpressions/BoundLiteralExpression.cs index d9adedc..6a1aaba 100644 --- a/Upsilon/Binder/BoundExpressions/BoundLiteralExpression.cs +++ b/Upsilon/Binder/BoundExpressions/BoundLiteralExpression.cs @@ -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 GetNodeAtPosition(int characterPosition) { - return this; + yield return this; } public override Type Type => Value.Type; diff --git a/Upsilon/Binder/BoundExpressions/BoundTableExpression.cs b/Upsilon/Binder/BoundExpressions/BoundTableExpression.cs index 23f1887..3f94a2c 100644 --- a/Upsilon/Binder/BoundExpressions/BoundTableExpression.cs +++ b/Upsilon/Binder/BoundExpressions/BoundTableExpression.cs @@ -15,14 +15,15 @@ namespace Upsilon.Binder } public override BoundKind Kind => BoundKind.BoundTableExpression; - public override BoundNode GetNodeAtPosition(int characterPosition) + public override IEnumerable 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; } diff --git a/Upsilon/Binder/BoundExpressions/BoundUnaryExpression.cs b/Upsilon/Binder/BoundExpressions/BoundUnaryExpression.cs index 3cbdfb0..3e5019e 100644 --- a/Upsilon/Binder/BoundExpressions/BoundUnaryExpression.cs +++ b/Upsilon/Binder/BoundExpressions/BoundUnaryExpression.cs @@ -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 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; } diff --git a/Upsilon/Binder/BoundExpressions/BoundVariableExpression.cs b/Upsilon/Binder/BoundExpressions/BoundVariableExpression.cs index 6fb4602..8bb3fa0 100644 --- a/Upsilon/Binder/BoundExpressions/BoundVariableExpression.cs +++ b/Upsilon/Binder/BoundExpressions/BoundVariableExpression.cs @@ -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 GetNodeAtPosition(int characterPosition) { - return Variable; + yield return Variable; } public override Type Type => Variable.Type; diff --git a/Upsilon/Binder/BoundNode.cs b/Upsilon/Binder/BoundNode.cs index 2563f34..6a5b559 100644 --- a/Upsilon/Binder/BoundNode.cs +++ b/Upsilon/Binder/BoundNode.cs @@ -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 GetNodeAtPosition(int characterPosition); } } \ No newline at end of file diff --git a/Upsilon/Binder/BoundStatements/BoundBlockStatement.cs b/Upsilon/Binder/BoundStatements/BoundBlockStatement.cs index c13d3f6..eddfaf7 100644 --- a/Upsilon/Binder/BoundStatements/BoundBlockStatement.cs +++ b/Upsilon/Binder/BoundStatements/BoundBlockStatement.cs @@ -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 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 Statements { get; } diff --git a/Upsilon/Binder/BoundStatements/BoundBreakStatement.cs b/Upsilon/Binder/BoundStatements/BoundBreakStatement.cs index 157f0fb..06f56cd 100644 --- a/Upsilon/Binder/BoundStatements/BoundBreakStatement.cs +++ b/Upsilon/Binder/BoundStatements/BoundBreakStatement.cs @@ -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 GetNodeAtPosition(int characterPosition) { if (characterPosition >= Span.Start && characterPosition <= Span.End) - return this; - return null; + yield return this; + yield return null; } } } \ No newline at end of file diff --git a/Upsilon/Binder/BoundStatements/BoundExpressionStatement.cs b/Upsilon/Binder/BoundStatements/BoundExpressionStatement.cs index 4eb1035..569cb15 100644 --- a/Upsilon/Binder/BoundStatements/BoundExpressionStatement.cs +++ b/Upsilon/Binder/BoundStatements/BoundExpressionStatement.cs @@ -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 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) diff --git a/Upsilon/Binder/BoundStatements/BoundFunctionAssignmentStatement.cs b/Upsilon/Binder/BoundStatements/BoundFunctionAssignmentStatement.cs index 26613fe..30a5f76 100644 --- a/Upsilon/Binder/BoundStatements/BoundFunctionAssignmentStatement.cs +++ b/Upsilon/Binder/BoundStatements/BoundFunctionAssignmentStatement.cs @@ -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 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; } } } \ No newline at end of file diff --git a/Upsilon/Binder/BoundStatements/BoundGenericForStatement.cs b/Upsilon/Binder/BoundStatements/BoundGenericForStatement.cs index a855a37..9844a6f 100644 --- a/Upsilon/Binder/BoundStatements/BoundGenericForStatement.cs +++ b/Upsilon/Binder/BoundStatements/BoundGenericForStatement.cs @@ -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 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; } } } \ No newline at end of file diff --git a/Upsilon/Binder/BoundStatements/BoundIfStatement.cs b/Upsilon/Binder/BoundStatements/BoundIfStatement.cs index 774b152..00cce71 100644 --- a/Upsilon/Binder/BoundStatements/BoundIfStatement.cs +++ b/Upsilon/Binder/BoundStatements/BoundIfStatement.cs @@ -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 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 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; } } } \ No newline at end of file diff --git a/Upsilon/Binder/BoundStatements/BoundMultiAssignmentStatement.cs b/Upsilon/Binder/BoundStatements/BoundMultiAssignmentStatement.cs index 1fe1ec6..1d35623 100644 --- a/Upsilon/Binder/BoundStatements/BoundMultiAssignmentStatement.cs +++ b/Upsilon/Binder/BoundStatements/BoundMultiAssignmentStatement.cs @@ -17,11 +17,13 @@ namespace Upsilon.Binder } public override BoundKind Kind => BoundKind.BoundMultiAssignmentStatement; - public override BoundNode GetNodeAtPosition(int characterPosition) + public override IEnumerable 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; } } diff --git a/Upsilon/Binder/BoundStatements/BoundNumericForStatement.cs b/Upsilon/Binder/BoundStatements/BoundNumericForStatement.cs index 41c59e1..3c9daca 100644 --- a/Upsilon/Binder/BoundStatements/BoundNumericForStatement.cs +++ b/Upsilon/Binder/BoundStatements/BoundNumericForStatement.cs @@ -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 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; } } diff --git a/Upsilon/Binder/BoundStatements/BoundReturnStatement.cs b/Upsilon/Binder/BoundStatements/BoundReturnStatement.cs index 6df0552..4c5c013 100644 --- a/Upsilon/Binder/BoundStatements/BoundReturnStatement.cs +++ b/Upsilon/Binder/BoundStatements/BoundReturnStatement.cs @@ -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 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; } } } \ No newline at end of file diff --git a/Upsilon/Binder/BoundStatements/BoundScript.cs b/Upsilon/Binder/BoundStatements/BoundScript.cs index 74a541a..1f22a2d 100644 --- a/Upsilon/Binder/BoundStatements/BoundScript.cs +++ b/Upsilon/Binder/BoundStatements/BoundScript.cs @@ -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 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; } } } \ No newline at end of file diff --git a/Upsilon/Binder/BoundStatements/BoundTableAssigmentStatement.cs b/Upsilon/Binder/BoundStatements/BoundTableAssigmentStatement.cs index f307965..704c116 100644 --- a/Upsilon/Binder/BoundStatements/BoundTableAssigmentStatement.cs +++ b/Upsilon/Binder/BoundStatements/BoundTableAssigmentStatement.cs @@ -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 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; } } diff --git a/Upsilon/Binder/BoundStatements/BoundVariableAssignment.cs b/Upsilon/Binder/BoundStatements/BoundVariableAssignment.cs index 2d75d34..d21ea95 100644 --- a/Upsilon/Binder/BoundStatements/BoundVariableAssignment.cs +++ b/Upsilon/Binder/BoundStatements/BoundVariableAssignment.cs @@ -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 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; } } diff --git a/Upsilon/Binder/BoundStatements/UnboundFunctionExpression.cs b/Upsilon/Binder/BoundStatements/UnboundFunctionExpression.cs index 6ffa9af..66ae2a8 100644 --- a/Upsilon/Binder/BoundStatements/UnboundFunctionExpression.cs +++ b/Upsilon/Binder/BoundStatements/UnboundFunctionExpression.cs @@ -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 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; } } } \ No newline at end of file diff --git a/Upsilon/Binder/BoundVariableSymbol.cs b/Upsilon/Binder/BoundVariableSymbol.cs index aecca45..4aa3f61 100644 --- a/Upsilon/Binder/BoundVariableSymbol.cs +++ b/Upsilon/Binder/BoundVariableSymbol.cs @@ -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 GetNodeAtPosition(int characterPosition) { - return this; + yield return this; } public override Type Type => VariableSymbol.Type; diff --git a/Upsilon/Utilities/SearchHelper.cs b/Upsilon/Utilities/SearchHelper.cs new file mode 100644 index 0000000..49f9e56 --- /dev/null +++ b/Upsilon/Utilities/SearchHelper.cs @@ -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(); + } + } +} \ No newline at end of file