%{
/*=-=-=-=-=-=-=-=-=-=-  RCCL/RCI Notice of Copyright  -=-=-=-=-=-=-=-=-=-=-=*
 *									    *
 *	Copyright (C) 1987 by John Lloyd. Permission to    		    *
 *	use, distribute and copy is granted, but only for non-commercial    *
 *	purposes and providing the authors are acknowledged and this 	    *
 *	copyright notice is displayed prominently.			    *
 *									    *
 *	The authors provide this software in hope that it will be useful,   *
 *	but do not assume responsibility for its use.			    *
 *									    *
 *=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/

/* The lexical specification for a desk calculator */

#undef input
#undef unput

char *strcpy();
char *index();

extern int lineWidth;
extern int tabSize;
static int inputColumn;
static int cursorPosition;
static int trialText = 0;

record (n)
{
	int i, l;

	inputColumn = cursorPosition;

	l = strlen (yytext);
	for (i=0; i<l; i++)
	 { switch (yytext[i])
	    { case '\n':
		 cursorPosition = 0;
		 break;
	      case '\t':
		 cursorPosition = 
			((cursorPosition/tabSize+1)*tabSize)%lineWidth;
		 break;
	      default:
		 cursorPosition =
		 	(cursorPosition+1)%lineWidth;
		 break;
	    }
	 }
	if (n == STR)
  	 { /* account for the trailing " in the string literal */
	   cursorPosition = (cursorPosition+1)%lineWidth; 
	 }
	return (n);
}

setInputColumn (n)
{
	inputColumn = cursorPosition = n % lineWidth;
}

getInputColumn ()
{
	return (inputColumn);
}

%}

uint	[0-9]+
gint	[0-9][0-9a-fA-F]*
idchar  [a-zA-Z_]
sint	[-+]?[0-9]+
real	({uint}"."|{uint}"."{uint}|"."{uint})
exp	[Ee]{sint}
cvti	[0-9]+
cvts	[a-zA-Z]+
%%
[ \t]			  record (0);
"\n"			  return (record (ENTER));
"+"			  return (record (1));
"-"			  return (record (2));
"*"			  return (record (3));
"/"			  return (record (4));
"("			  return (record (5));
")"			  return (record (6));
"="			  return (record (12));
","			  return (record (13));
"^"			  return (record (14));
"%"			  return (record (15));
";"			  return (record (16));
"<"			  return (record (17));
">"			  return (record (18));
"."			  return (record (19));
"'"			  return (record (20));
"["			  return (record (21));
"]"			  return (record (22));
":"			  return (record (23));
"\\"			  return (record (24));
"help"|"HELP"|"?"	  return (record (HELP));
"key"|"KEY"		  return (record (KEY));
{cvti}#			{ int b;
	
			  yytext[yyleng-1] = ' ';
	 		  if (readInt (yytext, &b, 10, SIGNED) == -1)
			   { return (record (ERR));
			   }
			  if ((b=acceptOutputBaseInteger(b)) == -1)
			   { return (record (ERR));
			   }
			  yylval.count = b;
			  return (record (CONVERT));
			}
{cvts}#			{ int b;
			  yytext[yyleng-1] = '\0';
			  if ((b=acceptOutputBaseString(yytext)) == -1)
			   { return (record (ERR));
			   }
			  yylval.count = b;
			  yytext[yyleng-1] = '#';
			  return (record (CONVERT));
			}
0x			{ yylval.count = 16;
			  return (record (CONVERT));
			}
0o			{ yylval.count = 8;
			  return (record (CONVERT));
			}
0b			{ yylval.count = 2;
			  return (record (CONVERT));
			}
{cvti}#[0-9a-fA-F]+     { int b, i;
			  char *ns;

			  ns = index (yytext, '#');
			  *ns = '\0';
		  	  ns++;
	 		  if (readInt (yytext, &b, 10, SIGNED) == -1)
			   { return (record (ERR));
			   }
			  if ((b=acceptInputBaseInteger(b)) == -1)
			   { return (record (ERR));
			   }
			  if (readInt (ns, &i, b, UNSIGNED) == -1)
			   { return (record (ERR));
			   }
			  yylval.g.type = INTEGER;
			  yylval.g.val.i = i;
			  yylval.g.name = NULL;
			  return (record (INT));
			}
{cvts}#[0-9a-fA-F]+     { int b, i;
			  char *ns;

			  ns = index (yytext, '#');
			  *ns = '\0';
			  ns++;
			  if ((b=acceptInputBaseString(yytext)) == -1)
			   { return (record (ERR));
			   }
			  if (readInt (ns, &i, b, UNSIGNED) == -1)
			   { return (record (ERR));
			   }
			  yylval.g.type = INTEGER;
			  yylval.g.val.i = i;
			  yylval.g.name = NULL;
			  return (record (INT));
			}
0[xob][0-9a-fA-F]+      { int i;
			  int base;

			  switch (yytext[1])
			   { case 'x': base = 16;
				       break;
			     case 'o': base = 8;
				       break;
			     case 'b': base = 2;
				       break;
			   }
			  if (readInt (&yytext[2], &i, base, UNSIGNED) == -1)
			   { return (record (ERR));
			   }
			  yylval.g.type = INTEGER;
			  yylval.g.val.i = i;
			  yylval.g.name = NULL;
			  return (record (INT));
			}
[0-9][0-9a-fA-F]*	{ int i;

		 	  if (readInt (yytext, &i, defaultInputBase(),
					   SIGNED) == -1)
			   { return (record (ERR));
			   }
			  yylval.g.type = INTEGER;
			  yylval.g.val.i = i;
			  yylval.g.name = NULL;
			  return (record (INT));
			}
("$"|{idchar})({idchar}|[0-9])*	{
			 char *s;
			  s = (char *) talloc (strlen (yytext)+1);
			  yylval.g.name = strcpy (s, yytext);
			  return (record (IDENTIFIER));
			}
({real}({exp})?|{uint}{exp})    {
			 yylval.g.type = DOUBLE;
			 yylval.g.name = NULL;
 			 sscanf (yytext, "%lf", &yylval.g.val.d);
			 return (record (DBLE));
			}
\"[^"]*			{ 
			 if (yytext[yyleng-1] == '\\')
			  { yymore();
			  }
			 else
			  { int c1, c2, l;
			    char *s1, *s2, *sr;

			    s1 = yytext + 1;
			    s2 = sr = (char*)talloc(strlen (yytext));

			    while (c1 = *s1++)
			     { if (c1 == '\\')
				{ if ((c2 = *s1) == '"')
				   { c1 = '"'; s1++;
				   }
				}
			       *s2++ = c1;
			     }
			    *s2 = '\0';
			    yylval.g.type = STRING;
			    yylval.g.val.s = sr;
			    yylval.g.name = NULL;
			    input();
			    return (record (STR));
			  }
			}
.			{ 
			 char *s;
			 s = strcpy ((char *)talloc(strlen(yytext)+1),yytext);
			 return (record (ERR));
			}
%%

yywrap ()
{
 	return(1);
}

#ifdef LINUX_CFG

#else
input() 
{
	if (yysptr > yysbuf)
	 { yytchar = *(--yysptr);
	 }
 	else
  	 { int c = getc(yyin);
	   yytchar = c;
	   putLog (c);
	 }
	if (yytchar == '\n')
  	 { yylineno++;
	 }
	if (yytchar == EOF)
  	 { return (0);
	 }
	else
 	 { return (yytchar);
	 }
}

unput(c) 
{	
	yytchar = (c);
	if (yytchar == '\n')
	 { yylineno--;
	 }
	*yysptr++ = yytchar;
}
#endif