public static object RelationalMetamethod(Context context, ExprType op, object left, object right) { if (left.GetType() != right.GetType()) { return(false); } // There are no metamethods for 'a > b' and 'a >= b' so they are translated to 'b < a' and 'b <= a' respectively var invert = op == ExprType.GreaterThan || op == ExprType.GreaterThanOrEqual; var metamethod = GetRelationalMetamethod(context, op, left, right); if (metamethod != null) { if (invert) { Context.DynamicCache.GetDynamicCall2()(metamethod, right, left); } else { Context.DynamicCache.GetDynamicCall2()(metamethod, left, right); } } // In the absence of a '<=' metamethod, try '<', 'a <= b' is translated to 'not (b < a)' if (op != ExprType.LessThanOrEqual && op != ExprType.GreaterThanOrEqual) { return(false); } metamethod = GetRelationalMetamethod(context, ExprType.LessThan, left, right); if (metamethod != null) { if (invert) { Not(Context.DynamicCache.GetDynamicCall2()(metamethod, right, left)); } else { Not(Context.DynamicCache.GetDynamicCall2()(metamethod, left, right)); } } var leftTypeName = BaseLibrary.Type(left); var rightTypeName = BaseLibrary.Type(right); if (leftTypeName == rightTypeName) { throw new LuaRuntimeException(ExceptionMessage.OP_TYPE_TWO_ERROR, "compare", leftTypeName); } throw new LuaRuntimeException(ExceptionMessage.OP_TYPE_WITH_ERROR, "compare", leftTypeName, rightTypeName); }
public static object ConcatMetamethod(Context context, object left, object right) { var metamethod = GetMetamethod(context, left, Constant.CONCAT_METAMETHOD) ?? GetMetamethod(context, right, Constant.CONCAT_METAMETHOD); if (metamethod != null) { return(Context.DynamicCache.GetDynamicCall2()(metamethod, left, right)); } var typeName = left is string?BaseLibrary.Type(left) : BaseLibrary.Type(right); throw new LuaRuntimeException(ExceptionMessage.OP_TYPE_ERROR, "concatenate", typeName); }
public static object CallMetamethod(Context context, object obj, object[] args) { var metamethod = GetMetamethod(context, obj, Constant.CALL_METAMETHOD); if (metamethod != null) { var array = new object[args.Length + 1]; array[0] = obj; Array.Copy(args, 0, array, 1, args.Length); return(Context.DynamicCache.GetDynamicCall1()(metamethod, new Varargs(array))); } throw new LuaRuntimeException(ExceptionMessage.OP_TYPE_ERROR, "call", BaseLibrary.Type(obj)); }
public static object NumericMetamethod(Context context, ExprType op, object left, object right) { var methodName = GetMethodName(op); var metamethod = GetMetamethod(context, left, methodName) ?? GetMetamethod(context, right, methodName); if (metamethod != null) { return(Context.DynamicCache.GetDynamicCall2()(metamethod, left, right)); } var typeName = BaseLibrary.Type(BaseLibrary.ToNumber(left) == null ? left : right); throw new LuaRuntimeException(ExceptionMessage.OP_TYPE_ERROR, "perform arithmetic on", typeName); }
public static object NewIndexMetamethod(Context context, object obj, object key, object value) { var metamethod = GetMetamethod(context, obj, Constant.NEWINDEX_METAMETHOD); if (metamethod != null) { if (metamethod is Delegate) { return(Context.DynamicCache.GetDynamicCall3()(metamethod, obj, key, value)); } if (metamethod is LuaTable) { return(Context.DynamicCache.GetDynamicNewIndex()(obj, key, value)); } } if (obj is LuaTable) { return(null); } throw new LuaRuntimeException(ExceptionMessage.OP_TYPE_ERROR, "index", BaseLibrary.Type(obj)); }
public static object UnaryMinusMetamethod(Context context, object obj) { var metamethod = GetMetamethod(context, obj, Constant.UNARYMINUS_METAMETHOD); if (metamethod != null) { return(Context.DynamicCache.GetDynamicCall1()(metamethod, obj)); } throw new LuaRuntimeException(ExceptionMessage.OP_TYPE_ERROR, "perform arithmetic on", BaseLibrary.Type(obj)); }
public static object LengthMetamethod(Context context, object obj) { var metamethod = GetMetamethod(context, obj, Constant.LENGTH_METAMETHOD); if (metamethod != null) { return(Context.DynamicCache.GetDynamicCall1()(metamethod, obj)); } throw new LuaRuntimeException(ExceptionMessage.OP_TYPE_ERROR, "get length of", BaseLibrary.Type(obj)); }