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