// 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 cps_ir.cps_fragment;

import 'cps_ir_nodes.dart';
import '../constants/values.dart';
import '../universe/selector.dart' show Selector;
import '../types/types.dart' show TypeMask;
import '../io/source_information.dart';
import '../elements/elements.dart';

/// Builds a CPS fragment that can be plugged into another CPS term.
///
/// A CPS fragment contains a CPS term, possibly with a "hole" in it denoting
/// where to insert new IR nodes. We say a fragment is "open" if it has such
/// a hole. Otherwise, the fragment is "closed" and cannot be extended further.
///
/// This class is designed for building non-trivial CPS terms in a readable and
/// non-error prone manner. It is not designed to manipulate existing IR nodes,
/// nor is it intended to shield the user from every complexity in the IR.
///
/// EXAMPLES:
///
/// Call `cont` with `obj.field + 1` as argument:
///
///   CpsFragment cps = new CpsFragment();
///   var fieldValue = cps.letPrim(new GetField(obj, field));
///   var plusOne = cps.applyBuiltin(BuiltinOperator.NumAdd,
///                                  [fieldValue, cps.makeOne()]);
///   cps.invokeContinuation(cont, [plusOne]);
///
/// If `condition` is true then invoke `cont1`, else `cont2`.
///
///   cps.ifTruthy(condition).invokeContinuation(cont1, []);
///   cps.invokeContinuation(cont2, []);
///
/// If `condition` is true then invoke `cont` with a bound primitive:
///
///   CpsFragment branch = cps.ifTruthy(condition);
///   branch.invokeContinuation(cont, [branch.letPrim(arg)]);
///
/// Loop and call a method until it returns false:
///
///   Continuation loop = cps.beginLoop();
///   var result = cps.invokeMethod(receiver, selector, ...);
///   cps.ifFalsy(result).invokeContinuation(exit, []);
///   cps.continueLoop(loop);
///
class CpsFragment {
  /// The root of the IR built using this fragment.
  Expression root;

  /// Node whose body is the hole in this CPS fragment. May be null.
  InteriorNode context;

  /// Source information to attach to every IR node created in the fragment.
  SourceInformation sourceInformation;

  CpsFragment([this.sourceInformation, this.context]);

  bool get isOpen => root == null || context != null;
  bool get isClosed => !isOpen;
  bool get isEmpty => root == null;

  /// Asserts that the fragment is non-empty and closed and returns the IR that
  /// was built.
  Expression get result {
    assert(!isEmpty);
    assert(isClosed);
    return root;
  }

  /// Put the given expression into the fragment's hole.
  ///
  /// Afterwards the fragment is closed and cannot be extended until a new
  /// [context] is set.
  void put(Expression node) {
    assert(root == null || context != null); // We must put the node somewhere.
    if (root == null) {
      root = node;
    }
    if (context != null) {
      context.body = node;
      node.parent = context;
    }
    context = null;
  }

  /// Bind a primitive. Returns the same primitive for convenience.
  Primitive letPrim(Primitive prim) {
    assert(prim != null);
    LetPrim let = new LetPrim(prim);
    put(let);
    context = let;
    return prim;
  }

  /// Bind a constant value.
  Primitive makeConstant(ConstantValue constant) {
    return letPrim(new Constant(constant));
  }

  Primitive makeZero() => makeConstant(new IntConstantValue(0));
  Primitive makeOne() => makeConstant(new IntConstantValue(1));
  Primitive makeMinusOne() => makeConstant(new IntConstantValue(-1));
  Primitive makeNull() => makeConstant(new NullConstantValue());
  Primitive makeTrue() => makeConstant(new TrueConstantValue());
  Primitive makeFalse() => makeConstant(new FalseConstantValue());

  /// Invoke a built-in operator.
  Primitive applyBuiltin(BuiltinOperator op, List<Primitive> args) {
    return letPrim(new ApplyBuiltinOperator(op, args, sourceInformation));
  }

  Primitive refine(Primitive value, TypeMask type) {
    return letPrim(new Refinement(value, type));
  }

  Primitive invokeBuiltin(BuiltinMethod method,
                          Primitive receiver,
                          List<Primitive> arguments,
                          {bool receiverIsNotNull: false}) {
    ApplyBuiltinMethod apply =
        new ApplyBuiltinMethod(method, receiver, arguments, sourceInformation);
    apply.receiverIsNotNull = receiverIsNotNull;
    return letPrim(apply);
  }

  /// Inserts an invocation and returns a primitive holding the returned value.
  Primitive invokeMethod(Primitive receiver,
      Selector selector,
      TypeMask mask,
      List<Primitive> arguments,
      [CallingConvention callingConvention = CallingConvention.Normal]) {
    InvokeMethod invoke =
        new InvokeMethod(receiver, selector, mask, arguments,
                         sourceInformation: sourceInformation,
                         callingConvention: callingConvention);
    return letPrim(invoke);
  }

  /// Inserts an invocation and returns a primitive holding the returned value.
  Primitive invokeStatic(FunctionElement target, List<Primitive> arguments) {
    return letPrim(new InvokeStatic(target, new Selector.fromElement(target),
        arguments, sourceInformation));
  }

  /// Inserts an invocation to a static function that throws an error.
  ///
  /// This closes the fragment; no more nodes may be added.
  void invokeStaticThrower(FunctionElement target, List<Primitive> arguments) {
    invokeStatic(target, arguments);
    put(new Unreachable());
  }

  /// Invoke a non-recursive continuation.
  ///
  /// This closes the fragment; no more nodes may be inserted.
  void invokeContinuation(Continuation cont, [List<Primitive> arguments]) {
    if (arguments == null) arguments = <Primitive>[];
    put(new InvokeContinuation(cont, arguments));
  }

  /// Build a loop with the given loop variables and initial values.
  /// Call [continueLoop] with the returned continuation to iterate the loop.
  ///
  /// The loop body becomes the new hole.
  Continuation beginLoop([List<Parameter> loopVars,
                          List<Primitive> initialValues]) {
    if (initialValues == null) {
      assert(loopVars == null);
      loopVars = <Parameter>[];
      initialValues = <Primitive>[];
    }
    Continuation cont = new Continuation(loopVars);
    put(new LetCont(cont, new InvokeContinuation(cont, initialValues)));
    context = cont;
    return cont;
  }

  /// Continue a loop started by [beginLoop].
  ///
  /// This closes the fragment; no more nodes may be inserted.
  void continueLoop(Continuation cont, [List<Primitive> updatedLoopVariables]) {
    put(new InvokeContinuation(cont, updatedLoopVariables, isRecursive: true));
  }

  /// Branch on [condition].
  ///
  /// Returns a new fragment for the 'then' branch, or the 'else' branch
  /// if [negate] is true.
  ///
  /// The other branch becomes the new hole.
  CpsFragment branch(Primitive condition,
                     {bool negate: false,
                      bool strict: false}) {
    Continuation trueCont = new Continuation(<Parameter>[]);
    Continuation falseCont = new Continuation(<Parameter>[]);
    put(new LetCont.two(trueCont, falseCont,
            new Branch(condition, trueCont, falseCont, strict: strict)));
    if (negate) {
      context = trueCont;
      return new CpsFragment(sourceInformation, falseCont);
    } else {
      context = falseCont;
      return new CpsFragment(sourceInformation, trueCont);
    }
  }

  /// Branch on [condition].
  ///
  /// Returns a new fragment for the 'then' branch.
  ///
  /// The 'else' branch becomes the new hole.
  CpsFragment ifTruthy(Primitive condition) => branch(condition);

  /// Branch on [condition].
  ///
  /// Returns a new fragment for the 'else' branch.
  ///
  /// The 'then' branch becomes the new hole.
  CpsFragment ifFalsy(Primitive condition) => branch(condition, negate: true);

  /// Create a new empty continuation and bind it here.
  ///
  /// Convenient for making a join point where multiple branches
  /// meet later.
  ///
  /// The LetCont body becomes the new hole.
  ///
  /// Example use:
  ///
  ///   Continuation fail = cps.letCont();
  ///
  ///   // Fail if something
  ///   cps.ifTrue(<condition>)
  ///      ..invokeMethod(<method>)
  ///      ..invokeContinuation(fail);
  ///
  ///   // Fail if something else
  ///   cps.ifTrue(<anotherCondition>)
  ///      ..invokeMethod(<anotherMethod>)
  ///      ..invokeContinuation(fail);
  ///
  ///   // Build the fail branch
  ///   cps.insideContinuation(fail)
  ///      ..invokeStaticThrower(...);
  ///
  ///   // Go to the happy branch
  ///   cps.invokeContinuation(cont..)
  ///
  Continuation letCont([List<Parameter> parameters]) {
    if (parameters == null) parameters = <Parameter>[];
    Continuation cont = new Continuation(parameters);
    bindContinuation(cont);
    return cont;
  }

  /// Binds an existing continuation at this position.
  ///
  /// The LetCont body becomes the new hole.
  void bindContinuation(Continuation cont) {
    LetCont let = new LetCont(cont, null);
    put(let);
    context = let;
  }

  /// Inlines [target] at the current position, substituting the provided
  /// arguments.
  ///
  /// Returns a primitive containing the function's return value.
  ///
  /// The new hole is the the point after [target] has returned. The fragment
  /// remains open, even if [target] never returns.
  ///
  /// The [target] function is destroyed and should not be reused.
  Primitive inlineFunction(FunctionDefinition target,
                           Primitive thisArgument,
                           List<Primitive> arguments,
                           {Entity hint}) {
    if (thisArgument != null) {
      target.thisParameter.replaceUsesWith(thisArgument);
    }
    for (int i = 0; i < arguments.length; ++i) {
      target.parameters[i].replaceUsesWith(arguments[i]);
    }
    Continuation returnCont = target.returnContinuation;
    bindContinuation(returnCont);
    put(target.body);
    Parameter returnValue = returnCont.parameters.single;
    returnValue.hint = hint;
    context = returnCont;
    return returnValue;
  }

  /// Returns a fragment whose context is the body of the given continuation.
  ///
  /// Does not change the state of this CPS fragment.
  ///
  /// Useful for building the body of a continuation created using [letCont].
  CpsFragment insideContinuation(Continuation cont) {
    return new CpsFragment(sourceInformation, cont);
  }

  /// Puts the given fragment into this one.
  ///
  /// If [other] was an open fragment, its hole becomes the new hole
  /// in this fragment.
  ///
  /// [other] is reset to an empty fragment after this.
  void append(CpsFragment other) {
    if (other.root == null) return;
    put(other.root);
    context = other.context;
    other.context = null;
    other.root = null;
  }

  /// Reads the value of the given mutable variable.
  Primitive getMutable(MutableVariable variable) {
    return letPrim(new GetMutable(variable));
  }

  /// Sets the value of the given mutable variable.
  void setMutable(MutableVariable variable, Primitive value) {
    letPrim(new SetMutable(variable, value));
  }

  /// Declare a new mutable variable.
  void letMutable(MutableVariable variable, Primitive initialValue) {
    LetMutable let = new LetMutable(variable, initialValue);
    put(let);
    context = let;
  }

  void insertBelow(InteriorNode node) {
    assert(isOpen);
    if (isEmpty) return;
    Expression child = node.body;
    node.body = root;
    root.parent = node;
    context.body = child;
    child.parent = context;
    root = context = null;
  }

  void insertAbove(InteriorExpression node) {
    insertBelow(node.parent);
  }
}

/// Removes [node], unlinking all its references and replaces it with [newNode].
void destroyAndReplace(Expression node, Expression newNode) {
  InteriorNode parent = node.parent;
  RemovalVisitor.remove(node);
  parent.body = newNode;
  newNode.parent = parent;
}

/// Removes all [Refinement] uses of a given primitive that has no effective
/// uses.
void destroyRefinementsOfDeadPrimitive(Primitive prim) {
  while (prim.firstRef != null) {
    Refinement refine = prim.firstRef.parent;
    destroyRefinementsOfDeadPrimitive(refine);
    LetPrim letPrim = refine.parent;
    InteriorNode parent = letPrim.parent;
    parent.body = letPrim.body;
    letPrim.body.parent = parent;
    prim.firstRef.unlink();
  }
}
