// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

package com.google.dart.compiler.parser;

import java.util.HashMap;
import java.util.Map;

/**
 * Dart tokens and associated data.
 *
 * Note: Token ordinals matter for some accessors, so don't change the order of these without
 * knowing what you're doing.
 */
public enum Token {
  /* End-of-stream. */
  EOS(null, 0),

  /* Punctuators. */
  AT("@", 0),
  LPAREN("(", 0),
  RPAREN(")", 0),
  LBRACK("[", 0),
  RBRACK("]", 0),
  LBRACE("{", 0),
  RBRACE("}", 0),
  COLON(":", 0),
  SEMICOLON(";", 0),
  PERIOD(".", 0),
  CASCADE("..", 2),
  ELLIPSIS("...", 0),
  COMMA(",", 0),
  CONDITIONAL("?", 3),
  ARROW("=>", 0),

  /* Assignment operators. */
  ASSIGN("=", 1),
  ASSIGN_BIT_OR("|=", 1),
  ASSIGN_BIT_XOR("^=", 1),
  ASSIGN_BIT_AND("&=", 1),
  ASSIGN_SHL("<<=", 1),
  ASSIGN_SAR(">>=", 1),
  ASSIGN_ADD("+=", 1),
  ASSIGN_SUB("-=", 1),
  ASSIGN_MUL("*=", 1),
  ASSIGN_DIV("/=", 1),
  ASSIGN_MOD("%=", 1),
  ASSIGN_TRUNC("~/=", 1),

  /* Binary operators sorted by precedence. */
  OR("||", 4),
  AND("&&", 5),
  BIT_OR("|", 6),
  BIT_XOR("^", 7),
  BIT_AND("&", 8),
  SHL("<<", 11),
  SAR(">>", 11),
  ADD("+", 12),
  SUB("-", 12),
  MUL("*", 13),
  DIV("/", 13),
  TRUNC("~/", 13),
  MOD("%", 13),

  /* Compare operators sorted by precedence. */
  EQ("==", 9),
  NE("!=", 9),
  EQ_STRICT("===", 9),
  NE_STRICT("!==", 9),
  LT("<", 10),
  GT(">", 10),
  LTE("<=", 10),
  GTE(">=", 10),
  AS("as", 10),
  IS("is", 10),

  /* Unary operators. */
  NOT("!", 0),
  BIT_NOT("~", 0),

  /* Count operators (also unary). */
  INC("++", 0),
  DEC("--", 0),

  /* [] operator overloading. */
  INDEX("[]", 0),
  ASSIGN_INDEX("[]=", 0),

  /* Keywords. */
  ASSERT("assert", 0),
  BREAK("break", 0),
  CASE("case", 0),
  CATCH("catch", 0),
  CLASS("class",0),
  CONST("const", 0),
  CONTINUE("continue", 0),
  DEFAULT("default", 0),
  DO("do", 0),
  ELSE("else", 0),
  EXTENDS("extends", 0),
  FINAL("final", 0),
  FINALLY("finally", 0),
  FOR("for", 0),
  IF("if", 0),
  IN("in", 0),
  NEW("new", 0),
  RETHROW("rethrow", 0),
  RETURN("return", 0),
  SUPER("super", 0),
  SWITCH("switch", 0),
  THIS("this", 0),
  THROW("throw", 0),
  TRY("try", 0),
  VAR("var", 0),
  VOID("void", 0),
  WHILE("while", 0),
  WITH("with", 0),

  /* Literals. */
  NULL_LITERAL("null", 0),
  TRUE_LITERAL("true", 0),
  FALSE_LITERAL("false", 0),
  HEX_LITERAL(null, 0),
  INTEGER_LITERAL(null, 0),
  DOUBLE_LITERAL(null, 0),
  STRING(null, 0),

  /** String interpolation and string templates. */
  STRING_SEGMENT(null, 0),
  STRING_LAST_SEGMENT(null, 0),
  // STRING_EMBED_EXP_START does not have a unique string representation in the code:
  //   "$id" yields the token STRING_EMBED_EXP_START after the '$', and similarly
  //   "${id}" yield the same token for '${'.
  STRING_EMBED_EXP_START(null, 0),
  STRING_EMBED_EXP_END(null, 0),

  // Note: STRING_EMBED_EXP_END uses the same symbol as RBRACE, but it is
  // recognized by the scanner when closing embedded expressions in string
  // interpolation and string templates.

  /* Directives */
  LIBRARY("#library", 0),
  IMPORT("#import", 0),
  SOURCE("#source", 0),
  RESOURCE("#resource", 0),
  NATIVE("#native", 0),

  /* Identifiers (not keywords). */
  IDENTIFIER(null, 0),
  WHITESPACE(null, 0),

  /* Pseudo tokens. */
  // If you add another pseudo token, don't forget to update the predicate below.
  ILLEGAL(null, 0),
  COMMENT(null, 0),

  /**
   * Non-token to be used by tools where a value outside the range of anything
   * returned by the scanner is needed. This is the equivalent of -1 in a C
   * tokenizer.
   *
   * This token is never returned by the scanner. It must have an ordinal
   * value outside the range of all tokens returned by the scanner.
   */
  NON_TOKEN(null, 0);

  private static Map<String, Token> tokens = new HashMap<String, Token>();

  static {
    for (Token tok : Token.values()) {
      if (tok.syntax_ != null) {
        tokens.put(tok.syntax_, tok);
      }
    }
  }

  /**
   * Given a string finds the corresponding token. Pseudo tokens (EOS, ILLEGAL and COMMENT) are
   * ignored.
   */
  public static Token lookup(String syntax) {
    Token token = tokens.get(syntax);
    if ("as".equals(syntax)) {
      return IDENTIFIER;
    }
    if (token == null) {
      return IDENTIFIER;
    }
    return token;
  }

  private final String syntax_;
  private final int precedence_;

  /**
   * The <CODE>syntax</CODE> parameter serves two purposes: 1. map tokens that
   * look like identifiers ("null", "true", etc.) to their correct token.
   * 2. Find the string-representation of operators.</BR>
   * When it is <CODE>null</CODE> then the token either doesn't have a unique
   * representation, or it is a pseudo token (which doesn't physically appear
   * in the source).
   */
  Token(String syntax, int precedence) {
    syntax_ = syntax;
    precedence_ = precedence;
  }

  public Token asBinaryOperator() {
    int ordinal = ordinal() - ASSIGN_BIT_OR.ordinal() + BIT_OR.ordinal();
    return values()[ordinal];
  }

  public int getPrecedence() {
    return precedence_;
  }

  public String getSyntax() {
    return syntax_;
  }

  public boolean isEqualityOperator() {
    int ordinal = ordinal();
    return EQ.ordinal() <= ordinal && ordinal <= NE_STRICT.ordinal();
  }

  public boolean isRelationalOperator() {
    int ordinal = ordinal();
    return LT.ordinal() <= ordinal && ordinal <= GTE.ordinal();
  }

  public boolean isAssignmentOperator() {
    int ordinal = ordinal();
    return ASSIGN.ordinal() <= ordinal && ordinal <= ASSIGN_TRUNC.ordinal();
  }

  public boolean isBinaryOperator() {
    int ordinal = ordinal();
    return (ASSIGN.ordinal() <= ordinal && ordinal <= IS.ordinal())
        || (ordinal == COMMA.ordinal());
  }

  public boolean isCountOperator() {
    int ordinal = ordinal();
    return INC.ordinal() <= ordinal && ordinal <= DEC.ordinal();
  }

  public boolean isUnaryOperator() {
    int ordinal = ordinal();
    return NOT.ordinal() <= ordinal && ordinal <= DEC.ordinal();
  }

  public boolean isUserDefinableOperator() {
    int ordinal = ordinal();
    return ((BIT_OR.ordinal() <= ordinal && ordinal <= GTE.ordinal())
        || this == BIT_NOT || this == INDEX || this == ASSIGN_INDEX)
        && this != NE && this != EQ_STRICT && this != NE_STRICT;
  }

  @Override
  public String toString() {
    String result = getSyntax();
    if (result == null) {
      return name();
    }
    return result;
  }
}
