//#####################################################################
// Copyright 2012.
// This file is part of PhysBAM whose distribution is governed by the license contained in the accompanying file PHYSBAM_COPYREGHT.txt.
//#####################################################################
// Class PROGRAM
//#####################################################################
#ifndef __PROGRAM__
#define __PROGRAM__

#include <Core/Arrays/ARRAY.h>
#include <Core/Symbolics/INSTRUCTION.h>
namespace PhysBAM{

template<class T> struct PROGRAM_CONTEXT;

template<class T>
struct PROGRAM
{
    int num_reg=0;
    MEM_IN num_in{};
    MEM_OUT num_out{};
    ARRAY<T,MEM_CONST> constants;
    ARRAY<RAW_INSTRUCTION> code;

    PROGRAM()=default;
    PROGRAM(const PROGRAM& p)=default;

    template<class U,class F>
    PROGRAM(const PROGRAM<U>& p,F f)
        :num_reg(p.num_reg),num_in(p.num_in),num_out(p.num_out),
        constants(p.constants.m),code(p.code)
    {
        for(MEM_CONST i{0};i<constants.m;i++)
            constants(i)=f(p.constants(i));
    }

    void Execute(ARRAY<T>& reg) const;
    void Execute(PROGRAM_CONTEXT<T>& context) const;
    void Execute_Op(ARRAY<T>& reg,int& ip) const;
    void Print() const;
};

template<class T>
T Evaluate_Op(OPERATION type,T in0,T in1,T in2);

template<class T> void
Simple_Compile(PROGRAM<T>& prog,const std::string& code,
    const ARRAY<std::string,MEM_IN>& var_in,const ARRAY<std::string,MEM_OUT>& var_out);
}
#endif
