public void WriteExpressions(LambdaDefinition definition) { var scope = definition.Scope(); var variableExpr = Expression.Variable(Variable.VariableType, Variable.Usage); definition.RegisterExpression(Variable, variableExpr); var invokeMethod = _setter.InitialValue.GetType().GetMethod("Invoke"); var invoke = Expression.Call(Expression.Constant(_setter.InitialValue), invokeMethod, scope); Expression cast = invoke; if (!variableExpr.Type.IsAssignableFrom(invoke.Type)) { cast = Expression.Convert(invoke, variableExpr.Type); } definition.Body.Add(Expression.Assign(variableExpr, cast)); if (!Variable.VariableType.IsValueType) { definition.TryRegisterDisposable(variableExpr); } if (Next is IResolverFrame next) { next.WriteExpressions(definition); } else { throw new InvalidCastException($"{Next.GetType().FullNameInCode()} does not implement {nameof(IResolverFrame)}"); } }
public void WriteExpressions(LambdaDefinition definition) { var listType = typeof(List <>).MakeGenericType(typeof(T)); var ctor = listType.GetConstructors().Single(x => x.GetParameters().Length == 1 && x.GetParameters()[0].ParameterType.IsEnumerable()); var initArray = Expression.NewArrayInit(ElementType, Elements.Select(definition.ExpressionFor)); var expr = definition.ExpressionFor(Variable); var assign = Expression.Assign(expr, Expression.New(ctor, initArray)); definition.Body.Add(assign); if (Next == null) { definition.Body.Add(expr); } else if (Next is IResolverFrame next) { next.WriteExpressions(definition); } else { throw new InvalidCastException($"{Next.GetType().GetFullName()} does not implement {nameof(IResolverFrame)}"); } }
public void WriteExpressions(LambdaDefinition definition) { var listType = typeof(List <>).MakeGenericType(typeof(T)); var ctor = listType.GetConstructors().Single(x => x.GetParameters().Length == 0); var addMethod = listType.GetMethod("Add"); var expr = definition.ExpressionFor(Variable); var assign = Expression.Assign(expr, Expression.New(ctor)); definition.Body.Add(assign); foreach (var variable in Elements) { var add = Expression.Call(expr, addMethod, definition.ExpressionFor(variable)); definition.Body.Add(add); } if (Next == null) { definition.Body.Add(expr); } else if (Next is IResolverFrame next) { next.WriteExpressions(definition); } else { throw new InvalidCastException($"{Next.GetType().GetFullName()} does not implement {nameof(IResolverFrame)}"); } }
public void WriteExpressions(LambdaDefinition definition) { var scope = definition.Scope(); var closedMethod = _openMethod.MakeGenericMethod(_serviceType); var expr = definition.ExpressionFor(Variable); var call = Expression.Call(scope, closedMethod); var assign = Expression.Assign(expr, call); definition.Body.Add(assign); if (Next == null) { definition.Body.Add(expr); } else if (Next is IResolverFrame next) { next.WriteExpressions(definition); } else { throw new InvalidCastException($"{Next.GetType().FullNameInCode()} does not implement {nameof(IResolverFrame)}"); } }
public void WriteExpressions(LambdaDefinition definition) { var variableExpr = definition.RegisterExpression(Variable); definition.Body.Add(Expression.Assign(variableExpr, Expression.Convert(definition.ExpressionFor(_scope), Variable.VariableType))); Next?.As <IResolverFrame>().WriteExpressions(definition); }
public static void TryRegisterDisposable(this LambdaDefinition definition, Expression parameter) { var scope = definition.Arguments.Single(); var @call = Expression.Call(scope, _tryRegisterDisposable, parameter); definition.Body.Add(@call); }
public override Expression ToVariableExpression(LambdaDefinition definition) { if (InitialValue != null) { return(Expression.Constant(InitialValue, VariableType)); } throw new InvalidOperationException("No initial value to create an expression"); }
public void short_hand_register_variable() { var definition = new LambdaDefinition(); var variable = Variable.For <IWidget>(); definition.RegisterExpression(variable); definition.ExpressionFor(variable).ShouldNotBeNull(); }
public void register_a_variable_and_fetch_happy_path() { var definition = new LambdaDefinition(); var variable = Variable.For <IWidget>(); var expression = variable.ToVariableExpression(definition); definition.RegisterExpression(variable, expression); definition.ExpressionFor(variable).ShouldBeSameAs(expression); }
public static void RegisterDisposable(this LambdaDefinition definition, Expression parameter, Type variableType) { var scope = definition.Arguments.Single(); var disposables = Expression.Call(scope, _getDisposables); var @call = Expression.Call(disposables, _add, variableType.CanBeCastTo <IDisposable>() ? parameter : Expression.Convert(parameter, typeof(IDisposable))); definition.Body.Add(@call); }
public void compile_simple() { var definition = new LambdaDefinition(); var parameter = Expression.Parameter(typeof(string)); definition.Arguments = new ParameterExpression[] { parameter }; definition.Body.Add(parameter); var func = definition.Compile <Func <string, string> >(); func("hello").ShouldBe("hello"); }
public void WriteExpressions(LambdaDefinition definition) { // No next, not disposable var isDisposed = BuiltType.CanBeCastTo <IDisposable>() || BuiltType.CanBeCastTo <IAsyncDisposable>(); var callCtor = Expression.New(Ctor, Parameters.Select(definition.ExpressionFor)); if (Next == null && !isDisposed && !Setters.Any()) { definition.Body.Add(callCtor); } else { var variableExpr = Expression.Parameter(BuiltType, Variable.Usage); definition.RegisterExpression(Variable, variableExpr); definition.Assign(variableExpr, callCtor); foreach (var setter in Setters) { var setMethod = BuiltType.GetProperty(setter.PropertyName).SetMethod; var value = definition.ExpressionFor(setter.Variable); var call = Expression.Call(variableExpr, setMethod, value); definition.Body.Add(call); } if (isDisposed) { definition.RegisterDisposable(variableExpr, Variable.VariableType); } if (Next == null) { definition.Body.Add(definition.ExpressionFor(Variable)); } else { if (Next is IResolverFrame next) { next.WriteExpressions(definition); } else { throw new InvalidCastException($"{Next.GetType().GetFullName()} does not implement {nameof(IResolverFrame)}"); } } } }
private IElement DifferentiateOnce(ScriptNode Node, Variables Variables) { if (Node is VariableReference VariableReference) { if (Variables.TryGetVariable(VariableReference.VariableName, out Variable v)) { if (v.ValueObject is IDifferentiable Differentiable) { return(this.DifferentiateOnce(Differentiable, Variables)); } else if (v.ValueObject is ILambdaExpression) { throw new ScriptRuntimeException(VariableReference.VariableName + " not differentiable.", this); } else { return(DoubleNumber.ZeroElement); } } else { LambdaDefinition f = Expression.GetFunctionLambdaDefinition(VariableReference.VariableName, this.Start, this.Length, this.Expression); if (f != null) { if (f is IDifferentiable Differentiable) { return(this.DifferentiateOnce(Differentiable, Variables)); } else { throw new ScriptRuntimeException(VariableReference.VariableName + " not differentiable.", this); } } else { throw new ScriptRuntimeException(VariableReference.VariableName + " not defined.", this); } } } else if (Node is IDifferentiable Differentiable) { return(this.DifferentiateOnce(Differentiable, Variables)); } else { throw new ScriptRuntimeException("Not differentiable.", this); } }
public void WriteExpressions(LambdaDefinition definition) { var scope = definition.Scope(); var expr = definition.ExpressionFor(Variable); var instance = Variable.Instance; var @call = Expression.Call(Expression.Constant(instance), _resolveMethod, scope); var assign = Expression.Assign(expr, Expression.Convert(@call, Variable.VariableType)); definition.Body.Add(assign); if (Next is IResolverFrame next) { next.WriteExpressions(definition); } else { throw new InvalidCastException($"{Next.GetType().GetFullName()} does not implement {nameof(IResolverFrame)}"); } }
public void WriteExpressions(LambdaDefinition definition) { var init = Expression.NewArrayInit(ElementType, Elements.Select(definition.ExpressionFor)); var expr = definition.ExpressionFor(Variable); var assign = Expression.Assign(expr, init); definition.Body.Add(assign); if (Next == null) { definition.Body.Add(expr); } else if (Next is IResolverFrame next) { next.WriteExpressions(definition); } else { throw new InvalidCastException($"{Next.GetType().GetFullName()} does not implement {nameof(IResolverFrame)}"); } }
public Func <Scope, object> BuildResolver() { var arranger = new MethodFrameArranger(this, this); arranger.Arrange(out var mode, out var top); var definition = new LambdaDefinition { Context = _scope }; var scope = definition.RegisterExpression(_scopeArgument).As <ParameterExpression>(); definition.Arguments = new [] { scope }; if (top is IResolverFrame frame) { frame.WriteExpressions(definition); return(definition.Compile <Func <Scope, object> >()); } throw new InvalidOperationException($"Frame type {top} does not implement {nameof(IResolverFrame)}"); }
public override string ToString() { return(LambdaDefinition.ToString(this)); }
public static Expression CompileLambdaDef(Symbol name, Cons forms, AnalysisScope scope, LambdaKind kind, out string doc) { CheckMinLength(forms, 0); if (Length(forms) == 1) { PrintWarning("Function body contains no forms."); } var args = (Cons)First(forms); var body = Cdr(forms); var funscope = new AnalysisScope(scope, name == null ? null : name.Name); funscope.IsLambda = true; var template = new LambdaDefinition(); template.Name = name; template.Signature = CompileFormalArgs(args, scope, kind); if (kind == LambdaKind.Method) { var container = name.Value as MultiMethod; if (container != null) { var m = template.Signature; var g = container.Signature; var m1 = m.RequiredArgsCount; var m2 = m.Parameters.Count; var m3 = m.ArgModifier; var g1 = g.RequiredArgsCount; var g2 = g.Parameters.Count; var g3 = g.ArgModifier; if (m1 != g1) { throw new LispException("Method does not match multi-method: number of required arguments"); } if (m3 != g3) { throw new LispException("Method does not match multi-method: different argument modifiers"); } if (g3 != Symbols.Key && m2 != g2) { throw new LispException("Method does not match multi-method: number of arguments"); } if (g3 == Symbols.Key) { // Replace keyword parameters with the full list from the generic definition, but keep the defaults var usedKeys = template.Signature.Parameters.GetRange(m1, m2 - m1); var replacementKeys = container.Signature.Parameters.GetRange(g1, g2 - g1); template.Signature.Parameters.RemoveRange(m1, m2 - m1); template.Signature.Names.RemoveRange(m1, m2 - m1); foreach (var par in replacementKeys) { var oldpar = usedKeys.FirstOrDefault(x => x.Sym == par.Sym); if (oldpar != null) { var newpar = new ParameterDef(par.Sym, initForm: oldpar.InitForm); template.Signature.Parameters.Add(newpar); template.Signature.Names.Add(par.Sym); } else { // Insert place holder var newpar = new ParameterDef(par.Sym, hidden: true); template.Signature.Parameters.Add(newpar); template.Signature.Names.Add(newpar.Sym); } } } } } if (name != null) { template.Syntax = MakeListStar(template.Name, args); } template.Source = MakeListStar(Symbols.Lambda, args, body); doc = ""; if (body != null) { if (body.Car is string) { doc = (string)body.Car; if (body.Cdr != null) { body = body.Cdr; } } } var lambdaListNative = funscope.DefineNativeLocal(Symbols.LambdaList, ScopeFlags.All); var selfNative = funscope.DefineNativeLocal(Symbols.Self, ScopeFlags.All); var argsNative = funscope.DefineNativeLocal(Symbols.Args, ScopeFlags.All); Expression code; var rawparams = template.Signature.ArgModifier == Symbols.RawParams; var names = GetLambdaArgumentNames(template.Signature); var temp = GenTemp(); var body4 = FormatCode(LambdaTemplate, Symbols.Args, temp, GetDeclarations(rawparams, names, temp), body); code = Compile(body4, funscope); template.Proc = CompileToFunction3(code, lambdaListNative, selfNative, argsNative); return CallRuntime(MakeLambdaClosureMethod, Expression.Constant(template, typeof(LambdaDefinition))); }
public static Expression Scope(this LambdaDefinition definition) { return(definition.Arguments.Single()); }