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

// SExpressionUnstringifier implements the inverse operation to
// [SExpressionStringifier].

library sexpr_unstringifier;

import 'package:compiler/implementation/dart2jslib.dart' as dart2js
  show Constant, IntConstant, NullConstant, StringConstant,
       DoubleConstant, TrueConstant, FalseConstant, MessageKind;
import 'package:compiler/implementation/dart_types.dart' as dart_types
  show DartType;
import 'package:compiler/implementation/elements/elements.dart'
  show Entity, Element, Elements, Local, TypeVariableElement, ErroneousElement,
       TypeDeclarationElement, ExecutableElement;
import 'package:compiler/implementation/elements/modelx.dart'
  show ErroneousElementX, TypeVariableElementX;
import 'package:compiler/implementation/tree/tree.dart'show LiteralDartString;
import 'package:compiler/implementation/universe/universe.dart'
  show Selector, SelectorKind;
import 'package:compiler/implementation/cps_ir/cps_ir_nodes.dart';

/// Used whenever a node constructed by [SExpressionUnstringifier] needs a
/// named entity.
class DummyEntity extends Entity {
  final String name;
  DummyEntity(this.name);
}

/// Used whenever a node constructed by [SExpressionUnstringifier] needs a
/// local.
class DummyLocal extends DummyEntity implements Local {
  DummyLocal(String name) : super(name);

  ExecutableElement get executableContext => null;
}

/// Used whenever a node constructed by [SExpressionUnstringifier] requires
/// an [Element] or [FunctionElement]. Extends [ErroneousElementX] since there
/// is currently a large amount of overhead when extending the base abstract
/// classes, and erroneous elements conveniently also skip several assertion
/// checks in CPS IR nodes that are irrelevant to us.
class DummyElement extends ErroneousElementX
    implements TypeVariableElement {
  DummyElement(String name)
      : super(dart2js.MessageKind.GENERIC, {}, name, null);

  final dart_types.DartType bound = null;
  final TypeDeclarationElement typeDeclaration = null;
}

/// Used whenever a node constructed by [SExpressionUnstringifier] requires
/// a named type.
class DummyNamedType extends dart_types.DartType {
  final String name;

  final kind = null;
  final element = null;

  DummyNamedType(this.name);

  subst(arguments, parameters) => null;
  unalias(compiler) => null;
  accept(visitor, argument) => null;

  String toString() => name;
}

/// Represents a list of tokens, but is basically a partial view into a list
/// with appropriate convenience methods.
class Tokens {
  final List<String> _list;
  int _index; // Current index into the list.

  Tokens(List<String> this._list) : _index = 0;

  String get current => _list[_index];
  String get next    => _list[_index + 1];

  String read([String expected]) {
    if (expected != null) {
      assert(current == expected);
    }
    return _list[_index++];
  }

  /// Consumes the preamble to a new node, consisting of an opening parenthesis
  /// and a tag.
  void consumeStart([String tag]) {
    read("(");
    if (tag != null) {
      read(tag);
    }
  }

  void consumeEnd() {
    read(")");
  }

  bool get hasNext  => _index < _list.length;
  String toString() => _list.sublist(_index).toString();
}

/// Constructs a minimal in-memory representation of the IR represented
/// by the given string. Many fields are currently simply set to null.
class SExpressionUnstringifier {

  // Expressions
  static const String BRANCH = "Branch";
  static const String CONCATENATE_STRINGS = "ConcatenateStrings";
  static const String DECLARE_FUNCTION = "DeclareFunction";
  static const String INVOKE_CONSTRUCTOR = "InvokeConstructor";
  static const String INVOKE_CONTINUATION = "InvokeContinuation";
  static const String INVOKE_CONTINUATION_RECURSIVE = "InvokeContinuation*";
  static const String INVOKE_STATIC = "InvokeStatic";
  static const String INVOKE_SUPER_METHOD = "InvokeSuperMethod";
  static const String INVOKE_METHOD = "InvokeMethod";
  static const String LET_PRIM = "LetPrim";
  static const String LET_CONT = "LetCont";
  static const String LET_CONT_RECURSIVE = "LetCont*";
  static const String SET_CLOSURE_VARIABLE = "SetClosureVariable";
  static const String TYPE_OPERATOR = "TypeOperator";

  // Primitives
  static const String CONSTANT = "Constant";
  static const String CREATE_FUNCTION = "CreateFunction";
  static const String GET_CLOSURE_VARIABLE = "GetClosureVariable";
  static const String LITERAL_LIST = "LiteralList";
  static const String LITERAL_MAP = "LiteralMap";
  static const String REIFY_TYPE_VAR = "ReifyTypeVar";
  static const String THIS = "This";

  // Other
  static const String FUNCTION_DEFINITION = "FunctionDefinition";
  static const String IS_TRUE = "IsTrue";

  final Map<String, Definition> name2variable =
      <String, Definition>{ "return": new Continuation.retrn() };

  // Operator names used for canonicalization. In theory, we could simply use
  // Elements.isOperatorName() on the parsed tokens; however, comparisons are
  // done using identical() for performance reasons, which are reliable only for
  // compile-time literal strings.
  static Set<String> OPERATORS = new Set<String>.from(
      [ '~', '==', '[]', '*', '/', '%', '~/', '+', '<<', 'unary-'
      , '>>', '>=', '>', '<=', '<', '&', '^', '|', '[]=', '-'
      ]);

  // The tokens currently being parsed.
  Tokens tokens;

  FunctionDefinition unstringify(String s) {
    tokens = tokenize(s);
    FunctionDefinition def = parseFunctionDefinition();
    assert(!tokens.hasNext);
    return def;
  }

  /// Returns a new named dummy selector with a roughly appropriate kind.
  Selector dummySelector(String name, int argumentCount) {
    SelectorKind kind;
    if (name == "[]") {
      kind = SelectorKind.INDEX;
    } else if (Elements.isOperatorName(name)) {
      kind = SelectorKind.OPERATOR;
    } else {
      kind = SelectorKind.CALL;
    }
    return new Selector(kind, name, null, argumentCount);
  }

  /// Returns the tokens in s. Note that string literals are not necessarily
  /// preserved; for instance, "(literalString)" is transformed to
  /// " ( literalString ) ".
  Tokens tokenize(String s) =>
      new Tokens(
          s.replaceAll("(", " ( ")
           .replaceAll(")", " ) ")
           .replaceAll(new RegExp(r"[ \t\n]+"), " ")
           .trim()
           .split(" ")
           .map(canonicalizeOperators)
           .toList());

  /// Canonicalizes strings containing operator names.
  String canonicalizeOperators(String token) {
    String opname = OPERATORS.lookup(token);
    if (opname != null) {
      return opname;
    }
    return token;
  }

  Expression parseExpression() {
    assert(tokens.current == "(");

    switch (tokens.next) {
      case BRANCH:
        return parseBranch();
      case CONCATENATE_STRINGS:
        return parseConcatenateStrings();
      case DECLARE_FUNCTION:
        return parseDeclareFunction();
      case INVOKE_CONSTRUCTOR:
        return parseInvokeConstructor();
      case INVOKE_CONTINUATION:
        return parseInvokeContinuation(false);
      case INVOKE_CONTINUATION_RECURSIVE:
        return parseInvokeContinuation(true);
      case INVOKE_METHOD:
        return parseInvokeMethod();
      case INVOKE_STATIC:
        return parseInvokeStatic();
      case INVOKE_SUPER_METHOD:
        return parseInvokeSuperMethod();
      case LET_PRIM:
        return parseLetPrim();
      case LET_CONT:
        return parseLetCont(false);
      case LET_CONT_RECURSIVE:
        return parseLetCont(true);
      case SET_CLOSURE_VARIABLE:
        return parseSetClosureVariable();
      case TYPE_OPERATOR:
        return parseTypeOperator();
      default:
        assert(false);
    }

    return null;
  }

  /// def1 def2 ... defn cont )
  /// Note that cont is *not* included in the returned list and not consumed.
  List<Definition> parseDefinitionList() {
    List<Definition> defs = <Definition>[];
    while (tokens.next != ")") {
      Definition def = name2variable[tokens.read()];
      assert(def != null);
      defs.add(def);
    }
    return defs;
  }

  /// (prim1 prim2 ... primn)
  List<Primitive> parsePrimitiveList() {
    tokens.consumeStart();
    List<Primitive> prims = <Primitive>[];
    while (tokens.current != ")") {
      Primitive prim = name2variable[tokens.read()];
      assert(prim != null);
      prims.add(prim);
    }
    tokens.consumeEnd();
    return prims;
  }

  /// (FunctionDefinition name (args cont) body)
  FunctionDefinition parseFunctionDefinition() {
    tokens.consumeStart(FUNCTION_DEFINITION);

    // name
    Element element = new DummyElement("");
    if (tokens.current != "(") {
      // This is a named function.
      element = new DummyElement(tokens.read());
    }

    // (args cont)
    List<Parameter> parameters = <Parameter>[];
    tokens.consumeStart();
    while (tokens.next != ")") {
      String paramName = tokens.read();
      Parameter param = new Parameter(new DummyElement(paramName));
      name2variable[paramName] = param;
      parameters.add(param);
    }

    String contName = tokens.read("return");
    Continuation cont = name2variable[contName];
    assert(cont != null);
    tokens.consumeEnd();

    // body
    Expression body = parseExpression();

    tokens.consumeEnd();
    return new FunctionDefinition(element, cont, parameters, body, null, null);
  }

  /// (IsTrue arg)
  Condition parseCondition() {
    // Handles IsTrue only for now.
    tokens.consumeStart(IS_TRUE);

    Definition value = name2variable[tokens.read()];
    assert(value != null);

    tokens.consumeEnd();
    return new IsTrue(value);
  }

  /// (Branch condition cont cont)
  Branch parseBranch() {
    tokens.consumeStart(BRANCH);

    Condition cond = parseCondition();
    Continuation trueCont = name2variable[tokens.read()];
    Continuation falseCont = name2variable[tokens.read()];
    assert(trueCont != null && falseCont != null);

    tokens.consumeEnd();
    return new Branch(cond, trueCont, falseCont);
  }

  /// (ConcatenateStrings args cont)
  ConcatenateStrings parseConcatenateStrings() {
    tokens.consumeStart(CONCATENATE_STRINGS);

    List<Definition> args = parseDefinitionList();

    Continuation cont = name2variable[tokens.read()];
    assert(cont != null);

    tokens.consumeEnd();
    return new ConcatenateStrings(cont, args);
  }

  /// (DeclareFunction name = function in body)
  DeclareFunction parseDeclareFunction() {
    tokens.consumeStart(DECLARE_FUNCTION);

    // name =
    Local local = new DummyLocal(tokens.read());
    tokens.read("=");

    // function in
    FunctionDefinition def = parseFunctionDefinition();
    tokens.read("in");

    // body
    Expression body = parseExpression();

    tokens.consumeEnd();
    return new DeclareFunction(local, def)..plug(body);
  }

  /// (InvokeConstructor name args cont)
  InvokeConstructor parseInvokeConstructor() {
    tokens.consumeStart(INVOKE_CONSTRUCTOR);

    String constructorName = tokens.read();
    List<String> split = constructorName.split(".");
    assert(split.length < 3);

    dart_types.DartType type = new DummyNamedType(split[0]);
    Element element = new DummyElement((split.length == 1) ? "" : split[1]);

    List<Definition> args = parseDefinitionList();

    Continuation cont = name2variable[tokens.read()];
    assert(cont != null);

    tokens.consumeEnd();
    Selector selector = dummySelector(constructorName, args.length);
    return new InvokeConstructor(type, element, selector, cont, args);
  }

  /// (InvokeContinuation name args)
  InvokeContinuation parseInvokeContinuation(bool recursive) {
    tokens.consumeStart(recursive
        ? INVOKE_CONTINUATION_RECURSIVE : INVOKE_CONTINUATION);

    Continuation cont = name2variable[tokens.read()];
    assert(cont != null);

    List<Definition> args = <Definition>[];
    while (tokens.current != ")") {
      Definition def = name2variable[tokens.read()];
      assert(def != null);
      args.add(def);
    }

    tokens.consumeEnd();
    return new InvokeContinuation(cont, args, recursive: recursive);
  }

  /// (InvokeMethod receiver method args cont)
  InvokeMethod parseInvokeMethod() {
    tokens.consumeStart(INVOKE_METHOD);

    Definition receiver = name2variable[tokens.read()];
    assert(receiver != null);

    String methodName = tokens.read();

    List<Definition> args = parseDefinitionList();

    Continuation cont = name2variable[tokens.read()];
    assert(cont != null);

    tokens.consumeEnd();
    Selector selector = dummySelector(methodName, args.length);
    return new InvokeMethod(receiver, selector, cont, args);
  }

  /// (InvokeStatic method args cont)
  InvokeStatic parseInvokeStatic() {
    tokens.consumeStart(INVOKE_STATIC);

    String methodName = tokens.read();

    List<Definition> args = parseDefinitionList();

    Continuation cont = name2variable[tokens.read()];
    assert(cont != null);

    Entity entity = new DummyEntity(methodName);
    Selector selector = dummySelector(methodName, args.length);

    tokens.consumeEnd();
    return new InvokeStatic(entity, selector, cont, args);
  }

  /// (InvokeSuperMethod method args cont)
  InvokeSuperMethod parseInvokeSuperMethod() {
    tokens.consumeStart(INVOKE_SUPER_METHOD);

    String methodName = tokens.read();

    List<Definition> args = parseDefinitionList();

    Continuation cont = name2variable[tokens.read()];
    assert(cont != null);

    tokens.consumeEnd();
    Selector selector = dummySelector(methodName, args.length);
    return new InvokeSuperMethod(selector, cont, args);
  }

  /// (LetCont (cont args) (cont_body)) body
  LetCont parseLetCont(bool recursive) {
    tokens.consumeStart(recursive ? LET_CONT_RECURSIVE : LET_CONT);

    // (name args) (cont_body))
    tokens.consumeStart();
    String name = tokens.read();

    List<Parameter> params = <Parameter>[];
    while (tokens.current != ")") {
      String paramName = tokens.read();
      Parameter param = new Parameter(new DummyElement(paramName));
      name2variable[paramName] = param;
      params.add(param);
    }
    tokens.consumeEnd();

    Continuation cont = new Continuation(params);
    name2variable[name] = cont;

    cont.isRecursive = recursive;
    cont.body = parseExpression();
    tokens.consumeEnd();

    // body
    Expression body = parseExpression();

    return new LetCont(cont, body);
  }

  /// (SetClosureVariable name value body)
  SetClosureVariable parseSetClosureVariable() {
    tokens.consumeStart(SET_CLOSURE_VARIABLE);

    Local local = new DummyLocal(tokens.read());
    Primitive value = name2variable[tokens.read()];
    assert(value != null);

    Expression body = parseExpression();

    tokens.consumeEnd();
    return new SetClosureVariable(local, value)
                  ..plug(body);
  }

  /// (TypeOperator operator recv type cont)
  TypeOperator parseTypeOperator() {
    tokens.consumeStart(TYPE_OPERATOR);

    String operator = tokens.read();

    Primitive recv = name2variable[tokens.read()];
    assert(recv != null);

    dart_types.DartType type = new DummyNamedType(tokens.read());

    Continuation cont = name2variable[tokens.read()];
    assert(cont != null);

    tokens.consumeEnd();
    return new TypeOperator(operator, recv, type, cont);
  }

  /// (LetPrim name (primitive)) body
  LetPrim parseLetPrim() {
    tokens.consumeStart(LET_PRIM);

    // name
    String name = tokens.read();

    // (primitive)
    Primitive primitive = parsePrimitive();
    name2variable[name] = primitive;
    tokens.consumeEnd();

    // body
    Expression body = parseExpression();

    return new LetPrim(primitive)..plug(body);
  }

  Primitive parsePrimitive() {
    assert(tokens.current == "(");

    switch (tokens.next) {
      case CONSTANT:
        return parseConstant();
      case CREATE_FUNCTION:
        return parseCreateFunction();
      case GET_CLOSURE_VARIABLE:
        return parseGetClosureVariable();
      case LITERAL_LIST:
        return parseLiteralList();
      case LITERAL_MAP:
        return parseLiteralMap();
      case REIFY_TYPE_VAR:
        return parseReifyTypeVar();
      case THIS:
        return parseThis();
      default:
        assert(false);
    }

    return null;
  }

  /// (Constant (constant))
  Constant parseConstant() {
    tokens.consumeStart(CONSTANT);
    String tag = tokens.read();

    // NullConstant.
    if (tag == "null") {
      tokens.consumeEnd();
      return new Constant(null, new dart2js.NullConstant());
    }

    // BoolConstant.
    if (tag == "true") {
      tokens.consumeEnd();
      return new Constant(null, new dart2js.TrueConstant());
    } else if (tag == "false") {
      tokens.consumeEnd();
      return new Constant(null, new dart2js.FalseConstant());
    }

    // StringConstant.
    if (tag == "StringConstant") {
      tokens.consumeStart();
      List<String> strings = <String>[];
      do {
        strings.add(tokens.read());
      } while (tokens.current != ")");
      tokens.consumeEnd();

      String string = strings.join(" ");
      assert(string.startsWith('"') && string.endsWith('"'));

      dart2js.StringConstant value = new dart2js.StringConstant(
          new LiteralDartString(string.substring(1, string.length - 1)));

      tokens.consumeEnd();
      return new Constant(null, value);
    }

    // IntConstant.
    int intValue = int.parse(tag, onError: (_) => null);
    if (intValue != null) {
      tokens.consumeEnd();
      return new Constant(null, new dart2js.IntConstant(intValue));
    }

    // DoubleConstant.
    double doubleValue = double.parse(tag, (_) => null);
    if (doubleValue != null) {
      tokens.consumeEnd();
      return new Constant(null, new dart2js.DoubleConstant(doubleValue));
    }

    assert(false);
    return null;
  }

  /// (CreateFunction (definition))
  CreateFunction parseCreateFunction() {
    tokens.consumeStart(CREATE_FUNCTION);
    FunctionDefinition def = parseFunctionDefinition();
    tokens.consumeEnd();
    return new CreateFunction(def);
  }

  /// (GetClosureVariable name)
  GetClosureVariable parseGetClosureVariable() {
    tokens.consumeStart(GET_CLOSURE_VARIABLE);

    Local local = new DummyLocal(tokens.read());
    tokens.consumeEnd();

    return new GetClosureVariable(local);
  }

  /// (LiteralList values)
  LiteralList parseLiteralList() {
    tokens.consumeStart(LITERAL_LIST);
    List<Primitive> values = parsePrimitiveList();
    tokens.consumeEnd();
    return new LiteralList(null, values);
  }

  /// (LiteralMap keys values)
  LiteralMap parseLiteralMap() {
    tokens.consumeStart(LITERAL_MAP);

    List<Primitive> keys   = parsePrimitiveList();
    List<Primitive> values = parsePrimitiveList();

    tokens.consumeEnd();
    return new LiteralMap(null, keys, values);
  }

  /// (ReifyTypeVar type)
  ReifyTypeVar parseReifyTypeVar() {
    tokens.consumeStart(REIFY_TYPE_VAR);

    TypeVariableElement type = new DummyElement(tokens.read());

    tokens.consumeEnd();
    return new ReifyTypeVar(type);
  }

  /// (This)
  This parseThis() {
    tokens.consumeStart(THIS);
    tokens.consumeEnd();
    return new This();
  }
}
