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;
|
Scope = innerScope;
|
||||||
var block = BindBlockStatement(e.Block);
|
var block = BindBlockStatement(e.Block);
|
||||||
Scope = Scope.ParentScope;
|
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;
|
return func;
|
||||||
}
|
}
|
||||||
else
|
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)
|
if (variableSymbol == null)
|
||||||
{
|
{
|
||||||
_unboundFunctions.Add( Guid.NewGuid().ToString(), unbound);
|
_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);
|
innerVariables = innerVariables.Union(Scope.Variables).ToDictionary(k => k.Key, v => v.Value);
|
||||||
|
var innerSCope = Scope;
|
||||||
Scope = s;
|
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)
|
private BoundExpression BindIndexExpression(IndexExpressionSyntax e, bool isAssignment = false)
|
||||||
|
|
|
@ -5,15 +5,17 @@ using Upsilon.Text;
|
||||||
|
|
||||||
namespace Upsilon.Binder
|
namespace Upsilon.Binder
|
||||||
{
|
{
|
||||||
public class BoundFunctionExpression : BoundExpression
|
public class BoundFunctionExpression : BoundExpression, IBoundNodeScopeOwner
|
||||||
{
|
{
|
||||||
public ImmutableArray<BoundVariableSymbol> Parameters { get; }
|
public ImmutableArray<BoundVariableSymbol> Parameters { get; }
|
||||||
public BoundBlockStatement Block { get; set; }
|
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;
|
Parameters = parameters;
|
||||||
Block = block;
|
Block = block;
|
||||||
|
Scope = scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override BoundKind Kind => BoundKind.BoundFunctionExpression;
|
public override BoundKind Kind => BoundKind.BoundFunctionExpression;
|
||||||
|
@ -32,5 +34,6 @@ namespace Upsilon.Binder
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Type Type => Type.Function;
|
public override Type Type => Type.Function;
|
||||||
|
public BoundScope Scope { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,13 +5,14 @@ using Upsilon.Text;
|
||||||
|
|
||||||
namespace Upsilon.Binder
|
namespace Upsilon.Binder
|
||||||
{
|
{
|
||||||
public class BoundTableExpression : BoundExpression
|
public class BoundTableExpression : BoundExpression, IBoundNodeScopeOwner
|
||||||
{
|
{
|
||||||
public BoundTableExpression(Dictionary<string, VariableSymbol> expressions,
|
public BoundTableExpression(Dictionary<string, VariableSymbol> expressions,
|
||||||
ImmutableArray<BoundStatement> statements, TextSpan span) : base(span)
|
ImmutableArray<BoundStatement> statements, TextSpan span, BoundScope scope) : base(span)
|
||||||
{
|
{
|
||||||
Expressions = expressions;
|
Expressions = expressions;
|
||||||
Statements = statements;
|
Statements = statements;
|
||||||
|
Scope = scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override BoundKind Kind => BoundKind.BoundTableExpression;
|
public override BoundKind Kind => BoundKind.BoundTableExpression;
|
||||||
|
@ -32,5 +33,6 @@ namespace Upsilon.Binder
|
||||||
|
|
||||||
public Dictionary<string, VariableSymbol> Expressions { get; }
|
public Dictionary<string, VariableSymbol> Expressions { get; }
|
||||||
public ImmutableArray<BoundStatement> Statements { get; }
|
public ImmutableArray<BoundStatement> Statements { get; }
|
||||||
|
public BoundScope Scope { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,7 +6,7 @@ namespace Upsilon.Binder
|
||||||
public class BoundScope : IDisposable
|
public class BoundScope : IDisposable
|
||||||
{
|
{
|
||||||
public readonly BoundScope ParentScope;
|
public readonly BoundScope ParentScope;
|
||||||
private BoundScope _readOnlyScope;
|
public BoundScope ReadOnlyScope { get; private set; }
|
||||||
public readonly Dictionary<string, VariableSymbol> Variables;
|
public readonly Dictionary<string, VariableSymbol> Variables;
|
||||||
|
|
||||||
public BoundScope(BoundScope parentScope)
|
public BoundScope(BoundScope parentScope)
|
||||||
|
@ -22,13 +22,13 @@ namespace Upsilon.Binder
|
||||||
|
|
||||||
public static BoundScope WithReadOnlyScope(BoundScope readOnlyScope)
|
public static BoundScope WithReadOnlyScope(BoundScope readOnlyScope)
|
||||||
{
|
{
|
||||||
var scope = new BoundScope(null) {_readOnlyScope = readOnlyScope};
|
var scope = new BoundScope(null) {ReadOnlyScope = readOnlyScope};
|
||||||
return scope;
|
return scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Variables.Clear();
|
//Variables.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DefineLocalVariable(VariableSymbol var)
|
public void DefineLocalVariable(VariableSymbol var)
|
||||||
|
@ -62,9 +62,9 @@ namespace Upsilon.Binder
|
||||||
{
|
{
|
||||||
return ParentScope.TryGetVariable(key, true, out result);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,13 +15,13 @@ namespace Upsilon.Binder
|
||||||
public override BoundKind Kind => BoundKind.BoundBlockStatement;
|
public override BoundKind Kind => BoundKind.BoundBlockStatement;
|
||||||
public override IEnumerable<BoundNode> GetNodeAtPosition(int characterPosition)
|
public override IEnumerable<BoundNode> GetNodeAtPosition(int characterPosition)
|
||||||
{
|
{
|
||||||
yield return this;
|
|
||||||
foreach (var statement in Statements)
|
foreach (var statement in Statements)
|
||||||
{
|
{
|
||||||
if (characterPosition >= statement.Span.Start && characterPosition <= statement.Span.End)
|
if (characterPosition >= statement.Span.Start && characterPosition <= statement.Span.End)
|
||||||
foreach (var boundNode in statement.GetNodeAtPosition(characterPosition))
|
foreach (var boundNode in statement.GetNodeAtPosition(characterPosition))
|
||||||
yield return boundNode;
|
yield return boundNode;
|
||||||
}
|
}
|
||||||
|
yield return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ImmutableArray<BoundStatement> Statements { get; }
|
public ImmutableArray<BoundStatement> Statements { get; }
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace Upsilon.Binder
|
||||||
foreach (var boundNode in Expression.GetNodeAtPosition(characterPosition))
|
foreach (var boundNode in Expression.GetNodeAtPosition(characterPosition))
|
||||||
yield return boundNode;
|
yield return boundNode;
|
||||||
|
|
||||||
yield return null;
|
yield return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BoundExpressionStatement(BoundExpression expression, TextSpan span):base(span)
|
public BoundExpressionStatement(BoundExpression expression, TextSpan span):base(span)
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace Upsilon.Binder
|
||||||
public class UnboundFunctionExpression : BoundFunctionExpression
|
public class UnboundFunctionExpression : BoundFunctionExpression
|
||||||
{
|
{
|
||||||
public UnboundFunctionExpression(ImmutableArray<BoundVariableSymbol> parameters,
|
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;
|
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 System.Linq;
|
||||||
using Upsilon.Binder;
|
using Upsilon.Binder;
|
||||||
|
|
||||||
|
@ -7,17 +8,35 @@ namespace Upsilon.Utilities
|
||||||
{
|
{
|
||||||
public static BoundScope GetScopeAt(this BoundScript script, int characterPosition)
|
public static BoundScope GetScopeAt(this BoundScript script, int characterPosition)
|
||||||
{
|
{
|
||||||
var scope = script.Scope;
|
|
||||||
foreach (var node in script.GetNodeAtPosition(characterPosition))
|
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)
|
public static BoundNode GetBottomNodeAtPosition(this BoundNode node, int characterPosition)
|
||||||
{
|
{
|
||||||
return node.GetNodeAtPosition(characterPosition).First();
|
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