/*===-- FileLexer.l - Scanner for TableGen Files ----------------*- C++ -*-===//
// 
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
// 
//===----------------------------------------------------------------------===//
//
// This file defines a simple flex scanner for TableGen files.  This is pretty
// straight-forward, except for the magic to handle file inclusion.
//
//===----------------------------------------------------------------------===*/

%option prefix="File"
%option yylineno
%option nostdinit
%option never-interactive
%option batch
%option nodefault
%option 8bit
%option outfile="Lexer.cpp"
%option ecs
%option noreject
%option noyymore

%x comment

%{
#include "Record.h"
typedef std::pair<llvm::Record*, std::vector<llvm::Init*>*> SubClassRefTy;
#include "FileParser.h"

int Fileparse();

namespace llvm {

// Global variable recording the location of the include directory
std::vector<std::string> IncludeDirectories;

/// ParseInt - This has to handle the special case of binary numbers 0b0101
///
static int ParseInt(const char *Str) {
  if (Str[0] == '0' && Str[1] == 'b')
    return strtol(Str+2, 0, 2);
  return strtol(Str, 0, 0); 
}

static int CommentDepth = 0;

struct IncludeRec {
  std::string Filename;
  FILE *File;
  unsigned LineNo;
  YY_BUFFER_STATE Buffer;

  IncludeRec(const std::string &FN, FILE *F)
    : Filename(FN), File(F), LineNo(0){
  }
};

static std::vector<IncludeRec> IncludeStack;

std::ostream &err() {
  if (IncludeStack.empty())
    return std::cerr << "At end of input: ";

  for (unsigned i = 0, e = IncludeStack.size()-1; i != e; ++i)
    std::cerr << "Included from " << IncludeStack[i].Filename << ":"
              << IncludeStack[i].LineNo << ":\n";
  return std::cerr << "Parsing " << IncludeStack.back().Filename << ":"
                   << Filelineno << ": ";
}

/// ParseFile - this function begins the parsing of the specified tablegen file.
///
void ParseFile(const std::string &Filename, 
               const std::vector<std::string> &IncludeDirs) {
  FILE *F = stdin;
  if (Filename != "-") {
    F = fopen(Filename.c_str(), "r");

    if (F == 0) {
      std::cerr << "Could not open input file '" + Filename + "'!\n";
      exit (1);
    }
    IncludeStack.push_back(IncludeRec(Filename, F));
  } else {
    IncludeStack.push_back(IncludeRec("<stdin>", stdin));
  }

  // Record the location of the include directory so that the lexer can find
  // it later.
  IncludeDirectories = IncludeDirs;
 
  Filein = F;
  Filelineno = 1;
  Fileparse();
  Filein = stdin;
}

/// HandleInclude - This function is called when an include directive is
/// encountered in the input stream...
///
static void HandleInclude(const char *Buffer) {
  unsigned Length = yyleng;
  assert(Buffer[Length-1] == '"');
  Buffer += strlen("include ");
  Length -= strlen("include ");
  while (*Buffer != '"') {
    ++Buffer;
    --Length;
  }
  assert(Length >= 2 && "Double quotes not found?");
  std::string Filename(Buffer+1, Buffer+Length-1);
  //std::cerr << "Filename = '" << Filename << "'\n";

  // Save the line number and lex buffer of the includer...
  IncludeStack.back().LineNo = Filelineno;
  IncludeStack.back().Buffer = YY_CURRENT_BUFFER;

  // Open the new input file...
  yyin = fopen(Filename.c_str(), "r");
  if (yyin == 0) {
    // If we couldn't find the file in the current directory, look for it in
    // the include directories.
    //
    std::string NextFilename;
    for (unsigned i = 0, e = IncludeDirectories.size(); i != e; ++i) {
      NextFilename = IncludeDirectories[i] + "/" + Filename;
      if ((yyin = fopen(NextFilename.c_str(), "r")))
        break;
    }
    
    if (yyin == 0) {
      err() << "Could not find include file '" << Filename << "'!\n";
      exit(1);
    }
    Filename = NextFilename;
  }

  // Add the file to our include stack...
  IncludeStack.push_back(IncludeRec(Filename, yyin));
  Filelineno = 1;  // Reset line numbering...
  //yyrestart(yyin);    // Start lexing the new file...

  yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
}

/// yywrap - This is called when the lexer runs out of input in one of the
/// files. Switch back to an includer if an includee has run out of input.
///
extern "C"
int yywrap(void) {
  if (IncludeStack.back().File != stdin)
    fclose(IncludeStack.back().File);
  IncludeStack.pop_back();
  if (IncludeStack.empty()) return 1;  // Top-level file is done.

  // Otherwise, we need to switch back to a file which included the current one.
  Filelineno = IncludeStack.back().LineNo;  // Restore current line number
  yy_switch_to_buffer(IncludeStack.back().Buffer);
  return 0;
}

} // End llvm namespace

using namespace llvm;

%}

Comment      \/\/.*

Identifier   [a-zA-Z_][0-9a-zA-Z_]*
Integer      [-+]?[0-9]+|0x[0-9a-fA-F]+|0b[01]+
CodeFragment \[\{([^}]+|\}[^\]])*\}\]
StringVal    \"[^"]*\"
IncludeStr   include[ \t\n]+\"[^"]*\"

%%

{Comment}      { /* Ignore comments */ }

{IncludeStr}   { HandleInclude(yytext); }
{CodeFragment} { Filelval.StrVal = new std::string(yytext+2, yytext+yyleng-2);
                 return CODEFRAGMENT; }

int            { return INT; }
bit            { return BIT; }
bits           { return BITS; }
string         { return STRING; }
list           { return LIST; }
code           { return CODE; }
dag            { return DAG; }

class          { return CLASS; }
def            { return DEF; }
field          { return FIELD; }
let            { return LET; }
in             { return IN; }

!sra           { return SRATOK; }
!srl           { return SRLTOK; }
!shl           { return SHLTOK; }
!strconcat     { return STRCONCATTOK; }


{Identifier}   { Filelval.StrVal = new std::string(yytext, yytext+yyleng);
                 return ID; }
${Identifier}  { Filelval.StrVal = new std::string(yytext+1, yytext+yyleng);
                 return VARNAME; } 

{StringVal}    { Filelval.StrVal = new std::string(yytext+1, yytext+yyleng-1);
                 return STRVAL; }

{Integer}      { Filelval.IntVal = ParseInt(Filetext); return INTVAL; }

[ \t\n\r]+     { /* Ignore whitespace */ }


"/*"                    { BEGIN(comment); CommentDepth++; }
<comment>[^*/]*         {} /* eat anything that's not a '*' or '/' */
<comment>"*"+[^*/]*     {} /* eat up '*'s not followed by '/'s */
<comment>"/*"           { ++CommentDepth; }
<comment>"/"+[^*/]*     {} /* eat up /'s not followed by *'s */
<comment>"*"+"/"        { if (!--CommentDepth) { BEGIN(INITIAL); } }
<comment><<EOF>>        { err() << "Unterminated comment!\n"; exit(1); }

.              { return Filetext[0]; }

%%

