internal static dynamic CreateArray(List <Expression> values) { var list = new List <object>(); values.ForEach(value => list.Add(CompilerServices.CreateLambdaForExpression(value)())); return(new NovaArray(list)); }
protected override Expression VisitVariable(VariableExpression node) { var name = CompilerServices.CreateLambdaForExpression(node.Name)(); if (name is string) { _variableNames.Add(name); } return(node); }
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)); }
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); }
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); }
private static dynamic Dynamic(Type returnType, CallSiteBinder binder, IEnumerable <Expression> args) { return(CompilerServices.CreateLambdaForExpression(Expression.Dynamic(binder, returnType, args.ToArray()))()); }
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); }
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); }
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)); }