Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        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));
        }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
        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));
        }
Esempio n. 6
0
        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));
        }
Esempio n. 7
0
        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));
        }