/*
 * Copyright 2020 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/sksl/DSLCore.h"

#include "include/core/SkTypes.h"
#include "include/private/SkSLDefines.h"
#include "include/private/SkSLProgramElement.h"
#include "include/private/SkSLStatement.h"
#include "include/private/SkSLSymbol.h"
#include "include/sksl/DSLModifiers.h"
#include "include/sksl/DSLSymbols.h"
#include "include/sksl/DSLType.h"
#include "include/sksl/DSLVar.h"
#include "include/sksl/SkSLPosition.h"
#include "src/sksl/SkSLBuiltinTypes.h"
#include "src/sksl/SkSLCompiler.h"
#include "src/sksl/SkSLContext.h"
#include "src/sksl/SkSLParsedModule.h"
#include "src/sksl/SkSLPool.h"
#include "src/sksl/SkSLProgramSettings.h"
#include "src/sksl/SkSLThreadContext.h"
#include "src/sksl/dsl/priv/DSLWriter.h"
#include "src/sksl/ir/SkSLBlock.h"
#include "src/sksl/ir/SkSLBreakStatement.h"
#include "src/sksl/ir/SkSLContinueStatement.h"
#include "src/sksl/ir/SkSLDiscardStatement.h"
#include "src/sksl/ir/SkSLDoStatement.h"
#include "src/sksl/ir/SkSLExpression.h"
#include "src/sksl/ir/SkSLExtension.h"
#include "src/sksl/ir/SkSLField.h"
#include "src/sksl/ir/SkSLForStatement.h"
#include "src/sksl/ir/SkSLFunctionCall.h"
#include "src/sksl/ir/SkSLIfStatement.h"
#include "src/sksl/ir/SkSLInterfaceBlock.h"
#include "src/sksl/ir/SkSLModifiersDeclaration.h"
#include "src/sksl/ir/SkSLProgram.h"
#include "src/sksl/ir/SkSLReturnStatement.h"
#include "src/sksl/ir/SkSLSwitchStatement.h"
#include "src/sksl/ir/SkSLSwizzle.h"
#include "src/sksl/ir/SkSLSymbolTable.h"
#include "src/sksl/ir/SkSLTernaryExpression.h"
#include "src/sksl/ir/SkSLType.h"
#include "src/sksl/ir/SkSLVarDeclarations.h"
#include "src/sksl/ir/SkSLVariable.h"
#include "src/sksl/transform/SkSLTransform.h"

#include <type_traits>
#include <vector>

namespace SkSL {

namespace dsl {

void Start(SkSL::Compiler* compiler, ProgramKind kind) {
    Start(compiler, kind, ProgramSettings());
}

void Start(SkSL::Compiler* compiler, ProgramKind kind, const ProgramSettings& settings) {
    ThreadContext::SetInstance(std::make_unique<ThreadContext>(compiler, kind, settings,
            compiler->moduleForProgramKind(kind), /*isModule=*/false));
}

void StartModule(SkSL::Compiler* compiler, ProgramKind kind, const ProgramSettings& settings,
                 SkSL::ParsedModule baseModule) {
    ThreadContext::SetInstance(std::make_unique<ThreadContext>(compiler, kind, settings,
            baseModule, /*isModule=*/true));
}

void End() {
    ThreadContext::SetInstance(nullptr);
}

ErrorReporter& GetErrorReporter() {
    return ThreadContext::GetErrorReporter();
}

void SetErrorReporter(ErrorReporter* errorReporter) {
    SkASSERT(errorReporter);
    ThreadContext::SetErrorReporter(errorReporter);
}

class DSLCore {
public:
    static std::unique_ptr<SkSL::Program> ReleaseProgram(std::unique_ptr<std::string> source) {
        ThreadContext& instance = ThreadContext::Instance();
        SkSL::Compiler& compiler = *instance.fCompiler;
        const SkSL::Context& context = *compiler.fContext;
        // Variables defined in the pre-includes need their declaring elements added to the program
        if (!instance.fConfig->fIsBuiltinCode && context.fBuiltins) {
            Transform::FindAndDeclareBuiltinVariables(context, instance.fConfig->fKind,
                    instance.fSharedElements);
        }
        Pool* pool = instance.fPool.get();
        auto result = std::make_unique<SkSL::Program>(std::move(source),
                                                      std::move(instance.fConfig),
                                                      compiler.fContext,
                                                      std::move(instance.fProgramElements),
                                                      std::move(instance.fSharedElements),
                                                      std::move(instance.fModifiersPool),
                                                      std::move(compiler.fSymbolTable),
                                                      std::move(instance.fPool),
                                                      instance.fInputs);
        bool success = false;
        if (!compiler.finalize(*result)) {
            // Do not return programs that failed to compile.
        } else if (!compiler.optimize(*result)) {
            // Do not return programs that failed to optimize.
        } else {
            // We have a successful program!
            success = true;
        }
        if (pool) {
            pool->detachFromThread();
        }
        SkASSERT(instance.fProgramElements.empty());
        SkASSERT(!ThreadContext::SymbolTable());
        return success ? std::move(result) : nullptr;
    }

    static DSLGlobalVar sk_FragColor() {
        return DSLGlobalVar("sk_FragColor");
    }

    static DSLGlobalVar sk_FragCoord() {
        return DSLGlobalVar("sk_FragCoord");
    }

    static DSLExpression sk_Position() {
        return DSLExpression(Symbol("sk_Position"));
    }

    template <typename... Args>
    static DSLExpression Call(const char* name, Position pos, Args... args) {
        SkSL::ExpressionArray argArray;
        argArray.reserve_back(sizeof...(args));
        ((void)argArray.push_back(args.release()), ...);

        return DSLExpression(SkSL::FunctionCall::Convert(ThreadContext::Context(), pos,
                ThreadContext::Compiler().convertIdentifier(Position(), name),
                std::move(argArray)));
    }

    static DSLStatement Break(Position pos) {
        return SkSL::BreakStatement::Make(pos);
    }

    static DSLStatement Continue(Position pos) {
        return SkSL::ContinueStatement::Make(pos);
    }

    static void Declare(const DSLModifiers& modifiers) {
        ThreadContext::ProgramElements().push_back(std::make_unique<SkSL::ModifiersDeclaration>(
                ThreadContext::Modifiers(modifiers.fModifiers)));
    }

    static DSLStatement Declare(DSLVar& var, Position pos) {
        return DSLWriter::Declaration(var);
    }

    static DSLStatement Declare(SkTArray<DSLVar>& vars, Position pos) {
        StatementArray statements;
        for (DSLVar& v : vars) {
            statements.push_back(Declare(v, pos).release());
        }
        return SkSL::Block::Make(pos, std::move(statements), Block::Kind::kCompoundStatement);
    }

    static void Declare(DSLGlobalVar& var, Position pos) {
        std::unique_ptr<SkSL::Statement> stmt = DSLWriter::Declaration(var);
        if (stmt) {
            if (!stmt->isEmpty()) {
                ThreadContext::ProgramElements().push_back(
                        std::make_unique<SkSL::GlobalVarDeclaration>(std::move(stmt)));
            }
        } else if (var.fName == SkSL::Compiler::FRAGCOLOR_NAME) {
            // sk_FragColor can end up with a null declaration despite no error occurring due to
            // specific treatment in the compiler. Ignore the null and just grab the existing
            // variable from the symbol table.
            const SkSL::Symbol* alreadyDeclared = (*ThreadContext::SymbolTable())[var.fName];
            if (alreadyDeclared && alreadyDeclared->is<Variable>()) {
                var.fVar = &alreadyDeclared->as<Variable>();
                var.fInitialized = true;
            }
        }
    }

    static void Declare(SkTArray<DSLGlobalVar>& vars, Position pos) {
        for (DSLGlobalVar& v : vars) {
            Declare(v, pos);
        }
    }

    static DSLStatement Discard(Position pos) {
        return SkSL::DiscardStatement::Make(pos);
    }

    static DSLStatement Do(DSLStatement stmt, DSLExpression test, Position pos) {
        return DSLStatement(DoStatement::Convert(ThreadContext::Context(), pos, stmt.release(),
                test.release()), pos);
    }

    static DSLStatement For(DSLStatement initializer, DSLExpression test,
                                    DSLExpression next, DSLStatement stmt, Position pos,
                                    const ForLoopPositions& forLoopPositions) {
        return DSLStatement(ForStatement::Convert(ThreadContext::Context(), pos, forLoopPositions,
                                                  initializer.releaseIfPossible(),
                                                  test.releaseIfPossible(),
                                                  next.releaseIfPossible(),
                                                  stmt.release(),
                                                  ThreadContext::SymbolTable()), pos);
    }

    static DSLStatement If(DSLExpression test, DSLStatement ifTrue, DSLStatement ifFalse,
            bool isStatic, Position pos) {
        return DSLStatement(IfStatement::Convert(ThreadContext::Context(), pos, isStatic,
                test.release(), ifTrue.release(), ifFalse.releaseIfPossible()), pos);
    }

    static void FindRTAdjust(SkSL::InterfaceBlock& intf, Position pos) {
        const std::vector<SkSL::Type::Field>& fields =
                intf.variable().type().componentType().fields();
        const Context& context = ThreadContext::Context();
        for (size_t i = 0; i < fields.size(); ++i) {
            const SkSL::Type::Field& f = fields[i];
            if (f.fName == SkSL::Compiler::RTADJUST_NAME) {
                if (f.fType->matches(*context.fTypes.fFloat4)) {
                    ThreadContext::RTAdjustData& rtAdjust = ThreadContext::RTAdjustState();
                    rtAdjust.fInterfaceBlock = &intf.variable();
                    rtAdjust.fFieldIndex = i;
                } else {
                    ThreadContext::ReportError("sk_RTAdjust must have type 'float4'", pos);
                }
                break;
            }
        }
    }

    static DSLGlobalVar InterfaceBlock(const DSLModifiers& modifiers, std::string_view typeName,
                                       SkTArray<DSLField> fields, std::string_view varName,
                                       int arraySize, Position pos) {
        // We need to create a new struct type for the interface block, but we don't want it in the
        // symbol table. Since dsl::Struct automatically sticks it in the symbol table, we create it
        // the old fashioned way with MakeStructType.
        std::vector<SkSL::Type::Field> skslFields;
        skslFields.reserve(fields.count());
        for (const DSLField& field : fields) {
            const SkSL::Type* baseType = &field.fType.skslType();
            if (baseType->isArray()) {
                baseType = &baseType->componentType();
            }
            SkSL::VarDeclaration::ErrorCheck(ThreadContext::Context(), field.fPosition,
                    field.fModifiers.fPosition, field.fModifiers.fModifiers, baseType,
                    Variable::Storage::kInterfaceBlock);
            skslFields.push_back(SkSL::Type::Field(field.fPosition, field.fModifiers.fModifiers,
                    field.fName, &field.fType.skslType()));
        }
        const SkSL::Type* structType =
                ThreadContext::SymbolTable()->takeOwnershipOfSymbol(SkSL::Type::MakeStructType(
                        pos, typeName, std::move(skslFields), /*interfaceBlock=*/true));
        DSLType varType = arraySize > 0 ? Array(structType, arraySize) : DSLType(structType);
        DSLGlobalVar var(modifiers, varType, !varName.empty() ? varName : typeName, DSLExpression(),
                pos);
        const SkSL::Variable* skslVar = DSLWriter::Var(var);
        if (skslVar) {
            auto intf = std::make_unique<SkSL::InterfaceBlock>(pos, *skslVar, typeName, varName,
                    arraySize, ThreadContext::SymbolTable());
            FindRTAdjust(*intf, pos);
            ThreadContext::ProgramElements().push_back(std::move(intf));
            if (varName.empty()) {
                const std::vector<SkSL::Type::Field>& structFields = structType->fields();
                for (size_t i = 0; i < structFields.size(); ++i) {
                    ThreadContext::SymbolTable()->add(std::make_unique<SkSL::Field>(
                            structFields[i].fPosition, skslVar, i));
                }
            } else {
                AddToSymbolTable(var);
            }
        }
        return var;
    }

    static DSLStatement Return(DSLExpression value, Position pos) {
        // Note that because Return is called before the function in which it resides exists, at
        // this point we do not know the function's return type. We therefore do not check for
        // errors, or coerce the value to the correct type, until the return statement is actually
        // added to a function. (This is done in FunctionDefinition::Convert.)
        return SkSL::ReturnStatement::Make(pos, value.releaseIfPossible());
    }

    static DSLExpression Swizzle(DSLExpression base, SkSL::SwizzleComponent::Type a,
                                 Position pos, Position maskPos) {
        return DSLExpression(Swizzle::Convert(ThreadContext::Context(), pos, maskPos,
                                              base.release(), ComponentArray{a}),
                             pos);
    }

    static DSLExpression Swizzle(DSLExpression base,
                                 SkSL::SwizzleComponent::Type a,
                                 SkSL::SwizzleComponent::Type b,
                                 Position pos,
                                 Position maskPos) {
        return DSLExpression(Swizzle::Convert(ThreadContext::Context(), pos, maskPos,
                                              base.release(), ComponentArray{a, b}),
                             pos);
    }

    static DSLExpression Swizzle(DSLExpression base,
                                 SkSL::SwizzleComponent::Type a,
                                 SkSL::SwizzleComponent::Type b,
                                 SkSL::SwizzleComponent::Type c,
                                 Position pos,
                                 Position maskPos) {
        return DSLExpression(Swizzle::Convert(ThreadContext::Context(), pos, maskPos, base.release(),
                                              ComponentArray{a, b, c}),
                             pos);
    }

    static DSLExpression Swizzle(DSLExpression base,
                                 SkSL::SwizzleComponent::Type a,
                                 SkSL::SwizzleComponent::Type b,
                                 SkSL::SwizzleComponent::Type c,
                                 SkSL::SwizzleComponent::Type d,
                                 Position pos,
                                 Position maskPos) {
        return DSLExpression(Swizzle::Convert(ThreadContext::Context(), pos, maskPos, base.release(),
                                              ComponentArray{a,b,c,d}),
                             pos);
    }

    static DSLExpression Select(DSLExpression test, DSLExpression ifTrue, DSLExpression ifFalse,
            Position pos) {
        auto result = TernaryExpression::Convert(ThreadContext::Context(), pos, test.release(),
                                          ifTrue.release(), ifFalse.release());
        SkASSERT(!result || result->fPosition == pos);
        return DSLExpression(std::move(result), pos);
    }

    static DSLStatement Switch(DSLExpression value, SkTArray<DSLCase> cases, bool isStatic,
                               Position pos) {
        ExpressionArray values;
        values.reserve_back(cases.count());
        StatementArray caseBlocks;
        caseBlocks.reserve_back(cases.count());
        for (DSLCase& c : cases) {
            values.push_back(c.fValue.releaseIfPossible());
            caseBlocks.push_back(SkSL::Block::Make(Position(), std::move(c.fStatements),
                                                   Block::Kind::kUnbracedBlock));
        }
        return DSLStatement(SwitchStatement::Convert(ThreadContext::Context(), pos, isStatic,
                                                     value.release(),
                                                     std::move(values),
                                                     std::move(caseBlocks),
                                                     ThreadContext::SymbolTable()), pos);
    }

    static DSLStatement While(DSLExpression test, DSLStatement stmt, Position pos) {
        return DSLStatement(ForStatement::ConvertWhile(ThreadContext::Context(), pos,
                                                       test.release(),
                                                       stmt.release(),
                                                       ThreadContext::SymbolTable()), pos);
    }
};

std::unique_ptr<SkSL::Program> ReleaseProgram(std::unique_ptr<std::string> source) {
    return DSLCore::ReleaseProgram(std::move(source));
}

DSLGlobalVar sk_FragColor() {
    return DSLCore::sk_FragColor();
}

DSLGlobalVar sk_FragCoord() {
    return DSLCore::sk_FragCoord();
}

DSLExpression sk_Position() {
    return DSLCore::sk_Position();
}

void AddExtension(std::string_view name, Position pos) {
    ThreadContext::ProgramElements().push_back(std::make_unique<SkSL::Extension>(pos, name));
}

DSLStatement Break(Position pos) {
    return DSLCore::Break(pos);
}

DSLStatement Continue(Position pos) {
    return DSLCore::Continue(pos);
}

void Declare(const DSLModifiers& modifiers, Position pos) {
    SkSL::ProgramKind kind = ThreadContext::GetProgramConfig()->fKind;
    if (!ProgramConfig::IsFragment(kind) &&
        !ProgramConfig::IsVertex(kind)) {
        ThreadContext::ReportError("layout qualifiers are not allowed in this kind of program",
                                   pos);
        return;
    }
    DSLCore::Declare(modifiers);
}

// Logically, we'd want the variable's initial value to appear on here in Declare, since that
// matches how we actually write code (and in fact that was what our first attempt looked like).
// Unfortunately, C++ doesn't guarantee execution order between arguments, and Declare() can appear
// as a function argument in constructs like Block(Declare(x, 0), foo(x)). If these are executed out
// of order, we will evaluate the reference to x before we evaluate Declare(x, 0), and thus the
// variable's initial value is unknown at the point of reference. There are probably some other
// issues with this as well, but it is particularly dangerous when x is const, since SkSL will
// expect its value to be known when it is referenced and will end up asserting, dereferencing a
// null pointer, or possibly doing something else awful.
//
// So, we put the initial value onto the Var itself instead of the Declare to guarantee that it is
// always executed in the correct order.
DSLStatement Declare(DSLVar& var, Position pos) {
    return DSLCore::Declare(var, pos);
}

DSLStatement Declare(SkTArray<DSLVar>& vars, Position pos) {
    return DSLCore::Declare(vars, pos);
}

void Declare(DSLGlobalVar& var, Position pos) {
    DSLCore::Declare(var, pos);
}

void Declare(SkTArray<DSLGlobalVar>& vars, Position pos) {
    DSLCore::Declare(vars, pos);
}

DSLStatement Discard(Position pos) {
    if (!ProgramConfig::IsFragment(ThreadContext::GetProgramConfig()->fKind)) {
        ThreadContext::ReportError("discard statement is only permitted in fragment shaders", pos);
    }
    return DSLCore::Discard(pos);
}

DSLStatement Do(DSLStatement stmt, DSLExpression test, Position pos) {
    return DSLCore::Do(std::move(stmt), std::move(test), pos);
}

DSLStatement For(DSLStatement initializer, DSLExpression test, DSLExpression next,
                 DSLStatement stmt, Position pos, ForLoopPositions forLoopPositions) {
    return DSLCore::For(std::move(initializer), std::move(test), std::move(next),
                        std::move(stmt), pos, forLoopPositions);
}

DSLStatement If(DSLExpression test, DSLStatement ifTrue, DSLStatement ifFalse, Position pos) {
    return DSLCore::If(std::move(test), std::move(ifTrue), std::move(ifFalse), /*isStatic=*/false,
                       pos);
}

DSLGlobalVar InterfaceBlock(const DSLModifiers& modifiers,  std::string_view typeName,
                            SkTArray<DSLField> fields, std::string_view varName, int arraySize,
                            Position pos) {
    SkSL::ProgramKind kind = ThreadContext::GetProgramConfig()->fKind;
    if (!ProgramConfig::IsFragment(kind) &&
        !ProgramConfig::IsVertex(kind)) {
        ThreadContext::ReportError("interface blocks are not allowed in this kind of program", pos);
        return DSLGlobalVar();
    }
    return DSLCore::InterfaceBlock(modifiers, typeName, std::move(fields), varName, arraySize, pos);
}

DSLStatement Return(DSLExpression expr, Position pos) {
    return DSLCore::Return(std::move(expr), pos);
}

DSLExpression Select(DSLExpression test, DSLExpression ifTrue, DSLExpression ifFalse,
                     Position pos) {
    return DSLCore::Select(std::move(test), std::move(ifTrue), std::move(ifFalse), pos);
}

DSLStatement StaticIf(DSLExpression test, DSLStatement ifTrue, DSLStatement ifFalse,
                      Position pos) {
    return DSLCore::If(std::move(test), std::move(ifTrue), std::move(ifFalse), /*isStatic=*/true,
            pos);
}

DSLStatement StaticSwitch(DSLExpression value, SkTArray<DSLCase> cases, Position pos) {
    return DSLCore::Switch(std::move(value), std::move(cases), /*isStatic=*/true, pos);
}

DSLStatement Switch(DSLExpression value, SkTArray<DSLCase> cases, Position pos) {
    return DSLCore::Switch(std::move(value), std::move(cases), /*isStatic=*/false, pos);
}

DSLStatement While(DSLExpression test, DSLStatement stmt, Position pos) {
    return DSLCore::While(std::move(test), std::move(stmt), pos);
}

DSLExpression Abs(DSLExpression x, Position pos) {
    return DSLCore::Call("abs", pos, std::move(x));
}

DSLExpression All(DSLExpression x, Position pos) {
    return DSLCore::Call("all", pos, std::move(x));
}

DSLExpression Any(DSLExpression x, Position pos) {
    return DSLCore::Call("any", pos, std::move(x));
}

DSLExpression Atan(DSLExpression y_over_x, Position pos) {
    return DSLCore::Call("atan", pos, std::move(y_over_x));
}

DSLExpression Atan(DSLExpression y, DSLExpression x, Position pos) {
    return DSLCore::Call("atan", pos, std::move(y), std::move(x));
}

DSLExpression Ceil(DSLExpression x, Position pos) {
    return DSLCore::Call("ceil", pos, std::move(x));
}

DSLExpression Clamp(DSLExpression x, DSLExpression min, DSLExpression max, Position pos) {
    return DSLCore::Call("clamp", pos, std::move(x), std::move(min), std::move(max));
}

DSLExpression Cos(DSLExpression x, Position pos) {
    return DSLCore::Call("cos", pos, std::move(x));
}

DSLExpression Cross(DSLExpression x, DSLExpression y, Position pos) {
    return DSLCore::Call("cross", pos, std::move(x), std::move(y));
}

DSLExpression Degrees(DSLExpression x, Position pos) {
    return DSLCore::Call("degrees", pos, std::move(x));
}

DSLExpression Distance(DSLExpression x, DSLExpression y, Position pos) {
    return DSLCore::Call("distance", pos, std::move(x), std::move(y));
}

DSLExpression Dot(DSLExpression x, DSLExpression y, Position pos) {
    return DSLCore::Call("dot", pos, std::move(x), std::move(y));
}

DSLExpression Equal(DSLExpression x, DSLExpression y, Position pos) {
    return DSLCore::Call("equal", pos, std::move(x), std::move(y));
}

DSLExpression Exp(DSLExpression x, Position pos) {
    return DSLCore::Call("exp", pos, std::move(x));
}

DSLExpression Exp2(DSLExpression x, Position pos) {
    return DSLCore::Call("exp2", pos, std::move(x));
}

DSLExpression Faceforward(DSLExpression n, DSLExpression i, DSLExpression nref, Position pos) {
    return DSLCore::Call("faceforward", pos, std::move(n), std::move(i), std::move(nref));
}

DSLExpression Fract(DSLExpression x, Position pos) {
    return DSLCore::Call("fract", pos, std::move(x));
}

DSLExpression Floor(DSLExpression x, Position pos) {
    return DSLCore::Call("floor", pos, std::move(x));
}

DSLExpression GreaterThan(DSLExpression x, DSLExpression y, Position pos) {
    return DSLCore::Call("greaterThan", pos, std::move(x), std::move(y));
}

DSLExpression GreaterThanEqual(DSLExpression x, DSLExpression y, Position pos) {
    return DSLCore::Call("greaterThanEqual", pos, std::move(x), std::move(y));
}

DSLExpression Inverse(DSLExpression x, Position pos) {
    return DSLCore::Call("inverse", pos, std::move(x));
}

DSLExpression Inversesqrt(DSLExpression x, Position pos) {
    return DSLCore::Call("inversesqrt", pos, std::move(x));
}

DSLExpression Length(DSLExpression x, Position pos) {
    return DSLCore::Call("length", pos, std::move(x));
}

DSLExpression LessThan(DSLExpression x, DSLExpression y, Position pos) {
    return DSLCore::Call("lessThan", pos, std::move(x), std::move(y));
}

DSLExpression LessThanEqual(DSLExpression x, DSLExpression y, Position pos) {
    return DSLCore::Call("lessThanEqual", pos, std::move(x), std::move(y));
}

DSLExpression Log(DSLExpression x, Position pos) {
    return DSLCore::Call("log", pos, std::move(x));
}

DSLExpression Log2(DSLExpression x, Position pos) {
    return DSLCore::Call("log2", pos, std::move(x));
}

DSLExpression Max(DSLExpression x, DSLExpression y, Position pos) {
    return DSLCore::Call("max", pos, std::move(x), std::move(y));
}

DSLExpression Min(DSLExpression x, DSLExpression y, Position pos) {
    return DSLCore::Call("min", pos, std::move(x), std::move(y));
}

DSLExpression Mix(DSLExpression x, DSLExpression y, DSLExpression a, Position pos) {
    return DSLCore::Call("mix", pos, std::move(x), std::move(y), std::move(a));
}

DSLExpression Mod(DSLExpression x, DSLExpression y, Position pos) {
    return DSLCore::Call("mod", pos, std::move(x), std::move(y));
}

DSLExpression Normalize(DSLExpression x, Position pos) {
    return DSLCore::Call("normalize", pos, std::move(x));
}

DSLExpression NotEqual(DSLExpression x, DSLExpression y, Position pos) {
    return DSLCore::Call("notEqual", pos, std::move(x), std::move(y));
}

DSLExpression Pow(DSLExpression x, DSLExpression y, Position pos) {
    return DSLCore::Call("pow", pos, std::move(x), std::move(y));
}

DSLExpression Radians(DSLExpression x, Position pos) {
    return DSLCore::Call("radians", pos, std::move(x));
}

DSLExpression Reflect(DSLExpression i, DSLExpression n, Position pos) {
    return DSLCore::Call("reflect", pos, std::move(i), std::move(n));
}

DSLExpression Refract(DSLExpression i, DSLExpression n, DSLExpression eta, Position pos) {
    return DSLCore::Call("refract", pos, std::move(i), std::move(n), std::move(eta));
}

DSLExpression Round(DSLExpression x, Position pos) {
    return DSLCore::Call("round", pos, std::move(x));
}

DSLExpression Saturate(DSLExpression x, Position pos) {
    return DSLCore::Call("saturate", pos, std::move(x));
}

DSLExpression Sign(DSLExpression x, Position pos) {
    return DSLCore::Call("sign", pos, std::move(x));
}

DSLExpression Sin(DSLExpression x, Position pos) {
    return DSLCore::Call("sin", pos, std::move(x));
}

DSLExpression Smoothstep(DSLExpression edge1, DSLExpression edge2, DSLExpression x,
                         Position pos) {
    return DSLCore::Call("smoothstep", pos, std::move(edge1), std::move(edge2), std::move(x));
}

DSLExpression Sqrt(DSLExpression x, Position pos) {
    return DSLCore::Call("sqrt", pos, std::move(x));
}

DSLExpression Step(DSLExpression edge, DSLExpression x, Position pos) {
    return DSLCore::Call("step", pos, std::move(edge), std::move(x));
}

DSLExpression Swizzle(DSLExpression base, SkSL::SwizzleComponent::Type a,
                      Position pos, Position maskPos) {
    return DSLCore::Swizzle(std::move(base), a, pos, maskPos);
}

DSLExpression Swizzle(DSLExpression base,
                      SkSL::SwizzleComponent::Type a,
                      SkSL::SwizzleComponent::Type b,
                      Position pos,
                      Position maskPos) {
    return DSLCore::Swizzle(std::move(base), a, b, pos, maskPos);
}

DSLExpression Swizzle(DSLExpression base,
                      SkSL::SwizzleComponent::Type a,
                      SkSL::SwizzleComponent::Type b,
                      SkSL::SwizzleComponent::Type c,
                      Position pos,
                      Position maskPos) {
    return DSLCore::Swizzle(std::move(base), a, b, c, pos, maskPos);
}

DSLExpression Swizzle(DSLExpression base,
                      SkSL::SwizzleComponent::Type a,
                      SkSL::SwizzleComponent::Type b,
                      SkSL::SwizzleComponent::Type c,
                      SkSL::SwizzleComponent::Type d,
                      Position pos,
                      Position maskPos) {
    return DSLCore::Swizzle(std::move(base), a, b, c, d, pos, maskPos);
}

DSLExpression Tan(DSLExpression x, Position pos) {
    return DSLCore::Call("tan", pos, std::move(x));
}

DSLExpression Unpremul(DSLExpression x, Position pos) {
    return DSLCore::Call("unpremul", pos, std::move(x));
}

} // namespace dsl

} // namespace SkSL
