Support for passing Script reference to functions. useful when options are required for function
This commit is contained in:
parent
3a3ed071d2
commit
9e27778af1
|
@ -1,3 +1,5 @@
|
||||||
|
using Upsilon.Evaluator;
|
||||||
|
|
||||||
namespace Upsilon.BaseTypes.ScriptFunction
|
namespace Upsilon.BaseTypes.ScriptFunction
|
||||||
{
|
{
|
||||||
internal abstract class ScriptFunction : ScriptType
|
internal abstract class ScriptFunction : ScriptType
|
||||||
|
@ -13,6 +15,6 @@ namespace Upsilon.BaseTypes.ScriptFunction
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract ScriptType Run(Diagnostics diagnostics, ScriptType[] variables);
|
public abstract ScriptType Run(Diagnostics diagnostics, ScriptType[] variables, Script script);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,26 +1,30 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Upsilon.BaseTypes.UserData;
|
using Upsilon.BaseTypes.UserData;
|
||||||
|
using Upsilon.Evaluator;
|
||||||
|
|
||||||
namespace Upsilon.BaseTypes.ScriptFunction
|
namespace Upsilon.BaseTypes.ScriptFunction
|
||||||
{
|
{
|
||||||
internal class ScriptMethodInfoFunction : ScriptFunction
|
internal class ScriptMethodInfoFunction : ScriptFunction
|
||||||
{
|
{
|
||||||
public ScriptMethodInfoFunction(UserDataMethod method, object o, bool directTypeManipulation)
|
public ScriptMethodInfoFunction(UserDataMethod method, object o, bool directTypeManipulation, bool passScriptReference = false)
|
||||||
{
|
{
|
||||||
_method = method;
|
_method = method;
|
||||||
_object = o;
|
_object = o;
|
||||||
_directTypeManipulation = directTypeManipulation;
|
_directTypeManipulation = directTypeManipulation;
|
||||||
|
_passScriptReference = passScriptReference;
|
||||||
ReturnType = _method.ReturnType;
|
ReturnType = _method.ReturnType;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly UserDataMethod _method;
|
private readonly UserDataMethod _method;
|
||||||
private readonly object _object;
|
private readonly object _object;
|
||||||
private readonly bool _directTypeManipulation;
|
private readonly bool _directTypeManipulation;
|
||||||
|
private readonly bool _passScriptReference;
|
||||||
public System.Type ReturnType { get; }
|
public System.Type ReturnType { get; }
|
||||||
|
|
||||||
public override ScriptType Run(Diagnostics diagnostics, ScriptType[] variables)
|
public override ScriptType Run(Diagnostics diagnostics, ScriptType[] variables, Script script)
|
||||||
{
|
{
|
||||||
var types = _directTypeManipulation
|
var types = _directTypeManipulation
|
||||||
? variables.Select(x => x.GetType()).ToArray()
|
? variables.Select(x => x.GetType()).ToArray()
|
||||||
|
@ -32,9 +36,10 @@ namespace Upsilon.BaseTypes.ScriptFunction
|
||||||
$"No valid function found on type '{_object.GetType()}' with name '{_method.Name}' " +
|
$"No valid function found on type '{_object.GetType()}' with name '{_method.Name}' " +
|
||||||
$"and parameter types: {string.Join(", ", types.Select(x => $"'{x.Name}'"))}");
|
$"and parameter types: {string.Join(", ", types.Select(x => $"'{x.Name}'"))}");
|
||||||
}
|
}
|
||||||
var objects = _directTypeManipulation
|
var objects = new List<object>();
|
||||||
|
objects.AddRange(_directTypeManipulation
|
||||||
? variables.Select(x => (object) x).ToList()
|
? variables.Select(x => (object) x).ToList()
|
||||||
: variables.Select(x => x.ToCSharpObject()).ToList();
|
: variables.Select(x => x.ToCSharpObject()).ToList());
|
||||||
var pars = method.GetParameters();
|
var pars = method.GetParameters();
|
||||||
if (pars.Length != objects.Count)
|
if (pars.Length != objects.Count)
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,9 +19,9 @@ namespace Upsilon.BaseTypes.ScriptFunction
|
||||||
EvaluationScope = evaluationScope;
|
EvaluationScope = evaluationScope;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override ScriptType Run(Diagnostics diagnostics, ScriptType[] variables)
|
public override ScriptType Run(Diagnostics diagnostics, ScriptType[] variables, Script script)
|
||||||
{
|
{
|
||||||
var innerEvaluator = new Evaluator.Evaluator(diagnostics, EvaluationScope);
|
var innerEvaluator = new Evaluator.Evaluator(diagnostics, EvaluationScope, script);
|
||||||
for (var i = 0; i < Parameters.Length; i++)
|
for (var i = 0; i < Parameters.Length; i++)
|
||||||
{
|
{
|
||||||
var parameterVariable = Parameters[i];
|
var parameterVariable = Parameters[i];
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Upsilon.Evaluator;
|
using Upsilon.Evaluator;
|
||||||
using Upsilon.Text;
|
using Upsilon.Text;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
|
||||||
using System.Net.Http.Headers;
|
|
||||||
using Upsilon.BaseTypes;
|
using Upsilon.BaseTypes;
|
||||||
using Upsilon.BaseTypes.Number;
|
using Upsilon.BaseTypes.Number;
|
||||||
using Upsilon.BaseTypes.ScriptFunction;
|
using Upsilon.BaseTypes.ScriptFunction;
|
||||||
|
@ -14,6 +12,7 @@ namespace Upsilon.Evaluator
|
||||||
{
|
{
|
||||||
internal class Evaluator : IDisposable
|
internal class Evaluator : IDisposable
|
||||||
{
|
{
|
||||||
|
private Script _script;
|
||||||
private Diagnostics _diagnostics;
|
private Diagnostics _diagnostics;
|
||||||
private ScriptType _lastValue;
|
private ScriptType _lastValue;
|
||||||
private ScriptType _returnValue;
|
private ScriptType _returnValue;
|
||||||
|
@ -21,23 +20,28 @@ namespace Upsilon.Evaluator
|
||||||
private bool HasReturned { get; set; }
|
private bool HasReturned { get; set; }
|
||||||
private bool HasBroken { get; set; }
|
private bool HasBroken { get; set; }
|
||||||
|
|
||||||
internal Evaluator(Diagnostics diagnostics, Dictionary<string, ScriptType> variables)
|
internal Evaluator(Diagnostics diagnostics, Dictionary<string, ScriptType> variables, Script script)
|
||||||
{
|
{
|
||||||
_diagnostics = diagnostics;
|
_diagnostics = diagnostics;
|
||||||
|
_script = script;
|
||||||
Scope = new EvaluationScope(variables);
|
Scope = new EvaluationScope(variables);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Evaluator(Diagnostics diagnostics, EvaluationScope parentScope)
|
internal Evaluator(Diagnostics diagnostics, EvaluationScope parentScope, Script script)
|
||||||
{
|
{
|
||||||
_diagnostics = diagnostics;
|
_diagnostics = diagnostics;
|
||||||
|
_script = script;
|
||||||
Scope = new EvaluationScope(parentScope);
|
Scope = new EvaluationScope(parentScope);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Evaluator(){}
|
private Evaluator(Script script)
|
||||||
|
|
||||||
internal static Evaluator CreateWithSetScope(Diagnostics diagnostics, EvaluationScope scope)
|
|
||||||
{
|
{
|
||||||
return new Evaluator {_diagnostics = diagnostics, Scope = scope};
|
_script = script;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static Evaluator CreateWithSetScope(Diagnostics diagnostics, EvaluationScope scope, Script script)
|
||||||
|
{
|
||||||
|
return new Evaluator(script) {_diagnostics = diagnostics, Scope = scope};
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
@ -63,7 +67,7 @@ namespace Upsilon.Evaluator
|
||||||
throw new ArgumentException(($"Function '{functionName}' could not be found"));
|
throw new ArgumentException(($"Function '{functionName}' could not be found"));
|
||||||
}
|
}
|
||||||
var function = (ScriptRuntimeFunction) statement;
|
var function = (ScriptRuntimeFunction) statement;
|
||||||
var innerEvaluator = new Evaluator(_diagnostics, Scope);
|
var innerEvaluator = new Evaluator(_diagnostics, Scope, _script);
|
||||||
if (parameters != null)
|
if (parameters != null)
|
||||||
{
|
{
|
||||||
for (var index = 0; index < parameters.Length; index++)
|
for (var index = 0; index < parameters.Length; index++)
|
||||||
|
@ -267,7 +271,6 @@ namespace Upsilon.Evaluator
|
||||||
{
|
{
|
||||||
return ((ScriptNumber)left) + ((ScriptNumber)right);
|
return ((ScriptNumber)left) + ((ScriptNumber)right);
|
||||||
}
|
}
|
||||||
goto default;
|
|
||||||
}
|
}
|
||||||
else if (left.Type == Type.String)
|
else if (left.Type == Type.String)
|
||||||
{
|
{
|
||||||
|
@ -442,7 +445,7 @@ namespace Upsilon.Evaluator
|
||||||
ls.Add(evaluate);
|
ls.Add(evaluate);
|
||||||
}
|
}
|
||||||
|
|
||||||
var val = function.Run(_diagnostics, ls.ToArray());
|
var val = function.Run(_diagnostics, ls.ToArray(), _script);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -456,7 +459,7 @@ namespace Upsilon.Evaluator
|
||||||
private ScriptType EvaluateTableExpression(BoundTableExpression e)
|
private ScriptType EvaluateTableExpression(BoundTableExpression e)
|
||||||
{
|
{
|
||||||
var tableScope = EvaluationScope.CreateWithGetOnlyParent(Scope);
|
var tableScope = EvaluationScope.CreateWithGetOnlyParent(Scope);
|
||||||
var innerEvaluator = new Evaluator(_diagnostics, tableScope);
|
var innerEvaluator = new Evaluator(_diagnostics, tableScope, _script);
|
||||||
var currentPos = 1;
|
var currentPos = 1;
|
||||||
foreach (var boundStatement in e.Statements)
|
foreach (var boundStatement in e.Statements)
|
||||||
{
|
{
|
||||||
|
@ -541,7 +544,7 @@ namespace Upsilon.Evaluator
|
||||||
|
|
||||||
private void EvaluateNumericForStatement(BoundNumericForStatement e)
|
private void EvaluateNumericForStatement(BoundNumericForStatement e)
|
||||||
{
|
{
|
||||||
var innerEvaluator = new Evaluator(_diagnostics, Scope);
|
var innerEvaluator = new Evaluator(_diagnostics, Scope, _script);
|
||||||
var startVal = (ScriptNumberLong)innerEvaluator.EvaluateExpression(e.BoundStart);
|
var startVal = (ScriptNumberLong)innerEvaluator.EvaluateExpression(e.BoundStart);
|
||||||
innerEvaluator.Scope.CreateLocal(e.Variable, startVal);
|
innerEvaluator.Scope.CreateLocal(e.Variable, startVal);
|
||||||
var stopVal = (ScriptNumberLong)innerEvaluator.EvaluateExpression(e.BoundStop);
|
var stopVal = (ScriptNumberLong)innerEvaluator.EvaluateExpression(e.BoundStop);
|
||||||
|
@ -574,7 +577,7 @@ namespace Upsilon.Evaluator
|
||||||
|
|
||||||
private void EvaluateGenericForStatement(BoundGenericForStatement e)
|
private void EvaluateGenericForStatement(BoundGenericForStatement e)
|
||||||
{
|
{
|
||||||
var innerEvaluator = new Evaluator(_diagnostics, Scope);
|
var innerEvaluator = new Evaluator(_diagnostics, Scope, _script);
|
||||||
var enumeratorObject = EvaluateExpression(e.BoundEnumerableExpression);
|
var enumeratorObject = EvaluateExpression(e.BoundEnumerableExpression);
|
||||||
if (!(enumeratorObject is IIterable iterable))
|
if (!(enumeratorObject is IIterable iterable))
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace Upsilon.Evaluator
|
||||||
|
|
||||||
var staticScope = options.OverrideStaticScope ?? StaticScope.Scope;
|
var staticScope = options.OverrideStaticScope ?? StaticScope.Scope;
|
||||||
Scope = EvaluationScope.CreateWithGetOnlyParent(staticScope);
|
Scope = EvaluationScope.CreateWithGetOnlyParent(staticScope);
|
||||||
Evaluator = Evaluator.CreateWithSetScope(Diagnostics, Scope);
|
Evaluator = Evaluator.CreateWithSetScope(Diagnostics, Scope, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Script(string scriptString, Binder.Binder binder, Evaluator evaluator, ScriptOptions options)
|
private Script(string scriptString, Binder.Binder binder, Evaluator evaluator, ScriptOptions options)
|
||||||
|
@ -45,7 +45,7 @@ namespace Upsilon.Evaluator
|
||||||
Diagnostics = new Diagnostics(ScriptString, options.ThrowExceptionOnError);
|
Diagnostics = new Diagnostics(ScriptString, options.ThrowExceptionOnError);
|
||||||
|
|
||||||
Binder = Upsilon.Binder.Binder.CreateWithSetScope(Diagnostics, binder.Scope);
|
Binder = Upsilon.Binder.Binder.CreateWithSetScope(Diagnostics, binder.Scope);
|
||||||
Evaluator = Evaluator.CreateWithSetScope(Diagnostics, evaluator.Scope);
|
Evaluator = Evaluator.CreateWithSetScope(Diagnostics, evaluator.Scope, this);
|
||||||
Scope = Evaluator.Scope;
|
Scope = Evaluator.Scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ using System;
|
||||||
using Upsilon.BaseTypes;
|
using Upsilon.BaseTypes;
|
||||||
using Upsilon.BaseTypes.Number;
|
using Upsilon.BaseTypes.Number;
|
||||||
using Upsilon.BaseTypes.ScriptTypeInterfaces;
|
using Upsilon.BaseTypes.ScriptTypeInterfaces;
|
||||||
|
using Upsilon.Evaluator;
|
||||||
|
|
||||||
// ReSharper disable UnusedMember.Global
|
// ReSharper disable UnusedMember.Global
|
||||||
// ReSharper disable MemberCanBePrivate.Global
|
// ReSharper disable MemberCanBePrivate.Global
|
||||||
|
@ -37,6 +38,13 @@ namespace Upsilon.StandardLibraries
|
||||||
return new PairsScriptIterator(table);
|
return new PairsScriptIterator(table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[StandardLibraryScriptFunction("require", true)]
|
||||||
|
public void Require(Script script, ScriptBoolean boolean, ScriptString message = null)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[StandardLibraryScriptFunction("tonumber")]
|
[StandardLibraryScriptFunction("tonumber")]
|
||||||
public ScriptNumber ToNumber(ScriptString obj)
|
public ScriptNumber ToNumber(ScriptString obj)
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,7 +17,8 @@ namespace Upsilon.StandardLibraries
|
||||||
var attr = methodInfo.GetCustomAttribute<StandardLibraryScriptFunctionAttribute>();
|
var attr = methodInfo.GetCustomAttribute<StandardLibraryScriptFunctionAttribute>();
|
||||||
if (attr != null)
|
if (attr != null)
|
||||||
{
|
{
|
||||||
dictionary.Add(attr.Name, new ScriptMethodInfoFunction(new UserDataMethod(methodInfo), this, true));
|
dictionary.Add(attr.Name,
|
||||||
|
new ScriptMethodInfoFunction(new UserDataMethod(methodInfo), this, true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,11 +5,13 @@ namespace Upsilon.StandardLibraries
|
||||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
|
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
|
||||||
public class StandardLibraryScriptFunctionAttribute : Attribute
|
public class StandardLibraryScriptFunctionAttribute : Attribute
|
||||||
{
|
{
|
||||||
public StandardLibraryScriptFunctionAttribute(string name)
|
public StandardLibraryScriptFunctionAttribute(string name, bool passScriptReference = false)
|
||||||
{
|
{
|
||||||
Name = name;
|
Name = name;
|
||||||
|
PassScriptReference = passScriptReference;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Name { get; }
|
public string Name { get; }
|
||||||
|
public bool PassScriptReference { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue