Various changes and tweaks to run better
This commit is contained in:
parent
f6947194b9
commit
43d9360145
|
@ -44,16 +44,6 @@ namespace Upsilon.BaseTypes.ScriptFunction
|
||||||
|
|
||||||
public override ScriptType Run(Diagnostics diagnostics, ScriptType[] variables, Script script, EvaluationScope scope)
|
public override ScriptType Run(Diagnostics diagnostics, ScriptType[] variables, Script script, EvaluationScope scope)
|
||||||
{
|
{
|
||||||
var types = _directTypeManipulation
|
|
||||||
? variables.Select(x => x.GetType()).ToArray()
|
|
||||||
: variables.Select(x => x.GetCSharpType()).ToArray();
|
|
||||||
var method = _method.GetMethod(types);
|
|
||||||
if (method == null)
|
|
||||||
{
|
|
||||||
throw new Exception(
|
|
||||||
$"No valid function found on type '{_object.GetType()}' with name '{_method.Name}' " +
|
|
||||||
$"and parameter types: {string.Join(", ", types.Select(x => $"'{x.Name}'"))}");
|
|
||||||
}
|
|
||||||
var objects = new List<object>();
|
var objects = new List<object>();
|
||||||
if (_passScriptReference)
|
if (_passScriptReference)
|
||||||
objects.Add(script);
|
objects.Add(script);
|
||||||
|
@ -62,19 +52,11 @@ namespace Upsilon.BaseTypes.ScriptFunction
|
||||||
objects.AddRange(_directTypeManipulation
|
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();
|
|
||||||
if (pars.Length != objects.Count)
|
|
||||||
{
|
|
||||||
for (var i = objects.Count; i < pars.Length; i++)
|
|
||||||
{
|
|
||||||
objects.Add(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
object result;
|
object result;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
result = method.Invoke(_object, objects.ToArray());
|
result = _object.GetType().InvokeMember(_method.Name, BindingFlags.InvokeMethod, System.Type.DefaultBinder,
|
||||||
|
_object, objects.ToArray());
|
||||||
}
|
}
|
||||||
catch (TargetInvocationException e)
|
catch (TargetInvocationException e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,6 +5,7 @@ using Upsilon.BaseTypes.Number;
|
||||||
using Upsilon.BaseTypes.ScriptFunction;
|
using Upsilon.BaseTypes.ScriptFunction;
|
||||||
using Upsilon.BaseTypes.ScriptTypeInterfaces;
|
using Upsilon.BaseTypes.ScriptTypeInterfaces;
|
||||||
using Upsilon.BaseTypes.UserData;
|
using Upsilon.BaseTypes.UserData;
|
||||||
|
using Upsilon.Text;
|
||||||
|
|
||||||
namespace Upsilon.BaseTypes
|
namespace Upsilon.BaseTypes
|
||||||
{
|
{
|
||||||
|
@ -19,6 +20,8 @@ namespace Upsilon.BaseTypes
|
||||||
return new ScriptBoolean(b);
|
return new ScriptBoolean(b);
|
||||||
case int i:
|
case int i:
|
||||||
return new ScriptNumberLong(i);
|
return new ScriptNumberLong(i);
|
||||||
|
case short s:
|
||||||
|
return new ScriptNumberLong(s);
|
||||||
case long i:
|
case long i:
|
||||||
return new ScriptNumberLong(i);
|
return new ScriptNumberLong(i);
|
||||||
case float f:
|
case float f:
|
||||||
|
|
|
@ -5,10 +5,10 @@ namespace Upsilon.BaseTypes.UserData
|
||||||
{
|
{
|
||||||
internal sealed class GenericUserData : ScriptType, IUserData
|
internal sealed class GenericUserData : ScriptType, IUserData
|
||||||
{
|
{
|
||||||
public GenericUserData(object dictionary)
|
public GenericUserData(object obj)
|
||||||
{
|
{
|
||||||
Value = dictionary;
|
Value = obj;
|
||||||
_typeInfo = UserDataTypeHandler.GetTypeInfo(dictionary.GetType());
|
_typeInfo = UserDataTypeHandler.GetTypeInfo(obj.GetType());
|
||||||
}
|
}
|
||||||
public override Type Type => Type.UserData;
|
public override Type Type => Type.UserData;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Upsilon.BaseTypes.UserData
|
||||||
|
{
|
||||||
|
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Method)]
|
||||||
|
public class UpsilonHiddenAttribute : Attribute
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,8 @@ using System;
|
||||||
|
|
||||||
namespace Upsilon.BaseTypes.UserData
|
namespace Upsilon.BaseTypes.UserData
|
||||||
{
|
{
|
||||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Enum, AllowMultiple = false, Inherited = true)]
|
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Enum | AttributeTargets.Interface,
|
||||||
|
AllowMultiple = false, Inherited = true)]
|
||||||
public class UpsilonUserDataAttribute : Attribute
|
public class UpsilonUserDataAttribute : Attribute
|
||||||
{
|
{
|
||||||
public UpsilonUserDataAttribute(string name)
|
public UpsilonUserDataAttribute(string name)
|
||||||
|
|
|
@ -38,6 +38,8 @@ namespace Upsilon.BaseTypes.UserData
|
||||||
public UserDataMethodParameter(ParameterInfo info)
|
public UserDataMethodParameter(ParameterInfo info)
|
||||||
{
|
{
|
||||||
Type = info.ParameterType;
|
Type = info.ParameterType;
|
||||||
|
if (Type.IsGenericType)
|
||||||
|
Type = Type.GetGenericTypeDefinition();
|
||||||
IsOptional = info.IsOptional;
|
IsOptional = info.IsOptional;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,6 +91,7 @@ namespace Upsilon.BaseTypes.UserData
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
var parameter = parameterTypes[index];
|
var parameter = parameterTypes[index];
|
||||||
|
if (parameter.IsGenericType) parameter = parameter.GetGenericTypeDefinition();
|
||||||
if (userDataMethodParameter.Type != parameter &&
|
if (userDataMethodParameter.Type != parameter &&
|
||||||
!userDataMethodParameter.Type.IsAssignableFrom(parameter))
|
!userDataMethodParameter.Type.IsAssignableFrom(parameter))
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,12 +10,20 @@ namespace Upsilon.BaseTypes.UserData
|
||||||
{
|
{
|
||||||
public UserDataType(System.Type type)
|
public UserDataType(System.Type type)
|
||||||
{
|
{
|
||||||
|
if (type.IsGenericType)
|
||||||
|
{
|
||||||
|
type = type.GetGenericTypeDefinition();
|
||||||
|
}
|
||||||
Type = type;
|
Type = type;
|
||||||
Variables = type.GetFields().ToDictionary(x => x.Name.ToLowerInvariant(), x => x);
|
Variables = type.GetFields().ToDictionary(x => x.Name.ToLowerInvariant(), x => x);
|
||||||
Properties = type.GetProperties().ToDictionary(x => x.Name.ToLowerInvariant(), x => x);
|
Properties = type.GetProperties().ToDictionary(x => x.Name.ToLowerInvariant(), x => x);
|
||||||
Methods = new Dictionary<string, UserDataMethod>();
|
Methods = new Dictionary<string, UserDataMethod>();
|
||||||
foreach (var methodInfo in type.GetMethods())
|
foreach (var methodInfo in type.GetMethods())
|
||||||
{
|
{
|
||||||
|
var hiddenAttribute = methodInfo.GetCustomAttribute(typeof(UpsilonHiddenAttribute));
|
||||||
|
if (hiddenAttribute != null)
|
||||||
|
continue;
|
||||||
|
|
||||||
var commonName = methodInfo.Name.ToLowerInvariant();
|
var commonName = methodInfo.Name.ToLowerInvariant();
|
||||||
var attribute = methodInfo.GetCustomAttribute(typeof(ScriptFunctionAttribute));
|
var attribute = methodInfo.GetCustomAttribute(typeof(ScriptFunctionAttribute));
|
||||||
if (attribute is ScriptFunctionAttribute sfa )
|
if (attribute is ScriptFunctionAttribute sfa )
|
||||||
|
@ -43,7 +51,10 @@ namespace Upsilon.BaseTypes.UserData
|
||||||
|
|
||||||
public (ScriptType Type, bool Failed, string Error) Get(object value, string member)
|
public (ScriptType Type, bool Failed, string Error) Get(object value, string member)
|
||||||
{
|
{
|
||||||
if (value.GetType() != Type)
|
var valueType = value.GetType();
|
||||||
|
if (valueType.IsGenericType)
|
||||||
|
valueType = valueType.GetGenericTypeDefinition();
|
||||||
|
if (valueType != Type)
|
||||||
return (null, true, "Invalid Type");
|
return (null, true, "Invalid Type");
|
||||||
member = member.ToLowerInvariant();
|
member = member.ToLowerInvariant();
|
||||||
if (Variables.TryGetValue(member, out var info))
|
if (Variables.TryGetValue(member, out var info))
|
||||||
|
@ -93,6 +104,12 @@ namespace Upsilon.BaseTypes.UserData
|
||||||
return (new ScriptNull(), true);
|
return (new ScriptNull(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HACK: Ugly solution for generic methods
|
||||||
|
if (method.ContainsGenericParameters)
|
||||||
|
{
|
||||||
|
method = value.GetType().GetMethod(method.Name, new[] {par1.GetCSharpType(), par2.GetCSharpType()});
|
||||||
|
}
|
||||||
|
|
||||||
return (method.Invoke(value, new[] {par1.ToCSharpObject(), par2.ToCSharpObject()}).ToScriptType(), false);
|
return (method.Invoke(value, new[] {par1.ToCSharpObject(), par2.ToCSharpObject()}).ToScriptType(), false);
|
||||||
}
|
}
|
||||||
public (ScriptType Type, bool Failed) UnaryOperator(object value, ScriptType par1, OperatorType op)
|
public (ScriptType Type, bool Failed) UnaryOperator(object value, ScriptType par1, OperatorType op)
|
||||||
|
@ -103,6 +120,12 @@ namespace Upsilon.BaseTypes.UserData
|
||||||
return (new ScriptNull(), true);
|
return (new ScriptNull(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HACK: Ugly solution for generic methods
|
||||||
|
if (method.ContainsGenericParameters)
|
||||||
|
{
|
||||||
|
method = value.GetType().GetMethod(method.Name, new[] {par1.GetCSharpType()});
|
||||||
|
}
|
||||||
|
|
||||||
return (method.Invoke(value, new[] {par1.ToCSharpObject()}).ToScriptType(), false);
|
return (method.Invoke(value, new[] {par1.ToCSharpObject()}).ToScriptType(), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,23 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Upsilon.BoundTypes;
|
using Upsilon.BoundTypes;
|
||||||
|
using Upsilon.Exceptions;
|
||||||
using Upsilon.StandardLibraries;
|
using Upsilon.StandardLibraries;
|
||||||
|
using Upsilon.Text;
|
||||||
|
|
||||||
namespace Upsilon.BaseTypes.UserData
|
namespace Upsilon.BaseTypes.UserData
|
||||||
{
|
{
|
||||||
public static class UserDataTypeHandler
|
public static class UserDataTypeHandler
|
||||||
{
|
{
|
||||||
private static readonly Dictionary<System.Type, UserDataType> Types = new Dictionary<System.Type, UserDataType>();
|
private static readonly ConcurrentDictionary<System.Type, UserDataType> Types
|
||||||
|
= new ConcurrentDictionary<System.Type, UserDataType>();
|
||||||
|
|
||||||
public static void LoadType(System.Type t, string name)
|
public static void LoadType(System.Type t, string name)
|
||||||
{
|
{
|
||||||
var info = new UserDataType(t);
|
var info = new UserDataType(t);
|
||||||
Types.Add(t, info);
|
Types.AddOrUpdate(t, info, (type, dataType) => dataType);
|
||||||
UserDataBoundTypeDefinition boundType;
|
UserDataBoundTypeDefinition boundType;
|
||||||
if (t.IsEnum)
|
if (t.IsEnum)
|
||||||
{
|
{
|
||||||
|
@ -55,7 +59,14 @@ namespace Upsilon.BaseTypes.UserData
|
||||||
|
|
||||||
internal static UserDataType GetTypeInfo(System.Type t)
|
internal static UserDataType GetTypeInfo(System.Type t)
|
||||||
{
|
{
|
||||||
return Types[t];
|
if (t.IsGenericType)
|
||||||
|
t = t.GetGenericTypeDefinition();
|
||||||
|
if (Types.TryGetValue(t, out var result))
|
||||||
|
return result;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception($"Can't use type '{t.FullName}' as script type, it's not registered for use.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -86,6 +86,9 @@ namespace Upsilon.BaseTypes.UserData
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (t1.IsGenericType) t1 = t1.GetGenericTypeDefinition();
|
||||||
|
if (t2.IsGenericType) t2 = t2.GetGenericTypeDefinition();
|
||||||
|
|
||||||
|
|
||||||
foreach (var operatorMethod in m)
|
foreach (var operatorMethod in m)
|
||||||
{
|
{
|
||||||
|
|
|
@ -316,10 +316,12 @@ namespace Upsilon.Binder
|
||||||
(UserDataBoundTypeDefinition) ((UserDataVariableSymbol) indexerVariable).BoundTypeDefinition;
|
(UserDataBoundTypeDefinition) ((UserDataVariableSymbol) indexerVariable).BoundTypeDefinition;
|
||||||
var bDefProperty = parent.Properties[fullStopIndexExpression.Index.ToLowerInvariant()];
|
var bDefProperty = parent.Properties[fullStopIndexExpression.Index.ToLowerInvariant()];
|
||||||
var boundDef = BoundTypeHandler.GetTypeDefinition(bDefProperty.ActualType);
|
var boundDef = BoundTypeHandler.GetTypeDefinition(bDefProperty.ActualType);
|
||||||
|
if (boundDef != null)
|
||||||
|
{
|
||||||
return new UserDataVariableSymbol(fullStopIndexExpression.Index, boundDef, parent);
|
return new UserDataVariableSymbol(fullStopIndexExpression.Index, boundDef, parent);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (indexerVariable.Type == Type.Unknown)
|
else if (indexerVariable.Type == Type.Unknown)
|
||||||
{
|
{
|
||||||
if (indexerVariable is UserDataVariableSymbol funcSymbol)
|
if (indexerVariable is UserDataVariableSymbol funcSymbol)
|
||||||
{
|
{
|
||||||
|
@ -335,8 +337,7 @@ namespace Upsilon.Binder
|
||||||
return new VariableSymbol(fullStopIndexExpression.Index, Type.Unknown, true);
|
return new VariableSymbol(fullStopIndexExpression.Index, Type.Unknown, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (expression.Kind == BoundKind.BoundFunctionCallExpression)
|
||||||
if (expression.Kind == BoundKind.BoundFunctionCallExpression)
|
|
||||||
{
|
{
|
||||||
return new VariableSymbol("", expression.Type, true);
|
return new VariableSymbol("", expression.Type, true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Concurrent;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Upsilon.BaseTypes;
|
using Upsilon.BaseTypes;
|
||||||
|
|
||||||
|
@ -7,33 +7,29 @@ namespace Upsilon.BoundTypes
|
||||||
{
|
{
|
||||||
public static class BoundTypeHandler
|
public static class BoundTypeHandler
|
||||||
{
|
{
|
||||||
private static readonly Dictionary<string, BoundTypeDefinition> DefaultTypeDefinitions =
|
private static void AddDefaults(ConcurrentDictionary<string, BoundTypeDefinition> dic)
|
||||||
new Dictionary<string, BoundTypeDefinition>
|
|
||||||
{
|
{
|
||||||
{"string", new BoundTypeDefinition(Type.String, typeof(string))},
|
dic.TryAdd("string", new BoundTypeDefinition(Type.String, typeof(string)));
|
||||||
{
|
dic.TryAdd("number", new BoundTypeDefinition(Type.Number,
|
||||||
"number",
|
new[] {typeof(int), typeof(long), typeof(float), typeof(double)}));
|
||||||
new BoundTypeDefinition(Type.Number,
|
dic.TryAdd("bool", new BoundTypeDefinition(Type.Boolean, typeof(bool)));
|
||||||
new[] {typeof(int), typeof(long), typeof(float), typeof(double)})
|
dic.TryAdd("table", new BoundTypeDefinition(Type.Table, typeof(IEnumerator)));
|
||||||
},
|
dic.TryAdd("function", new BoundTypeDefinition(Type.Function, new System.Type[0]));
|
||||||
{"bool", new BoundTypeDefinition(Type.Boolean, typeof(bool))},
|
}
|
||||||
{"table", new BoundTypeDefinition(Type.Table, typeof(IEnumerator))},
|
|
||||||
{"function", new BoundTypeDefinition(Type.Function, new System.Type[0])},
|
|
||||||
};
|
|
||||||
|
|
||||||
private static Dictionary<string, BoundTypeDefinition> _typeDefinitions =
|
private static readonly ConcurrentDictionary<string, BoundTypeDefinition> TypeDefinitions = Reset();
|
||||||
new Dictionary<string, BoundTypeDefinition>(DefaultTypeDefinitions);
|
|
||||||
|
|
||||||
public static void Reset()
|
public static ConcurrentDictionary<string, BoundTypeDefinition> Reset()
|
||||||
{
|
{
|
||||||
_typeDefinitions =
|
var dic = new ConcurrentDictionary<string, BoundTypeDefinition>();
|
||||||
new Dictionary<string, BoundTypeDefinition>(DefaultTypeDefinitions);
|
AddDefaults(dic);
|
||||||
|
return dic;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BoundTypeDefinition GetTypeDefinition(string key)
|
public static BoundTypeDefinition GetTypeDefinition(string key)
|
||||||
{
|
{
|
||||||
var normalizedName = key.ToLowerInvariant();
|
var normalizedName = key.ToLowerInvariant();
|
||||||
if (_typeDefinitions.TryGetValue(normalizedName, out var bt))
|
if (TypeDefinitions.TryGetValue(normalizedName, out var bt))
|
||||||
{
|
{
|
||||||
return bt;
|
return bt;
|
||||||
}
|
}
|
||||||
|
@ -42,20 +38,13 @@ namespace Upsilon.BoundTypes
|
||||||
|
|
||||||
public static BoundTypeDefinition GetTypeDefinition(System.Type type)
|
public static BoundTypeDefinition GetTypeDefinition(System.Type type)
|
||||||
{
|
{
|
||||||
return _typeDefinitions.Values.FirstOrDefault(x => x.ValidInternalTypes.Contains(type));
|
return TypeDefinitions.Values.FirstOrDefault(x => x.ValidInternalTypes.Contains(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void LoadUserDataTypeDefinition(UserDataBoundTypeDefinition def)
|
public static void LoadUserDataTypeDefinition(UserDataBoundTypeDefinition def)
|
||||||
{
|
{
|
||||||
var key = def.Name.ToLowerInvariant();
|
var key = def.Name.ToLowerInvariant();
|
||||||
if (_typeDefinitions.ContainsKey(key))
|
TypeDefinitions.AddOrUpdate(key, def, (s, definition) => definition);
|
||||||
{
|
|
||||||
_typeDefinitions[key] = def;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_typeDefinitions.Add(key, def);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -75,9 +75,26 @@ namespace Upsilon.Evaluator
|
||||||
{
|
{
|
||||||
for (var index = 0; index < parameters.Length; index++)
|
for (var index = 0; index < parameters.Length; index++)
|
||||||
{
|
{
|
||||||
var parameter = parameters[index];
|
object parameter;
|
||||||
var parameterSymbol = (UserDataVariableSymbol)function.Parameters[index].VariableSymbol;
|
if (index < parameters.Length)
|
||||||
if (parameterSymbol.BoundTypeDefinition != null)
|
{
|
||||||
|
parameter = parameters[index];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parameter = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
UserDataVariableSymbol parameterSymbol;
|
||||||
|
if (index < function.Parameters.Length)
|
||||||
|
{
|
||||||
|
parameterSymbol = (UserDataVariableSymbol)function.Parameters[index].VariableSymbol;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (parameterSymbol.BoundTypeDefinition != null && parameter != null)
|
||||||
{
|
{
|
||||||
bool isCompatible = false;
|
bool isCompatible = false;
|
||||||
var parameterType = parameter.GetType();
|
var parameterType = parameter.GetType();
|
||||||
|
@ -97,7 +114,8 @@ namespace Upsilon.Evaluator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
innerEvaluator.Scope.CreateLocal(parameterSymbol, parameter.ToScriptType());
|
var parameterConverted = parameter == null ? new ScriptNull() : parameter.ToScriptType();
|
||||||
|
innerEvaluator.Scope.CreateLocal(parameterSymbol, parameterConverted);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,7 +398,7 @@ namespace Upsilon.Evaluator
|
||||||
case BoundBinaryOperator.OperatorKind.Or:
|
case BoundBinaryOperator.OperatorKind.Or:
|
||||||
return new ScriptBoolean((ScriptBoolean) left || (ScriptBoolean) right);
|
return new ScriptBoolean((ScriptBoolean) left || (ScriptBoolean) right);
|
||||||
default:
|
default:
|
||||||
throw new Exception("Invalid Binary Operator: " + e.Operator);
|
throw new Exception("Invalid Binary Operator: " + e.Operator.Kind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,20 @@ namespace Upsilon.Evaluator
|
||||||
Evaluator = Evaluator.CreateWithSetScope(Diagnostics, Scope, this);
|
Evaluator = Evaluator.CreateWithSetScope(Diagnostics, Scope, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Script(BoundScript s, ScriptOptions options )
|
||||||
|
{
|
||||||
|
FileName = s.FileName;
|
||||||
|
Options = options;
|
||||||
|
Diagnostics = new Diagnostics(ScriptString, options.ThrowExceptionOnError, s.FileName);
|
||||||
|
|
||||||
|
_bound = s;
|
||||||
|
Binder = Upsilon.Binder.Binder.CreateWithSetScope(Diagnostics, s.Scope, this);
|
||||||
|
|
||||||
|
var staticScope = options.OverrideStaticScope ?? StaticScope.Scope;
|
||||||
|
Scope = EvaluationScope.CreateWithGetOnlyParent(staticScope);
|
||||||
|
Evaluator = Evaluator.CreateWithSetScope(Diagnostics, Scope, this);
|
||||||
|
}
|
||||||
|
|
||||||
private Script(string fileName, string scriptString, Binder.Binder binder, Evaluator evaluator, ScriptOptions options)
|
private Script(string fileName, string scriptString, Binder.Binder binder, Evaluator evaluator, ScriptOptions options)
|
||||||
{
|
{
|
||||||
ScriptString = new SourceText(scriptString);
|
ScriptString = new SourceText(scriptString);
|
||||||
|
@ -75,6 +89,7 @@ namespace Upsilon.Evaluator
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
internal void Parse()
|
internal void Parse()
|
||||||
{
|
{
|
||||||
_parsed = Parser.Parser.Parse(_scriptString, Diagnostics, Options.SaveDataComments);
|
_parsed = Parser.Parser.Parse(_scriptString, Diagnostics, Options.SaveDataComments);
|
||||||
|
@ -98,6 +113,8 @@ namespace Upsilon.Evaluator
|
||||||
|
|
||||||
private static T Convert<T>(ScriptType t)
|
private static T Convert<T>(ScriptType t)
|
||||||
{
|
{
|
||||||
|
if (t == null)
|
||||||
|
return default(T);
|
||||||
if (typeof(T) == typeof(double))
|
if (typeof(T) == typeof(double))
|
||||||
return (T)(object)System.Convert.ToDouble(t.ToCSharpObject());
|
return (T)(object)System.Convert.ToDouble(t.ToCSharpObject());
|
||||||
if (typeof(T) == typeof(long))
|
if (typeof(T) == typeof(long))
|
||||||
|
|
|
@ -4,12 +4,11 @@ namespace Upsilon.Evaluator
|
||||||
{
|
{
|
||||||
public class ScriptLoader
|
public class ScriptLoader
|
||||||
{
|
{
|
||||||
public virtual string FilePath { get; } = "./";
|
public virtual string FilePath { get; set; } = "./";
|
||||||
public virtual string ModulesPath { get; } = "./modules/";
|
public virtual string ModulesPath { get; set; } = "./modules/";
|
||||||
|
|
||||||
public virtual string LoadFile(string fileName)
|
public virtual string LoadFile(string fileName)
|
||||||
{
|
{
|
||||||
var path = FilePath;
|
|
||||||
var resolvedName = ResolveFileName(FilePath, fileName);
|
var resolvedName = ResolveFileName(FilePath, fileName);
|
||||||
if (File.Exists(resolvedName))
|
if (File.Exists(resolvedName))
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,6 +19,8 @@ namespace Upsilon
|
||||||
{
|
{
|
||||||
if (options == null) options = DefaultOptions;
|
if (options == null) options = DefaultOptions;
|
||||||
var input = options.ScriptLoader.LoadFile(fileName);
|
var input = options.ScriptLoader.LoadFile(fileName);
|
||||||
|
if (input == null)
|
||||||
|
return null;
|
||||||
var script = new Script(input,fileName, options);
|
var script = new Script(input,fileName, options);
|
||||||
script.Parse();
|
script.Parse();
|
||||||
return script;
|
return script;
|
||||||
|
@ -70,6 +72,12 @@ namespace Upsilon
|
||||||
return script.Evaluate();
|
return script.Evaluate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static object EvaluateScript(BoundScript input, ScriptOptions options = null)
|
||||||
|
{
|
||||||
|
var script = new Script(input, options);
|
||||||
|
return script.Evaluate();
|
||||||
|
}
|
||||||
|
|
||||||
public static T EvaluateFunction<T>(string input, string function, object[] parameters = null, ScriptOptions options = null)
|
public static T EvaluateFunction<T>(string input, string function, object[] parameters = null, ScriptOptions options = null)
|
||||||
{
|
{
|
||||||
var script = ParseInputAndEvaluate(input, options);
|
var script = ParseInputAndEvaluate(input, options);
|
||||||
|
|
Loading…
Reference in New Issue