Esempio n. 1
0
        internal static dynamic Range(Expression startExpr, Expression endExpr, bool inclusive)
        {
            var start = (int)(CompilerServices.CreateLambdaForExpression(startExpr) ());
            var end   = (int)(CompilerServices.CreateLambdaForExpression(endExpr) ());

            return(new KumaRange(start, end, inclusive));
        }
Esempio n. 2
0
        internal static dynamic CreateArray(List <Expression> values)
        {
            var list = new List <object>();

            values.ForEach(value => list.Add(CompilerServices.CreateLambdaForExpression(value)()));
            return(new KumaArray(list));
        }
        protected override Expression VisitVariable(VariableExpression node)
        {
            var name = CompilerServices.CreateLambdaForExpression(node.Name)();

            if (name is string)
            {
                _variableNames.Add(name);
            }
            return(node);
        }
Esempio n. 4
0
        internal static dynamic CreateDictionary(IEnumerable <Expression> values)
        {
            var dict = new Dictionary <object, object>();

            foreach (var val in values.Select(_val => CompilerServices.CreateLambdaForExpression(_val)()))
            {
                dict[((KeyValuePair <object, object>)val).Key] = ((KeyValuePair <object, object>)val).Value;
            }
            return(new KumaDictionary(dict));
        }
        public override object Run(Scope scope)
        {
            var body = (Body as BlockExpression);

            body.Scope.MergeWithScope(Kuma.Globals);
            body.Scope.MergeWithScope(scope);

            var visitor = new VariableNameVisitor();

            visitor.Visit(body);

            body.SetChildrenScopes(body.Scope);

            var block = CompilerServices.CreateLambdaForExpression(body);
            var res   = block();

            if (res is Symbol)
            {
                var symval = new BlockExpression(new List <Expression> {
                    new VariableExpression(res)
                }, body.Scope);
                res = CompilerServices.CreateLambdaForExpression(symval)();
            }
            else if (res is KumaInstance)
            {
                var so = (KumaInstance)res;
                if (so is KumaBoxedInstance)
                {
                    res = ((KumaBoxedInstance)so).BoxedObject;
                }
            }
            else if (res is KumaNumber)
            {
                res = KumaNumber.Convert(res);
            }
            else if (res is KumaString)
            {
                res = (string)res;
            }
            else if (res is KumaArray)
            {
                res = ConvertElements((KumaArray)res);
            }
            else if (res is KumaDictionary)
            {
                res = ConvertElements((KumaDictionary)res);
            }

            body.Scope.MergeIntoScope(scope);

            return(res);
        }
        internal object Run(KumaScope scope)
        {
            var body = (BlockExpression)Body;

            body.SetScope(scope);

            body.SetChildrenScopes(body.Scope);

            var block = CompilerServices.CreateLambdaForExpression(Expression.Block(body));

            var res = block();

            if (res is Symbol)
            {
                var symval = new BlockExpression(new List <Expression> {
                    new VariableExpression(res)
                }, body.Scope);
                res = CompilerServices.CreateLambdaForExpression(symval)();
            }

            return(res);
        }
Esempio n. 7
0
 private static dynamic Dynamic(Type returnType, CallSiteBinder binder, IEnumerable <Expression> args)
 {
     return(CompilerServices.CreateLambdaForExpression(Expression.Dynamic(binder, returnType, args.ToArray()))());
 }
        private bool CheckForMatch(KumaNativeFunction function, List <FunctionArgument> args)
        {
            if (function.Arguments.Count == args.Count)
            {
                var _args = new List <object>();
                args.ForEach(arg => {
                    var val = CompilerServices.CreateLambdaForExpression(arg.Value)();
                    if (val is KumaString)
                    {
                        val = (string)val;
                    }
                    if (val is KumaNumber)
                    {
                        val = KumaNumber.Convert((KumaNumber)val);
                    }
                    _args.Add(val);
                });
                var match = true;
                var i     = 0;
                foreach (var param in function.Method.GetParameters())
                {
                    if (_args[i++].GetType() != param.ParameterType)
                    {
                        match = false;
                        break;
                    }
                }
                return(match);
            }
            if (args.Count > function.Arguments.Count)
            {
                if (function.Arguments.Any() && function.Arguments.Last().IsVarArg)
                {
                    return(true);
                }
                return(false);
            }
            var myCount    = args.Count;
            var theirCount = function.Arguments.Count;

            function.Arguments.ForEach(arg => {
                if (arg.HasDefault)
                {
                    theirCount--;
                }
            });
            var vo = 0;

            if (function.Arguments.Any() && function.Arguments.Last().IsVarArg)
            {
                vo = 1;
            }
            if (myCount == theirCount)
            {
                return(true);
            }
            if (myCount + vo == theirCount)
            {
                return(true);
            }
            return(false);
        }
Esempio n. 9
0
        internal static dynamic Assign(VariableExpression @var, dynamic value, E type, bool isConst, object rawScope)
        {
            var scope = (KumaScope)rawScope;
            var map   = new Dictionary <ExpressionType, ExpressionType> ();

            map[E.AddAssign]         = E.Add;
            map[E.AndAssign]         = E.And;
            map[E.DivideAssign]      = E.Divide;
            map[E.ExclusiveOrAssign] = E.ExclusiveOr;
            map[E.LeftShiftAssign]   = E.LeftShift;
            map[E.ModuloAssign]      = E.Modulo;
            map[E.MultiplyAssign]    = E.Multiply;
            map[E.OrAssign]          = E.Or;
            map[E.PowerAssign]       = E.Power;
            map[E.RightShiftAssign]  = E.RightShift;
            map[E.SubtractAssign]    = E.Subtract;

            var incDecMap = new List <ExpressionType> {
                E.PreIncrementAssign,
                E.PreDecrementAssign,
                E.PostIncrementAssign,
                E.PostDecrementAssign
            };

            if (@var.Name is InstanceReferenceExpression)
            {
                var iref = CompilerServices.CompileExpression(@var.Name as InstanceReferenceExpression, scope);
                var lval = CompilerServices.CompileExpression(iref.LValue, scope);
                if (map.ContainsKey(type))
                {
                    value =
                        CompilerServices.CreateLambdaForExpression(
                            KumaExpression.Binary(
                                Expression.Constant(Resolve(CompilerServices.CompileExpression(iref, scope), scope)),
                                Expression.Constant(value), map[type])) ();
                }
                if (incDecMap.Contains(type))
                {
                    var gmArgs = new List <Expression> ();
                    gmArgs.Add(Expression.Constant(lval, typeof(object)));
                    if (type == E.PreIncrementAssign || type == E.PreDecrementAssign)
                    {
                        var val = Resolve(CompilerServices.CompileExpression(iref, scope), scope);
                        Assign(@var, 1, type == E.PreIncrementAssign ? E.AddAssign : E.SubtractAssign, false, rawScope);
                        return(val);
                    }
                    Assign(@var, 1, type == E.PostIncrementAssign ? E.AddAssign : E.SubtractAssign, false, rawScope);
                    return(Resolve(CompilerServices.CompileExpression(iref, scope), scope));
                }

                var smArgs = new List <Expression> ();
                smArgs.Add(Expression.Constant(lval, typeof(object)));
                smArgs.Add(Expression.Constant(value, typeof(object)));
                return(Dynamic(typeof(object), new InteropBinder.SetMember(iref.Key, scope), smArgs));
            }
            if (@var.HasSym)
            {
                var sym = @var.Sym;

                var symFound = false;
                while (scope.ParentScope != null)
                {
                    scope = scope.ParentScope;
                    if (scope[sym] != null)
                    {
                        symFound = true;
                        break;
                    }
                }
                if (!symFound)
                {
                    scope = (KumaScope)rawScope;
                }

                if (map.ContainsKey(type))
                {
                    var nvalue =
                        CompilerServices.CreateLambdaForExpression(
                            KumaExpression.Binary(Expression.Constant(ResolveSymbol(sym, scope)),
                                                  Expression.Constant(value), map[type])) ();
                    scope[sym] = nvalue;
                    return(nvalue);
                }

                if (incDecMap.Contains(type))
                {
                    if (type == E.PreIncrementAssign || type == E.PreDecrementAssign)
                    {
                        var val = ResolveSymbol(sym, scope);
                        Assign(@var, 1, type == E.PreIncrementAssign ? E.AddAssign : E.SubtractAssign, false, rawScope);
                        return(val);
                    }
                    Assign(@var, 1, type == E.PostIncrementAssign ? E.AddAssign : E.SubtractAssign, false, rawScope);
                    return(ResolveSymbol(sym, scope));
                }

                scope[sym] = value;
                if (isConst)
                {
                    scope.Constants.Add(sym.Name);
                }
                return(value);
            }
            string name = CompilerServices.CompileExpression(@var.Name, scope);

            if (name.StartsWith("$") && name != "$:")
            {
                scope = scope.GlobalScope;
                name  = name.Substring(1);
            }
            var found = false;

            if (name.StartsWith("@"))
            {
                if (scope["<kuma_context_invokemember>"] != null)
                {
                    var ivar =
                        KumaExpression.Variable(
                            KumaExpression.InstanceRef(KumaExpression.Variable(Expression.Constant("self")),
                                                       Expression.Constant(name.Substring(1))));
                    if (map.ContainsKey(type))
                    {
                        value =
                            CompilerServices.CreateLambdaForExpression(
                                KumaExpression.Binary(ivar, Expression.Constant(value), map[type])) ();
                    }
                    var assn = KumaExpression.Assign(KumaExpression.LeftHandValue(ivar), Expression.Constant(value));
                    return(CompilerServices.CompileExpression(assn, scope));
                }
                found = true;
                name  = name.Substring(1);
            }
            if (name == "self")
            {
                if (scope["<kuma_context_selfname>"] != null &&
                    scope["<kuma_context_selfscope>"] != null &&
                    scope["<kuma_context_invokemember>"] != null)
                {
                    name  = scope["<kuma_context_selfname>"];
                    scope = scope["<kuma_context_selfscope>"];
                    found = true;
                }
            }
            while (scope.ParentScope != null && !found)
            {
                scope = scope.ParentScope;
                if (scope[name] != null)
                {
                    found = true;
                    break;
                }
            }
            if (!found)
            {
                scope = (KumaScope)rawScope;
            }

            if (map.ContainsKey(type))
            {
                var nvalue =
                    CompilerServices.CreateLambdaForExpression(
                        KumaExpression.Binary(Expression.Constant(Resolve(name, scope)), Expression.Constant(value),
                                              map[type])) ();
                scope[name] = nvalue;
                return(nvalue);
            }

            if (incDecMap.Contains(type))
            {
                if (type == E.PostIncrementAssign || type == E.PostDecrementAssign)
                {
                    var val = Resolve(name, scope);
                    Assign(@var, 1, type == E.PostIncrementAssign ? E.AddAssign : E.SubtractAssign, false, rawScope);
                    return(val);
                }
                Assign(@var, 1, type == E.PreIncrementAssign ? E.AddAssign : E.SubtractAssign, false, rawScope);
                return(Resolve(name, scope));
            }

            scope[name] = value;
            if (isConst)
            {
                scope.Constants.Add(name);
            }
            return(value);
        }
Esempio n. 10
0
        internal static dynamic AccessSet(object container, List <FunctionArgument> args, object value, E type,
                                          object rawScope)
        {
            var map = new Dictionary <ExpressionType, ExpressionType>();

            map[E.AddAssign]         = E.Add;
            map[E.AndAssign]         = E.And;
            map[E.DivideAssign]      = E.Divide;
            map[E.ExclusiveOrAssign] = E.ExclusiveOr;
            map[E.LeftShiftAssign]   = E.LeftShift;
            map[E.ModuloAssign]      = E.Modulo;
            map[E.MultiplyAssign]    = E.Multiply;
            map[E.OrAssign]          = E.Or;
            map[E.PowerAssign]       = E.Power;
            map[E.RightShiftAssign]  = E.RightShift;
            map[E.SubtractAssign]    = E.Subtract;

            var incDecMap = new List <ExpressionType> {
                E.PreIncrementAssign,
                E.PreDecrementAssign,
                E.PostIncrementAssign,
                E.PostDecrementAssign
            };

            var names = new List <string>();

            for (var i = 0; i < args.Count; i++)
            {
                names.Add(string.Format("index{0}", i));
            }

            var scope    = rawScope as KumaScope;
            var realArgs = new List <object>();

            args.ForEach(arg => realArgs.Add(CompilerServices.CompileExpression(arg.Value, scope)));


            if (map.ContainsKey(type))
            {
                var nvalue =
                    CompilerServices.CreateLambdaForExpression(
                        KumaExpression.Binary(Expression.Constant(Access(container, args, scope)),
                                              Expression.Constant(value),
                                              map[type]))();
                value = nvalue;
            }

            if (incDecMap.Contains(type))
            {
                if (type == E.PostIncrementAssign || type == E.PostDecrementAssign)
                {
                    var val = Access(container, args, scope);
                    AccessSet(container, args, 1, type == E.PostIncrementAssign ? E.AddAssign : E.SubtractAssign,
                              rawScope);
                    return(val);
                }
                AccessSet(container, args, 1, type == E.PreIncrementAssign ? E.AddAssign : E.SubtractAssign, rawScope);
                return(Access(container, args, scope));
            }

            var eArgs = new List <Expression>();

            eArgs.Add(Expression.Constant(container, typeof(object)));
            realArgs.ForEach(arg => eArgs.Add(Expression.Constant(arg)));
            eArgs.Add(Expression.Constant(value, typeof(object)));
            return(Dynamic(typeof(object),
                           new InteropBinder.SetIndex(scope, new CallInfo(args.Count, names)), eArgs));
        }