Beispiel #1
0
 public static Expr UnaryMinus(Context context, DynamicMetaObject target)
 {
     return Expr.Invoke(
         Expr.Constant((Func<Context, object, object>)LuaOps.UnaryMinusMetamethod),
         Expr.Constant(context, typeof(Context)),
         Expr.Convert(target.Expression, typeof(object)));
 }
Beispiel #2
0
        public static object Concat(Context context, object left, object right)
        {
            if ((left is string || left is double) && (right is double || right is string))
                return String.Concat(left, right);

            return ConcatMetamethod(context, left, right);
        }
Beispiel #3
0
 public static Expr Index(Context context, DynamicMetaObject target, DynamicMetaObject[] indexes)
 {
     return Expr.Invoke(
         Expr.Constant((Func<Context, object, object, object>)LuaOps.IndexMetamethod),
         Expr.Constant(context, typeof(Context)),
         Expr.Convert(target.Expression, typeof(object)),
         Expr.Convert(indexes[0].Expression, typeof(object)));
 }
Beispiel #4
0
 public static Expr BinaryOp(Context context, ExprType operation, DynamicMetaObject left, DynamicMetaObject right)
 {
     return Expr.Invoke(
         Expr.Constant((Func<Context, ExprType, object, object, object>)LuaOps.BinaryOpMetamethod),
         Expr.Constant(context, typeof(Context)),
         Expr.Constant(operation),
         Expr.Convert(left.Expression, typeof(object)),
         Expr.Convert(right.Expression, typeof(object)));
 }
Beispiel #5
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);
        }
Beispiel #6
0
        public static object GetMetamethod(Context context, object obj, string methodName)
        {
            LuaTable table;

            if ((table = obj as LuaTable) != null)
                table = table.Metatable;
            else if (context != null)
                table = context.GetTypeMetatable(obj);

            return methodName == null || table == null ? null : table.GetValue(methodName);
        }
Beispiel #7
0
        public static Expr Call(Context context, DynamicMetaObject target, DynamicMetaObject[] args)
        {
            var expression = Expr.Invoke(
                Expr.Constant((Func<Context, object, object[], object>)LuaOps.CallMetamethod),
                Expr.Constant(context, typeof(Context)),
                Expr.Convert(target.Expression, typeof(object)),
                Expr.NewArrayInit(
                    typeof(object),
                    args.Select(arg => Expr.Convert(arg.Expression, typeof(object)))));

            return expression;
        }
Beispiel #8
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));
        }
Beispiel #9
0
        public static Expr ConvertToNumberAndCheck(Context context, Expr expression, string format, params object[] args)
        {
            var numberVar = Expr.Variable(typeof(double));
            var assignNumber = Expr.Assign(numberVar, ConvertToNumber(context, expression));

            return Expr.Block(
                new[] {numberVar},
                assignNumber,
                Expr.Condition(
                    Expr.Invoke(
                        Expr.Constant((Func<double, bool>)Double.IsNaN), numberVar),
                    Expr.Block(
                        Expr.Throw(Expr.New(MemberInfos.NewRuntimeException, Expr.Constant(format), Expr.Constant(args))),
                        Expr.Constant(Double.NaN)),
                    numberVar));
        }
Beispiel #10
0
        public static object BinaryOpMetamethod(Context context, ExprType op, object left, object right)
        {
            switch (op)
            {
                case ExprType.Add:
                case ExprType.Subtract:
                case ExprType.Multiply:
                case ExprType.Divide:
                case ExprType.Modulo:
                case ExprType.Power:
                    return NumericMetamethod(context, op, left, right);

                case ExprType.GreaterThan:
                case ExprType.GreaterThanOrEqual:
                case ExprType.LessThan:
                case ExprType.LessThanOrEqual:
                    return RelationalMetamethod(context, op, left, right);

                default:
                    throw new ArgumentOutOfRangeException("op");
            }
        }
Beispiel #11
0
        public static object Length(Context context, object obj)
        {
            string str;
            LuaTable table;

            if ((str = obj as string) != null)
                return str.Length;
            if ((table = obj as LuaTable) != null)
                return table.Length();

            return LengthMetamethod(context, obj);
        }
Beispiel #12
0
 static object GetRelationalMetamethod(Context context, ExprType op, object left, object right)
 {
     var methodName = GetMethodName(op);
     var metamethodLeft = GetMetamethod(context, left, methodName);
     var metamethodRight = GetMetamethod(context, right, methodName);
     return metamethodLeft != metamethodRight ? null : metamethodLeft;
 }
Beispiel #13
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));
        }
Beispiel #14
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);
        }
Beispiel #15
0
 public static Expr ConvertToNumber(Context context, Expr expression)
 {
     var convertBinder = Context.DynamicCache.GetConvertBinder(typeof(double));
     return Expr.Dynamic(convertBinder, typeof(double), expression);
 }
Beispiel #16
0
        public static object IndexMetamethod(Context context, object obj, object key)
        {
            var metamethod = GetMetamethod(context, obj, Constant.INDEX_METAMETHOD);

            if (metamethod != null)
            {
                if (metamethod is Delegate)
                    return Context.DynamicCache.GetDynamicCall2()(metamethod, obj, key);
                if (metamethod is LuaTable)
                    return Context.DynamicCache.GetDynamicIndex()(obj, key);
            }

            if (obj is LuaTable)
                return null;
            throw new LuaRuntimeException(ExceptionMessage.OP_TYPE_ERROR, "index", BaseLibrary.Type(obj));
        }
Beispiel #17
0
 public BaseLibrary(Context context)
     : base(context)
 {
 }
Beispiel #18
0
 public StringLibrary(Context context)
     : base(context)
 {
 }
Beispiel #19
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));
        }
Beispiel #20
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);
        }
Beispiel #21
0
 protected Library(Context context)
 {
     Context = context;
 }
Beispiel #22
0
 public static Expr ConvertToBoolean(Context context, Expr expression)
 {
     var convertBinder = Context.DynamicCache.GetConvertBinder(typeof(bool));
     return Expr.Dynamic(convertBinder, typeof(bool), expression);
 }