package expressionConsole; import java.util.Observable; import parser.RecursiveDescentParser; import parser.Value; import valueTypes.ErrorValue; /** * The model of the expression console in the Model View Controller paradigm. * This model is a singleton class. * * @author Curran Kelleher * */ public class ExpressionConsoleModel extends Observable { /** * The object containing all history information. */ private ExpressionConsoleHistory expressionHistory = new ExpressionConsoleHistory(); /** * The parser we will use to parse the function string. */ private RecursiveDescentParser parser = new RecursiveDescentParser(); /** * The singleton instance of this class */ static ExpressionConsoleModel INSTANCE = null; /** * The constructor is private because the class is a singleton, so can only * be instantiated from within. * */ private ExpressionConsoleModel() { } /** * Returns a reference to the singleton instance of this class. * * @return a reference to the singleton instance of this class. */ public static ExpressionConsoleModel getInstance() { if (INSTANCE == null) INSTANCE = new ExpressionConsoleModel(); return INSTANCE; } /** * Enters the specified expression in the console and evaluates it. * * @param expressionString * the expression String */ public void enterExpression(String expressionString) { // add the input to the history expressionHistory.getExpressionList().add( new ExpressionConsoleHistoryEntry(expressionString, ExpressionConsoleHistoryEntry.INPUT)); // evaluate the expression Value parseResult = parser.parse(expressionString).evaluate(); // add the result to the history expressionHistory .getExpressionList() .add( new ExpressionConsoleHistoryEntry( parseResult.toString(), parseResult instanceof ErrorValue ? ExpressionConsoleHistoryEntry.CONSOLE_RESPONSE_ERROR : ExpressionConsoleHistoryEntry.CONSOLE_RESPONSE_SUCCESS)); // send the notification (presumably the view and controller are // listening) setChanged(); notifyObservers(); } /** * Enters the specified String in the console without evaluating it. It is * displayed in the style of an error. * * @param messageString * the string to display */ public void enterErrorMessage(String messageString) { // add the message to the history expressionHistory.getExpressionList().add( new ExpressionConsoleHistoryEntry(messageString, ExpressionConsoleHistoryEntry.CONSOLE_RESPONSE_ERROR)); // send the notification (presumably the view and controller are // listening) setChanged(); notifyObservers(); } /** * Enters the specified String in the console without evaluating it. * * @param messageString * the string to display */ public void enterMessage(String messageString) { // add the message to the history expressionHistory.getExpressionList().add( new ExpressionConsoleHistoryEntry(messageString, ExpressionConsoleHistoryEntry.MESSAGE)); // send the notification (presumably the view and controller are // listening) setChanged(); notifyObservers(); } /** * The list containing the full history of console entries. * * @return The list containing the full history of console entries. */ public ExpressionConsoleHistory getExpressionHistory() { return expressionHistory; } /** * Gets the parser used by the console. * * @return The parser used by the console. */ public RecursiveDescentParser getParser() { return parser; } /** * Records into the history the current state of the symbol table, which * maps Variable names to Values. This is necessary for the history to * initialize properly when loaded. * */ public void recordInitialVariableValues() { expressionHistory.recordInitialVariableValues(); } /** * Executes (does not display anything) the specified function (It can include many expressions separated by ';' characters). Calling this * is equivalent to calling * <code>ExpressionConsoleModel.getInstance().getParser().parse( "executeFunction({" + function + "})").evaluate();</code> * * @param function the function string to evaluate */ public void executeFunction(String function) { parser.parse("executeFunction({" + function + "})").evaluate(); } }