Exemplo n.º 1
0
        internal static dynamic Throw(Expression rawObjExpr, object rawScope)
        {
            var scope  = rawScope as NovaScope ?? new NovaScope();
            var rawObj = CompilerServices.CompileExpression(rawObjExpr, scope);

            var obj = rawObj as NovaInstance;

            if (obj == null)
            {
                throw new Exception();
            }
            var instance = obj as NovaBoxedInstance;

            if (instance == null)
            {
                throw new NovaException(obj);
            }
            var exc = instance.BoxedObject as Exception;

            if (exc != null)
            {
                throw exc;
            }
            throw new Exception();
        }
Exemplo n.º 2
0
        internal static dynamic Switch(object rawTest, List <SwitchCase> cases, object rawDefaultBlock, object rawScope)
        {
            var test         = (Expression)rawTest;
            var defaultBlock = rawDefaultBlock != null
                ? (Expression)rawDefaultBlock
                : NovaExpression.NovaBlock(NovaExpression.Default(cases.First().Body.Type));
            var scope = (NovaScope)rawScope;

            dynamic retVal = null;

            var found = false;
            var tval  = CompilerServices.CompileExpression(test, scope);

            foreach (var @case in cases.Where(@case => @case.TestValues.Select(testValue => CompilerServices.CompileExpression(testValue, scope))
                                              .Any(xval => Binary(tval, xval, E.Equal, scope))))
            {
                found  = true;
                retVal = CompilerServices.CompileExpression(@case.Body, scope);
            }

            if (!found)
            {
                retVal = CompilerServices.CompileExpression(defaultBlock, scope);
            }

            return(retVal);
        }
Exemplo n.º 3
0
        internal static dynamic DefineClassOpen(object rawValue, List <Expression> contents, object rawScope)
        {
            var scope = (NovaScope)rawScope;

            var value = CompilerServices.CompileExpression((Expression)rawValue, scope);

            if (value == null)
            {
                return(null);
            }

            var @class = value as NovaClass;

            if (@class != null)
            {
                return(DefineCategory(@class, contents, scope));
            }
            var instance = value as NovaInstance;

            if (instance != null)
            {
                return(DefineCategory(instance.Class, contents, scope));
            }
            var newVal = Nova.Box(value);

            return(DefineCategory(((NovaInstance)newVal).Class, contents, scope));
        }
        internal static dynamic CreateArray(List <Expression> values)
        {
            var list = new List <object>();

            values.ForEach(value => list.Add(CompilerServices.CreateLambdaForExpression(value)()));
            return(new NovaArray(list));
        }
        internal static dynamic Resolve(object rawName, object rawScope)
        {
            if (rawName.GetType() == typeof(InstanceReference))
            {
                var iref   = (InstanceReference)rawName;
                var lval   = CompilerServices.CompileExpression(iref.LValue, (NovaScope)rawScope);
                var gmArgs = new List <Expression>();
                gmArgs.Add(Expression.Constant(lval, typeof(object)));
                return(Dynamic(typeof(object), new InteropBinder.GetMember(iref.Key, (NovaScope)rawScope), gmArgs));
            }
            var name  = (string)rawName;
            var scope = (NovaScope)rawScope;

            if (name.StartsWith("$") && name != "$:")
            {
                scope = scope.GlobalScope;
                name  = name.Substring(1);
            }
            if (name.StartsWith("@") && scope["<nova_context_invokemember>"] != null)
            {
                if (name.StartsWith("@@"))
                {
                    var _val = Resolve("self", scope);
                    if (!(_val is NovaInstance))
                    {
                        // native object?
                        _val = Nova.Box((object)_val, scope);
                    }
                    var @class = ((NovaInstance)_val).Class;
                    return
                        (CompilerServices.CompileExpression(
                             NovaExpression.Variable(NovaExpression.InstanceRef(Expression.Constant(@class),
                                                                                Expression.Constant(name.Substring(2)))), scope));
                }
                return
                    (CompilerServices.CompileExpression(
                         NovaExpression.Variable(
                             NovaExpression.InstanceRef(NovaExpression.Variable(Expression.Constant("self")),
                                                        Expression.Constant(name.Substring(1)))), scope));
            }

            var val = scope[name];

            // The cast is needed here because if we get a non-nullable type (such as System.Int32) the check here will throw an exception.
            // By casting to System.Object we can avoid the exception since it is a boxed value that can be null.
            if ((object)val == null)
            {
                Type type;
                if ((type = NovaTypeResolver.Resolve(name)) != null)
                {
                    var @class = NovaClass.BoxClass(type);
                    scope.GlobalScope[@class.Name] = @class;
                    val = @class;
                }
            }
            return(val);
        }
        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 NovaDictionary(dict));
        }
Exemplo n.º 7
0
        protected override Expression VisitVariable(VariableExpression node)
        {
            var name = CompilerServices.CreateLambdaForExpression(node.Name)();

            if (name is string)
            {
                _variableNames.Add(name);
            }
            return(node);
        }
Exemplo n.º 8
0
        internal static dynamic Yield(object function, List <FunctionArgument> values, object scope)
        {
            if (!(function is MulticastDelegate))
            {
                return(Call(function, values, scope, NovaExpressionType.Empty, false, false));
            }
            var p = new List <object>();

            values.ForEach(val => p.Add(CompilerServices.CompileExpression(val.Value, scope as NovaScope)));
            return(GenDelegate(function, p, scope));
        }
Exemplo n.º 9
0
        internal static dynamic Invoke(Type targetType, MethodBase minfo, List <FunctionArgument> args,
                                       NovaScope scope)
        {
            var isClassMethod = minfo.IsStatic;

            object target = scope.Variables.ContainsKey("self")
                ? scope["self"]
                : isClassMethod ? targetType : targetType.GetConstructor(new Type[] {}).Invoke(null);

            var arguments = new List <object>();

            args.ForEach(arg => {
                var _val = CompilerServices.CompileExpression(arg.Value, scope);
                if (_val is NovaString)
                {
                    _val = (string)_val;
                }
                if (_val is NovaNumber)
                {
                    _val = NovaNumber.Convert((NovaNumber)_val);
                }
                arguments.Add(_val);
            });

            while (arguments.Count < minfo.GetParameters().Count())
            {
                arguments.Add(null);
            }

            if (minfo.IsConstructor)
            {
                var ctor = (ConstructorInfo)minfo;
                return(ctor.Invoke(arguments.ToArray()));
            }

            if (target is NovaInstance && !(target is NovaBoxedInstance) &&
                ((NovaInstance)target).BackingObject != null)
            {
                target = ((NovaInstance)target).BackingObject;
            }

            dynamic val = null;

            if (((MethodInfo)minfo).ReturnType != typeof(void))
            {
                val = minfo.Invoke(target, arguments.ToArray());
            }
            else
            {
                minfo.Invoke(target, arguments.ToArray());
            }

            return(val);
        }
Exemplo n.º 10
0
        public override object Run(Scope scope)
        {
            var body = (Body as BlockExpression);

            body.Scope.MergeWithScope(Nova.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 NovaInstance)
            {
                var so = (NovaInstance)res;
                if (so is NovaBoxedInstance)
                {
                    res = ((NovaBoxedInstance)so).BoxedObject;
                }
            }
            else if (res is NovaNumber)
            {
                res = NovaNumber.Convert(res);
            }
            else if (res is NovaString)
            {
                res = (string)res;
            }
            else if (res is NovaArray)
            {
                res = ConvertElements((NovaArray)res);
            }
            else if (res is NovaDictionary)
            {
                res = ConvertElements((NovaDictionary)res);
            }

            body.Scope.MergeIntoScope(scope);

            return(res);
        }
Exemplo n.º 11
0
        internal static dynamic ObjectMethodChange(object rawSelf, object rawName, bool isRemove, object rawScope)
        {
            var scope = (NovaScope)rawScope;
            var name  = (string)rawName;

            var self = CompilerServices.CompileExpression((Expression)rawSelf, scope);

            var @class = self as NovaClass;

            if (@class != null)
            {
                if (isRemove)
                {
                    @class.RemovedMethods.Add(name);
                }
                else
                {
                    @class.UndefinedMethods.Add(name);
                }
            }
            else
            {
                var instance = self as NovaInstance;
                if (instance != null)
                {
                    if (isRemove)
                    {
                        instance.RemovedMethods.Add(name);
                    }
                    else
                    {
                        instance.UndefinedMethods.Add(name);
                    }
                }
                else
                {
                    var newVal = Nova.Box(self);
                    if (isRemove)
                    {
                        ((NovaInstance)newVal).RemovedMethods.Add(name);
                    }
                    else
                    {
                        ((NovaInstance)newVal).UndefinedMethods.Add(name);
                    }
                }
            }


            return(null);
        }
Exemplo n.º 12
0
        internal static dynamic Sync(object rawName, object rawBlock, object rawScope)
        {
            var varName = (string)rawName;
            var block   = (Expression)rawBlock;
            var scope   = (NovaScope)rawScope;

            var var = scope[varName];

            dynamic retVal = null;

            lock (var)
            {
                retVal = CompilerServices.CompileExpression(block, scope);
            }

            return(retVal);
        }
        internal static dynamic Access(object container, List <FunctionArgument> args, object rawScope)
        {
            var names = new List <string>();

            for (var i = 0; i < args.Count; i++)
            {
                names.Add(string.Format("index{0}", i));
            }
            var scope    = rawScope as NovaScope;
            var realArgs = new List <object>();

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

            var eArgs = new List <Expression>();

            eArgs.Add(Expression.Constant(container, typeof(object)));
            realArgs.ForEach(arg => eArgs.Add(Expression.Constant(arg)));
            return(Dynamic(typeof(object),
                           new InteropBinder.GetIndex(scope, new CallInfo(args.Count, names)), eArgs));
        }
Exemplo n.º 14
0
        internal static dynamic DefineModule(object rawName, List <Expression> contents, object rawScope)
        {
            lock (_classDefineLock) {
                var scope       = (NovaScope)rawScope;
                var defineScope = _inClassDefine ? scope : scope.GlobalScope;

                var name = (string)rawName;

                var xScope = new NovaScope(scope);

                var module = new NovaModule {
                    Name = name, Context = scope
                };

                contents.ForEach(content => module.Contents.Add(CompilerServices.CompileExpression(content, xScope)));

                defineScope[module.Name] = module;

                return(module);
            }
        }
        internal static dynamic ConditionalAssign(VariableExpression @var, dynamic value, NovaExpressionType conditionalAssignmentType, bool isConst,
                                                  object rawScope)
        {
            var scope = rawScope as NovaScope;
            var v     = Resolve(CompilerServices.CompileExpression(@var.Name, scope), scope);

            if (Boolean(v))
            {
                if (conditionalAssignmentType == NovaExpressionType.IfNotNullAssign)
                {
                    return(Assign(@var, value, E.Assign, isConst, scope));
                }
            }
            else
            {
                if (conditionalAssignmentType == NovaExpressionType.IfNullAssign)
                {
                    return(Assign(@var, value, E.Assign, isConst, scope));
                }
            }
            return(v);
        }
Exemplo n.º 16
0
        internal object Run(NovaScope 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);
        }
Exemplo n.º 17
0
        internal static dynamic DefineCategory(NovaClass @class, List <Expression> contents, object rawScope)
        {
            lock (_classDefineLock) {
                var scope = (NovaScope)rawScope;
                _inClassDefine = true;
                _className     = @class.Name;

                scope["self"]      = @class;
                scope[_className]  = @class;
                _currentClassScope = scope;

                contents.ForEach(content => {
                    if (content is IncludeExpression)
                    {
                        // We only include modules here so make sure this include references a module
                        var names = ((IncludeExpression)content).Names;

                        dynamic module = null;

                        var index = 0;
                        names.ForEach(mname => {
                            if (module != null && (module is NovaModule))
                            {
                                module = module.Context[mname];
                            }
                            else if (index == 0)
                            {
                                module = scope[mname];
                            }
                            index = index + 1;
                        });

                        if (module != null)
                        {
                            if (module is NovaModule)
                            {
                                ((NovaModule)module).Contents.ForEach(mcon => {
                                    if (mcon is NovaFunction)
                                    {
                                        if ((mcon as NovaFunction).IsSingleton ||
                                            (mcon as NovaFunction).Name == "new")
                                        {
                                            NovaClass.AddMethod(@class.ClassMethods, mcon as NovaFunction);
                                        }
                                        else
                                        {
                                            NovaClass.AddMethod(@class.InstanceMethods, mcon as NovaFunction);
                                        }
                                        if (@class.RemovedMethods.Contains((mcon as NovaFunction).Name))
                                        {
                                            @class.RemovedMethods.Remove((mcon as NovaFunction).Name);
                                        }
                                        if (@class.UndefinedMethods.Contains((mcon as NovaFunction).Name))
                                        {
                                            @class.UndefinedMethods.Remove((mcon as NovaFunction).Name);
                                        }
                                    }
                                });

                                scope.MergeWithScope(module.Context);
                            }
                            else if (module is NovaClass)
                            {
                                scope[((NovaClass)module).Name] = module;
                            }
                        }
                    }
                });

                contents.ForEach(content => {
                    if (!(content is IncludeExpression))
                    {
                        var result = CompilerServices.CompileExpression(content, scope);
                        if (result is NovaFunction)
                        {
                            if ((result as NovaFunction).IsSingleton)
                            {
                                NovaClass.AddMethod(@class.ClassMethods, result as NovaFunction);
                            }
                            else
                            {
                                NovaClass.AddMethod(@class.InstanceMethods, result as NovaFunction);
                            }
                            if (@class.RemovedMethods.Contains((result as NovaFunction).Name))
                            {
                                @class.RemovedMethods.Remove((result as NovaFunction).Name);
                            }
                            if (@class.UndefinedMethods.Contains((result as NovaFunction).Name))
                            {
                                @class.UndefinedMethods.Remove((result as NovaFunction).Name);
                            }
                        }
                    }
                });

                @class.Context.MergeWithScope(scope);
                return(@class);
            }
        }
Exemplo n.º 18
0
 private static dynamic Dynamic(Type returnType, CallSiteBinder binder, IEnumerable <Expression> args)
 {
     return(CompilerServices.CreateLambdaForExpression(Expression.Dynamic(binder, returnType, args.ToArray()))());
 }
Exemplo n.º 19
0
        private bool CheckForMatch(NovaNativeFunction 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 NovaString)
                    {
                        val = (string)val;
                    }
                    if (val is NovaNumber)
                    {
                        val = NovaNumber.Convert((NovaNumber)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);
        }
Exemplo n.º 20
0
        internal static dynamic Begin(object rawTryExpression, List <Expression> rescueBlocksRaw,
                                      object rawEnsureBlock, object rawElseBlock, object rawScope)
        {
            var     tryExpression   = (Expression)rawTryExpression;
            var     ensureBlock     = (Expression)rawEnsureBlock;
            var     elseBlock       = (Expression)rawElseBlock;
            var     scope           = (NovaScope)rawScope;
            dynamic retVal          = null;
            var     exceptionRaised = false;
            var     ensureRun       = false;
            var     rescueBlocks    = new List <RescueExpression>();

            rescueBlocksRaw.ForEach(
                rawBlock =>
            {
                var block = rawBlock as RescueExpression;
                if (block != null)
                {
                    rescueBlocks.Add(block);
                }
            });

            try
            {
                retVal = CompilerServices.CompileExpression(tryExpression, scope);
            }
            catch (Exception e)
            {
                var NovaException = e as NovaException;
                var exType        = NovaException != null ? NovaException.ExceptionClass.Name : e.GetType().Name;
                var found         = false;
                exceptionRaised = true;
                foreach (var rescueBlock in rescueBlocks)
                {
                    var exceptionTypes = new List <string>();
                    if (!rescueBlock.IsWildcard)
                    {
                        foreach (var type in rescueBlock.ExceptionTypes)
                        {
                            var obj      = Resolve(type, scope);
                            var instance = obj as NovaInstance;
                            if (instance != null)
                            {
                                exceptionTypes.Add(instance.Class.Name);
                            }
                            else
                            {
                                var @class = obj as NovaClass;
                                if (@class != null)
                                {
                                    exceptionTypes.Add(@class.Name);
                                }
                                var s = obj as string;
                                if (s != null)
                                {
                                    exceptionTypes.Add(s);
                                }
                                var ss = obj as NovaString;
                                if (ss != null)
                                {
                                    exceptionTypes.Add(ss);
                                }
                            }
                        }
                    }
                    var exMatches = rescueBlock.IsWildcard;
                    if (!exMatches)
                    {
                        if ((from type in exceptionTypes select NovaTypeResolver.Resolve(type) into _exType where _exType != null let __exType = NovaTypeResolver.Resolve(exType) where __exType != null && __exType.IsSubclassOf(_exType) || __exType == _exType select _exType).Any())
                        {
                            exMatches = true;
                        }
                    }
                    found = exMatches;
                    if (!found)
                    {
                        if (exceptionTypes.Contains(exType))
                        {
                            found = true;
                        }
                        else
                        {
                            continue;
                        }
                    }
                    var exception = e as NovaException;
                    if (exception != null)
                    {
                        scope[rescueBlock.VarName] = exception.InnerObject;
                    }
                    else
                    {
                        scope[rescueBlock.VarName] = e;
                    }
                    try
                    {
                        retVal = CompilerServices.CompileExpression(rescueBlock.Body, scope);
                    }
                    catch (Exception)
                    {
                        if (ensureBlock == null)
                        {
                            throw;
                        }
                        ensureRun = true;
                        CompilerServices.CompileExpression(ensureBlock, scope);
                        throw;
                    }
                    break;
                }
                if (!found)
                {
                    throw;
                }
            }
            finally
            {
                if (!exceptionRaised && elseBlock != null)
                {
                    CompilerServices.CompileExpression(elseBlock, scope);
                }
                if (!ensureRun && ensureBlock != null)
                {
                    CompilerServices.CompileExpression(ensureBlock, scope);
                }
            }
            return(retVal);
        }
Exemplo n.º 21
0
        private static dynamic Match(object rawLeft, object rawRight, NovaExpressionType novaBinaryNodeType, object rawScope)
        {
            var scope = (NovaScope)rawScope;

            var left  = CompilerServices.CompileExpression((Expression)rawLeft, scope);
            var right = CompilerServices.CompileExpression((Expression)rawRight, scope);

            var NovaName = "=~";
            var clrName  = InteropBinder.ToClrOperatorName(NovaName);

            if (left is NovaInstance)
            {
                var lo = (NovaInstance)left;
                DynamicMetaObject dmo = lo.GetMetaObject(Expression.Constant(left));
                if (InteropBinder.InvokeMember.SearchForFunction(lo.Class, NovaName, lo, L(Arg(right)), true) != null)
                {
                    if (novaBinaryNodeType == NovaExpressionType.NotMatch)
                    {
                        return(!dmo.BindInvokeMember(new InteropBinder.InvokeMember(NovaName, new CallInfo(1), scope),
                                                     _DMO(DMO(scope), DMO(Arg(right)))));
                    }
                    return(dmo.BindInvokeMember(new InteropBinder.InvokeMember(NovaName, new CallInfo(1), scope),
                                                _DMO(DMO(scope), DMO(Arg(right)))));
                }
                if (InteropBinder.InvokeMember.SearchForFunction(lo.Class, clrName, lo, L(Arg(right)), true) != null)
                {
                    if (novaBinaryNodeType == NovaExpressionType.NotMatch)
                    {
                        return(!dmo.BindInvokeMember(new InteropBinder.InvokeMember(clrName, new CallInfo(1), scope),
                                                     _DMO(DMO(scope), DMO(Arg(right)))));
                    }
                    return(dmo.BindInvokeMember(new InteropBinder.InvokeMember(clrName, new CallInfo(1), scope),
                                                _DMO(DMO(scope), DMO(Arg(right)))));
                }
            }

            var Value = Nova.Box(left);

            if (Value.Class != null)
            {
                var _dmo = Value.GetMetaObject(Expression.Constant(Value));
                if (InteropBinder.InvokeMember.SearchForFunction(Value.Class, NovaName, Value, L(Arg(right)), true) !=
                    null)
                {
                    if (novaBinaryNodeType == NovaExpressionType.NotMatch)
                    {
                        return(!_dmo.BindInvokeMember(new InteropBinder.InvokeMember(NovaName, new CallInfo(1), scope),
                                                      _DMO(DMO(scope), DMO(Arg(right)))));
                    }
                    return(_dmo.BindInvokeMember(new InteropBinder.InvokeMember(NovaName, new CallInfo(1), scope),
                                                 _DMO(DMO(scope), DMO(Arg(right)))));
                }
                if (InteropBinder.InvokeMember.SearchForFunction(Value.Class, clrName, Value, L(Arg(right)), true) !=
                    null)
                {
                    if (novaBinaryNodeType == NovaExpressionType.NotMatch)
                    {
                        return(!_dmo.BindInvokeMember(new InteropBinder.InvokeMember(clrName, new CallInfo(1), scope),
                                                      _DMO(DMO(scope), DMO(Arg(right)))));
                    }
                    return(_dmo.BindInvokeMember(new InteropBinder.InvokeMember(clrName, new CallInfo(1), scope),
                                                 _DMO(DMO(scope), DMO(Arg(right)))));
                }
            }

            if (!(left is Regex || right is Regex))
            {
                return(null);
            }

            var left1 = left as Regex;
            var regex = left1 ?? (Regex)right;

            var str = (left is Regex) ? (string)right : (string)left;

            if (!regex.Match(str).Success)
            {
                return(novaBinaryNodeType == NovaExpressionType.NotMatch);
            }
            var groups = regex.Match(str).Groups;

            foreach (var groupName in regex.GetGroupNames())
            {
                scope[groupName] = groups[groupName].Value;
            }


            return(novaBinaryNodeType == NovaExpressionType.Match);
        }
Exemplo n.º 22
0
        internal static dynamic SingletonDefine(Expression rawSingleton, object rawName, object rawArguments,
                                                object rawBody, object rawScope)
        {
            var scope = (NovaScope)rawScope;

            var name = (string)rawName;

            var args = (List <FunctionArgument>)rawArguments;

            var body     = (BlockExpression)rawBody;
            var function = new NovaFunction(name, args, body, scope);

            object singleton = CompilerServices.CompileExpression(rawSingleton, scope);

            if ((singleton is NovaClass))
            {
                var @class = (NovaClass)singleton;
                if (_inClassDefine)
                {
                    if (@class.Name == _className)
                    {
                        function.IsSingleton = true;
                        return(function);
                    }
                    NovaClass.AddMethod(@class.InstanceMethods, function);
                    if (@class.RemovedMethods.Contains(name))
                    {
                        @class.RemovedMethods.Remove(name);
                    }
                    if (@class.UndefinedMethods.Contains(name))
                    {
                        @class.UndefinedMethods.Remove(name);
                    }
                }
                else
                {
                    NovaClass.AddMethod(@class.InstanceMethods, function);
                    if (@class.RemovedMethods.Contains(name))
                    {
                        @class.RemovedMethods.Remove(name);
                    }
                    if (@class.UndefinedMethods.Contains(name))
                    {
                        @class.UndefinedMethods.Remove(name);
                    }
                }
            }
            else if (singleton is NovaInstance)
            {
                var @object = (NovaInstance)singleton;
                @object.SingletonMethods[name] = function;
                if (@object.RemovedMethods.Contains(name))
                {
                    @object.RemovedMethods.Remove(name);
                }
                if (@object.UndefinedMethods.Contains(name))
                {
                    @object.UndefinedMethods.Remove(name);
                }
            }

            return(function);
        }
        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 NovaScope;
            var realArgs = new List <object>();

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


            if (map.ContainsKey(type))
            {
                var nvalue =
                    CompilerServices.CreateLambdaForExpression(
                        NovaExpression.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));
        }
        internal static dynamic String(object rawEval, object rawScope)
        {
            StringBuilder @new;
            var           eval = rawEval as String;

            var components = eval.Split(new[] { "#{" }, StringSplitOptions.None);

            if (components.Count() == 1)
            {
                return(new NovaString(eval));
            }
            @new = new StringBuilder(components[0]);
            for (var i = 1; i < components.Count(); i++)
            {
                var parts        = components[i].Split(new[] { "}" }, StringSplitOptions.None);
                var expression   = parts[0];
                var escapeString = false;
                if (expression != null && expression[0] == ':')
                {
                    escapeString = true;
                    expression   = expression.Substring(1);
                }
                if (expression != null)
                {
                    var scope       = (NovaScope)rawScope;
                    var xexpression = string.Format("{0};", expression);

                    var        res = NovaParser.Parse(xexpression);
                    Expression block;
                    if (res != null)
                    {
                        block = NovaExpression.NovaBlock(res);
                    }
                    else
                    {
                        return(null);
                    }
                    var myScope = new NovaScope();
                    var visitor = new VariableNameVisitor();
                    visitor.Visit(block);
                    visitor.VariableNames.ForEach(name => myScope[name] = scope[name]);
                    var val = CompilerServices.CompileExpression(block, myScope);
                    if (val != null)
                    {
                        string stringVal = val.ToString();
                        if (escapeString && val is string)
                        {
                            stringVal = string.Format("\"{0}\"", stringVal);
                        }
                        @new.Append(stringVal ?? "");
                    }
                    else
                    {
                        @new.Append(expression);
                    }
                }
                if (parts.Count() > 1)
                {
                    @new.Append(parts[1]);
                    var j = 2;
                    while (j < parts.Count())
                    {
                        @new.Append("}");
                        @new.Append(parts[j++]);
                    }
                }
            }

            return(new NovaString(@new.ToString()));
        }
        internal static dynamic Assign(VariableExpression @var, dynamic value, E type, bool isConst, object rawScope)
        {
            var scope = (NovaScope)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(
                            NovaExpression.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 = (NovaScope)rawScope;
                }

                if (map.ContainsKey(type))
                {
                    var nvalue =
                        CompilerServices.CreateLambdaForExpression(
                            NovaExpression.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["<nova_context_invokemember>"] != null)
                {
                    var ivar =
                        NovaExpression.Variable(
                            NovaExpression.InstanceRef(NovaExpression.Variable(Expression.Constant("self")),
                                                       Expression.Constant(name.Substring(1))));
                    if (map.ContainsKey(type))
                    {
                        value =
                            CompilerServices.CreateLambdaForExpression(
                                NovaExpression.Binary(ivar, Expression.Constant(value), map[type]))();
                    }
                    var assn = NovaExpression.Assign(NovaExpression.LeftHandValue(ivar), Expression.Constant(value));
                    return(CompilerServices.CompileExpression(assn, scope));
                }
                found = true;
                name  = name.Substring(1);
            }
            if (name == "self")
            {
                if (scope["<nova_context_selfname>"] != null &&
                    scope["<nova_context_selfscope>"] != null &&
                    scope["<nova_context_invokemember>"] != null)
                {
                    name  = scope["<nova_context_selfname>"];
                    scope = scope["<nova_context_selfscope>"];
                    found = true;
                }
            }
            while (scope.ParentScope != null && !found)
            {
                scope = scope.ParentScope;
                if (scope[name] != null)
                {
                    found = true;
                    break;
                }
            }
            if (!found)
            {
                scope = (NovaScope)rawScope;
            }

            if (map.ContainsKey(type))
            {
                var nvalue =
                    CompilerServices.CreateLambdaForExpression(
                        NovaExpression.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);
        }
Exemplo n.º 26
0
        internal static dynamic Call(object func, List <FunctionArgument> args, object scope, NovaExpressionType pipeType, bool isOp, bool isPostfix)
        {
            if (func == null)
            {
                if (((NovaScope)scope).GlobalScope["Kernel"] == null)
                {
                    // map and check Kernel
                }
                throw new NotImplementedException();
            }
            var realArgs    = new List <object>();
            var names       = new List <string>();
            var offsetCount = 0;

            if (func is NovaFunction && !(func is NovaPartialFunction))
            {
                args.ForEach(realArgs.Add);
                realArgs.Insert(0, scope);
                if (realArgs.Count() - 1 < names.Count())
                {
                    (func as NovaFunction).Arguments.ForEach(arg => {
                        if (arg.HasDefault)
                        {
                            realArgs.Add(new FunctionArgument(arg.Name, arg.DefaultValue));
                        }
                    });
                }
                offsetCount = 1;
                if (pipeType != NovaExpressionType.Empty)
                {
                    realArgs.Add(pipeType);
                    offsetCount = 2;
                }
                (func as NovaFunction).SetScope(scope as NovaScope);
            }
            else if (func.GetType() == typeof(InstanceReference))
            {
                args.ForEach(realArgs.Add);
                realArgs.Insert(0, scope);
                offsetCount = 1;
                if (pipeType != NovaExpressionType.Empty)
                {
                    realArgs.Add(pipeType);
                    offsetCount = 2;
                }
                var iref   = (InstanceReference)func;
                var lval   = CompilerServices.CompileExpression(iref.LValue, (NovaScope)scope);
                var imArgs = new List <Expression>();
                realArgs.ForEach(arg => imArgs.Add(Expression.Constant(arg)));
                imArgs.Insert(0, Expression.Constant(lval, typeof(object)));
                if (isOp)
                {
                    imArgs.Add(Expression.Constant(new NovaUnaryBoolean(isPostfix)));
                }
                if (iref.LValue is VariableExpression &&
                    CompilerServices.CompileExpression((iref.LValue as VariableExpression).Name, (NovaScope)scope) ==
                    "super")
                {
                    imArgs.Add(Expression.Constant(new NovaDoNotWrapBoolean(true)));
                }
                return(Dynamic(typeof(object),
                               new InteropBinder.InvokeMember(iref.Key, new CallInfo(realArgs.Count - offsetCount, names),
                                                              (NovaScope)scope), imArgs));
            }
            else
            {
                // Nova name logic does not work here
                args.ForEach(arg => realArgs.Add(CompilerServices.CompileExpression(arg.Value, scope as NovaScope)));
            }

            var bArgs = new List <Expression>();

            realArgs.ForEach(arg => bArgs.Add(Expression.Constant(ConvertIfNumber(arg))));
            bArgs.Insert(0, Expression.Constant(func, typeof(object)));
            return(Dynamic(typeof(object),
                           new InteropBinder.Invoke(scope as NovaScope,
                                                    new CallInfo(realArgs.Count - offsetCount, names)), bArgs));
        }
        internal static dynamic ParallelAssign(
            List <ParallelAssignmentExpression.ParallelAssignmentInfo> leftHandValues,
            List <ParallelAssignmentExpression.ParallelAssignmentInfo> rightHandValues, object rawScope)
        {
            var scope   = rawScope as NovaScope;
            var rvalues = new List <object>();
            var fval    = CompilerServices.CompileExpression(rightHandValues[0].Value as Expression, scope);

            if (fval is List <object> && !rightHandValues[0].IsWildcard)
            {
                rvalues = new List <object>(fval as List <object>);
            }
            else
            {
                foreach (var rvalue in rightHandValues)
                {
                    var val = CompilerServices.CompileExpression(rvalue.Value as Expression, scope);
                    if (rvalue.IsWildcard)
                    {
                        if (val is List <object> )
                        {
                            (val as List <object>).ForEach(value => rvalues.Add(value));
                        }
                        else
                        {
                            rvalues.Add(val);
                        }
                    }
                    else
                    {
                        rvalues.Add(val);
                    }
                }
            }

            var i      = 0;
            var k      = 0;
            var result = new NovaArray();

            foreach (var _lvalue in leftHandValues)
            {
                var lvalue = _lvalue.Value;
                if (i >= rvalues.Count)
                {
                    break;
                }
                k++;
                if (lvalue is List <ParallelAssignmentExpression.ParallelAssignmentInfo> )
                {
                    result.Add(ParallelAssign(lvalue as List <ParallelAssignmentExpression.ParallelAssignmentInfo>,
                                              new List <ParallelAssignmentExpression.ParallelAssignmentInfo> {
                        new ParallelAssignmentExpression.ParallelAssignmentInfo {
                            IsWildcard = false,
                            Value      = Expression.Constant(rvalues[i++])
                        }
                    }, scope));
                }
                else if (_lvalue.IsWildcard)
                {
                    var mvalues = new NovaArray();
                    for (var j = i; j < rvalues.Count; j++)
                    {
                        mvalues.Add(rvalues[j]);
                    }
                    result.Add(Assign(lvalue as VariableExpression, mvalues, E.Assign, false, rawScope));
                    break;
                }
                else
                {
                    result.Add(Assign(lvalue as VariableExpression, rvalues[i++], E.Assign, false, rawScope));
                }
            }

            if (k < leftHandValues.Count)
            {
                for (var j = k; j < leftHandValues.Count; j++)
                {
                    if (leftHandValues[j].Value is List <ParallelAssignmentExpression.ParallelAssignmentInfo> )
                    {
                        var lvalues =
                            leftHandValues[j].Value as List <ParallelAssignmentExpression.ParallelAssignmentInfo>;
                        for (var l = 0; l < lvalues.Count; l++)
                        {
                            result.Add(Assign(lvalues[l].Value as VariableExpression, null, E.Assign, false, scope));
                        }
                    }
                    else
                    {
                        result.Add(Assign(leftHandValues[j].Value as VariableExpression, null, E.Assign, false, scope));
                    }
                }
            }

            return(result.Count > 1 ? result : result[0]);
        }
Exemplo n.º 28
0
        internal static dynamic DefineClass(object rawName, object rawParent, List <Expression> contents, object rawScope)
        {
            lock (_classDefineLock) {
                if (Resolve(rawName, rawScope) != null)
                {
                    return(DefineCategory(Resolve(rawName, rawScope), contents, rawScope));
                }
                var scope       = (NovaScope)rawScope;
                var defineScope = _inClassDefine ? scope : scope.GlobalScope;
                _inClassDefine = true;
                NovaClass parent;
                if (rawParent == null)
                {
                    if (scope.GlobalScope["Object"] == null)
                    {
                        scope.GlobalScope["Object"] = Nova.Box(typeof(object));
                    }
                    parent = scope.GlobalScope["Object"];
                }
                else
                {
                    var dParent = Resolve(rawParent as string, scope);
                    if (dParent == null)
                    {
                        _inClassDefine = false;
                        return(null);
                    }
                    if (dParent is Type)
                    {
                        parent = Nova.Box(dParent);
                    }
                    else
                    {
                        parent = dParent as NovaClass;
                    }
                    if (parent == null)
                    {
                        _inClassDefine = false;
                        return(null);
                    }
                }

                var name = (string)rawName;
                _className = name;

                var @class = new NovaClass {
                    Name = _className, Parent = parent
                };
                var xScope = new NovaScope(scope);
                xScope["self"]     = @class;
                xScope[_className] = @class;
                _currentClassScope = xScope;

                contents.ForEach(content => {
                    if (content is IncludeExpression)
                    {
                        // We only include modules here so make sure this include references a module
                        var names = ((IncludeExpression)content).Names;

                        dynamic module = null;

                        var index = 0;
                        names.ForEach(mname => {
                            if ((module is NovaModule))
                            {
                                module = module.Context[mname];
                            }
                            else if (index == 0)
                            {
                                module = scope[mname];
                            }
                            index = index + 1;
                        });

                        if (module != null)
                        {
                            if (module is NovaModule)
                            {
                                ((NovaModule)module).Contents.ForEach(mcon => {
                                    if (mcon is NovaFunction)
                                    {
                                        if ((mcon as NovaFunction).IsSingleton ||
                                            (mcon as NovaFunction).Name == "new")
                                        {
                                            NovaClass.AddMethod(@class.ClassMethods, mcon as NovaFunction);
                                        }
                                        else
                                        {
                                            NovaClass.AddMethod(@class.InstanceMethods, mcon as NovaFunction);
                                        }
                                        if (@class.RemovedMethods.Contains((mcon as NovaFunction).Name))
                                        {
                                            @class.RemovedMethods.Remove((mcon as NovaFunction).Name);
                                        }
                                        if (@class.UndefinedMethods.Contains((mcon as NovaFunction).Name))
                                        {
                                            @class.UndefinedMethods.Remove((mcon as NovaFunction).Name);
                                        }
                                    }
                                });

                                xScope.MergeWithScope(module.Context);
                            }
                            else if (module is NovaClass)
                            {
                                xScope[((NovaClass)module).Name] = module;
                            }
                        }
                    }
                });

                contents.ForEach(content => {
                    if (!(content is IncludeExpression))
                    {
                        var result = CompilerServices.CompileExpression(content, xScope);
                        if (result is NovaFunction)
                        {
                            if ((result as NovaFunction).IsSingleton || (result as NovaFunction).Name == "new")
                            {
                                NovaClass.AddMethod(@class.ClassMethods, result as NovaFunction);
                            }
                            else
                            {
                                NovaClass.AddMethod(@class.InstanceMethods, result as NovaFunction);
                            }
                            if (@class.RemovedMethods.Contains((result as NovaFunction).Name))
                            {
                                @class.RemovedMethods.Remove((result as NovaFunction).Name);
                            }
                            if (@class.UndefinedMethods.Contains((result as NovaFunction).Name))
                            {
                                @class.UndefinedMethods.Remove((result as NovaFunction).Name);
                            }
                        }
                    }
                });

                if ([email protected]("new"))
                {
                    NovaClass.AddMethod(@class.ClassMethods, new NovaFunction("new", new List <FunctionArgument>(),
                                                                              NovaExpression.NovaBlock(
                                                                                  NovaExpression.Return(new List <FunctionArgument> {
                        new FunctionArgument(null, NovaExpression.Variable(Expression.Constant("self")))
                    }),
                                                                                  Expression.Label(NovaParser.ReturnTarget, Expression.Constant(null, typeof(object)))),
                                                                              new NovaScope()));
                }
                @class.Context           = xScope;
                defineScope[@class.Name] = @class;
                _inClassDefine           = false;
                return(@class);
            }
        }