Support for getting a bound scope at a specific character position
This commit is contained in:
parent
8ece53db5b
commit
14e30d0855
|
@ -395,12 +395,13 @@ namespace Upsilon.Binder
|
|||
Scope = innerScope;
|
||||
var block = BindBlockStatement(e.Block);
|
||||
Scope = Scope.ParentScope;
|
||||
var func = new BoundFunctionExpression(parameters.ToImmutable(), (BoundBlockStatement) block, e.Span);
|
||||
var func = new BoundFunctionExpression(parameters.ToImmutable(), (BoundBlockStatement) block, e.Span,
|
||||
innerScope);
|
||||
return func;
|
||||
}
|
||||
else
|
||||
{
|
||||
var unbound = new UnboundFunctionExpression(parameters.ToImmutable(), e.Block, e.Span);
|
||||
var unbound = new UnboundFunctionExpression(parameters.ToImmutable(), e.Block, e.Span, innerScope);
|
||||
if (variableSymbol == null)
|
||||
{
|
||||
_unboundFunctions.Add( Guid.NewGuid().ToString(), unbound);
|
||||
|
@ -496,8 +497,9 @@ namespace Upsilon.Binder
|
|||
}
|
||||
|
||||
innerVariables = innerVariables.Union(Scope.Variables).ToDictionary(k => k.Key, v => v.Value);
|
||||
var innerSCope = Scope;
|
||||
Scope = s;
|
||||
return new BoundTableExpression(innerVariables, statements.ToImmutable(), e.Span);
|
||||
return new BoundTableExpression(innerVariables, statements.ToImmutable(), e.Span, innerSCope);
|
||||
}
|
||||
|
||||
private BoundExpression BindIndexExpression(IndexExpressionSyntax e, bool isAssignment = false)
|
||||
|
|
|
@ -5,15 +5,17 @@ using Upsilon.Text;
|
|||
|
||||
namespace Upsilon.Binder
|
||||
{
|
||||
public class BoundFunctionExpression : BoundExpression
|
||||
public class BoundFunctionExpression : BoundExpression, IBoundNodeScopeOwner
|
||||
{
|
||||
public ImmutableArray<BoundVariableSymbol> Parameters { get; }
|
||||
public BoundBlockStatement Block { get; set; }
|
||||
|
||||
public BoundFunctionExpression(ImmutableArray<BoundVariableSymbol> parameters, BoundBlockStatement block, TextSpan span) : base(span)
|
||||
public BoundFunctionExpression(ImmutableArray<BoundVariableSymbol> parameters, BoundBlockStatement block, TextSpan span,
|
||||
BoundScope scope) : base(span)
|
||||
{
|
||||
Parameters = parameters;
|
||||
Block = block;
|
||||
Scope = scope;
|
||||
}
|
||||
|
||||
public override BoundKind Kind => BoundKind.BoundFunctionExpression;
|
||||
|
@ -32,5 +34,6 @@ namespace Upsilon.Binder
|
|||
}
|
||||
|
||||
public override Type Type => Type.Function;
|
||||
public BoundScope Scope { get; set; }
|
||||
}
|
||||
}
|
|
@ -5,13 +5,14 @@ using Upsilon.Text;
|
|||
|
||||
namespace Upsilon.Binder
|
||||
{
|
||||
public class BoundTableExpression : BoundExpression
|
||||
public class BoundTableExpression : BoundExpression, IBoundNodeScopeOwner
|
||||
{
|
||||
public BoundTableExpression(Dictionary<string, VariableSymbol> expressions,
|
||||
ImmutableArray<BoundStatement> statements, TextSpan span) : base(span)
|
||||
ImmutableArray<BoundStatement> statements, TextSpan span, BoundScope scope) : base(span)
|
||||
{
|
||||
Expressions = expressions;
|
||||
Statements = statements;
|
||||
Scope = scope;
|
||||
}
|
||||
|
||||
public override BoundKind Kind => BoundKind.BoundTableExpression;
|
||||
|
@ -32,5 +33,6 @@ namespace Upsilon.Binder
|
|||
|
||||
public Dictionary<string, VariableSymbol> Expressions { get; }
|
||||
public ImmutableArray<BoundStatement> Statements { get; }
|
||||
public BoundScope Scope { get; set; }
|
||||
}
|
||||
}
|
|
@ -6,7 +6,7 @@ namespace Upsilon.Binder
|
|||
public class BoundScope : IDisposable
|
||||
{
|
||||
public readonly BoundScope ParentScope;
|
||||
private BoundScope _readOnlyScope;
|
||||
public BoundScope ReadOnlyScope { get; private set; }
|
||||
public readonly Dictionary<string, VariableSymbol> Variables;
|
||||
|
||||
public BoundScope(BoundScope parentScope)
|
||||
|
@ -22,13 +22,13 @@ namespace Upsilon.Binder
|
|||
|
||||
public static BoundScope WithReadOnlyScope(BoundScope readOnlyScope)
|
||||
{
|
||||
var scope = new BoundScope(null) {_readOnlyScope = readOnlyScope};
|
||||
var scope = new BoundScope(null) {ReadOnlyScope = readOnlyScope};
|
||||
return scope;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Variables.Clear();
|
||||
//Variables.Clear();
|
||||
}
|
||||
|
||||
public void DefineLocalVariable(VariableSymbol var)
|
||||
|
@ -62,9 +62,9 @@ namespace Upsilon.Binder
|
|||
{
|
||||
return ParentScope.TryGetVariable(key, true, out result);
|
||||
}
|
||||
if (_readOnlyScope != null && allowUpperScopes)
|
||||
if (ReadOnlyScope != null && allowUpperScopes)
|
||||
{
|
||||
return _readOnlyScope.TryGetVariable(key, true, out result);
|
||||
return ReadOnlyScope.TryGetVariable(key, true, out result);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -15,13 +15,13 @@ namespace Upsilon.Binder
|
|||
public override BoundKind Kind => BoundKind.BoundBlockStatement;
|
||||
public override IEnumerable<BoundNode> GetNodeAtPosition(int characterPosition)
|
||||
{
|
||||
yield return this;
|
||||
foreach (var statement in Statements)
|
||||
{
|
||||
if (characterPosition >= statement.Span.Start && characterPosition <= statement.Span.End)
|
||||
foreach (var boundNode in statement.GetNodeAtPosition(characterPosition))
|
||||
yield return boundNode;
|
||||
}
|
||||
yield return this;
|
||||
}
|
||||
|
||||
public ImmutableArray<BoundStatement> Statements { get; }
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace Upsilon.Binder
|
|||
foreach (var boundNode in Expression.GetNodeAtPosition(characterPosition))
|
||||
yield return boundNode;
|
||||
|
||||
yield return null;
|
||||
yield return this;
|
||||
}
|
||||
|
||||
public BoundExpressionStatement(BoundExpression expression, TextSpan span):base(span)
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace Upsilon.Binder
|
|||
public class UnboundFunctionExpression : BoundFunctionExpression
|
||||
{
|
||||
public UnboundFunctionExpression(ImmutableArray<BoundVariableSymbol> parameters,
|
||||
BlockStatementSyntax unboundBlock, TextSpan span) : base(parameters, null, span)
|
||||
BlockStatementSyntax unboundBlock, TextSpan span, BoundScope scope) : base(parameters, null, span, scope)
|
||||
{
|
||||
UnboundBlock = unboundBlock;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
namespace Upsilon.Binder
|
||||
{
|
||||
public interface IBoundNodeScopeOwner
|
||||
{
|
||||
BoundScope Scope { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Upsilon.Binder;
|
||||
|
||||
|
@ -7,17 +8,35 @@ namespace Upsilon.Utilities
|
|||
{
|
||||
public static BoundScope GetScopeAt(this BoundScript script, int characterPosition)
|
||||
{
|
||||
var scope = script.Scope;
|
||||
foreach (var node in script.GetNodeAtPosition(characterPosition))
|
||||
{
|
||||
|
||||
if (node is IBoundNodeScopeOwner scopeOwner && scopeOwner.Scope != null)
|
||||
{
|
||||
return scopeOwner.Scope;
|
||||
}
|
||||
}
|
||||
return scope;
|
||||
return script.Scope;
|
||||
}
|
||||
|
||||
public static BoundNode GetBottomNodeAtPosition(this BoundNode node, int characterPosition)
|
||||
{
|
||||
return node.GetNodeAtPosition(characterPosition).First();
|
||||
}
|
||||
|
||||
public static Dictionary<string, VariableSymbol> GetBoundScopeVisibleVariables(this BoundScope scope)
|
||||
{
|
||||
IEnumerable<KeyValuePair<string, VariableSymbol>> dictionary = scope.Variables;
|
||||
if (scope.ParentScope != null)
|
||||
{
|
||||
dictionary= dictionary.Union(scope.ParentScope.GetBoundScopeVisibleVariables());
|
||||
}
|
||||
|
||||
if (scope.ReadOnlyScope != null)
|
||||
{
|
||||
dictionary = dictionary.Union(scope.ReadOnlyScope.GetBoundScopeVisibleVariables());
|
||||
}
|
||||
|
||||
return dictionary.ToDictionary(k => k.Key, v => v.Value);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue