Handle Unary operator overloading for UserData
This commit is contained in:
parent
c627100e9c
commit
605b98284d
|
@ -48,5 +48,10 @@ namespace Upsilon.BaseTypes.UserData
|
||||||
{
|
{
|
||||||
return _typeInfo.BinaryOperator(Value, par1, op, par2);
|
return _typeInfo.BinaryOperator(Value, par1, op, par2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public (LuaType Type, bool Failed) UnaryOperator(LuaType par1, OperatorType op)
|
||||||
|
{
|
||||||
|
return _typeInfo.UnaryOperator(Value, par1, op);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -82,5 +82,15 @@ namespace Upsilon.BaseTypes.UserData
|
||||||
|
|
||||||
return (method.Invoke(value, new[] {par1.ToCSharpObject(), par2.ToCSharpObject()}).ToLuaType(), false);
|
return (method.Invoke(value, new[] {par1.ToCSharpObject(), par2.ToCSharpObject()}).ToLuaType(), false);
|
||||||
}
|
}
|
||||||
|
public (LuaType Type, bool Failed) UnaryOperator(object value, LuaType par1, OperatorType op)
|
||||||
|
{
|
||||||
|
var method = OperatorHandler.GetUnaryOperator(op, par1.GetCSharpType());
|
||||||
|
if (method == null)
|
||||||
|
{
|
||||||
|
return (new LuaNull(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (method.Invoke(value, new[] {par1.ToCSharpObject()}).ToLuaType(), false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -50,6 +50,8 @@ namespace Upsilon.Binder
|
||||||
throw new Exception("Unknown unary operator token: " + operatorToken);
|
throw new Exception("Unknown unary operator token: " + operatorToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (inType == Type.Unknown)
|
||||||
|
return _operators.FirstOrDefault(op => op.Kind == kind);
|
||||||
return _operators.FirstOrDefault(op => op.Kind == kind && op.InType == inType);
|
return _operators.FirstOrDefault(op => op.Kind == kind && op.InType == inType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,9 +165,28 @@ namespace Upsilon.Evaluator
|
||||||
case BoundUnaryOperator.OperatorKind.Identity:
|
case BoundUnaryOperator.OperatorKind.Identity:
|
||||||
return operand;
|
return operand;
|
||||||
case BoundUnaryOperator.OperatorKind.Negation:
|
case BoundUnaryOperator.OperatorKind.Negation:
|
||||||
return -((Number)operand);
|
if (operand.Type == Type.Number)
|
||||||
|
return -((Number)operand);
|
||||||
|
else if (operand.Type == Type.UserData)
|
||||||
|
{
|
||||||
|
var ud = (UserData) operand;
|
||||||
|
var (type, failed) = ud.UnaryOperator(operand, OperatorType.UnaryNegation);
|
||||||
|
if (failed) goto default;
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
goto default;
|
||||||
case BoundUnaryOperator.OperatorKind.LogicalNegation:
|
case BoundUnaryOperator.OperatorKind.LogicalNegation:
|
||||||
return !(LuaBoolean) operand;
|
if (operand.Type == Type.Boolean)
|
||||||
|
return !(LuaBoolean) operand;
|
||||||
|
else if (operand.Type == Type.UserData)
|
||||||
|
{
|
||||||
|
var ud = (UserData) operand;
|
||||||
|
var (type, failed) = ud.UnaryOperator(operand, OperatorType.LogicalNot);
|
||||||
|
if (failed) goto default;
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
goto default;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new Exception("Invalid Unary Operator: " + e.Operator.Kind);
|
throw new Exception("Invalid Unary Operator: " + e.Operator.Kind);
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,11 @@ namespace UpsilonTests
|
||||||
return new UserDataHelper(a.Value - b.Value);
|
return new UserDataHelper(a.Value - b.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static UserDataHelper operator -(UserDataHelper a)
|
||||||
|
{
|
||||||
|
return new UserDataHelper(-a.Value);
|
||||||
|
}
|
||||||
|
|
||||||
public static UserDataHelper operator *(UserDataHelper a, UserDataHelper b)
|
public static UserDataHelper operator *(UserDataHelper a, UserDataHelper b)
|
||||||
{
|
{
|
||||||
return new UserDataHelper(a.Value * b.Value);
|
return new UserDataHelper(a.Value * b.Value);
|
||||||
|
@ -145,5 +150,21 @@ end
|
||||||
Assert.Equal(10, result.Value);
|
Assert.Equal(10, result.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestNegation()
|
||||||
|
{
|
||||||
|
const string input = @"
|
||||||
|
function negate(o1)
|
||||||
|
return -o1
|
||||||
|
end
|
||||||
|
";
|
||||||
|
var script = new Script(input);
|
||||||
|
Assert.Empty(script.Diagnostics.Messages);
|
||||||
|
var o1 = new UserDataHelper(100);
|
||||||
|
var result = script.EvaluateFunction<UserDataHelper>("negate", new object[] {o1});
|
||||||
|
Assert.Empty(script.Diagnostics.Messages);
|
||||||
|
Assert.Equal(-100, result.Value);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue