Beispiel #1
0
 private LuaScope(LuaScope parent)
 {
     this.context = parent.context;
     this.parent = parent;
     this.variables = new Dictionary<string, ParamExpr>();
     this.labels = new Dictionary<string, LabelTarget>();
 }
Beispiel #2
0
 public static LuaScope CreateRoot(CodeContext context)
 {
     Contract.Requires(context != null);
     var scope = new LuaScope(context);
     scope.labels.Add(ReturnLabelName, Expr.Label(typeof(object)));
     return scope;
 }
Beispiel #3
0
        public static object BinaryOpMetamethod(CodeContext context, ExprType op, object left, object right)
        {
            ContractUtils.RequiresNotNull(context, "context");

            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);

                case ExprType.Equal:
                    return EquateMetamethod(context, op, left, right);
                case ExprType.NotEqual:
                    return Not(EquateMetamethod(context, ExprType.Equal, left, right));

                default:
                    throw new ArgumentOutOfRangeException("op");
            }
        }
Beispiel #4
0
 private LuaScope(CodeContext context)
 {
     this.context = context;
     this.parent = null;
     this.variables = new Dictionary<string, ParamExpr>();
     this.labels = new Dictionary<string, LabelTarget>();
 }
        /// <summary>
        /// Wraps a new function definition, so that the function can be registered as a Lua function with the relevant
        /// CodeContext. This allows the function to benefit from custom execution environments.
        /// </summary>
        public FunctionDefinitionExpression(CodeContext context, LuaScope scope, IEnumerable<string> identifiers, LambdaExpression function)
        {
            _context = context;
            _scope = scope;
            _body = function;

            _identifier = identifiers.Merge((s1, s2) => s1 + "." + s2);
        }
Beispiel #6
0
        public static object Concat(CodeContext context, object left, object right)
        {
            ContractUtils.RequiresNotNull(context, "context");

            if ((left is string || left is double) && (right is double || right is string))
                return String.Concat(left, right);

            return ConcatMetamethod(context, left, right);
        }
        /// <summary>
        /// Creates a wrapper around a function which represents entry into its scope
        /// </summary>
        /// <param name="context">The context under which this function is compiled</param>
        /// <param name="body">The block expression which represents this function's execution</param>
        /// <param name="evalScope">The scope in which the body will be executed, holding local values</param>
        /// <param name="upScope">The scope in which the function will execute, storing up values (which persist between calls)</param>
        public FunctionScopeExpression(CodeContext context, LuaScope evalScope, LuaScope upScope, string identifier, Expression body)
        {
            _context = Expression.Constant(context);
            _body = body;
            _stack = Expression.Constant(new FunctionStack(context, upScope, evalScope, identifier));

            _evalScope = evalScope;
            _upScope = upScope;
        }
Beispiel #8
0
        public static object ConcatMetamethod(CodeContext context, object left, object right)
        {
            ContractUtils.RequiresNotNull(context, "context");

            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 LuaRuntimeException.Create(context, ExceptionMessage.OP_TYPE_ERROR, "concatenate", typeName);
        }
Beispiel #9
0
        public static object CallMetamethod(CodeContext context, object obj, object[] args)
        {
            ContractUtils.RequiresNotNull(context, "context");

            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 LuaRuntimeException.Create(context, ExceptionMessage.OP_TYPE_ERROR, "call", BaseLibrary.Type(obj));
        }
Beispiel #10
0
        public static Expr ConvertToNumberAndCheck(CodeContext 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(context), Expr.Constant(format), Expr.Constant(args))),
                        Expr.Constant(Double.NaN)),
                    numberVar));
        }
 public static Expr BinaryOp(CodeContext context, ExprType operation, DynamicMetaObject left, DynamicMetaObject right)
 {
     return BinaryOp(Expr.Constant(context, typeof(CodeContext)), operation, left, right);
 }
        public static Expr WrapStackTrace(Expr expr, CodeContext context, FunctionStack callSite)
        {
            var tempVar = Expr.Variable(typeof(object), "$metamethod_result$");

            return Expr.Block(new[] { tempVar },
                LuaExpr.FunctionScope(context, callSite.ExecScope, callSite.UpScope, new[] { callSite.Identifier }, Expr.Assign(tempVar, expr)));
        }
 public static Expr UnaryMinus(CodeContext context, DynamicMetaObject target)
 {
     return UnaryMinus(Expr.Constant(context, typeof(CodeContext)), target);
 }
Beispiel #14
0
        public static object NewIndexMetamethod(CodeContext context, object obj, object key, object value)
        {
            ContractUtils.RequiresNotNull(context, "context");

            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 (obj as LuaTable).SetValue(key, value);
                //var targetParam = Expr.Parameter(typeof(object));
                //var keyParam = Expr.Parameter(typeof(object));
                //var valParam = Expr.Parameter(typeof(object));

                //var expression = Expr.Call(
                //    Expr.Convert(targetParam, typeof(LuaTable)),
                //    MemberInfos.LuaTableSetValue,
                //    keyParam,
                //    valParam);

                //return Expr.Lambda<Func<object, object, object, object>>(
                //    Expr.Block(typeof(object),
                //    new[] { targetParam, keyParam, valParam },
                //    expression)
                //    , targetParam, keyParam, valParam).Compile()(obj, key, value);
            }

            throw LuaRuntimeException.Create(context, ExceptionMessage.OP_TYPE_ERROR, "index", BaseLibrary.Type(obj));
        }
Beispiel #15
0
 public InteropLibrary(CodeContext context, params Type[] types)
     : base(context)
 {
     InteropMetatable = GenerateMetatable(context);
 }
 public static Expr NewIndex(CodeContext context, DynamicMetaObject target, DynamicMetaObject[] indexes, DynamicMetaObject value)
 {
     return NewIndex(Expr.Constant(context, typeof(CodeContext)), target, indexes, value);
 }
Beispiel #17
0
        public static object EquateMetamethod(CodeContext context, ExprType op, object left, object right)
        {
            ContractUtils.RequiresNotNull(context, "context");

            var leftTypeName = BaseLibrary.Type(left);
            var rightTypeName = BaseLibrary.Type(right);

            if (left == null && right == null)
                return true;

            var metamethod = GetRelationalMetamethod(context, op, left, right);

            if (metamethod != null)
                return context.DynamicCache.GetDynamicCall2()(metamethod, left, right);
            else
                return left == null ? right.Equals(left) : left.Equals(right);
        }
Beispiel #18
0
        public static object Length(CodeContext context, object obj)
        {
            ContractUtils.RequiresNotNull(context, "context");

            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 #19
0
        public static object LengthMetamethod(CodeContext context, object obj)
        {
            ContractUtils.RequiresNotNull(context, "context");

            var metamethod = GetMetamethod(context, obj, Constant.LENGTH_METAMETHOD);
            if (metamethod != null)
                return context.DynamicCache.GetDynamicCall1()(metamethod, obj);

            throw LuaRuntimeException.Create(context, ExceptionMessage.OP_TYPE_ERROR, "get length of", BaseLibrary.Type(obj));
        }
Beispiel #20
0
 static object GetRelationalMetamethod(CodeContext 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 #21
0
        public static object UnaryMinusMetamethod(CodeContext context, object obj)
        {
            ContractUtils.RequiresNotNull(context, "context");

            var metamethod = GetMetamethod(context, obj, Constant.UNARYMINUS_METAMETHOD);
            if (metamethod != null)
                return context.DynamicCache.GetDynamicCall1()(metamethod, obj);

            throw LuaRuntimeException.Create(context, ExceptionMessage.OP_TYPE_ERROR, "perform arithmetic on", BaseLibrary.Type(obj));
        }
Beispiel #22
0
        public static object RelationalMetamethod(CodeContext context, ExprType op, object left, object right)
        {
            ContractUtils.RequiresNotNull(context, "context");

            var leftTypeName = BaseLibrary.Type(left);
            var rightTypeName = BaseLibrary.Type(right);

            //if (left.GetType() != right.GetType())
            //    throw LuaRuntimeException.Create(ExceptionMessage.OP_TYPE_WITH_ERROR, "compare", leftTypeName, rightTypeName);

            // 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)
                    return context.DynamicCache.GetDynamicCall2()(metamethod, right, left);
                else
                    return 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)
                throw LuaRuntimeException.Create(context, ExceptionMessage.OP_TYPE_WITH_ERROR, "compare", leftTypeName, rightTypeName);

            metamethod = GetRelationalMetamethod(context, ExprType.LessThan, left, right);
            if (metamethod != null)
            {
                if (invert)
                    return Not(context.DynamicCache.GetDynamicCall2()(metamethod, right, left));
                else
                    return Not(context.DynamicCache.GetDynamicCall2()(metamethod, left, right));
            }

            if (leftTypeName == rightTypeName)
                throw LuaRuntimeException.Create(context, ExceptionMessage.OP_TYPE_TWO_ERROR, "compare", leftTypeName);
            throw LuaRuntimeException.Create(context, ExceptionMessage.OP_TYPE_WITH_ERROR, "compare", leftTypeName, rightTypeName);
        }
 public static Expr Call(CodeContext context, DynamicMetaObject target, DynamicMetaObject[] args)
 {
     return Call(Expr.Constant(context, typeof(CodeContext)), target, args);
 }
Beispiel #24
0
 public static Expr CheckNumberForNan(CodeContext context, Expr number, string format, params object[] args)
 {
     return Expr.IfThen(
         Expr.Invoke(Expr.Constant((Func<double, bool>)Double.IsNaN), number),
         Expr.Throw(Expr.New(MemberInfos.NewRuntimeException, Expr.Constant(context), Expr.Constant(format), Expr.Constant(args))));
 }
 public static Expr Index(CodeContext context, DynamicMetaObject target, DynamicMetaObject[] indexes)
 {
     return Index(Expr.Constant(context, typeof(CodeContext)), target, indexes);
 }
Beispiel #26
0
 public static Expr ConvertToBoolean(CodeContext context, Expr expression)
 {
     var convertBinder = context.CreateConvertBinder(typeof(bool), false);
     return Expr.Dynamic(convertBinder, typeof(bool), expression);
 }
Beispiel #27
0
        internal LuaTable GenerateMetatable(CodeContext context)
        {
            LuaTable table = new LuaTable(context);
            table.SetConstant(Constant.INDEX_METAMETHOD, (Func<object, object, object>)InteropIndex);
            table.SetConstant(Constant.NEWINDEX_METAMETHOD, (Func<object, object, object, object>)InteropNewIndex);
            table.SetConstant(Constant.CALL_METAMETHOD, (Func<object, object[], object>)InteropCall);
            table.SetConstant(Constant.CONCAT_METAMETHOD, (Func<string, object, string>)Concat);
            table.SetConstant(Constant.TOSTRING_METAFIELD, (Func<object, string>)ToString);
            table.SetConstant(Constant.LENGTH_METAMETHOD, (Func<object, object>)InteropLength);

            return table;
        }
Beispiel #28
0
 public static Expr ConvertToNumber(CodeContext context, Expr expression)
 {
     var convertBinder = context.CreateConvertBinder(typeof(double), false);
     return Expr.Dynamic(convertBinder, typeof(double), expression);
 }
Beispiel #29
0
 public OSLibrary(CodeContext context)
     : base(context)
 {
 }
Beispiel #30
0
        public static object NumericMetamethod(CodeContext context, ExprType op, object left, object right)
        {
            ContractUtils.RequiresNotNull(context, "context");

            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(context, left) == null ? left : right);
            throw LuaRuntimeException.Create(context, ExceptionMessage.OP_TYPE_ERROR, "perform arithmetic on", typeName);
        }