/*===-- 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 "llvm/Config/config.h"
#include "llvm/Support/Streams.h"
#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 strtoll(Str+2, 0, 2);
  return strtoll(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()) {
    cerr << "At end of input: ";
    return *cerr.stream();
  }

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

/// 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) {
      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);
  //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; }
defm           { return DEFM; }
multiclass     { return MULTICLASS; }
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]; }

%%

