예제 #1
0
 public KumaFunction(string name, List <FunctionArgument> arguments, BlockExpression body, KumaScope context)
 {
     Name      = name;
     Arguments = arguments;
     Body      = body;
     Context   = context;
 }
예제 #2
0
        public static KumaBoxedInstance Box(object obj, KumaScope scope = null)
        {
            if (obj == null)
            {
                return(null);
            }
            if (_boxCache.ContainsKey(obj))
            {
                _boxCache[obj].BoxedScope.MergeWithScope(scope ?? new KumaScope());
                return(_boxCache[obj]);
            }
            var boxed = new KumaBoxedInstance(obj, scope ?? new KumaScope());

            _boxCache[obj] = boxed;
            if (scope != null)
            {
                string name;
                var    _scope = scope.SearchForObject(obj, out name);
                if (_scope != null)
                {
                    _scope[name] = boxed;
                }
            }
            return(boxed);
        }
예제 #3
0
 public KumaPartialFunction(KumaFunction function, List <FunctionArgument> args, KumaScope scope)
     : base(function.Name, new List <FunctionArgument>(), null, null)
 {
     WrappedFunction  = function;
     PartialArguments = args;
     WrappedScope     = scope;
 }
예제 #4
0
 public KumaInstance(KumaClass @class)
 {
     _class            = @class;
     SingletonMethods  = new Dictionary <string, KumaFunction>();
     UndefinedMethods  = new List <string>();
     RemovedMethods    = new List <string>();
     InstanceVariables = new KumaScope();
 }
예제 #5
0
 public KumaScope(KumaScope parent)
 {
     Variables   = new Dictionary <string, dynamic> ();
     SymVars     = new Dictionary <Symbol, dynamic> ();
     ParentScope = parent;
     Aliases     = new Dictionary <string, string> ();
     Constants   = new List <string> ();
 }
예제 #6
0
 internal KumaClass()
 {
     ClassMethods     = new Dictionary <string, KumaMethodTable>();
     InstanceMethods  = new Dictionary <string, KumaMethodTable>();
     UndefinedMethods = new List <string>();
     RemovedMethods   = new List <string>();
     Context          = new KumaScope();
 }
        internal static dynamic CompileExpression(Expression e, KumaScope scope)
        {
            Expression newExpression = KumaExpression.Convert(e, typeof(object));

            newExpression.SetScope(scope);
            var l = CreateLambdaForExpression(newExpression);

            return(l());
        }
예제 #8
0
        internal static dynamic Invoke(Type targetType, MethodBase minfo, List <FunctionArgument> args,
                                       KumaScope 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 KumaString)
                {
                    _val = (string)_val;
                }
                if (_val is KumaNumber)
                {
                    _val = KumaNumber.Convert((KumaNumber)_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 KumaInstance && !(target is KumaBoxedInstance) &&
                ((KumaInstance)target).BackingObject != null)
            {
                target = ((KumaInstance)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);
        }
예제 #9
0
 private dynamic Resolve(Symbol sym, KumaScope startingScope)
 {
     if (SymVars.ContainsKey(sym))
     {
         return(SymVars[sym]);
     }
     if (ParentScope != null)
     {
         return(ParentScope.Resolve(sym, startingScope));
     }
     return(startingScope.Resolve(sym.Name));
 }
예제 #10
0
        public static KumaBoxedInstance BoxNoCache(object obj, KumaScope scope = null)
        {
            if (obj == null)
            {
                return(null);
            }
            var boxed = new KumaBoxedInstance(obj, scope ?? new KumaScope());

            if (scope != null)
            {
                string name;
                var    _scope = scope.SearchForObject(obj, out name);
                if (_scope != null)
                {
                    _scope[name] = boxed;
                }
            }
            return(boxed);
        }
        internal static dynamic DefineModule(object rawName, List <Expression> contents, object rawScope)
        {
            lock (_classDefineLock) {
                var scope       = (KumaScope)rawScope;
                var defineScope = _inClassDefine ? scope : scope.GlobalScope;

                var name = (string)rawName;

                var xScope = new KumaScope(scope);

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

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

                defineScope[module.Name] = module;

                return(module);
            }
        }
예제 #12
0
        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);
        }
예제 #13
0
 public KumaClass(string name, KumaClass parent, List <KumaFunction> classMethods,
                  List <KumaFunction> instanceMethods)
 {
     Name         = name;
     ClassMethods = new Dictionary <string, KumaMethodTable>();
     classMethods.ForEach(func => AddMethod(ClassMethods, func));
     if (!ClassMethods.ContainsKey("new"))
     {
         AddMethod(ClassMethods, new KumaFunction("new", new List <FunctionArgument>(),
                                                  KumaExpression.KumaBlock(
                                                      KumaExpression.Return(new List <FunctionArgument> {
             new FunctionArgument(null, KumaExpression.Variable(Expression.Constant("self")))
         }),
                                                      Expression.Label(KumaParser.ReturnTarget, Expression.Constant(null, typeof(object)))),
                                                  new KumaScope()));
     }
     InstanceMethods = new Dictionary <string, KumaMethodTable>();
     instanceMethods.ForEach(func => AddMethod(InstanceMethods, func));
     UndefinedMethods = new List <string>();
     RemovedMethods   = new List <string>();
     Context          = new KumaScope();
     Parent           = parent;
 }
예제 #14
0
 public void SetScope(KumaScope scope)
 {
     _scope = scope;
 }
예제 #15
0
        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 KumaString(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       = (KumaScope)rawScope;
                    var xexpression = string.Format("{0};", expression);

                    var        res = KumaParser.Parse(xexpression);
                    Expression block;
                    if (res != null)
                    {
                        block = KumaExpression.KumaBlock(res);
                    }
                    else
                    {
                        return(null);
                    }
                    var myScope = new KumaScope();
                    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 KumaString(@new.ToString()));
        }
        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       = (KumaScope)rawScope;
                var defineScope = _inClassDefine ? scope : scope.GlobalScope;
                _inClassDefine = true;
                KumaClass parent;
                if (rawParent == null)
                {
                    if (scope.GlobalScope["Object"] == null)
                    {
                        scope.GlobalScope["Object"] = Kuma.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 = Kuma.Box(dParent);
                    }
                    else
                    {
                        parent = dParent as KumaClass;
                    }
                    if (parent == null)
                    {
                        _inClassDefine = false;
                        return(null);
                    }
                }

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

                var @class = new KumaClass {
                    Name = _className, Parent = parent
                };
                var xScope = new KumaScope(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 KumaModule))
                            {
                                module = module.Context[mname];
                            }
                            else if (index == 0)
                            {
                                module = scope[mname];
                            }
                            index = index + 1;
                        });

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

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

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

                if ([email protected]("new"))
                {
                    KumaClass.AddMethod(@class.ClassMethods, new KumaFunction("new", new List <FunctionArgument>(),
                                                                              KumaExpression.KumaBlock(
                                                                                  KumaExpression.Return(new List <FunctionArgument> {
                        new FunctionArgument(null, KumaExpression.Variable(Expression.Constant("self")))
                    }),
                                                                                  Expression.Label(KumaParser.ReturnTarget, Expression.Constant(null, typeof(object)))),
                                                                              new KumaScope()));
                }
                @class.Context           = xScope;
                defineScope[@class.Name] = @class;
                _inClassDefine           = false;
                return(@class);
            }
        }
예제 #17
0
 public KumaModule(string name, KumaScope context, List <object> contents)
 {
     Name     = name;
     Contents = contents;
     Context  = context;
 }
예제 #18
0
 public void MergeWithScope(KumaScope other)
 {
     Variables = other.Variables.MergeLeft(Variables);
     SymVars   = other.SymVars.MergeLeft(SymVars);
 }
        internal static dynamic DefineCategory(KumaClass @class, List <Expression> contents, object rawScope)
        {
            lock (_classDefineLock) {
                var scope = (KumaScope)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 KumaModule))
                            {
                                module = module.Context[mname];
                            }
                            else if (index == 0)
                            {
                                module = scope[mname];
                            }
                            index = index + 1;
                        });

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

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

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

                @class.Context.MergeWithScope(scope);
                return(@class);
            }
        }
예제 #20
0
 protected KumaBoxedInstance(object obj, KumaScope scope) : base(GetBoxClass(obj))
 {
     BoxedObject = obj;
     BoxedScope  = scope;
 }
예제 #21
0
 internal KumaBoxedInstance(object obj, KumaScope scope, KumaClass @class) : base(@class)
 {
     BoxedObject = obj;
     BoxedScope  = scope;
 }