Support for passing Script reference to functions. useful when options are required for function

This commit is contained in:
Deukhoofd 2018-11-30 11:31:45 +01:00
parent 3a3ed071d2
commit 9e27778af1
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
9 changed files with 46 additions and 27 deletions

View File

@ -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);
} }
} }

View File

@ -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)
{ {

View File

@ -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];

View File

@ -1,5 +1,3 @@
using System.Collections;
using System.Collections.Generic;
using Upsilon.Evaluator; using Upsilon.Evaluator;
using Upsilon.Text; using Upsilon.Text;

View File

@ -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))
{ {

View File

@ -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;
} }

View File

@ -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)
{ {

View File

@ -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));
} }
} }

View File

@ -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; }
} }
} }