Upsilon/Upsilon/BaseTypes/UserData/GenericUserData.cs

81 lines
2.4 KiB
C#

using Upsilon.BoundTypes;
using Upsilon.Evaluator;
using Upsilon.Text;
namespace Upsilon.BaseTypes.UserData
{
internal sealed class GenericUserData : ScriptType, IUserData
{
public GenericUserData(object obj)
{
Value = obj;
var type = obj.GetType();
_typeInfo = UserDataTypeHandler.GetTypeInfo(type);
Type = new TypeContainer(_typeInfo.BoundTypeName);
}
public override TypeContainer Type { get; }
private object Value { get; }
private readonly UserDataType _typeInfo;
public override object ToCSharpObject()
{
return Value;
}
public override System.Type GetCSharpType()
{
return Value.GetType();
}
public ScriptType Get(Diagnostics diagnostics, TextSpan span, ScriptType index, EvaluationScope scope)
{
var s = index.ToCSharpObject().ToString();
var (type, failed, error) = _typeInfo.Get(Value, s);
if (failed)
{
diagnostics.LogError(error, span);
}
return type;
}
public void Set(Diagnostics diagnostics, TextSpan span, ScriptType index, ScriptType value)
{
var s = index.ToCSharpObject().ToString();
var (failed, error) = _typeInfo.Set(Value, s, value);
if (failed)
{
diagnostics.LogError(error, span);
}
}
public (ScriptType Type, bool Failed) BinaryOperator(ScriptType par1, OperatorType op, ScriptType par2)
{
return _typeInfo.BinaryOperator(Value, par1, op, par2);
}
public (ScriptType Type, bool Failed) UnaryOperator(ScriptType par1, OperatorType op)
{
return _typeInfo.UnaryOperator(Value, par1, op);
}
protected bool Equals(GenericUserData other)
{
return Value.Equals(other.Value);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() == Value.GetType())
{
return obj.Equals(Value);
}
if (obj.GetType() != this.GetType()) return false;
return Equals((GenericUserData) obj);
}
}
}