/**
 * Implement array operations, such as `a[] = b[] + c[]`.
 *
 * Specification: $(LINK2 https://dlang.org/spec/arrays.html#array-operations, Array Operations)
 *
 * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
 * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
 * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
 * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/arrayop.d, _arrayop.d)
 * Documentation:  https://dlang.org/phobos/dmd_arrayop.html
 * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/arrayop.d
 */

module dmd.arrayop;

import core.stdc.stdio;
import dmd.arraytypes;
import dmd.astenums;
import dmd.declaration;
import dmd.dscope;
import dmd.dsymbol;
import dmd.expression;
import dmd.expressionsem;
import dmd.func;
import dmd.globals;
import dmd.hdrgen;
import dmd.id;
import dmd.identifier;
import dmd.location;
import dmd.mtype;
import dmd.common.outbuffer;
import dmd.statement;
import dmd.tokens;
import dmd.visitor;

/**********************************************
 * Check that there are no uses of arrays without [].
 */
bool isArrayOpValid(Expression e)
{
    //printf("isArrayOpValid() %s\n", e.toChars());
    if (e.op == EXP.slice)
        return true;
    if (e.op == EXP.arrayLiteral)
    {
        Type t = e.type.toBasetype();
        while (t.ty == Tarray || t.ty == Tsarray)
            t = t.nextOf().toBasetype();
        return (t.ty != Tvoid);
    }
    Type tb = e.type.toBasetype();
    if (tb.ty == Tarray || tb.ty == Tsarray)
    {
        if (isUnaArrayOp(e.op))
        {
            return isArrayOpValid(e.isUnaExp().e1);
        }
        if (isBinArrayOp(e.op) || isBinAssignArrayOp(e.op) || e.op == EXP.assign)
        {
            BinExp be = e.isBinExp();
            return isArrayOpValid(be.e1) && isArrayOpValid(be.e2);
        }
        if (e.op == EXP.construct)
        {
            BinExp be = e.isBinExp();
            return be.e1.op == EXP.slice && isArrayOpValid(be.e2);
        }
        // if (e.op == EXP.call)
        // {
        // TODO: Decide if [] is required after arrayop calls.
        // }
        return false;
    }
    return true;
}

bool isNonAssignmentArrayOp(Expression e)
{
    if (e.op == EXP.slice)
        return isNonAssignmentArrayOp(e.isSliceExp().e1);

    Type tb = e.type.toBasetype();
    if (tb.ty == Tarray || tb.ty == Tsarray)
    {
        return (isUnaArrayOp(e.op) || isBinArrayOp(e.op));
    }
    return false;
}

bool checkNonAssignmentArrayOp(Expression e, bool suggestion = false)
{
    if (isNonAssignmentArrayOp(e))
    {
        const(char)* s = "";
        if (suggestion)
            s = " (possible missing [])";
        e.error("array operation `%s` without destination memory not allowed%s", e.toChars(), s);
        return true;
    }
    return false;
}

/***********************************
 * Construct the array operation expression, call object._arrayOp!(tiargs)(args).
 *
 * Encode operand types and operations into tiargs using reverse polish notation (RPN) to preserve precedence.
 * Unary operations are prefixed with "u" (e.g. "u~").
 * Pass operand values (slices or scalars) as args.
 *
 * Scalar expression sub-trees of `e` are evaluated before calling
 * into druntime to hoist them out of the loop. This is a valid
 * evaluation order as the actual array operations have no
 * side-effect.
 * References:
 * https://github.com/dlang/dmd/blob/cdfadf8a18f474e6a1b8352af2541efe3e3467cc/druntime/src/object.d#L4694
 * https://github.com/dlang/dmd/blob/master/druntime/src/core/internal/array/operations.d
 */
Expression arrayOp(BinExp e, Scope* sc)
{
    //printf("BinExp.arrayOp() %s\n", e.toChars());
    Type tb = e.type.toBasetype();
    assert(tb.ty == Tarray || tb.ty == Tsarray);
    Type tbn = tb.nextOf().toBasetype();
    if (tbn.ty == Tvoid)
    {
        e.error("cannot perform array operations on `void[]` arrays");
        return ErrorExp.get();
    }
    if (!isArrayOpValid(e))
        return arrayOpInvalidError(e);

    auto tiargs = new Objects();
    auto args = buildArrayOp(sc, e, tiargs);

    import dmd.dtemplate : TemplateDeclaration;
    __gshared TemplateDeclaration arrayOp;
    if (arrayOp is null)
    {
        // Create .object._arrayOp
        Identifier idArrayOp = Identifier.idPool("_arrayOp");
        Expression id = new IdentifierExp(e.loc, Id.empty);
        id = new DotIdExp(e.loc, id, Id.object);
        id = new DotIdExp(e.loc, id, idArrayOp);

        id = id.expressionSemantic(sc);
        if (auto te = id.isTemplateExp())
            arrayOp = te.td;
        else
            ObjectNotFound(idArrayOp);   // fatal error
    }

    auto fd = resolveFuncCall(e.loc, sc, arrayOp, tiargs, null, ArgumentList(args), FuncResolveFlag.standard);
    if (!fd || fd.errors)
        return ErrorExp.get();
    return new CallExp(e.loc, new VarExp(e.loc, fd, false), args).expressionSemantic(sc);
}

/// ditto
Expression arrayOp(BinAssignExp e, Scope* sc)
{
    //printf("BinAssignExp.arrayOp() %s\n", e.toChars());

    /* Check that the elements of e1 can be assigned to
     */
    Type tn = e.e1.type.toBasetype().nextOf();

    if (tn && (!tn.isMutable() || !tn.isAssignable()))
    {
        e.error("slice `%s` is not mutable", e.e1.toChars());
        if (e.op == EXP.addAssign)
            checkPossibleAddCatError!(AddAssignExp, CatAssignExp)(e.isAddAssignExp);
        return ErrorExp.get();
    }
    if (e.e1.op == EXP.arrayLiteral)
    {
        return e.e1.modifiableLvalue(sc, e.e1);
    }

    return arrayOp(e.isBinExp(), sc);
}

/******************************************
 * Convert the expression tree e to template and function arguments,
 * using reverse polish notation (RPN) to encode order of operations.
 * Encode operations as string arguments, using a "u" prefix for unary operations.
 */
private Expressions* buildArrayOp(Scope* sc, Expression e, Objects* tiargs)
{
    extern (C++) final class BuildArrayOpVisitor : Visitor
    {
        alias visit = Visitor.visit;
        Scope* sc;
        Objects* tiargs;
        Expressions* args;

    public:
        extern (D) this(Scope* sc, Objects* tiargs) scope
        {
            this.sc = sc;
            this.tiargs = tiargs;
            this.args = new Expressions();
        }

        override void visit(Expression e)
        {
            tiargs.push(e.type);
            args.push(e);
        }

        override void visit(SliceExp e)
        {
            visit(cast(Expression) e);
        }

        override void visit(CastExp e)
        {
            visit(cast(Expression) e);
        }

        override void visit(UnaExp e)
        {
            Type tb = e.type.toBasetype();
            if (tb.ty != Tarray && tb.ty != Tsarray) // hoist scalar expressions
            {
                visit(cast(Expression) e);
            }
            else
            {
                // RPN, prefix unary ops with u
                OutBuffer buf;
                buf.writestring("u");
                buf.writestring(EXPtoString(e.op));
                e.e1.accept(this);
                tiargs.push(new StringExp(Loc.initial, buf.extractSlice()).expressionSemantic(sc));
            }
        }

        override void visit(BinExp e)
        {
            Type tb = e.type.toBasetype();
            if (tb.ty != Tarray && tb.ty != Tsarray) // hoist scalar expressions
            {
                visit(cast(Expression) e);
            }
            else
            {
                // RPN
                e.e1.accept(this);
                e.e2.accept(this);
                tiargs.push(new StringExp(Loc.initial, EXPtoString(e.op)).expressionSemantic(sc));
            }
        }
    }

    scope v = new BuildArrayOpVisitor(sc, tiargs);
    e.accept(v);
    return v.args;
}

/***********************************************
 * Some implicit casting can be performed by the _arrayOp template.
 * Params:
 *      tfrom = type converting from
 *      tto   = type converting to
 * Returns:
 *      true if can be performed by _arrayOp
 */
bool isArrayOpImplicitCast(TypeDArray tfrom, TypeDArray tto)
{
    const tyf = tfrom.nextOf().toBasetype().ty;
    const tyt = tto  .nextOf().toBasetype().ty;
    return tyf == tyt ||
           tyf == Tint32 && tyt == Tfloat64;
}

/***********************************************
 * Test if expression is a unary array op.
 */
bool isUnaArrayOp(EXP op)
{
    switch (op)
    {
    case EXP.negate:
    case EXP.tilde:
        return true;
    default:
        break;
    }
    return false;
}

/***********************************************
 * Test if expression is a binary array op.
 */
bool isBinArrayOp(EXP op)
{
    switch (op)
    {
    case EXP.add:
    case EXP.min:
    case EXP.mul:
    case EXP.div:
    case EXP.mod:
    case EXP.xor:
    case EXP.and:
    case EXP.or:
    case EXP.pow:
        return true;
    default:
        break;
    }
    return false;
}

/***********************************************
 * Test if expression is a binary assignment array op.
 */
bool isBinAssignArrayOp(EXP op)
{
    switch (op)
    {
    case EXP.addAssign:
    case EXP.minAssign:
    case EXP.mulAssign:
    case EXP.divAssign:
    case EXP.modAssign:
    case EXP.xorAssign:
    case EXP.andAssign:
    case EXP.orAssign:
    case EXP.powAssign:
        return true;
    default:
        break;
    }
    return false;
}

/***********************************************
 * Test if operand is a valid array op operand.
 */
bool isArrayOpOperand(Expression e)
{
    //printf("Expression.isArrayOpOperand() %s\n", e.toChars());
    if (e.op == EXP.slice)
        return true;
    if (e.op == EXP.arrayLiteral)
    {
        Type t = e.type.toBasetype();
        while (t.ty == Tarray || t.ty == Tsarray)
            t = t.nextOf().toBasetype();
        return (t.ty != Tvoid);
    }
    Type tb = e.type.toBasetype();
    if (tb.ty == Tarray)
    {
        return (isUnaArrayOp(e.op) ||
                isBinArrayOp(e.op) ||
                isBinAssignArrayOp(e.op) ||
                e.op == EXP.assign);
    }
    return false;
}


/***************************************************
 * Print error message about invalid array operation.
 * Params:
 *      e = expression with the invalid array operation
 * Returns:
 *      instance of ErrorExp
 */

ErrorExp arrayOpInvalidError(Expression e)
{
    e.error("invalid array operation `%s` (possible missing [])", e.toChars());
    if (e.op == EXP.add)
        checkPossibleAddCatError!(AddExp, CatExp)(e.isAddExp());
    else if (e.op == EXP.addAssign)
        checkPossibleAddCatError!(AddAssignExp, CatAssignExp)(e.isAddAssignExp());
    return ErrorExp.get();
}

private void checkPossibleAddCatError(AddT, CatT)(AddT ae)
{
    if (!ae.e2.type || ae.e2.type.ty != Tarray || !ae.e2.type.implicitConvTo(ae.e1.type))
        return;
    CatT ce = new CatT(ae.loc, ae.e1, ae.e2);
    ae.errorSupplemental("did you mean to concatenate (`%s`) instead ?", ce.toChars());
}
