View Javadoc

1   ////////////////////////////////////////////////////////////////////////////////
2   // MillScript: an Open Spice interpreter and batch website creation tool
3   // Copyright (C) 2001-2004 Open World Ltd
4   // Copyright (C) 2004-2005 Kevin Rogers
5   //
6   // This file is part of MillScript.
7   //
8   // MillScript is free software; you can redistribute it and/or modify it under
9   // the terms of the GNU General Public License as published by the Free
10  // Software Foundation; either version 2 of the License, or (at your option)
11  // any later version.
12  //
13  // MillScript is distributed in the hope that it will be useful, but WITHOUT
14  // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16  // more details.
17  //
18  // You should have received a copy of the GNU General Public License along with
19  // MillScript; if not, write to the Free Software Foundation, Inc., 59 Temple
20  // Place, Suite 330, Boston, MA  02111-1307  USA
21  ////////////////////////////////////////////////////////////////////////////////
22  package org.millscript.millscript;
23  
24  import org.millscript.commons.alert.Alert;
25  import org.millscript.commons.alert.EscapeException;
26  import org.millscript.commons.alert.reporters.StandardMishapAlertReporter;
27  import org.millscript.commons.alert.reporters.StandardWarningAlertReporter;
28  import org.millscript.millscript.alert.Alerts;
29  import org.millscript.millscript.syntax.Parser;
30  import org.millscript.millscript.syntax.ParserImpl;
31  
32  import java.io.IOException;
33  import java.io.InputStreamReader;
34  import java.io.Reader;
35  
36  import jline.ConsoleReader;
37  import jline.ConsoleReaderInputStream;
38  
39  /**
40   * This class is used to start an interactive MillScript session.
41   */
42  public class Interactive extends Session {
43  
44      /**
45       * Constructs a new interactive session object.
46       */
47      public Interactive() {
48          config.getLogger().println( "MillScript " + Resources.getMessage( "version" ) );
49      }
50  
51      /**
52       * @see org.millscript.millscript.Session#compile(java.lang.String, java.io.Reader)
53       */
54      @Override
55      public void compile( final String origin, final Reader r ) {
56          Parser parser = new ParserImpl( origin, r, true, config );
57          // Start a never ending parsing loop, which we will return out of when
58          // we reach the end of file.
59          for (;;) {
60              try {
61                  // Try to compile whatever we can.
62                  this.state.compileAllowResults( parser, true );
63                  // The above method will only return normally if we're at the
64                  // end of file, so we simply reutrn if we get here.
65                  return;
66              } catch ( Exception e ) {
67                  // Report the exception
68                  this.config.reportException( e );
69              } finally {
70                  // ok, we've broken out of the compile loop
71                  // No need to check for end of file, as that will be handled in
72                  // the normal way above. We should only get here when an
73                  // exception that broke us out of the compile loop, so we've
74                  // already reported it above, now we should tidy up the session
75                  // and try to continue.
76                  System.out.flush();
77                  System.err.flush();
78                  engine.getConfig().getLogger().println( "Resetting input and resuming execution" );
79                  try {
80                      // Skip any remaining characters
81                      while ( r.ready() ) {
82                          r.skip( 1 );
83                      }
84                      parser = new ParserImpl( origin, r, true, config );
85                  } catch ( IOException ex ) {
86                      //  OK, just carry on ...
87                      engine.getConfig().getLogger().println( "!!! Input cannot be reset, resuming anyway" );
88                  }
89                  engine.getConfig().getLogger().println( "" );
90                  System.out.flush();
91                  System.err.flush();
92                  engine.getMachine().reset();
93              }
94          }
95      }
96  
97      /**
98       * Runs an interactive session first compiling and executing the specified
99       * MillScript files.
100      *
101      * @param args  array of String arguments, treated as files to compile and
102      * execute before starting an interactive session
103      */
104     public static void main( final String[] args ) {
105         try {
106             final Interactive interactive = new Interactive();
107             long startTime = System.currentTimeMillis();
108             interactive.compile( args );
109             final ConsoleReaderInputStream cris = new ConsoleReaderInputStream(
110                 new ConsoleReader()
111             );
112             cris.setPrompt( interactive.config.getInteractivePrompt() );
113             interactive.compile(
114                 "origin",
115                 new InputStreamReader(
116                     cris,
117                     "UTF-8"
118                 )
119             );
120             interactive.printStatistics( startTime );
121             interactive.summarizeResults();
122         } catch ( Alert ex ) {
123             if ( ex.isMishap() ) {
124                 StandardMishapAlertReporter.MISHAP_REPORTER.report( ex );
125             } else {
126                 StandardWarningAlertReporter.WARNING_REPORTER.report( ex );
127             }
128         } catch ( EscapeException ex ) {
129             if ( ex.getAlert().isMishap() ) {
130                 StandardMishapAlertReporter.MISHAP_REPORTER.report( ex.getAlert() );
131             } else {
132                 StandardWarningAlertReporter.WARNING_REPORTER.report( ex.getAlert() );
133             }
134         } catch ( IOException ex ) {
135             throw(
136                 Alerts.compile(
137                     "Problem opening console for interactive session",
138                     null
139                 ).
140                 culprit( "reason", ex.getMessage() ).
141                 mishap()
142             );
143         }
144     }
145 
146 }