From 9e27778af1ccc1e9378a6b9e64827af1eb40fd62 Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Fri, 30 Nov 2018 11:31:45 +0100 Subject: [PATCH] Support for passing Script reference to functions. useful when options are required for function --- .../ScriptFunction/ScriptFunction.cs | 4 ++- .../ScriptMethodInfoFunction.cs | 13 +++++--- .../ScriptFunction/ScriptRuntimeFunction.cs | 4 +-- .../ScriptTypeInterfaces/IIndexable.cs | 2 -- Upsilon/Evaluator/Evaluator.cs | 31 ++++++++++--------- Upsilon/Evaluator/Script.cs | 4 +-- Upsilon/StandardLibraries/BasicFunctions.cs | 8 +++++ Upsilon/StandardLibraries/ScriptLibrary.cs | 3 +- .../StandardLibraryScriptFunctionAttribute.cs | 4 ++- 9 files changed, 46 insertions(+), 27 deletions(-) diff --git a/Upsilon/BaseTypes/ScriptFunction/ScriptFunction.cs b/Upsilon/BaseTypes/ScriptFunction/ScriptFunction.cs index 970d13a..9e91ec3 100644 --- a/Upsilon/BaseTypes/ScriptFunction/ScriptFunction.cs +++ b/Upsilon/BaseTypes/ScriptFunction/ScriptFunction.cs @@ -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); } } \ No newline at end of file diff --git a/Upsilon/BaseTypes/ScriptFunction/ScriptMethodInfoFunction.cs b/Upsilon/BaseTypes/ScriptFunction/ScriptMethodInfoFunction.cs index a47bab7..b05457e 100644 --- a/Upsilon/BaseTypes/ScriptFunction/ScriptMethodInfoFunction.cs +++ b/Upsilon/BaseTypes/ScriptFunction/ScriptMethodInfoFunction.cs @@ -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(); + 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) { diff --git a/Upsilon/BaseTypes/ScriptFunction/ScriptRuntimeFunction.cs b/Upsilon/BaseTypes/ScriptFunction/ScriptRuntimeFunction.cs index 7a26c5a..3050412 100644 --- a/Upsilon/BaseTypes/ScriptFunction/ScriptRuntimeFunction.cs +++ b/Upsilon/BaseTypes/ScriptFunction/ScriptRuntimeFunction.cs @@ -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]; diff --git a/Upsilon/BaseTypes/ScriptTypeInterfaces/IIndexable.cs b/Upsilon/BaseTypes/ScriptTypeInterfaces/IIndexable.cs index ba4c8fd..d51aa88 100644 --- a/Upsilon/BaseTypes/ScriptTypeInterfaces/IIndexable.cs +++ b/Upsilon/BaseTypes/ScriptTypeInterfaces/IIndexable.cs @@ -1,5 +1,3 @@ -using System.Collections; -using System.Collections.Generic; using Upsilon.Evaluator; using Upsilon.Text; diff --git a/Upsilon/Evaluator/Evaluator.cs b/Upsilon/Evaluator/Evaluator.cs index a129445..3f4424b 100644 --- a/Upsilon/Evaluator/Evaluator.cs +++ b/Upsilon/Evaluator/Evaluator.cs @@ -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 variables) + internal Evaluator(Diagnostics diagnostics, Dictionary 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)) { diff --git a/Upsilon/Evaluator/Script.cs b/Upsilon/Evaluator/Script.cs index 7efc4a9..6473ba6 100644 --- a/Upsilon/Evaluator/Script.cs +++ b/Upsilon/Evaluator/Script.cs @@ -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; } diff --git a/Upsilon/StandardLibraries/BasicFunctions.cs b/Upsilon/StandardLibraries/BasicFunctions.cs index 4535726..3d24548 100644 --- a/Upsilon/StandardLibraries/BasicFunctions.cs +++ b/Upsilon/StandardLibraries/BasicFunctions.cs @@ -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) { diff --git a/Upsilon/StandardLibraries/ScriptLibrary.cs b/Upsilon/StandardLibraries/ScriptLibrary.cs index d7de7d4..5a9e88f 100644 --- a/Upsilon/StandardLibraries/ScriptLibrary.cs +++ b/Upsilon/StandardLibraries/ScriptLibrary.cs @@ -17,7 +17,8 @@ namespace Upsilon.StandardLibraries var attr = methodInfo.GetCustomAttribute(); 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)); } } diff --git a/Upsilon/StandardLibraries/StandardLibraryScriptFunctionAttribute.cs b/Upsilon/StandardLibraries/StandardLibraryScriptFunctionAttribute.cs index 56bd555..c368c84 100644 --- a/Upsilon/StandardLibraries/StandardLibraryScriptFunctionAttribute.cs +++ b/Upsilon/StandardLibraries/StandardLibraryScriptFunctionAttribute.cs @@ -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; } } } \ No newline at end of file