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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
if (inType == Type.Unknown)
|
||||
return _operators.FirstOrDefault(op => op.Kind == kind);
|
||||
return _operators.FirstOrDefault(op => op.Kind == kind && op.InType == inType);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -165,9 +165,28 @@ namespace Upsilon.Evaluator
|
|||
case BoundUnaryOperator.OperatorKind.Identity:
|
||||
return operand;
|
||||
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:
|
||||
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:
|
||||
throw new Exception("Invalid Unary Operator: " + e.Operator.Kind);
|
||||
}
|
||||
|
|
|
@ -46,6 +46,11 @@ namespace UpsilonTests
|
|||
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)
|
||||
{
|
||||
return new UserDataHelper(a.Value * b.Value);
|
||||
|
@ -145,5 +150,21 @@ end
|
|||
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