Added UserData support

This commit is contained in:
Deukhoofd 2018-11-19 17:22:25 +01:00
parent 7d551b6313
commit d1b1675bba
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
11 changed files with 193 additions and 13 deletions

View File

@ -5,6 +5,7 @@ namespace Upsilon.BaseTypes
internal interface IIndexable internal interface IIndexable
{ {
LuaType Get(string s, EvaluationScope scope); LuaType Get(string s, EvaluationScope scope);
void Set(string s, LuaType value);
} }
internal interface IScopeOwner internal interface IScopeOwner

View File

@ -83,5 +83,10 @@ namespace Upsilon.BaseTypes
var i = int.Parse(s); var i = int.Parse(s);
return new LuaString(Value[i - 1].ToString()); return new LuaString(Value[i - 1].ToString());
} }
public void Set(string s, LuaType value)
{
throw new NotSupportedException();
}
} }
} }

View File

@ -1,4 +1,3 @@
using System;
using Upsilon.BaseTypes.Number; using Upsilon.BaseTypes.Number;
namespace Upsilon.BaseTypes namespace Upsilon.BaseTypes
@ -19,12 +18,13 @@ namespace Upsilon.BaseTypes
return new NumberDouble(f); return new NumberDouble(f);
case double f: case double f:
return new NumberDouble(f); return new NumberDouble(f);
case string s:
return new LuaString(s);
case null:
return new LuaNull();
default: default:
throw new Exception(); return new UserData.UserData(o);
} }
} }
} }
} }

View File

@ -0,0 +1,32 @@
using Upsilon.Evaluator;
namespace Upsilon.BaseTypes.UserData
{
internal class UserData : LuaType, IIndexable
{
public UserData(object o)
{
Value = o;
_typeInfo = UserDataTypeHandler.GetTypeInfo(o.GetType());
}
public override Type Type => Type.UserData;
private object Value { get; }
private readonly UserDataType _typeInfo;
public override object ToCSharpObject()
{
return Value;
}
public LuaType Get(string s, EvaluationScope scope)
{
return _typeInfo.Get(Value, s);
}
public void Set(string s, LuaType value)
{
_typeInfo.Set(Value, s, value);
}
}
}

View File

@ -0,0 +1,51 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace Upsilon.BaseTypes.UserData
{
internal class UserDataType
{
public UserDataType(System.Type type)
{
Type = type;
Variables = type.GetFields().ToDictionary(x => x.Name, x => x);
Properties = type.GetProperties().ToDictionary(x => x.Name, x => x);
}
private System.Type Type { get; }
private Dictionary<string, FieldInfo> Variables { get; }
private Dictionary<string, PropertyInfo> Properties { get; }
public LuaType Get(object value, string member)
{
if (value.GetType() != Type)
return null;
if (Variables.TryGetValue(member, out var info))
{
return info.GetValue(value).ToLuaType();
}
if (Properties.TryGetValue(member, out var property))
{
return property.GetValue(value).ToLuaType();
}
return null;
}
public void Set(object value, string member, LuaType newValue)
{
if (value.GetType() != Type)
return;
if (Variables.TryGetValue(member, out var info))
{
info.SetValue(value, newValue.ToCSharpObject());
}
if (Properties.TryGetValue(member, out var property))
{
property.SetValue(value, newValue.ToCSharpObject());
}
return;
}
}
}

View File

@ -0,0 +1,25 @@
using System.Collections.Generic;
namespace Upsilon.BaseTypes.UserData
{
public static class UserDataTypeHandler
{
private static readonly Dictionary<System.Type, UserDataType> _types = new Dictionary<System.Type, UserDataType>();
public static void LoadType(System.Type t)
{
var info = new UserDataType(t);
_types.Add(t, info);
}
public static void LoadType<T>()
{
LoadType(typeof(T));
}
internal static UserDataType GetTypeInfo(System.Type t)
{
return _types[t];
}
}
}

View File

@ -355,13 +355,11 @@ namespace Upsilon.Evaluator
var table = EvaluateExpression(e.TableIndexExpression.Identifier); var table = EvaluateExpression(e.TableIndexExpression.Identifier);
var index = EvaluateExpression(e.TableIndexExpression.Index); var index = EvaluateExpression(e.TableIndexExpression.Index);
var value = EvaluateExpression(e.Value); var value = EvaluateExpression(e.Value);
if (table.Type != Type.Table) if (!(table is IIndexable indexable))
{ {
throw new Exception("Not a table"); throw new Exception("Cant assign to that");
} }
indexable.Set(index.ToString(), value);
var t = (LuaTable) table;
t.Set(index.ToString(), value);
} }
} }
} }

View File

@ -84,7 +84,9 @@ namespace Upsilon.Evaluator
public T Evaluate<T>() public T Evaluate<T>()
{ {
return Convert<T>(Evaluator.Evaluate(Bind())); var bound = Bind();
var evaluate = Evaluator.Evaluate(bound);
return Convert<T>(evaluate);
} }
public T EvaluateFunction<T>(string functionName, object[] parameters = null) public T EvaluateFunction<T>(string functionName, object[] parameters = null)

View File

@ -1,3 +1,5 @@
using System;
using System.Diagnostics;
using Upsilon.Evaluator; using Upsilon.Evaluator;
using Xunit; using Xunit;

View File

@ -0,0 +1,64 @@
using System;
using Upsilon.BaseTypes.UserData;
using Upsilon.Evaluator;
using Xunit;
namespace UpsilonTests
{
public class UserDataTests : IClassFixture<UserDataTests.UserDataTestsFixture>
{
public class UserDataTestsFixture : IDisposable
{
public UserDataTestsFixture()
{
UserDataTypeHandler.LoadType<UserDataHelper>();
}
public void Dispose()
{
}
}
#pragma warning disable 414, 649
private class UserDataHelper
{
public string FieldString = "TestField";
public string FieldStringSet;
}
#pragma warning restore 414, 649
[Fact]
public void AccessFieldsGet()
{
var obj = new UserDataHelper();
const string input = @"
function test(o)
return o[""FieldString""]
end
";
var script = new Script(input);
Assert.Empty(script.Diagnostics.Messages);
var result = script.EvaluateFunction<string>("test", new[] {obj});
Assert.Empty(script.Diagnostics.Messages);
Assert.Equal("TestField", result);
}
[Fact]
public void AccessFieldsSet()
{
var obj = new UserDataHelper();
const string input = @"
function test(o)
o[""FieldStringSet""] = ""Test""
end
";
var script = new Script(input);
Assert.Empty(script.Diagnostics.Messages);
script.EvaluateFunction("test", new[] {obj});
Assert.Empty(script.Diagnostics.Messages);
Assert.Equal("Test", obj.FieldStringSet);
}
}
}

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Text; using System.Text;
using Upsilon; using Upsilon;
using Upsilon.Evaluator; using Upsilon.Evaluator;
@ -17,7 +18,6 @@ namespace Ycicle
Console.Write("» "); Console.Write("» ");
var input = Console.ReadLine(); var input = Console.ReadLine();
if (input == "exit") return; if (input == "exit") return;
script = script == null ? new Script(input) : Script.ContinueWith(script, input); script = script == null ? new Script(input) : Script.ContinueWith(script, input);
if (script.Diagnostics.Messages.Count > 0) if (script.Diagnostics.Messages.Count > 0)
@ -32,8 +32,8 @@ namespace Ycicle
continue; continue;
} }
//Console.WriteLine(script.PrettyPrintSyntaxTree()); //Console.WriteLine(script.PrettyPrintSyntaxTree());
var evaluate = script.Evaluate<double>();
var evaluate = script.Evaluate();
if (script.Diagnostics.Messages.Count > 0) if (script.Diagnostics.Messages.Count > 0)
{ {
Console.ForegroundColor = ConsoleColor.Red; Console.ForegroundColor = ConsoleColor.Red;