import java.io.FileReader;
import java.io.StreamTokenizer;

/**
 * Class that represents a SILLY program as a stream of tokens.
 * 
 * @author Dave Reed
 * @version 2/9/07
 */
public class SourceCode {
	private StreamTokenizer tokens;

	/** 
	 * Constructs a SourceCode token stream, initialized to read from the file.
	 *   @param filename the name of the source code file to be read from
	 */
	public SourceCode(String filename) {
		try {
	        tokens = new StreamTokenizer(new FileReader(filename));
	    }
	    catch (java.io.FileNotFoundException e) {
	        System.out.println("SYSTEM ERROR: File not found");
	        System.exit(0);
	    }
	}

	/**
	 * Determines whether any tokens remain to be read from the program.
	 *   @return true if any tokens remain; otherwise, false
	 */
	public boolean hasNext() {
	    try {
	        int result = tokens.nextToken();
	        tokens.pushBack();
	        return (result != StreamTokenizer.TT_EOF);
	    }
	    catch (java.io.IOException e) {
	        return false;
	    }
	}
	
	/**
	 * Peeks ahead to the next token in the program without reading it.
	 *   @return the next Token in the program
	 */
	public Token peek() {
        Token nextToken = this.next();
        tokens.pushBack();
        return nextToken;
    }
	   
	/**
	 * Reads the next token in the program (and removes it from the stream).
	 *   @return the next Token in the program
	 */
	public Token next() {
	    try {
	        int result = tokens.nextToken();
            if (result == StreamTokenizer.TT_NUMBER) {
                return new Token((int)tokens.nval);
            }
            else if (result == '\"') {
                return new Token("\"" + tokens.sval + "\"");
            }
            else if (tokens.sval != null) {
                return new Token(tokens.sval);  
            }
            else {
                return new Token(""+(char)result);
            }
        }
        catch (java.io.IOException e) {
            System.out.println("SYNTAX ERROR: Unexpected end of file");
            System.exit(0);
            return null;
        }
	}
}
