// The "Logo" class.
import java.awt.*;
import hsa.Console;
import java.io.*;
import java.util.*;
public class Logo
{
static Console c; // The output console
/**
* Checks to see if a string can be parsed to an int
*
* @param testString string to be tested
* @return returns true or false
*/
public static boolean willParseInt (String testString)
{
//Try parsing to an int
try
{
Integer.parseInt (testString);
}
//Catch an exception if it occurs
catch (NumberFormatException e)
{
//An exception was found, return false
return false;
}
//If no exception occurs, this method returns true
return true;
} //willParseInt (String)
/**
* Runs a .logo file in 6 steps.
* First, the number of command lines in a given file are counted. The method
* then loads all of the commands into an array of 'LogoCmd' objects. During
* this, the number of errors and comments found are counted. If errors are
* found, the user will have the option of running the error checker or
* ignoring all bad entries. The turtle is then run with the commands.
*
* @param magnitudeTokens a string with all the tokens that require a magnitude
* @param simpleTokens a string with all the tokens not needing a magnitude
* @throws IOException if there is an error reading a file
*/
public static void runLogo (String magnitudeTokens, String simpleTokens) throws IOException
{
BufferedReader f;
String filePath;
String inputBuffer = "";
int commentCounter, errorCounter;
StringTokenizer tokenizer;
//Expandible Arrays
Vector commands = new Vector (1, 1); //For the LogoCmd objects
Vector tokens = new Vector (1, 1); //To gather all the tokens in a line
//Clear the screen
c.clear ();
//Display the title
c.println ("== Preparing to run a .logo file =========================\n");
//Get the filepath of the .logo
while (true)
{
c.print ("Enter the name of your file : ");
try
{
filePath = c.readLine ();
f = new BufferedReader (new FileReader (filePath));
break;
}
catch (IOException e)
{
c.println (" --> Error opening file. Ensure that this file exists.");
}
}
//Count and display the number of lines in this file
c.println ("");
c.println ("This file contains " + countLines (filePath) + " lines.");
//Start adding the commands to the expandable array
c.println ("");
c.println ("J-LOGO is now parsing this file...");
//Read current line and pass all tokens into the 'tokens' arrayList
do
{
//Pull a line from the file
inputBuffer = f.readLine ();
if (inputBuffer == null)
break;
//Resize token array and load tokens for the line
tokenizer = new StringTokenizer (inputBuffer, " ");
tokens.setSize (tokenizer.countTokens ());
for (int tok = 1 ; tok <= tokenizer.countTokens () ; tok++)
{
tokens.add (tok - 1, (String) tokenizer.nextToken ());
}
//Parse commands and load them into the 'commands'
int tokenAt = 1;
while (true)
{
//Break the loop if the token is a comment or if tokenAt exceeds the 'tokens' Array size
if (((String) tokens.elementAt (tokenAt - 1)).indexOf ("!!") > -1 || tokenAt > tokens.size ())
{
break;
}
//Check to see if the command is one that requires a magnitude
if (magnitudeTokens.indexOf ((String) tokens.elementAt (tokenAt - 1)) > -1)
{
//If the next token is a number, make a LogoCmd object with the given magnitude
if (willParseInt (((String) tokens.elementAt (tokenAt))))
{
commands.addElement (new LogoCmd ((String) tokens.elementAt (tokenAt - 1), Integer.parseInt ((String) tokens.elementAt (tokenAt))));
tokenAt += 2;
}
//If the next token is not a number, make a LogoCmd object with magnitude 1
else
{
commands.addElement (new LogoCmd ((String) tokens.elementAt (tokenAt - 1), 1));
tokenAt++;
}
}
//If the command doesn't require a magnitude, create a new no magnitude LogoCmd object
else if (simpleTokens.indexOf ((String) tokens.get (tokenAt - 1)) > -1)
{
commands.addElement (new LogoCmd ((String) tokens.elementAt (tokenAt - 1)));
tokenAt++;
}
}
}
while (inputBuffer != null);
} //runLogo (String, String)
/**
* Returns the number of lines in the text file at the provided
* path.
*
* @param filePath path to the file to be counted
* @return The number of lines counted before 'null' was returned
* @throws IOException If there is an error reading the file
*/
public static int countLines (String filePath) throws IOException
{
BufferedReader f = new BufferedReader (new FileReader (filePath));
int lineCounter = 0;
String inputBuffer = "";
//Count lines and add to counter until 'null' is returned.
while (inputBuffer != null)
{
inputBuffer = f.readLine (); //read a line from file
if (inputBuffer != null) //check if null is ! returned
{
lineCounter++; //add to counter
}
else //null is returned
{
break; //exit the loop immeadiately
}
}
return lineCounter; //return 'lineCounter'
} //countLines (String)
/**
* Reports all the errors in a file in a new console window.
* NOTE : CURRENTLY INCOMPLETE
*
* @param filePath path to the file to be error checked
* @param commands an array of LogoCmd objects with the data to check
*/
public static void errorReport (String filePath, LogoCmd commands[])
{
Console e = new Console (20, 80, "Error Report");
} //errorReport (String, LogoCmd)
public static void main (String[] args) throws IOException
{
c = new Console ();
final String cmdsMagnitude = "fd bk lt rt lw lc";
final String cmdsNoMagnitude = "hm pu pd";
char menuInput;
//Main program loop
while (true)
{
//Clear the screen
c.clear ();
//Display the menu
c.println (" ******************************* ");
c.println (" | J - LOGO | ");
c.println (" *********************************");
c.println (" | 1) Run a .logo |");
c.println (" | 2) Exit Program |");
c.println (" *******************************");
//Prompt user for input
menuInput = c.getChar ();
//Perform the appropriate operation
switch (menuInput)
{
case '1':
runLogo (cmdsMagnitude, cmdsNoMagnitude);
break;
case '2':
System.exit (0);
default:
}
}
//Close the console
//c.close ();
} //main (String [])
} // NewLogo class
|