示例#1
0
        /// <summary>
        /// Modifie la valeur d'un élément d'une collection.
        /// L'élément est désigné par les paramètres d'indexation.
        /// </summary>
        /// <param name="var"></param>
        /// <param name="indexingParameters"></param>
        void SetElementValue(object val, object newValue, Context context)
        {
            dynamic newValueDynamic = newValue;
            dynamic index;

            // TODO : support des arrays multi-dimensionels.
            if (IndexingParameters.Count > 1)
            {
                for (int i = 0; i <= IndexingParameters.Count - 1; i++)
                {
                    List <IGettable> parameters = IndexingParameters[i];
                    if (parameters.Count == 0)
                    {
                        throw new Exception("Expected indexing parameter");
                    }

                    // On laisse faire le runtime pour la résolution dynamique =D
                    dynamic tmp = val;
                    index = IndexingParameters[0][0].GetValue(context);
                    val   = tmp[index];
                }
                dynamic enumValFinal = val;
                index = IndexingParameters.Last().First().GetValue(context);
                enumValFinal[index] = newValueDynamic;
            }
            else if (IndexingParameters.Count == 1)
            {
                dynamic enumValFinal = val;
                index = IndexingParameters.First().First().GetValue(context);
                enumValFinal[index] = newValueDynamic;
            }
        }
示例#2
0
        /// <summary>
        /// Retourne la valeur de cette expression, si celle ci n'est liée à aucun objet.
        /// (i.e si elle est de la forme :
        /// machin() ou machin MAIS PAS truc.machin
        /// </summary>
        /// <returns></returns>
        public object GetObjectUnboundValue(Context context)
        {
            switch (this.SubExpType)
            {
            // Groupe d'expression.
            // --------------------------------------------------------------
            case ExpTypes.ExpressionGroup:
                return(Group.GetValue(context));

            // Expression constante d'un objet
            // --------------------------------------------------------------
            case ExpTypes.ConstantObject:
                // Objet constant : 0, "jiji", 0.0, true, etc...
                if (constantValueCache == null)
                {
                    constantValueCache = Parsing.ParseBasicType(this.Name);
                }
                return(constantValueCache);

            // Expression constante d'un type.
            // --------------------------------------------------------------
            case ExpTypes.ConstantTypeName:
                if (constantValueCache == null)
                {
                    constantValueCache = new InternalTypeRepresentation(
                        ReflectionUtils.FindType(
                            context,
                            null,
                            Name,
                            GenericParameters,
                            IndexingParameters,
                            false));
                }

                return(constantValueCache);

            // Expression "new"
            // --------------------------------------------------------------
            case ExpTypes.NewObject:
                // Si le Type de l'instance n'est pas encore connu,
                if (findTypeResultCache == null)
                {
                    findTypeResultCache = ReflectionUtils.FindType(
                        context,
                        null,
                        Name,
                        GenericParameters,
                        IndexingParameters,
                        false);
                }

                // Raccourci pour faire moins moche
                var result = findTypeResultCache;

                // C'est s'il n'y a pas de paramètres.
                int paramsCount = Parameters == null ? 0 : Parameters.Count;
                // Le nombre de paramètres d'index est donné par le nombre d'éléments
                // de la dernière liste de la liste de paramètres d'indexation.
                int indexingParametersCount = IndexingParameters.Count == 0 ? 0 : IndexingParameters.Last().Count;

                object[] args = new object[indexingParametersCount + paramsCount];
                int      j    = 0;

                // On ajoute les paramètres de taille d'array
                if (IndexingParameters.Count != 0)
                {
                    foreach (IGettable gettable in IndexingParameters.Last())
                    {
                        args[j] = gettable.GetValue(context);
                        j++;
                    }
                }
                // On ajoute les paramètres du constructeur.
                if (Parameters != null)
                {
                    foreach (IGettable obj in Parameters)
                    {
                        args[j] = obj.GetValue(context);
                        j++;
                    }
                }
                // Note : les paramètres génériques sont inclus dans le type.
                return(Activator.CreateInstance(findTypeResultCache, args));

            // Expression "new"
            // --------------------------------------------------------------
            case ExpTypes.Variable:
                // C'est une variable locale ou globale, non associée à un objet.
                object val;
                if (context.LocalVariables.ContainsKey(Name))
                {
                    val = context.LocalVariables[Name].Value;
                }
                else if (context.GlobalContext.Variables.ContainsKey(Name))
                {
                    val = context.GlobalContext.Variables[Name].Value;
                }
                else
                {
                    Type t = ReflectionUtils.FindType(context, null, Name, GenericParameters, IndexingParameters, false);

                    if (t == null)
                    {
                        throw new InterpreterException(String.Format("Impossible de trouver la variable locale ou globale '{0}'.", Name));
                    }

                    val = new InternalTypeRepresentation(t);
                }


                // On regarde s'il y a des paramètres d'indexation :
                if (IndexingParameters.Count == 0)
                {
                    return(val);
                }
                else
                {
                    // On parcours les indexers.
                    // TODO : support des arrays multi-dimensionels.
                    for (int i = 0; i < IndexingParameters.Count; i++)
                    {
                        List <IGettable> parameters = IndexingParameters[i];
                        if (parameters.Count == 0)
                        {
                            throw new Exception("Expected indexing parameter");
                        }

                        // On laisse faire le runtime pour la résolution dynamique =D
                        dynamic tmp   = val;
                        dynamic index = IndexingParameters[0][0].GetValue(context);
                        val = tmp[index];
                    }
                    return(val);
                }

            case ExpTypes.Method:
                // C'est une méthode locale ou globale, non associée à un objet.
                // Cela appellera la méthode.
                Function func;
                if (context.LocalVariables.ContainsKey(Name))
                {
                    if (context.LocalVariables[Name].Value is Function)
                    {
                        func = (Function)context.LocalVariables[Name].Value;
                    }
                    else
                    {
                        throw new InterpreterException(String.Format("Impossible de trouver la fonction locale ou globale {0}.", Name));
                    }
                }
                else
                {
                    throw new InterpreterException(String.Format("Impossible de trouver la fonction locale ou globale {0}.", Name));
                }
                // Obtient les valeurs des paramètres.
                object[] parameterValues = new object[Parameters.Count];
                for (int i = 0; i < Parameters.Count; i++)
                {
                    parameterValues[i] = Parameters[i].GetValue(context);
                }
                return(func.Call(parameterValues, context));
            }
            throw new Exception();
        }