/*
 *  Copyright (c) 2008 Cyrille Berger <cberger@cberger.net>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * either version 2, or (at your option) any later version of the License.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#ifndef _CAUCHY_TOKEN_H_
#define _CAUCHY_TOKEN_H_

#include <Cauchy/String.h>
#include "Type.h"
#include <sstream>

namespace Cauchy {
  /**
   * @internal
   * @ingroup Cauchy
   * This structure holds information concerning a token, like position (line / column),
   * type or value (for string, integer, float or identifier).
   */
  struct Token {
    /**
      * List of possible token type
      */
    enum Type {
    // Not really token
      COMMENT = -5, ///< We want preservation of matlab comments in the output
      UNFINISHED_STRING = -4,
      END_OF_FILE = -3,
      END_OF_LINE = -2,
      UNKNOWN = - 1,
    // Special characters
      SEMI = 0, ///< ;
      COLON, ///< :
      COMA, ///< ,
      DOT, ///< .
      TRANSPOSE, ///< '
      STARTBRACE, ///< {
      ENDBRACE, ///< }
      STARTBRACKET, ///< (
      ENDBRACKET, ///< )
      STARTBOXBRACKET, ///< [
      ENDBOXBRACKET, ///< ]
      EQUAL, ///< =
      EQUALEQUAL, ///< ==
      PLUSEQUAL, ///< +=
      DOTPLUSEQUAL, ///< .+=
      MINUSEQUAL, ///< -=
      DOTMINUSEQUAL, ///< .-=
      MULTIPLYEQUAL, ///< *=
      DOTMULTIPLYEQUAL, ///< .*=
      DIVIDEEQUAL, ///< /=
      DOTDIVIDEEQUAL, ///< ./=
      DIFFERENT, ///< !=
      AND, ///< and &&
      OR, ///< or ||
      INFERIOR, ///< <
      INFERIOREQUAL, ///< <=
      SUPPERIOR, ///< >
      SUPPERIOREQUAL, ///< >=
      PLUS, ///< + followed by a space
      PLUSSMTHG, ///< + not followed by a space
      DOTPLUS, ///< .+
      PLUSPLUS, ///< ++
      MINUS, ///< -
      MINUSSMTHG, ///< - not followed by a space
      DOTMINUS, ///< .-
      MINUSMINUS, ///< --
      MULTIPLY, ///< *
      DOTMULTIPLY, ///< .*
      DIVIDE, ///< /
      DOTDIVIDE, ///< ./
      TILDE, ///< ~
      NOT, ///< not !
      POWER, ///< ^ (** in octave)
      DOTPOWER, ///< .^ (.** in octave)
      AROBASE, ///< @
      // Constants
      FLOAT_CONSTANT,
      INTEGER_CONSTANT,
      COMPLEX_CONSTANT,
      STRING_CONSTANT,
      IDENTIFIER,
      // Keywords,
      ELSE,
      FOR,
      IF,
      ELSEIF,
      RETURN,
      WHILE,
      END,
      FUNCTION,
      GLOBAL,
      BREAK
    };
    /// type of the token
    Type type;
    /// line of the token
    int line;
    /// Column of the token
    int column;
    /// String or identifier name
    String string;
    Token();
    /**
      * Creates a token of the given type
      */
    Token(Type _type, int _line, int _column);
    /**
      * Creates an identifier or a string constant or a number constant
      */
    Token(Type _type, const String& _string, int _line, int _column);
    bool isExpressionTerminal();
    bool isConstant() const;
    bool isBinaryOperator() const;
    int binaryOperationPriority() const;
    bool isUnaryOperator() const;
    bool isOperator() const;
    bool isPrimary() const;
    static String typeToString(Type );
  };

};


#endif
