%{
/* 
 * Laddie to Clay Compiler
 * Author: Lea Wittie and Derrin Pierret
 * Copyright (c) 2007 Bucknell University
 *
 * Permission is hereby granted, free of charge, to any individual or
 * institution obtaining a copy of this software and associated
 * documentation files (the "Software"), to use, copy, modify, and
 * distribute without restriction, provided that this copyright and
 * permission notice is maintained, intact, in all copies and supporting
 * documentation.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL BUCKNELL UNIVERSITY BE LIABLE FOR ANY CLAIM, DAMAGES
 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */ 

using namespace std;
#include<iostream>
#include<string>
//#include <cmath>
#include "compiler.h"
#include "support.h"
#include "morekinds.h"  

void foo(char* s);
TreeNode * make_int();
TreeNode * make_hex();
TreeNode * make_bool();
TreeNode * make_id();

%}

%%

"=="    { colno+=strlen(yytext); foo("=="); return EQEQ; }
"<="    { colno+=strlen(yytext); foo("<="); return LEQ; }
">="    { colno+=strlen(yytext); foo(">="); return GEQ; }
"!="    { colno+=strlen(yytext); foo("!="); return NEQ; }
"&&"    { colno+=strlen(yytext); foo("&&"); return ANDAND; }
"||"    { colno+=strlen(yytext); foo("||"); return OROR; }

":"     { colno+=strlen(yytext); foo(":"); return ':'; }
"!"	{ colno+=strlen(yytext); foo("!"); return '!'; }
","	{ colno+=strlen(yytext); foo(","); return ','; }
";"	{ colno+=strlen(yytext); foo(";"); return ';'; }
"="	{ colno+=strlen(yytext); foo("="); return '='; }
">"	{ colno+=strlen(yytext); foo(">"); return '>'; }
"<"	{ colno+=strlen(yytext); foo("<"); return '<'; }
"["	{ colno+=strlen(yytext); foo("["); return '['; }
"]"	{ colno+=strlen(yytext); foo("]"); return ']'; }
"{"	{ colno+=strlen(yytext); foo("{"); return '{'; }
"}"	{ colno+=strlen(yytext); foo("}"); return '}'; }
")"	{ colno+=strlen(yytext); foo(")"); return ')'; }
"("	{ colno+=strlen(yytext); foo("("); return '('; }
"+"	{ colno+=strlen(yytext); foo("+"); return '+'; }
"-"	{ colno+=strlen(yytext); foo("-"); return '-'; }
"*"	{ colno+=strlen(yytext); foo("*"); return '*'; }

[\t ]		{ colno+=strlen(yytext);
		/* eats up white space */}

[0-9]+		{ colno+=strlen(yytext); foo("INT"); yylval.tnp = make_int();
		return INT;}

"true"|"false" 	{colno+=strlen(yytext); 
		foo("BOOL"); yylval.tnp = make_bool();
		return BOOL;}

0x[0-9a-fA-F]+	{colno+=strlen(yytext); foo("HEX"); yylval.tnp = make_hex(); 
		return HEX;}

"access"	{colno+=strlen(yytext);foo("ACCESS");  return ACCESS;}
"ensures"   {colno+=strlen(yytext);foo("ENSURES");   return ENSURES;}
"requires" {colno+=strlen(yytext);foo("REQUIRES");  return REQUIRES;}
"boolean"	{colno+=strlen(yytext);foo("BOOLEAN"); return BOOLEAN;}
"count"         {colno+=strlen(yytext);foo("COUNT");   return COUNT;}
"default"	{colno+=strlen(yytext);foo("DEFAULT"); return DEFAULT;}
"enum"		{colno+=strlen(yytext); foo("ENUM");   return ENUM;}
"fixed"         {colno+=strlen(yytext);foo("FIXED");   return FIXED;}
"integer"	{colno+=strlen(yytext);foo("INTEGER"); return INTEGER;}
"name"		{colno+=strlen(yytext); foo("NAME");   return NAME;}
"old"           {colno+=strlen(yytext);foo("OLD");     return OLD;}
"port"		{colno+=strlen(yytext); foo("PORT");   return PORT;}
"preserved"     {colno+=strlen(yytext);foo("PRESERVED"); return PRESERVED;}
"read_value"    {colno+=strlen(yytext);foo("READ_VALUE"); return READ_VALUE;}
"rw"|"readwrite"  {colno+=strlen(yytext);foo("RW");return RW;}
"read"          {colno+=strlen(yytext);foo("R"); return R;}
"repeated"      {colno+=strlen(yytext);foo("REPEATED"); return REPEATED;}
"size"		{colno+=strlen(yytext);foo("SIZE");    return SIZE;}
"static"        {colno+=strlen(yytext);foo("STATIC");  return STATIC;}
"switch"	{colno+=strlen(yytext);foo("SWITCH");  return SWITCH;}
"test_input"    {colno+=strlen(yytext);foo("TEST_INPUT"); return TEST_INPUT;}
"type"          {colno+=strlen(yytext);foo("TYPE"); return TYPE;}
"value"		{colno+=strlen(yytext); foo("VALUE");  return VALUE;}
"volatile"      {colno+=strlen(yytext);foo("VOLATILE"); return VOLATILE;}
"write_value"   {colno+=strlen(yytext);foo("WRITE_VALUE"); return WRITE_VALUE;}
"write"	{colno+=strlen(yytext);foo("W"); return W;}

[a-zA-Z_][0-9a-zA-Z_]*	{colno+=strlen(yytext); foo("ID"); 
                yylval.tnp = make_id(); return ID;}

\n		{ // gjkhk
   colno = 0;
		lineno++;
		/*return yytext[0];*/ }

"//"[^'\n']* { /* This is the one // comment */ }

"/*"            { // This is the /* */ comment
     char c;
     int done = 0;
     do {
	  while ( (c = yyinput()) != '*') {
	       if (c == '\n') {
		    lineno++; colno = 0;
               }
	       else	
	            colno++;
	  }

	  while ( (c = yyinput()) == '*') { colno++; };

	  if (c == '\n') {
	       lineno++; colno = 0;
	  }	
	  if (c == '/') {
	       done = 1; colno++;
          }
     } while (!done);    }

.            {cerr << "Lexical error! "
		   << ", unexpected character " << yytext[0] << endl;
                 cerr<<"Line = "<<lineno<<" Colno = "<<colno<<endl;	
              exit(1);}
%%

void foo(char* s) {
//	cout << s << " ";
}

TreeNode * make_int() {
  TreeNode * node = new TreeNode(intType, lineno);
  node->numval = atoi(yytext);
  return node;
}

TreeNode * make_hex() {
  	TreeNode * node = new TreeNode(hexType, lineno);
	int x;
	sscanf(yytext+2, "%x", &x);  
        node->numval = x;
  	return node;
}

TreeNode * make_bool() {
  TreeNode * node = new TreeNode(boolType, lineno);
// make all flavors of true be T and all false be F
  if(yytext[0] == 't' || yytext[0] == 'T')
     node->strval = "T"; // string(yytext);	
  else
     node->strval = "F";
  return node;
}

TreeNode * make_id() {
  TreeNode * node = new TreeNode(idType, lineno);
  node->strval = string(yytext);
  return node;
}
