Exemple #1
0
        /// <summary>
        /// Guarda un valor determinado, entero o booleano.
        /// </summary>
        /// <param name="where">Donde guardar el valor. La expresion puede ser una variable, o un arreglo.</param>
        /// <param name="what">La expresion que contiene el valor a guardar. Es evaluada, y el valor resultante guardado.</param>
        public void Assign(string where, string what)
        {
            what = what.ToLower();
             where = where.ToLower();
             if (where.Contains("[") && where.Contains("]")) // Es un array?
             {

            Tokenizer t = new Tokenizer(where);
            var enumerator = t.GetTokens().GetEnumerator();
            enumerator.MoveNext();

            if (enumerator.Current.Type != TokenType.Name)
            {
               throw new InvalidOperationException(string.Format("{0} is not either a valid variable or array expression.", where));
            }
            else if (Variables.ContainsVariable(enumerator.Current.Value))
            {
               throw new InvalidOperationException(string.Format("There is another variable with the name {0}.", enumerator.Current.Value));
            }

            SaveToArray(where, Evaluate(what));
             }
             else // Es una variable entonces...
             {
            Tokenizer t = new Tokenizer(where);

            var enumerator = t.GetTokens().GetEnumerator();
            enumerator.MoveNext();
            if (!enumerator.MoveNext())
            {
               Variable v = new Variable(Evaluate(what));
               Variables[where] = v;
            }
            else throw new InvalidOperationException(string.Format("{0} is not either a valid variable or array expression.", where));
             }
        }
Exemple #2
0
        /// <summary>
        /// Evalua una expresion aritmetica determinada.
        /// </summary>
        /// <param name="expression">La expresion a evaluar.</param>
        /// <returns>Un string que representa el valor de la expresion evaluada.</returns>
        public string Evaluate(string expression)
        {
            if (expression == null)
            throw new InvalidOperationException("Nothing to evaluate.");
             if (expression == "") return expression;

             Stack<Token> operatorStack = new Stack<Token>();
             string postfixExpression = "";
             Tokenizer tokenizer = new Tokenizer(expression);
             IEnumerable<Token> tokens = tokenizer.GetTokens();

             IEnumerator<Token> enumerator = tokens.GetEnumerator();

             Token prevToken = null;
             while (enumerator.MoveNext())
             {
            Token currentToken = enumerator.Current;
            bool unaryMinusBeforeParenthesis = false;
            switch (currentToken.Type){
               case TokenType.OpenedParenthesis: // Si hay un parentesis, recupera la expresion completa y la evalua recursivamente.
                  string auxExp = "";

                  int openPCount = 1;
                  int closedPCount = 0;

                  do{
                     if (!enumerator.MoveNext()) throw new InvalidOperationException("Unbalanced parenthesis");
                     if (enumerator.Current.Type == TokenType.OpenedParenthesis) openPCount++;
                     else if (enumerator.Current.Type == TokenType.ClosedParenthesis) closedPCount++;

                     if (enumerator.Current.Type != TokenType.ClosedParenthesis || closedPCount < openPCount)
                        auxExp += enumerator.Current.Value + " ";

                  } while (closedPCount != openPCount);

                  string extra = unaryMinusBeforeParenthesis ? "-1 * " : " ";

                  postfixExpression += Evaluate(auxExp) + extra;
                  break;

               case TokenType.ClosedParenthesis:
                  throw new InvalidOperationException("Unbalanced parenthesis");

               case TokenType.Name: // Si es un nombre, pregunta por su tipo y lo sustituye por su valor
                  string name = currentToken.Value;
                  if (Variables.ContainsVariable(name)) // Es una variable?
                  {
                     Variable v = Variables[name];
                     if (v.Type != VariableType.Empty)
                        postfixExpression += Variables[name] + " ";
                  }
                  else if (Arrays.ArrayExists(currentToken.Value)) // Es un array?
                  {
                     string array = name;

                     while (enumerator.MoveNext() && enumerator.Current.Type!=TokenType.ClosedBracket)
                        array += enumerator.Current.Value;

                     array += "]";

                     postfixExpression += GetArrayValue(array) + " ";
                  }
                  else throw new InvalidOperationException(string.Format("Unknown name token: \"{0}\".",name));
                  break;

                  // Si es un valor, simplemente lo agrega a la expresion en postfijo
               case TokenType.True:
               case TokenType.False:
               case TokenType.Constant:
                  postfixExpression += currentToken.Value + " ";
                  break;

               case TokenType.Minus:
                  if (GetTokenPriority(prevToken) > 0){
                     enumerator.MoveNext();
                     currentToken = enumerator.Current;
                     if (currentToken.Type == TokenType.Constant){
                        postfixExpression += "-" + currentToken.Value + " ";
                     }
                     else if (currentToken.Type == TokenType.OpenedParenthesis){
                        unaryMinusBeforeParenthesis = !unaryMinusBeforeParenthesis;
                        goto case TokenType.OpenedParenthesis;
                     }

                  }
                  else
                     goto case TokenType.Plus;
                  break;

                  // Si es un operador...
               case TokenType.Plus:
               case TokenType.Asterisk:
               case TokenType.Slash:
               case TokenType.Percent:
               case TokenType.Ampersand:
               case TokenType.Caret:
               case TokenType.Greater:
               case TokenType.GreaterEqual:
               case TokenType.Less:
               case TokenType.LessEqual:
               case TokenType.Equal:
               case TokenType.NotEqual:
                  if (operatorStack.Count == 0)
                     operatorStack.Push(currentToken); // ... se agrega al stack si no habian otros operadores.
                  else{ // Si habian otros, los agrega a la expresion en postfijo hasta que no haya ninguno de menor prioridad.
                     int topOperPriority = GetTokenPriority(operatorStack.Peek());
                     int currentTokenPriority = GetTokenPriority(currentToken);
                     while (operatorStack.Count > 0 && topOperPriority >= currentTokenPriority){
                        postfixExpression += operatorStack.Pop().Value + " ";
                        if (operatorStack.Count > 0) topOperPriority = GetTokenPriority(operatorStack.Peek());
                     }
                     operatorStack.Push(currentToken);
                  }
                  break;

               case TokenType.Invalid:
                  throw new InvalidOperationException("Invalid token in expression.");
            }
            prevToken = enumerator.Current;
             }
             // Si la expresion termino de parsearse, agrega los operadores restantes a la expresion en postfijo.
             while (operatorStack.Count > 0)
             {
            postfixExpression += operatorStack.Pop().Value + " ";
             }

             return EvaluatePostfix(postfixExpression); // Pasa la expresion construida al metodo que evalua en si.
        }
Exemple #3
0
        /// <summary>
        /// Guarda un valor en el array dado.
        /// </summary>
        /// <param name="arrayWithIndices">Array donde guardar el valor.</param>
        /// <param name="expression">Expresion a evaluar.</param>
        private void SaveToArray(string arrayWithIndices, string expression)
        {
            Tokenizer t = new Tokenizer(arrayWithIndices);

             var enumerator = t.GetTokens().GetEnumerator();
             string arrayName = "";

             enumerator.MoveNext();
             if (enumerator.Current.Type == TokenType.Name)
            arrayName = enumerator.Current.Value;
             else throw new Exception("Invalid array name.");

             enumerator.MoveNext();
             if (enumerator.Current.Type != TokenType.OpenedBracket) throw new Exception("Invalid array name.");

             string preIndex = "";
             while (enumerator.MoveNext()){
            preIndex += enumerator.Current.Value;
             }
             preIndex.Replace("]", ""); // Quitar el último corchete

             string index = ParseArrayIndex(preIndex);

             index = index.Trim();
             Arrays.AssignToArray(arrayName, index, new Variable(Evaluate(expression)));
        }
Exemple #4
0
        /// <summary>
        /// Separa el nombre del array de sus indices.
        /// </summary>
        /// <param name="arrayWithIndices"></param>
        /// <returns></returns>
        private Variable GetArrayValue(string arrayWithIndices)
        {
            string arrayName = "";
             Tokenizer t = new Tokenizer(arrayWithIndices);

             var enumerator = t.GetTokens().GetEnumerator();

             enumerator.MoveNext(); // Pone el cursor en el nombre
             arrayName = enumerator.Current.Value;

             string preIndex = "";

             enumerator.MoveNext(); // Pone el cursor en el [

             while (enumerator.MoveNext() && enumerator.Current.Type!= TokenType.ClosedBracket){
            preIndex += enumerator.Current.Value + " ";
             }
             enumerator.MoveNext();

             string index = ParseArrayIndex(preIndex);

             return Arrays.GetValueInArray(arrayName, index);
        }
Exemple #5
0
        /// <summary>
        /// Evalua una expresion dada en notacion postfijo.
        /// </summary>
        /// <param name="postfixExp">Expresion en postfijo a evaluar.</param>
        /// <returns>El valor resultante de la evaluacion.</returns>
        private string EvaluatePostfix(string postfixExp)
        {
            Stack<Operand> operandStack = new Stack<Operand>();

             string[] tokenArray = postfixExp.Split(' ');

             foreach (string pretoken in tokenArray)
             {
            Tokenizer token = new Tokenizer(pretoken);
            IEnumerator<Token> enumerator = token.GetTokens().GetEnumerator();

            while (enumerator.MoveNext())
            {
               Token item = enumerator.Current;
               switch (item.Type)
               {
                  case TokenType.True:
                     operandStack.Push(new Operand(true));
                     break;
                  case TokenType.False:
                     operandStack.Push(new Operand(false));
                     break;
                  case TokenType.Constant:
                     operandStack.Push(new Operand(int.Parse(item.Value)));
                     break;

                  case TokenType.Minus:
                     if (enumerator.MoveNext() && enumerator.Current.Type != TokenType.Minus) operandStack.Push(new Operand(int.Parse(enumerator.Current.Value) * -1));
                     else goto case TokenType.Plus;

                     break;

                  case TokenType.Plus:
                  case TokenType.Asterisk:
                  case TokenType.Slash:
                  case TokenType.Percent:
                  case TokenType.Ampersand:
                  case TokenType.Caret:
                  case TokenType.Greater:
                  case TokenType.GreaterEqual:
                  case TokenType.Less:
                  case TokenType.LessEqual:
                  case TokenType.Equal:
                  case TokenType.NotEqual:
                     try
                     {
                        IOperator oper = Operations[item.Value];
                        Operand op2 = operandStack.Pop();
                        Operand op1 = operandStack.Pop();
                        operandStack.Push(oper.Eval(op1, op2));
                     }
                     catch (InvalidCastException e)
                     {
                        throw new InvalidOperationException("Incorrect expression.", e);
                     }
                     break;
                  default:
                     throw new InvalidOperationException("Incorrect input expression.");
               }
            }

             }

             if (operandStack.Count == 1)
             {
            string result = operandStack.Pop().Value.ToString();
            return result;
             }
             else throw new Exception("Unknown error.");
        }
Exemple #6
0
        /// <summary>
        /// Dada una expresion, reconoce los nombres de sensores presentes en ella, 
        /// y sustituye esos literales por sus valores.
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        private string ParseSensorData(string expression)
        {
            if (expression == null || expression == "") return "";
             Tokenizer tokenizer = new Tokenizer(expression);

             var enumerator = tokenizer.GetTokens().GetEnumerator();

             while (enumerator.MoveNext())
             {
            Token current = enumerator.Current;

            string possibleSensorName = "";
            string possibleSensorProperty = "";

            if (current != null && current.Type == TokenType.Name)
            {

               possibleSensorName = current.Value;
               enumerator.MoveNext();
               if (enumerator.Current.Type == TokenType.Dot)
               {
                  enumerator.MoveNext();
                  if (enumerator.Current.Type == TokenType.Name)
                  {
                     possibleSensorProperty = enumerator.Current.Value;
                  }
                  else throw new Exception("Invalid expression");
               }
            }

            if (possibleSensorName != "" && possibleSensorProperty != "")
            {
               string fullSensorLiteral = possibleSensorName + "." + possibleSensorProperty;
               possibleSensorName = possibleSensorName.ToLower();
               possibleSensorProperty = possibleSensorProperty.ToLower();
               bool ok = false;

               //Comienza por parsear los colores.
               if (possibleSensorName == "color")
               {
                  Color c = Color.FromName(possibleSensorProperty);
                  if (c.IsKnownColor)
                  {
                     expression.Replace(fullSensorLiteral, c.ToArgb().ToString());
                  }
                  else throw new Exception("A specified color is not supported or does not exist.");
               }
               else
               {
                  // Se usa Reflection para obtener todos los sensores del robot con sus correspondientes valores.
                  RobotSensors conjunto = Robot.Sensors;

                  var typeOfSensores = conjunto.GetType();

                  PropertyInfo[] sensoresProperties = typeOfSensores.GetProperties();

                  string result = "";

                  foreach (PropertyInfo info in sensoresProperties)
                  {
                     var l = info.GetValue(conjunto, null);

                     Type currentSensorType = l.GetType();
                     if (currentSensorType.Name.ToLower() == possibleSensorName)
                     {
                        foreach (PropertyInfo sensorProperties in currentSensorType.GetProperties())
                        {
                           if (sensorProperties.Name.ToLower() == possibleSensorProperty)
                           {
                              var value = sensorProperties.GetValue(l, null);
                              if (value != null)
                              {
                                 result = value.ToString();
                                 expression = expression.Replace(fullSensorLiteral, result);
                                 ok = true;
                                 break;
                              }
                           }
                        }
                     }
                  }
                  if (!ok) throw new Exception("A specified sensor or property does not exist.");
               }
            }
             }
             return expression;
        }