// Copyright (c) 2015, 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.

library dart2js.operators;

import '../elements/elements.dart';
import '../universe/call_structure.dart' show CallStructure;
import '../universe/selector.dart' show Selector, SelectorKind;

enum UnaryOperatorKind { NOT, NEGATE, COMPLEMENT, }

class UnaryOperator {
  final UnaryOperatorKind kind;
  final String name;
  final String selectorName;

  const UnaryOperator(this.kind, this.name, this.selectorName);

  bool get isUserDefinable => selectorName != null;

  Selector get selector => new Selector(SelectorKind.OPERATOR,
      new PublicName(selectorName), CallStructure.NO_ARGS);

  String toString() => name;

  /// The unary ! operator.
  static const UnaryOperator NOT =
      const UnaryOperator(UnaryOperatorKind.NOT, '!', null);

  /// The unary - operator.
  static const UnaryOperator NEGATE =
      const UnaryOperator(UnaryOperatorKind.NEGATE, '-', 'unary-');

  /// The unary ~ operator.
  static const UnaryOperator COMPLEMENT =
      const UnaryOperator(UnaryOperatorKind.COMPLEMENT, '~', '~');

  static UnaryOperator parse(String value) {
    switch (value) {
      case '!':
        return NOT;
      case '-':
        return NEGATE;
      case '~':
        return COMPLEMENT;
      default:
        return null;
    }
  }

  static UnaryOperator fromKind(UnaryOperatorKind kind) {
    switch (kind) {
      case UnaryOperatorKind.NOT:
        return NOT;
      case UnaryOperatorKind.NEGATE:
        return NEGATE;
      case UnaryOperatorKind.COMPLEMENT:
        return COMPLEMENT;
    }
  }
}

enum BinaryOperatorKind {
  EQ,
  NOT_EQ,
  INDEX,
  ADD,
  SUB,
  MUL,
  DIV,
  IDIV,
  MOD,
  SHL,
  SHR,
  GTEQ,
  GT,
  LTEQ,
  LT,
  AND,
  OR,
  XOR,
  LOGICAL_AND,
  LOGICAL_OR,
  IF_NULL,
}

class BinaryOperator {
  final BinaryOperatorKind kind;
  final String name;

  const BinaryOperator._(this.kind, this.name);

  /// `true` if this operator can be implemented through an `operator [name]`
  /// method.
  bool get isUserDefinable => true;

  String get selectorName => name;

  String toString() => name;

  /// The == operator.
  static const BinaryOperator EQ =
      const BinaryOperator._(BinaryOperatorKind.EQ, '==');

  /// The != operator.
  static const BinaryOperator NOT_EQ = const _NotEqualsOperator();

  /// The [] operator.
  static const BinaryOperator INDEX =
      const BinaryOperator._(BinaryOperatorKind.INDEX, '[]');

  /// The binary + operator.
  static const BinaryOperator ADD =
      const BinaryOperator._(BinaryOperatorKind.ADD, '+');

  /// The binary - operator.
  static const BinaryOperator SUB =
      const BinaryOperator._(BinaryOperatorKind.SUB, '-');

  /// The binary * operator.
  static const BinaryOperator MUL =
      const BinaryOperator._(BinaryOperatorKind.MUL, '*');

  /// The binary / operator.
  static const BinaryOperator DIV =
      const BinaryOperator._(BinaryOperatorKind.DIV, '/');

  /// The binary ~/ operator.
  static const BinaryOperator IDIV =
      const BinaryOperator._(BinaryOperatorKind.IDIV, '~/');

  /// The binary % operator.
  static const BinaryOperator MOD =
      const BinaryOperator._(BinaryOperatorKind.MOD, '%');

  /// The binary << operator.
  static const BinaryOperator SHL =
      const BinaryOperator._(BinaryOperatorKind.SHL, '<<');

  /// The binary >> operator.
  static const BinaryOperator SHR =
      const BinaryOperator._(BinaryOperatorKind.SHR, '>>');

  /// The binary >= operator.
  static const BinaryOperator GTEQ =
      const BinaryOperator._(BinaryOperatorKind.GTEQ, '>=');

  /// The binary > operator.
  static const BinaryOperator GT =
      const BinaryOperator._(BinaryOperatorKind.GT, '>');

  /// The binary <= operator.
  static const BinaryOperator LTEQ =
      const BinaryOperator._(BinaryOperatorKind.LTEQ, '<=');

  /// The binary < operator.
  static const BinaryOperator LT =
      const BinaryOperator._(BinaryOperatorKind.LT, '<');

  /// The binary & operator.
  static const BinaryOperator AND =
      const BinaryOperator._(BinaryOperatorKind.AND, '&');

  /// The binary | operator.
  static const BinaryOperator OR =
      const BinaryOperator._(BinaryOperatorKind.OR, '|');

  /// The binary ^ operator.
  static const BinaryOperator XOR =
      const BinaryOperator._(BinaryOperatorKind.XOR, '^');

  /// The logical && operator.
  static const BinaryOperator LOGICAL_AND =
      const _LogicalOperator(BinaryOperatorKind.LOGICAL_AND, '&&');

  /// The binary | operator.
  static const BinaryOperator LOGICAL_OR =
      const _LogicalOperator(BinaryOperatorKind.LOGICAL_OR, '||');

  /// The if-null ?? operator.
  static const BinaryOperator IF_NULL =
      const _IfNullOperator(BinaryOperatorKind.IF_NULL, '??');

  static BinaryOperator parse(String value) {
    switch (value) {
      case '==':
        return EQ;
      case '!=':
        return NOT_EQ;
      case '[]':
        return INDEX;
      case '*':
        return MUL;
      case '/':
        return DIV;
      case '%':
        return MOD;
      case '~/':
        return IDIV;
      case '+':
        return ADD;
      case '-':
        return SUB;
      case '<<':
        return SHL;
      case '>>':
        return SHR;
      case '>=':
        return GTEQ;
      case '>':
        return GT;
      case '<=':
        return LTEQ;
      case '<':
        return LT;
      case '&':
        return AND;
      case '^':
        return XOR;
      case '|':
        return OR;
      case '&&':
        return LOGICAL_AND;
      case '||':
        return LOGICAL_OR;
      case '??':
        return IF_NULL;
      default:
        return null;
    }
  }

  static BinaryOperator fromKind(BinaryOperatorKind kind) {
    switch (kind) {
      case BinaryOperatorKind.EQ:
        return EQ;
      case BinaryOperatorKind.NOT_EQ:
        return NOT_EQ;
      case BinaryOperatorKind.INDEX:
        return INDEX;
      case BinaryOperatorKind.MUL:
        return MUL;
      case BinaryOperatorKind.DIV:
        return DIV;
      case BinaryOperatorKind.MOD:
        return MOD;
      case BinaryOperatorKind.IDIV:
        return IDIV;
      case BinaryOperatorKind.ADD:
        return ADD;
      case BinaryOperatorKind.SUB:
        return SUB;
      case BinaryOperatorKind.SHL:
        return SHL;
      case BinaryOperatorKind.SHR:
        return SHR;
      case BinaryOperatorKind.GTEQ:
        return GTEQ;
      case BinaryOperatorKind.GT:
        return GT;
      case BinaryOperatorKind.LTEQ:
        return LTEQ;
      case BinaryOperatorKind.LT:
        return LT;
      case BinaryOperatorKind.AND:
        return AND;
      case BinaryOperatorKind.XOR:
        return XOR;
      case BinaryOperatorKind.OR:
        return OR;
      case BinaryOperatorKind.LOGICAL_AND:
        return LOGICAL_AND;
      case BinaryOperatorKind.LOGICAL_OR:
        return LOGICAL_OR;
      case BinaryOperatorKind.IF_NULL:
        return IF_NULL;
    }
  }
}

/// The operator !=, which is not user definable operator but instead is a
/// negation of a call to user definable operator, namely ==.
class _NotEqualsOperator extends BinaryOperator {
  const _NotEqualsOperator() : super._(BinaryOperatorKind.NOT_EQ, '!=');

  bool get isUserDefinable => false;

  String get selectorName => '==';
}

/// The operators && and || which are not user definable operators but control
/// structures.
class _LogicalOperator extends BinaryOperator {
  const _LogicalOperator(BinaryOperatorKind kind, String name)
      : super._(kind, name);

  bool get isUserDefinable => false;

  String get selectorName => null;
}

/// The operators ?? is not user definable.
class _IfNullOperator extends BinaryOperator {
  const _IfNullOperator(BinaryOperatorKind kind, String name)
      : super._(kind, name);

  bool get isUserDefinable => false;

  String get selectorName => '??';
}

enum AssignmentOperatorKind {
  ASSIGN,
  IF_NULL,
  ADD,
  SUB,
  MUL,
  DIV,
  IDIV,
  MOD,
  SHL,
  SHR,
  AND,
  OR,
  XOR,
}

class AssignmentOperator {
  final AssignmentOperatorKind kind;
  final BinaryOperator binaryOperator;
  final String name;
  final bool isUserDefinable;

  const AssignmentOperator._(this.kind, this.name, this.binaryOperator,
      {this.isUserDefinable: true});

  String get selectorName {
    return binaryOperator != null ? binaryOperator.selectorName : null;
  }

  String toString() => name;

  /// The = operator.
  static const AssignmentOperator ASSIGN = const AssignmentOperator._(
      AssignmentOperatorKind.ASSIGN, '=', null,
      isUserDefinable: false);

  /// The ??= operator.
  static const AssignmentOperator IF_NULL = const AssignmentOperator._(
      AssignmentOperatorKind.IF_NULL, '??=', BinaryOperator.IF_NULL,
      isUserDefinable: false);

  /// The += assignment operator.
  static const AssignmentOperator ADD = const AssignmentOperator._(
      AssignmentOperatorKind.ADD, '+=', BinaryOperator.ADD);

  /// The -= assignment operator.
  static const AssignmentOperator SUB = const AssignmentOperator._(
      AssignmentOperatorKind.SUB, '-=', BinaryOperator.SUB);

  /// The *= assignment operator.
  static const AssignmentOperator MUL = const AssignmentOperator._(
      AssignmentOperatorKind.MUL, '*=', BinaryOperator.MUL);

  /// The /= assignment operator.
  static const AssignmentOperator DIV = const AssignmentOperator._(
      AssignmentOperatorKind.DIV, '/=', BinaryOperator.DIV);

  /// The ~/= assignment operator.
  static const AssignmentOperator IDIV = const AssignmentOperator._(
      AssignmentOperatorKind.IDIV, '~/=', BinaryOperator.IDIV);

  /// The %= assignment operator.
  static const AssignmentOperator MOD = const AssignmentOperator._(
      AssignmentOperatorKind.MOD, '%=', BinaryOperator.MOD);

  /// The <<= assignment operator.
  static const AssignmentOperator SHL = const AssignmentOperator._(
      AssignmentOperatorKind.SHL, '<<=', BinaryOperator.SHL);

  /// The >>= assignment operator.
  static const AssignmentOperator SHR = const AssignmentOperator._(
      AssignmentOperatorKind.SHR, '>>=', BinaryOperator.SHR);

  /// The &= assignment operator.
  static const AssignmentOperator AND = const AssignmentOperator._(
      AssignmentOperatorKind.AND, '&=', BinaryOperator.AND);

  /// The |= assignment operator.
  static const AssignmentOperator OR = const AssignmentOperator._(
      AssignmentOperatorKind.OR, '|=', BinaryOperator.OR);

  /// The ^= assignment operator.
  static const AssignmentOperator XOR = const AssignmentOperator._(
      AssignmentOperatorKind.XOR, '^=', BinaryOperator.XOR);

  static AssignmentOperator parse(String value) {
    switch (value) {
      case '=':
        return ASSIGN;
      case '??=':
        return IF_NULL;
      case '*=':
        return MUL;
      case '/=':
        return DIV;
      case '%=':
        return MOD;
      case '~/=':
        return IDIV;
      case '+=':
        return ADD;
      case '-=':
        return SUB;
      case '<<=':
        return SHL;
      case '>>=':
        return SHR;
      case '&=':
        return AND;
      case '^=':
        return XOR;
      case '|=':
        return OR;
      default:
        return null;
    }
  }

  static AssignmentOperator fromKind(AssignmentOperatorKind kind) {
    switch (kind) {
      case AssignmentOperatorKind.ASSIGN:
        return ASSIGN;
      case AssignmentOperatorKind.IF_NULL:
        return IF_NULL;
      case AssignmentOperatorKind.ADD:
        return ADD;
      case AssignmentOperatorKind.SUB:
        return SUB;
      case AssignmentOperatorKind.MUL:
        return MUL;
      case AssignmentOperatorKind.DIV:
        return DIV;
      case AssignmentOperatorKind.IDIV:
        return IDIV;
      case AssignmentOperatorKind.MOD:
        return MOD;
      case AssignmentOperatorKind.SHL:
        return SHL;
      case AssignmentOperatorKind.SHR:
        return SHR;
      case AssignmentOperatorKind.AND:
        return AND;
      case AssignmentOperatorKind.OR:
        return OR;
      case AssignmentOperatorKind.XOR:
        return XOR;
    }
  }
}

enum IncDecOperatorKind { INC, DEC }

class IncDecOperator {
  final IncDecOperatorKind kind;
  final String name;
  final BinaryOperator binaryOperator;

  const IncDecOperator._(this.kind, this.name, this.binaryOperator);

  String get selectorName => binaryOperator.selectorName;

  String toString() => name;

  /// The prefix/postfix ++ operator.
  static const IncDecOperator INC =
      const IncDecOperator._(IncDecOperatorKind.INC, '++', BinaryOperator.ADD);

  /// The prefix/postfix -- operator.
  static const IncDecOperator DEC =
      const IncDecOperator._(IncDecOperatorKind.DEC, '--', BinaryOperator.SUB);

  static IncDecOperator parse(String value) {
    switch (value) {
      case '++':
        return INC;
      case '--':
        return DEC;
      default:
        return null;
    }
  }

  static IncDecOperator fromKind(IncDecOperatorKind kind) {
    switch (kind) {
      case IncDecOperatorKind.INC:
        return INC;
      case IncDecOperatorKind.DEC:
        return DEC;
    }
  }
}
