// 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;
    }
  }
}


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;
    }
  }
}
