//
// Created by pgess on 24/03/2020.
//

#include "analysis/typehints.h"
#include "analysis/predefinedanns.h"
#include "analysis/utils.h"

namespace xreate{namespace typehints{

namespace impl {
template<class Hint>
inline Hint getHint(const Expression& e, const Hint& def, unsigned annId, const ExpandedType& hintT){
  std::list<Expression> hintsL;
  auto predefined = analysis::PredefinedAnns::instance();
  for(const auto& tag: e.tags){hintsL.push_back(tag.second);}
  const Expression& hintActual = analysis::findAnnById(annId, hintT, hintsL);
  if (!hintActual.isValid()){
    return def;
  }

  return parse<Hint>(hintActual);
}
}

template<> IntBits parse(const Expression& e){
  return {(unsigned) e.operands.at(0).getValueDouble()};
}

template<> Array parse(const Expression& e){
  return {(unsigned) e.operands.at(0).getValueDouble()};
}

template<>
IntBits getHint(const Expression& e, const IntBits& def){
  auto predefined = analysis::PredefinedAnns::instance();
  return impl::getHint<IntBits>(e, def,
                                (unsigned) analysis::PredefinedAnns::IntHints::SIZE,
                                ExpandedType(predefined.hintsIntT)
  );
}

template<>
Array getHint(const Expression& e, const Array& def){
  auto predefined = analysis::PredefinedAnns::instance();
  return impl::getHint<Array>(e, def,
                              (unsigned) analysis::PredefinedAnns::ContHints::ARRAY,
                              ExpandedType(predefined.hintsContT)
  );
}

}}