/// <summary> /// Constructs a DLR Expression tree representing setting a variable inside a context. /// </summary> /// <param name="runtime"></param> /// <param name="variableContainer">The container where the lookup should be performed</param> /// <param name="contextParts"> /// Contains 2 strings: /// 1. The name of the context /// 2. The name of the variable inside the context /// </param> /// <param name="value">Expression containing the value of the variable</param> /// <remarks> /// The returned DLR Expression tree will try to fetch the context inside the container. /// If the context does not exists, this will result an exception. /// If the exception occured, the context will be created inside the catch block. /// After this the context surely exists, so we can simply set the variable to the provided value. /// /// </remarks> /// <returns>>Expression tree for setting a value for the given context parts</returns> internal static DLR.Expression SetVariable(Aplus runtime, DLR.Expression variableContainer, string[] contextParts, DLR.Expression value) { // Get the context DLR.Expression getContext = DLR.Expression.TryCatch( DLR.Expression.Dynamic( runtime.GetMemberBinder(contextParts[0]), typeof(object), variableContainer ), DLR.Expression.Catch( // Context not found, create one! typeof(Error.Value), DLR.Expression.Dynamic( runtime.SetMemberBinder(contextParts[0]), typeof(object), variableContainer, DLR.Expression.Constant(new ScopeStorage()) ) ) ); DLR.Expression setVariable = DLR.Expression.Dynamic( runtime.SetMemberBinder(contextParts[1]), typeof(object), getContext, value ); return setVariable; }
/// <summary> /// Constructs a DLR Expression tree representing setting a variable inside a context. /// </summary> /// <param name="runtime"></param> /// <param name="variableContainer">The container where the lookup should be performed</param> /// <param name="contextParts"> /// Contains 2 strings: /// 1. The name of the context /// 2. The name of the variable inside the context /// </param> /// <param name="value">Expression containing the value of the variable</param> /// <remarks> /// The returned DLR Expression tree will try to fetch the context inside the container. /// If the context does not exists, this will result an exception. /// If the exception occured, the context will be created inside the catch block. /// After this the context surely exists, so we can simply set the variable to the provided value. /// /// </remarks> /// <returns>>Expression tree for setting a value for the given context parts</returns> internal static DLR.Expression SetVariable(Aplus runtime, DLR.Expression variableContainer, string[] contextParts, DLR.Expression value) { // Get the context DLR.Expression getContext = DLR.Expression.TryCatch( DLR.Expression.Dynamic( runtime.GetMemberBinder(contextParts[0]), typeof(object), variableContainer ), DLR.Expression.Catch( // Context not found, create one! typeof(Error.Value), DLR.Expression.Dynamic( runtime.SetMemberBinder(contextParts[0]), typeof(object), variableContainer, DLR.Expression.Constant(new ScopeStorage()) ) ) ); DLR.Expression setVariable = DLR.Expression.Dynamic( runtime.SetMemberBinder(contextParts[1]), typeof(object), getContext, value ); return(setVariable); }
/// <summary> /// Constructs a DLR Expression tree representing accessing a variable inside a context /// </summary> /// <param name="runtime"></param> /// <param name="variableContainer">The container where the lookup should be performed</param> /// <param name="contextParts"> /// Contains 2 strings: /// 1. The name of the context /// 2. The name of the variable inside the context /// </param> /// <returns>Expression tree for retrieving a value for the given context parts</returns> internal static DLR.Expression GetVariable(Aplus runtime, DLR.Expression variableContainer, string[] contextParts) { // Get the context DLR.Expression contextAccess = DLR.Expression.Dynamic( runtime.GetMemberBinder(contextParts[0]), typeof(object), variableContainer ); // Get the variable from the context DLR.Expression variableAccess = DLR.Expression.Dynamic( runtime.GetMemberBinder(contextParts[1]), typeof(object), contextAccess ); return variableAccess; }
/// <summary> /// Constructs a DLR Expression tree representing accessing a variable inside a context /// </summary> /// <param name="runtime"></param> /// <param name="variableContainer">The container where the lookup should be performed</param> /// <param name="contextParts"> /// Contains 2 strings: /// 1. The name of the context /// 2. The name of the variable inside the context /// </param> /// <returns>Expression tree for retrieving a value for the given context parts</returns> internal static DLR.Expression GetVariable(Aplus runtime, DLR.Expression variableContainer, string[] contextParts) { // Get the context DLR.Expression contextAccess = DLR.Expression.Dynamic( runtime.GetMemberBinder(contextParts[0]), typeof(object), variableContainer ); // Get the variable from the context DLR.Expression variableAccess = DLR.Expression.Dynamic( runtime.GetMemberBinder(contextParts[1]), typeof(object), contextAccess ); return(variableAccess); }
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); }