//
// Author:
//   Leif Kornstaedt <kornstae@ps.uni-sb.de>
//
// Copyright:
//   Leif Kornstaedt, 1996, 1997
//
// Last change:
//   $Date: 1999/01/21 09:55:27 $ by $Author: schulte $
//   $Revision: 1.14 $
//
// This file is part of Mozart, an implementation of Oz 3:
//    http://www.mozart-oz.org
//
// See the file "LICENSE" or
//    http://www.mozart-oz.org/LICENSE.html
// for information on usage and redistribution
// of this file, and for a DISCLAIMER OF ALL
// WARRANTIES.
//

//
// This file is included by lexers generated by Gump.
//

#include "mozart.h"

static void setEmptyBuffer(yyFlexLexer *i) {
  static yy_buffer_state *p = 0;
  if (!p) {
    p = new yy_buffer_state;
    p->yy_input_file = 0;
    p->yy_ch_buf = new char[2];
    p->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
    p->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
    p->yy_buf_pos = &p->yy_ch_buf[0];
    p->yy_buf_size = 0;
    p->yy_n_chars = 0;
    p->yy_is_our_buffer = 1;
    p->yy_is_interactive = 0;
    p->yy_at_bol = 1;
    p->yy_fill_buffer = 0;
    p->yy_buffer_status = YY_BUFFER_NEW;
  }
  i->yy_switch_to_buffer(p);
}

OZ_BI_define(yy_lexer_create, 0, 1)
{
  yyFlexLexer *flexLexer = new yyFlexLexer();
  setEmptyBuffer(flexLexer);
  OZ_Term t = OZ_makeForeignPointer(flexLexer);
  OZ_RETURN(t);
}
OZ_BI_end

OZ_BI_define(yy_lexer_delete, 1, 0)
{
  OZ_declareForeignPointer(0, p);
  delete (yyFlexLexer *) p;
  return PROCEED;
}
OZ_BI_end

OZ_BI_define(yy_lexer_getNextMatch, 1, 1)
{
  OZ_declareForeignPointer(0, p);
  yyFlexLexer *lexer = (yyFlexLexer *) p;
  int res = lexer->yylex();
  if (res == -1) {
    return OZ_raiseErrorC("gump",2,OZ_atom("fatalError"),
			  OZ_string(lexer->yy_last_error_msg));
  } else {
    OZ_RETURN_INT(res);
  }
}
OZ_BI_end

OZ_BI_define(yy_lexer_getAtom, 1, 1)
{
  OZ_declareForeignPointer(0, p);
  OZ_RETURN_ATOM((char *) ((yyFlexLexer *) p)->YYText());
}
OZ_BI_end

OZ_BI_define(yy_lexer_getString, 1, 1)
{
  // this does not use OZ_string because we don't necessarily want
  // to stop at the first NUL
  OZ_declareForeignPointer(0, p);
  yyFlexLexer *obj = (yyFlexLexer *) p;
  int i = obj->YYLeng();
  const unsigned char *yytext = (unsigned char*) obj->YYText();
  OZ_Term str = OZ_nil();
  for (i--; i >= 0; i--)
    str = OZ_cons(OZ_int(yytext[i]), str);
  OZ_RETURN(str);
}
OZ_BI_end

OZ_BI_define(yy_lexer_getLength, 1, 1)
{
  OZ_declareForeignPointer(0, p);
  OZ_RETURN_INT(((yyFlexLexer *) p)->YYLeng());
}
OZ_BI_end

OZ_BI_define(yy_lexer_switchToBuffer, 2, 0)
{
  OZ_declareForeignPointer(0, p);
  OZ_declareForeignPointer(1, q);
  ((yyFlexLexer *) p)->yy_switch_to_buffer((yy_buffer_state *) q);
  return PROCEED;
}
OZ_BI_end

OZ_BI_define(yy_lexer_setMode, 2, 0)
{
  OZ_declareForeignPointer(0, p);
  OZ_declareInt(1, i);
  ((yyFlexLexer *) p)->yy_start = i * 2 + 1;
  return PROCEED;
}
OZ_BI_end

OZ_BI_define(yy_lexer_currentMode, 1, 1)
{
  OZ_declareForeignPointer(0, p);
  OZ_RETURN_INT((((yyFlexLexer *) p)->yy_start - 1) / 2);
}
OZ_BI_end

OZ_BI_define(yy_lexer_input, 1, 1)
{
  OZ_declareForeignPointer(0, p);
  OZ_RETURN_INT(((yyFlexLexer *) p)->yyinput());
}
OZ_BI_end

OZ_C_proc_interface *oz_init_module(void) {
  static OZ_C_proc_interface oz_interface[] = {
    {"create",0,1,yy_lexer_create},
    {"delete",1,0,yy_lexer_delete},
    {"getNextMatch",1,1,yy_lexer_getNextMatch},
    {"getAtom",1,1,yy_lexer_getAtom},
    {"getString",1,1,yy_lexer_getString},
    {"getLength",1,1,yy_lexer_getLength},
    {"switchToBuffer",2,0,yy_lexer_switchToBuffer},
    {"setMode",2,0,yy_lexer_setMode},
    {"currentMode",1,1,yy_lexer_currentMode},
    {"input",1,1,yy_lexer_input},
    {0,0,0,0}
  };
  return oz_interface;
}
