/// <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> /// 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> /// Wraps the expression inside a Dynamic cast to AType /// </summary> /// <param name="expression">Expression to cast.</param> /// <param name="runtime"></param> /// <returns></returns> internal static DLR.DynamicExpression ToAType(this DLR.Expression expression, Aplus runtime) { return(DLR.Expression.Dynamic(runtime.ConvertBinder(typeof(AType)), typeof(AType), expression)); }
public override DLR.Expression Generate(AplusScope scope) { DLR.Expression result; Aplus runtime = scope.GetRuntime(); if (this.Type == IdentifierType.SystemName && runtime.SystemFunctions.ContainsKey(this.Name)) { // Check if the name is a system function's name and we have such system function // and return it result = DLR.Expression.Constant(runtime.SystemFunctions[this.Name]); return(result); } DLR.Expression variableContainer = scope.GetModuleExpression(); string[] contextParts = CreateContextNames(runtime.CurrentContext); // Check if the scope is a method if (scope.IsMethod) { DLR.Expression parentVariableContainer = scope.Parent.GetModuleExpression(); // Check for variable in method scope // (maybe the variable is defined in the method header) DLR.Expression localVariable = scope.FindIdentifier(this.variableName); if (localVariable != null) { // Found a variable defined in the method's header return(localVariable); } if (this.type == IdentifierType.UnQualifiedName) { // 1). we check if the variable exists in the function's scope // 2). check if the variable exits in the current context (error if not found) // // if(((IDictionary<String, Object>)($FunctionScope).ContainsKey($VARIABLE)) // { // return $FunctionScope.$VARIABLE; // } // else // { // return $GlobalScope.$VARIABLE // } // DLR.Expression getVariable = DLR.Expression.Condition( DLR.Expression.Call( DLR.Expression.Convert(variableContainer, typeof(IDictionary <string, object>)), typeof(IDictionary <string, object>).GetMethod("ContainsKey"), DLR.Expression.Constant(this.variableName) ), // True case: DLR.Expression.Dynamic( runtime.GetMemberBinder(this.variableName), typeof(object), variableContainer ), // False case: BuildGlobalAccessor(scope, runtime, parentVariableContainer, contextParts), // resulting type typeof(object) ); result = DLR.Expression.Dynamic( runtime.ConvertBinder(typeof(AType)), typeof(AType), getVariable ); return(result); } else if (this.type == IdentifierType.QualifiedName) { // Found a variable like: .var // for this check the parent's variables variableContainer = parentVariableContainer; // Fallback to the non-method case } } result = Tools.CloneMemoryMappedFile(BuildGlobalAccessor(scope, runtime, variableContainer, contextParts)); return(result); }