/* Do NOT modify this file! */
/* Better yet.  Don't even read it! */


/*
 * Tokenization implementations for RL Assignment
 *
 * Copyright J. Dean Brock, 2010
 * This file released under terms of the GNU General Public License
 *
 */

#include <stdio.h>
#include <ctype.h>
#include <string.h>

#include "RLtoken.h"

#define TOKNOCHAR  -2009
#define TOKMXCHARS 10
enum TokenType getNextToken(FILE * f, char *field ) {
    static int nextChar = TOKNOCHAR ;   /* Used only for readahead */
    int readChar ;                      /* The active character */
    int fldPntr ;                      /* Field pointer */


    if (nextChar == TOKNOCHAR) {
        readChar = fgetc(f) ;
    } else {
        readChar = nextChar ;
    }
    /* skip blanks */
    while (isspace(readChar) && readChar != '\n')
        readChar = fgetc(f) ;

    /* process character */
    if (readChar == EOF) {
        nextChar = EOF ;
        return tokEoF ;
    } else if (readChar == '\n') {
        nextChar = TOKNOCHAR ;
        return tokEoL ;
    } else if (readChar == '=') {
        nextChar = TOKNOCHAR ;
        return tokEq ;
    } else if (readChar == '+') {
        nextChar = TOKNOCHAR ;
        return tokSer ;
    } else if (readChar == '|') {
        nextChar = TOKNOCHAR ;
        return tokPar ;
    } else if (isalpha(readChar)) {
        field[0] = readChar ;
        fldPntr = 1 ;
        while (fldPntr<TOKMXCHARS
                && (isalpha(readChar=fgetc(f)))) {
            field[fldPntr++] = readChar ;
        }
        if (fldPntr == TOKMXCHARS) {
            nextChar = TOKNOCHAR ;
        } else {
            nextChar = readChar ;
        }
        field[fldPntr] = '\0' ;
        return tokVar ;
    } else if (isdigit(readChar)) {
        /* Really need to do some refactoring with the last case */
        field[0] = readChar ;
        fldPntr = 1 ;
        while (fldPntr<TOKMXCHARS
                && (isdigit(readChar=fgetc(f)))) {
            field[fldPntr++] = readChar ;
        }
        if (fldPntr == TOKMXCHARS) {
            nextChar = TOKNOCHAR ;
        } else {
            nextChar = readChar ;
        }
        field[fldPntr] = '\0' ;
        return tokConst ;
    } else {
        nextChar = EOF ;
        return tokErr ;
    }

}

char * tokenToString(enum TokenType t) {
    switch(t) {
        case tokErr:
            return "Error" ;
        case tokEoF :
            return "End-of-File" ;
        case tokEoL :
            return "End-of-Line" ;
        case tokEq :
            return "=" ;
        case tokSer :
            return "+" ;
        case tokPar :
            return "|" ;
        case tokVar :
            return "Variable" ;
        case tokConst :
            return "Constant" ;
        default:
            return "BAD TOKEN" ;
    }
}
