/**
 * @author David Levine
 * 
 * String Tokenizer, with simple handling
 *  Created Sep, 2007 for CS 210
 *
 * Modification history:
 *  -  read from console (if no arg, or "console"), Sept 26/27
 *  - report exceptions with printStackTrace()  per suggestion
 */

import java.io.*;


class Tokenizer {
     private StreamTokenizer in;
     private boolean atEOF;
   static boolean VERBOSE = false;

    private Token current = null;
    /**
     * set up a StreamTokenizer to read from specified file
     */

    public Tokenizer (String file) throws IOException {
	Reader fileIn;
	if (file == null || "keyboard".equals(file))
            fileIn = new InputStreamReader(System.in);
        else
            fileIn = new FileReader(file);

	in = new StreamTokenizer(fileIn);
	 // customization:  
	 // - '/' alone is not an end-of-line comment
	 // - recognize "//" and "/*" comments
	in.ordinaryChar('/');
	in.slashSlashComments(true);
	in.slashStarComments(true);
	 // - '.' is an operator, not part of a word
	in.ordinaryChar('.');
	
	atEOF = false;
    }
    
    /**
     * get next token, returns Token object.
     *  Token will always have 'sval' corresponding to text scanned.
     *  Type field will give more info:  number, word, etc.
     * Returns null at end of file
     */
    public Token getNext() {
    
		  // advance to next token
		try {in.nextToken();}
		catch (Exception e){
			System.out.println("Ooops " + e);
			return null;
		}
		  // check for end of file ..
		if (in.ttype == StreamTokenizer.TT_EOF) {
			atEOF = true;
			return null;
		}
		// looks ok. Find out what kind of thing we've scanned,
		// and return a Token with appropriate fields set.
		Token t;
		
		switch (in.ttype) {
		case StreamTokenizer.TT_WORD:
		    if (VERBOSE) 
			System.out.println("text: " + in.sval);
		    t = new Token(in.sval);
		    break;
		case StreamTokenizer.TT_NUMBER:
		    if (VERBOSE) 
			System.out.println(" Num: " + in.nval);
		    t = new Token((long)in.nval);
		    break;
		default:
		    // if not a 'word' or 'number', it must be a
		    // symbol:  then ttype holds the character code.
		    if (VERBOSE) 
			System.out.println("spec: " + String.valueOf((char)in.ttype));
		    
		    if (in.ttype == '"' || in.ttype == '\'') 
			// quoted string
			// (special constructor to indicate special case)
			t = new Token(in.sval, (char)in.ttype);
		    else
			// simple operator
			t = new Token((char)in.ttype);
		}
		if (VERBOSE)
		    System.out.println("token: " + t);
		if (Lists.workList != null){
    		Lists.workList.print();
    		System.out.println();
    		System.out.println("just read token: " + t);
		}
		current = t;
		return t;
    }

    public Token getCurrent() {
    		return current;
    }
    
    public boolean atEOF (){
    	return atEOF;
    }
} // end class Tokenizer

	