public KumaFunction(string name, List <FunctionArgument> arguments, BlockExpression body, KumaScope context) { Name = name; Arguments = arguments; Body = body; Context = context; }
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); }
public KumaPartialFunction(KumaFunction function, List <FunctionArgument> args, KumaScope scope) : base(function.Name, new List <FunctionArgument>(), null, null) { WrappedFunction = function; PartialArguments = args; WrappedScope = scope; }
public KumaInstance(KumaClass @class) { _class = @class; SingletonMethods = new Dictionary <string, KumaFunction>(); UndefinedMethods = new List <string>(); RemovedMethods = new List <string>(); InstanceVariables = new KumaScope(); }
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> (); }
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()); }
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); }
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)); }
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); } }
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); }
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; }
public void SetScope(KumaScope scope) { _scope = scope; }
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); } }
public KumaModule(string name, KumaScope context, List <object> contents) { Name = name; Contents = contents; Context = context; }
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); } }
protected KumaBoxedInstance(object obj, KumaScope scope) : base(GetBoxClass(obj)) { BoxedObject = obj; BoxedScope = scope; }
internal KumaBoxedInstance(object obj, KumaScope scope, KumaClass @class) : base(@class) { BoxedObject = obj; BoxedScope = scope; }