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

#include "analysis/predefinedanns.h"
#include "analysis/resources.h"

namespace xreate{ namespace analysis{

PredefinedAnns
PredefinedAnns::__instance = PredefinedAnns();

PredefinedAnns::PredefinedAnns(){
  fnAnnsT = TypeAnnotation(TypeOperator::VARIANT, {});
  exprAnnsT = TypeAnnotation(TypeOperator::VARIANT, {});

  //Function annotations
  fnAnnsT.__operands.push_back(TypePrimitive::Invalid);
  fnAnnsT.fields.push_back(FN_ENTRY_PREDICATE);
  fnAnnsT.__operands.push_back(TypePrimitive::Invalid);
  fnAnnsT.fields.push_back(FN_EXTERIOR_PREDICATE);

  //interpretation
  i12nModeT = TypeAnnotation(TypeOperator::VARIANT, {
    TypePrimitive::Invalid,
    TypePrimitive::Invalid
  });
  i12nModeT.fields.push_back("on");
  i12nModeT.fields.push_back("off");

  exprAnnsT.__operands.push_back(i12nModeT);
  exprAnnsT.fields.push_back("i12n");

  //Int
  hintsIntT = TypeAnnotation(TypeOperator::VARIANT, {
    TypePrimitive ::Int
  });
  hintsIntT.fields.push_back("size");

  //Containers
  hintsContT = TypeAnnotation(TypeOperator::VARIANT, {
    TypePrimitive::Int,
    TypeAnnotation::alias("hintsContT")
  });
  hintsContT.fields.push_back("csize");
  hintsContT.fields.push_back("fly");
}

void
PredefinedAnns::registerVariants(std::map<std::string, std::pair<TypeAnnotation, int>> &__registry) const{
  //annotation; type; variant id;
  __registry = {
    //Functions:
    {FN_ENTRY_PREDICATE, {fnAnnsT,   (unsigned) FnAnnotations::ENTRY}},
    {FN_EXTERIOR_PREDICATE, {fnAnnsT,   (unsigned) FnAnnotations::EXTERIOR}},

    //Expressions:
    {"i12n",  {exprAnnsT, (unsigned) ExprAnnotations::I12N}},

    //Interpretation:
    {"on",    {i12nModeT, (unsigned) I12ModeTag::ON}},
    {"off",   {i12nModeT, (unsigned) I12ModeTag::OFF}},

    //Int:
    {"size", {hintsIntT, (unsigned) IntHints::SIZE}},

    //Containers
    {"csize", {hintsContT, (unsigned) ContHints::ARRAY}},
    {"fly",   {hintsContT, (unsigned) ContHints::FLY}},
  };
}

void
PredefinedAnns::registerAliases(std::map<std::string, TypeAnnotation> &__registry) const{
  __registry = {
    {"hintsContT", hintsContT}
  };
}
}}