#include "lexer.h"
#include <cstdlib>
#include <cstring>
#include <cctype>

/*
* Return the next lexical element in the string s.
*  Passing NULL into s, will cause the lexer to read the next element out
*  of the last string passed in.
*/
LexicalElement
nextElement(char *s) {
 static char *ptr = 0x00;
 LexicalElement result;

 //handle pointer reset
 if(s)
   ptr=s;

 //check for the end of the string
 if(!ptr || !*ptr) {
   goto EOS_REACHED;
 }

 //skip white space
 while(*ptr && isspace(*ptr)) ptr++;

 //check for the null terminator
 if(!*ptr) {
   goto EOS_REACHED;
 }

 //handle parens
 if(*ptr == '(') {
   result.type=LPAREN;
   result.value.c = '(';
   ptr++;
 } else if(*ptr == ')') {
   result.type=RPAREN;
   result.value.c = ')';
   ptr++;
 } else if(strchr("*+-/", *ptr)) {
   result.type = OPERATOR;
   result.value.c=*ptr;
   ptr++;
 } else if(isdigit(*ptr) || *ptr=='.') {
   //extract number
   char *end, *begin;
   char *buf;

   //find the end
   begin=ptr;
   ptr++;
   while(isdigit(*ptr) || *ptr=='.') ptr++;
   buf = strndup(begin, end-begin);

   //set up the result
   result.type  = NUMBER;
   result.value.num = atof(buf);

   //get rid of the duped string
   free(buf);
 }  else {
   result.type = ERROR;
   ptr++;
 }

 return result;

 //screw Dijkstra, praise Knuth!
 EOS_REACHED:
 result.type=EOS;
 return result;
}