#include "parser.h"
#include <iostream>

namespace sat_atpg {

int Parser::parse_bench(istream& f)
{
 string s,name,gate;
 
 while (! f.eof() )
   {
    getline (f,s);
    s=noSpaces(s);
    //cout << s << endl;
    if ((s.length()==0) || (s[0]=='#'))
      continue;
    unsigned int pos_equal = s.find('='); 
    unsigned int pos_brac = s.find('(');
    unsigned int pos_brac_end = s.find(')');
    //cout << pos_equal << " " << pos_brac << " " << pos_brac_end << endl;
    if (pos_brac>pos_brac_end) 
      { 	
       return -1; 
      }       
    if (pos_equal==string::npos)
      {
       if ((pos_brac == 5) && (toLowerCase(s.substr(0,5))==("input")))
         {
          name = s.substr(6,pos_brac_end-6);
          inputs.push( new Gate_token(INPUT,name,0));
         }
       else if ((pos_brac == 6) && (toLowerCase(s.substr(0,6))==("output")))
         {
          name = s.substr(7,pos_brac_end-7);
          outputs.push (new Gate_token(OUTPUT,name,0));
         }
       else return -1;
      }
    else
      {
       name = s.substr(0,pos_equal);
       gate = toLowerCase(s.substr(pos_equal+1,pos_brac-pos_equal-1));
       int kind; 
       if (gate == "and") 
         kind = AND;
       else if (gate == "nand")
         kind = NAND;
       else if (gate == "nor")
         kind = NOR;
       else if (gate == "or")
         kind = OR;
       else if (gate == "xor")
         kind = XOR;
       else if (gate == "not")
         kind = NOT;
       else if ((gate == "buff") || (gate == "buf"))
         kind = BUFF;
       else
         {
	  std::cerr << "Error: Unknown gate " << gate << " in bench file.";  
          return -1;
         }   
       int input_count = 1;
       unsigned int pos = s.find(',',pos_brac);
       while (pos != string::npos)
         {
          input_count++;
          pos = s.find(',',pos+1);
         } 
       Gate_token* t= new Gate_token(kind,name,input_count);
       pos = s.find(',');
       int last_pos = pos_brac+1;
       for (int i = 0; i<input_count-1; i++)
          {
           t->inputs[i] = s.substr(last_pos,pos-last_pos);
           last_pos = pos+1;
           pos = s.find(',',pos+1);
          }
       t->inputs[input_count-1] = s.substr(last_pos,pos_brac_end-last_pos);
       gates.push(t);
    }      
  }
return 0;
}

int Parser::parse_faults(istream& f)
{
 string s,from,to;
 bool polarity;
 while (! f.eof() )
   {
    getline (f,s);
    unsigned int pos_lom = s.find(" /");
    if (pos_lom==string::npos)
      return -1; 
    unsigned int pos_arrow = s.find("->");  
    if (pos_arrow==string::npos)
  	{
         from = s.substr(0,pos_lom);
         to = "";
        }
    else
       {
        from = s.substr(0,pos_arrow);
        to = s.substr(pos_arrow+2,pos_lom-pos_arrow-2);
       }
    polarity = (s.substr(pos_lom+2)=="1");
    faults.push(new Fault_token(from,to,polarity));
  }
return 0;
} 		 
}         
