/// <summary> /// Build a method for setting a variable in a context. /// </summary> /// <param name="environment"> /// <see cref="Aplus">Aplus</see>, which contains the variables. /// </param> /// <param name="contextParts"> /// (context, variablename), as returned from <see cref="CreateContextParts"/> method. /// </param> /// <param name="value">Value to set for the provided <see cref="contextParts">variable</see>.</param> /// <returns>Expression tree of a Lambda expression.</returns> internal static DLR.Expression <Func <AType> > BuildVariableAssignMethod(Aplus environment, string[] contextParts, AType value) { DLR.Expression <Func <AType> > lambda = DLR.Expression.Lambda <Func <AType> >( DLR.Expression.Convert( VariableHelper.SetVariable( environment, DLR.Expression.Constant(environment.Context), contextParts, DLR.Expression.Constant(value) ), typeof(AType) ) ); return(lambda); }
/// <summary> /// Executes the <paramref name="sourceCode"/> in the <paramref name="newContext"/>. /// </summary> /// <param name="environment"></param> /// <param name="sourceCode">The code to execute</param> /// <param name="newContext">The context name to switch to before executeing the code</param> /// <returns>The executed source code's result</returns> private static AType ExecuteWithContextSwitch(Aplus environment, string sourceCode, string newContext) { AType result; string oldContext = environment.CurrentContext; environment.CurrentContext = newContext; DLR.Expression <Func <Aplus, AType> > lambda = Function.Monadic.NonScalar.Other.ExecuteFunction.BuildExecuteMethod(sourceCode, environment); Func <Aplus, AType> method = lambda.Compile(); result = method(environment); environment.CurrentContext = oldContext; return(result); }
/// <summary> /// Build a method for accessing a variable in a context. /// </summary> /// <param name="environment"> /// <see cref="Aplus">Aplus</see>, which contains the variables. /// </param> /// <param name="contextParts"> /// (context, variablename), as returned from <see cref="CreateContextParts"/> method. /// </param> /// <returns>Expression tree of a Lambda expression.</returns> internal static DLR.Expression <Func <AType> > BuildVariableAccessMethod(Aplus environment, string[] contextParts) { DLR.Expression <Func <AType> > lambda = DLR.Expression.Lambda <Func <AType> >( // Convert the variable to an AType DLR.Expression.Dynamic( environment.ConvertBinder(typeof(AType)), typeof(AType), // Access the variable VariableHelper.GetVariable( environment, DLR.Expression.Constant(environment.Context), contextParts ) ) ); return(lambda); }
/// <summary> /// Executes the <paramref name="sourceCode"/> in the current context and catches errors (like monadic-do) /// </summary> /// <param name="environment"></param> /// <param name="sourcecode">The code to execute</param> /// <returns> /// 1) An AInteger if there is an error, this integer is the number of the error /// 2) The executed source code's result enclosed in an ABox /// </returns> private static AType ProtectedExecute(Aplus environment, string sourcecode) { AType result; try { DLR.Expression <Func <Aplus, AType> > lambda = Function.Monadic.NonScalar.Other.ExecuteFunction.BuildExecuteMethod(sourcecode, environment); Func <Aplus, AType> method = lambda.Compile(); // Enclose the result result = ABox.Create(method(environment)); } catch (Error error) { result = AInteger.Create((int)error.ErrorType); } return(result); }
public override AType Execute(AType argument, Aplus environment) { // Environment is required! Assert.NotNull(environment); if (argument.Type != ATypes.AChar) { throw new Error.Type(this.TypeErrorText); } if (argument.Rank > 1) { throw new Error.Rank(this.RankErrorText); } DLR.Expression <Func <Aplus, AType> > lambda = BuildExecuteMethod(argument.ToString(), environment); Func <Aplus, AType> method = lambda.Compile(); AType result = method(environment); return(result); }
static AipcConnection() { DLR.ParameterExpression functionParameter = DLR.Expression.Parameter(typeof(AType), "_FUNCTION_"); DLR.ParameterExpression environmentParameter = DLR.Expression.Parameter(typeof(Aplus), "_ENVIRONMENT_"); DLR.ParameterExpression handleParameter = DLR.Expression.Parameter(typeof(AType), "_HANDLE_NUMBER_"); DLR.ParameterExpression eventTypeParameter = DLR.Expression.Parameter(typeof(AType), "_EVENT_TYPE_"); DLR.ParameterExpression callDataParameter = DLR.Expression.Parameter(typeof(AType), "_CALL_DATA_"); /** * Build the following lambda method: * (function, env, handleNumber, eventType, callData) => function(env, callData, eventType, handleNumber); */ DLR.Expression <Func <AType, Aplus, AType, AType, AType, AType> > method = DLR.Expression.Lambda <Func <AType, Aplus, AType, AType, AType, AType> >( DLR.Expression.Convert( DLR.Expression.Dynamic( new Binder.InvokeBinder(new DYN.CallInfo(4)), typeof(object), functionParameter, environmentParameter, callDataParameter, eventTypeParameter, handleParameter ), typeof(AType) ), true, functionParameter, environmentParameter, handleParameter, eventTypeParameter, callDataParameter ); CallbackFunction = method.Compile(); }
internal static DLR.Expression <Func <Aplus, AType> > BuildExecuteMethod( string sourceCode, Aplus environment ) { DLR.Expression codebody; // TODO: fix the third function info argument AplusCore.Compiler.AST.Node tree = Compiler.Parse.String(sourceCode, environment.LexerMode, null); AplusScope scope = new AplusScope(null, "__EVAL__", environment, DLR.Expression.Parameter(typeof(Aplus), "__EVAL_RUNTIME__"), DLR.Expression.Parameter(typeof(DYN.IDynamicMetaObjectProvider), "__EVAL_MODULE__"), //DLR.Expression.Parameter(typeof(Aplus), "__EVAL_ENVIRONMENT__"), DLR.Expression.Label(typeof(AType), "__EVAL_EXIT__"), isEval: true ); if (tree == null) { codebody = DLR.Expression.Constant(null); } else if (environment.FunctionScope != null) { AplusScope functionScope = new AplusScope(scope, "__EVAL_IN_FUNCTION__", moduleParam: DLR.Expression.Parameter(typeof(DYN.ExpandoObject), "__EVAL_FUNCTION_SCOPE__"), returnTarget: scope.ReturnTarget, isMethod: true ); codebody = DLR.Expression.Block( new DLR.ParameterExpression[] { //scope.RuntimeExpression, // runtime scope.ModuleExpression, // root context functionScope.ModuleExpression // Function local scope }, //DLR.Expression.Assign( // scope.RuntimeExpression, scope.RuntimeExpression //), DLR.Expression.Assign( scope.ModuleExpression, DLR.Expression.PropertyOrField(scope.RuntimeExpression, "Context") ), DLR.Expression.Assign( functionScope.ModuleExpression, DLR.Expression.PropertyOrField(scope.RuntimeExpression, "FunctionScope") ), DLR.Expression.Label( scope.ReturnTarget, tree.Generate(functionScope) ) ); } else { codebody = DLR.Expression.Block( new DLR.ParameterExpression[] { //scope.RuntimeExpression, // runtime scope.ModuleExpression // root context }, //DLR.Expression.Assign( // scope.RuntimeExpression, scope.RuntimeExpression //), DLR.Expression.Assign( scope.ModuleExpression, DLR.Expression.PropertyOrField(scope.RuntimeExpression, "Context") ), DLR.Expression.Label( scope.ReturnTarget, tree.Generate(scope) ) ); } DLR.Expression <Func <Aplus, AType> > lambda = DLR.Expression.Lambda <Func <Aplus, AType> >( codebody, scope.GetRuntimeExpression() ); return(lambda); }
public AplusScriptCode(Aplus aplus, string code, SourceUnit sourceunit) : base(sourceunit) { this.aplus = aplus; this.lambda = ParseToLambda(code.Trim()); }