Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

Unicalc.java

Go to the documentation of this file.
00001 // file:    Unicalc.java
00002 // author:  Robert Keller
00003 // purpose: Shell for Unicalc application
00004 
00005 import java.io.*;
00006 import OpenList;
00007 import Quantity;
00008 import UnicalcParser;
00009 import LineBufferInputStream;
00010 
00011 /**
00012  * Unicalc defines one Unicalc application, with database readable from
00013  * a file.  Unicalc derives the conversion factor for converting one
00014  * kind of Quantity to another.  Quantities are multiplicative and 
00015  * conversions are defined by a database of equations.  
00016  *
00017  * Class Quantity does most of the work.  Class Unicalc is primarily a
00018  * shell for using Quantities.
00019  */
00020 
00021 class Unicalc
00022 {
00023 /** the default name of the database file */
00024 
00025 static String defaultDBfilename = "/cs/cs60/bin/unicalc.db";
00026 
00027 
00028 /** the first prompt string */
00029 
00030 static String promptString1 = "convert from: ";
00031 
00032 
00033 /** the second prompt string */
00034 
00035 static String promptString2 = "convert to: ";
00036 
00037 
00038 /** 
00039  * the Unicalc database in association list form
00040  *
00041  * Each element of the list is a list of two objects: a String and
00042  * a Quantity, denoting the left- and right-hand sides of a conversion
00043  * equation.
00044  */
00045 
00046 OpenList DB;                    
00047 
00048 
00049 /**
00050  * Read a database from the named file.  Each line of the file is a
00051  * string defining the left-hand unit and a corresponding expression
00052  * to which the unit is converted.
00053  */
00054 
00055 void readDB(String DBfilename)
00056   {
00057   DB = OpenList.nil;                            // Initialize database.
00058 
00059   FileInputStream filein = null;                // to keep compiler happy
00060 
00061   try
00062     {
00063     filein = new FileInputStream(DBfilename);   // Open databasefile.
00064     }
00065   catch( FileNotFoundException e )
00066     {
00067     System.out.println("*** Database file " + DBfilename + " not found.");
00068     System.exit(1);                             // Exit if no DB.
00069     }
00070 
00071   LineBufferInputStream in = new LineBufferInputStream(filein);
00072 
00073   while( !in.eof() )
00074     {
00075     String LHS = in.getString();                     // Read LHS of equation.
00076 
00077     String line = in.getNonBlankLine();              // Read RHS of equation.
00078 
00079     Object input = new UnicalcParser(line).parse();  // Parse the RHS
00080 
00081     Quantity RHS = Quantity.makeQuantity(input);     // Make Quantity from RHS.
00082 
00083     DB = OpenList.cons(OpenList.list(LHS, RHS), DB); // cons eqn to A-list.
00084     }
00085   }
00086 
00087 
00088 /**
00089  * Parse a Quantity from the input/
00090  */
00091 
00092 static Quantity getQuantity(LineBufferInputStream in, PrintStream out)
00093   {
00094   // Parse input to a tree, constructed using OpenList
00095 
00096   Object input;
00097 
00098   do
00099     {
00100     String line = in.getNonBlankLine();         // Get something to parse.
00101     input = new UnicalcParser(line).parse();    // Parse it to a tree.
00102     if( input == null )
00103       {
00104       out.println("Invalid input, please try again");
00105       }
00106     }
00107   while( input == null );                       // Make sure it is sensible.
00108 
00109   return Quantity.makeQuantity(input);          // Make Quantity from tree.
00110   }
00111 
00112 
00113 /**
00114  * Provide shell loop, reading from inStream and printing to out.
00115  * On each iteration, the user is prompted for "to" and "from" 
00116  * Quantity expressions, which are parsed to create trees, and then
00117  * Quantities.  One Quantity is converted to the other and the result
00118  * printed.
00119  */
00120 
00121 void loop(InputStream inStream, PrintStream out)
00122   {
00123   LineBufferInputStream in = new LineBufferInputStream(inStream);
00124 
00125   while( true )
00126     {
00127     prompt(promptString1, out);                    // First prompt.
00128     if( in.eof() ) break;                          // Make sure we have input.
00129 
00130     Quantity fromQuantity = getQuantity(in, out);  // Get "from" Quantity.
00131 
00132     prompt(promptString2, out);                    // Second prompt.
00133     if( in.eof() ) break;                          // Make sure we have input.
00134 
00135     Quantity toQuantity = getQuantity(in, out);    // Get "to" Quantity.
00136 
00137     Quantity conversion =                          // Convert "from" to "to"
00138         Quantity.convert(fromQuantity, toQuantity, DB);
00139 
00140     out.println("multiply by: " + conversion);     // Display results
00141     out.println("or divide by: " + Quantity.invert(conversion));
00142     out.println();
00143     }
00144   out.println();
00145   }
00146 
00147 
00148 /**
00149  * Prompt with a string on the output stream.
00150  */
00151 
00152 static void prompt(String promptString, PrintStream out)
00153   {
00154   out.print(promptString);
00155   out.flush();
00156   }
00157 
00158 
00159 /**
00160  * the Unicalc application program
00161  */
00162 
00163 static public void main(String arg[])
00164   {
00165   String DBfilename = defaultDBfilename;        // Use default database.
00166 
00167   Unicalc unicalc = new Unicalc();              // Create Unicalc instance.
00168 
00169   unicalc.readDB(DBfilename);                   // Populate database.
00170 
00171   unicalc.loop(System.in, System.out);          // Run shell.
00172   }
00173 
00174 }

Generated at Wed Oct 9 23:52:14 2002 for Unicalc by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001