
import java.io.*;
import antlr.CommonAST;
import antlr.collections.AST;
import antlr.RecognitionException;
import antlr.TokenStreamException;
import antlr.TokenStreamIOException;
import jamaica.*;

/**
 * The main class
 *
 * @author Hanhua Feng - hf2048@columbia.edu
 * @version $Id: MxMain.java,v 1.15 2003/05/13 17:34:31 hanhua Exp $
 */
class MxMain {
    static boolean verbose = false;

    public static void execFile( String filename ) {
        try 
        {
            InputStream input = ( null != filename ) ?
                (InputStream) new FileInputStream( filename ) :
                (InputStream) System.in;
                                     
            MxAntlrLexer lexer = new MxAntlrLexer( input );

            MxAntlrParser parser = new MxAntlrParser( lexer );

            // Parse the input program
            parser.program();

            if ( lexer.nr_error > 0 || parser.nr_error > 0 )
            {
                System.err.println( "Parsing errors found. Stop." );
                return;
            }

            CommonAST tree = (CommonAST)parser.getAST();

            if ( verbose )
            {
                // Print the resulting tree out in LISP notation
                System.out.println( 
                    "================ tree structure ======================" );
                System.out.println( tree.toStringList() );
            }

            MxAntlrWalker walker = new MxAntlrWalker();
            // Traverse the tree created by the parser

            if ( verbose )
                System.out.println( 
                    "================ program output ======================" );

            MxDataType r = walker.expr( tree );

            if ( verbose )
                System.out.println( 
                    "================ program return ======================" );
            if ( null != r )
                r.print();

            if ( verbose )
            {
                System.out.println( 
                    "================ global variables ====================" );
                walker.ipt.symt.what();
            }

        } catch( IOException e ) {
            System.err.println( "Error: I/O: " + e );
        } catch( RecognitionException e ) {
            System.err.println( "Error: Recognition: " + e );
        } catch( TokenStreamException e ) {
            System.err.println( "Error: Token stream: " + e );
        } catch( Exception e ) {
            System.err.println( "Error: " + e );
        }

        while ( Painter.frameCount() > 0 || Plotter.frameCount() > 0 )
        {
            try 
            {
                Thread.sleep( 1000 );
            } catch ( InterruptedException e ) {}
        }
    }

    public static void commandLine() {
        InputStream input = (InputStream) new DataInputStream( System.in );
        MxAntlrWalker walker = new MxAntlrWalker();

        for ( ;; ) 
        {
            try 
            {
                while( input.available() > 0 )
                    input.read();
            }
            catch ( IOException e ) {}

            System.out.print( "Mx> " );
            System.out.flush();

            MxAntlrLexer lexer = new MxAntlrLexer( input );
            MxAntlrParser parser = new MxAntlrParser( lexer );

            try
            {
                parser.cl_statement();
                CommonAST tree = (CommonAST)parser.getAST();
                MxDataType r = walker.expr( tree );
                if ( verbose && r != null)
                    r.print();
            } catch( RecognitionException e ) {
                System.err.println( "Recognition exception: " + e );
            } catch( TokenStreamException e ) {
                if ( e instanceof TokenStreamIOException ) {
                    System.err.println( "Token I/O exception" );
                    break;
                }
                System.err.println( "Error: Token stream: " + e );
            } catch( MxException e ) {
                System.err.println( "Error: Interpretive: " + e );
                e.printStackTrace();
            } catch( RuntimeException e ) {
                System.err.println( "Error: Runtime: " + e );
                e.printStackTrace();
            } catch( Exception e ) {
                System.err.println( "Error: " + e );
                e.printStackTrace();
            }

        }
    }

    public static void main( String[] args ) {

        verbose = args.length >= 1 && args[0].equals( "-v" );

        boolean batch = args.length >=1 && args[0].equals( "-b" );

        if ( args.length >= 1 && args[args.length-1].charAt(0) != '-' )
            execFile( args[args.length-1] );
        else if ( batch )
            execFile( null );
        else
            commandLine();

        System.exit( 0 );
    }
}
