/// <summary> /// Method called to process an expression. /// </summary> /// <param name="tokens"></param> /// <returns></returns> private double processTokens(List <Token> tokens) { this.tokens = tokens; //Analyse the syntax to see if it is valid. SyntaxAnalyser s = new SyntaxAnalyser(tokens); s.checkTokens(); //If it is then do some preprocessing on the input. Preprocessor p = new Preprocessor(tokens); this.tokens = p.processTokens(); getNextToken(); double value = analyseExpressions(double.NaN); if (WRITE_TO_FILE) { VariableFileHandle.saveVariables(variables); } return(value); }
/// <summary> /// Function used to save the variables into an external file. /// </summary> public static void saveVariablesIntoExternalFile() { Hashtable vars = VariableFileHandle.getVariables(); removeIrrelevantVariables(vars); //if the variable table is empty then throw an error. if (vars.Count == 0) { EmptyVarSaveException err = new EmptyVarSaveException("Variables Table is Empty."); ErrorMsg eMsg = new ErrorMsg(err.Message, err.ErrorCode); eMsg.ShowDialog(); return; } //Save the variables SaveFileDialog saveVar = new SaveFileDialog(); saveVar.Filter = "JSON file(*.json)|*.json"; saveVar.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); if (saveVar.ShowDialog() == true) { TextWriter TW = new StreamWriter(saveVar.FileName); int counter = 0; int total = vars.Count; TW.WriteLine("["); foreach (DictionaryEntry pair in vars) { string key = (string)pair.Key; string value = (string)pair.Value; TW.WriteLine("\t{"); TW.WriteLine("\t\t\"name\": " + "\"" + key + "\","); TW.WriteLine("\t\t\"value\": " + "\"" + value + "\""); if (counter == (total - 1)) { TW.WriteLine("\t}"); } else { TW.WriteLine("\t},"); } counter++; } TW.WriteLine("]"); TW.Close(); } }
/// <summary> /// Function to load the JSON file given by the user into the datagrid. /// </summary> /// <param name="w"></param> public static void loadVarFileIntoDataGrid(MainWindow w) { var openfileDialog = new OpenFileDialog { Filter = "JSON File (*.json)|*.json" }; var dialogResult = openfileDialog.ShowDialog(); if (dialogResult == true) { var filename = openfileDialog.FileName; JArray array = null; //Display a warning before proceeding. CustomMsg c = new CustomMsg("Are you sure you want to continue? This will override all variables currently stored in the table.", "Load Variable File"); c.ShowDialog(); bool?res = c.DialogResult; if (!((bool)res)) { return; } try { array = VariableFileHandle.LoadFromExternalFile(filename); Hashtable vars = new Hashtable(); // Put all the variables loaded into a hashtable of the form // key -> Name // value -> Tuple( Value, Type). foreach (JObject variable in array) { string variableName = variable["name"].ToString(); string variableValue = variable["value"].ToString(); vars.Add(variableName, variableValue); } VariableFileHandle.saveVariables(vars); w.loadVarsIntoDataGrid(); } catch (Exception e) { ErrorLoadingVariableFileException e1 = new ErrorLoadingVariableFileException("Error loading variable file."); ErrorMsg err = new ErrorMsg(e1.Message, e1.ErrorCode); err.ShowDialog(); } } }
/// <summary> /// Method to run the interpreter given a certain input. /// </summary> /// <param name="codeToRun"></param> /// <returns></returns> public string RunInterpreter(string codeToRun) { string temp = Regex.Replace(codeToRun, @"\s+", ""); //Check if the user has typed "clear" if (temp.Contains("clear")) { if (temp == "clear") { VariableFileHandle.clearVariables(); return("\tCleared Variables."); } else { throw new ClearCommandException("'clear' can only be used on its own, nothing else can be added."); } } //Use the lexer to tokenise the input List <Token> tokens = lexer.TokeniseInput(codeToRun); //Then put the gathered tokens into the parser. double result = parser.AnalyseTokens(tokens); switch (parser.status) { case Parser.STATUSES.PLOT_FUNCTION_CALLED: return("\tRefer to figure."); case Parser.STATUSES.UNASSIGNED_RESULT: string res = Convert.ToString(result); //assign it to Ans as that is the default variable name. vars["Ans"] = res; VariableFileHandle.saveVariables(vars); return("\tvar Ans = \n\t\t" + Convert.ToString(result)); case Parser.STATUSES.VARIABLE_ASSIGNED: return("\tvar " + parser.varName + " = \n\t\t" + vars[parser.varName]); default: return(""); } }
/// <summary> /// Function used by the saveAll function. /// </summary> /// <param name="location"></param> public static void saveVariablesIntoExternalFile(string location) { Console.WriteLine(location); Hashtable vars = VariableFileHandle.getVariables(); removeIrrelevantVariables(vars); //if the variable table is empty then throw an error. if (vars.Count == 0) { EmptyVarSaveException err = new EmptyVarSaveException("Variables Table is Empty."); ErrorMsg eMsg = new ErrorMsg(err.Message, err.ErrorCode); eMsg.ShowDialog(); return; } //Save the variables TextWriter TW = new StreamWriter(Path.Combine(location)); int counter = 0; int total = vars.Count; TW.WriteLine("["); foreach (DictionaryEntry pair in vars) { string key = (string)pair.Key; string value = (string)pair.Value; TW.WriteLine("\t{"); TW.WriteLine("\t\t\"name\": " + "\"" + key + "\","); TW.WriteLine("\t\t\"value\": " + "\"" + value + "\""); if (counter == (total - 1)) { TW.WriteLine("\t}"); } else { TW.WriteLine("\t},"); } counter++; } TW.WriteLine("]"); TW.Close(); }
/// <summary> /// Private method to get the enclosing expression. /// </summary> /// <param name="equation"></param> /// <param name="index"></param> private double getEnclosingExpression(List <Token> equation, ref int index, bool isFirstRun) { int bracketLevel = 0; List <Token> enclosingFunction = new List <Token>(); if (!isFirstRun) { bracketLevel = 1; enclosingFunction.Add(new Token(Globals.SUPPORTED_TOKENS.OPEN_BRACKET, "(")); } bool commaFound = false; if (isFirstRun) { beginIndex = index - 1; } //Get the equation enclosed in the brackets. while (true) { if (equation[index].GetType() == Globals.SUPPORTED_TOKENS.OPEN_BRACKET) { bracketLevel++; } else if (equation[index].GetType() == Globals.SUPPORTED_TOKENS.CLOSE_BRACKET) { bracketLevel--; } else if (equation[index].GetType() == Globals.SUPPORTED_TOKENS.COMMA) { bracketLevel--; commaFound = true; if (!hasSecondParameter) { //For functions that only have one parameter. throw new TooManyArgumentsException("This function only has one argument."); } else if (!(isFirstRun)) { //For functions that have two parameter. throw new TooManyArgumentsException("This function only has two arguments."); } else { enclosingFunction.Add(new Token(Globals.SUPPORTED_TOKENS.CLOSE_BRACKET, ")")); index++; break; } } enclosingFunction.Add(equation[index]); if (bracketLevel == 0) { break; } if (index == equation.Count - 1) { break; } index++; } if (bracketLevel != 0) { throw new MissingCloseBracketExceptionForFunction("No closing bracket found for corresponding open bracket."); } //Only occurs if a function that has two arguments only has one present. if (!(commaFound) && isFirstRun && hasSecondParameter) { throw new TooLittleArgumentsException("Second argument missing."); } //Read in the variables Hashtable vars = VariableFileHandle.getVariables(); //create a parser object Parser p = new Parser(vars); //Analyse the syntax of the enclosing function using the parser object. double result = p.AnalyseTokens(enclosingFunction); return(result); }
public Interpreter(ref LiveChartsDrawer l) { lexer = new Lexer(); vars = VariableFileHandle.getVariables(); parser = new Parser(vars, ref l); }
/// <summary> /// Method for getting the list of data points from the expression so they can be drawn by the graph drawer. /// Result stored in Plot Function object under data points. /// </summary> /// <returns></returns> public void getValues() { //Say if your expression is Y=X+2 //First step is to remove the Y= part and then evaulate the X+2 part by parsing it through the parser. removeFirst2Tokens(); //Next step is to get the variable name in the equation. string varName = getVariableName(); Hashtable vars = VariableFileHandle.getVariables(); //get the number of data values to plot. int numIncrements = Convert.ToInt32(Math.Floor((Xmax - Xmin) / inc) + 1); Parser p; bool flag = false; //Save the original equation. List <Token> eqnCopy = new List <Token>(Equation); //Iterate through every value of X and get a Y value. for (int i = 0; i < numIncrements; i++) { double Xvalue = Xmin + i * inc; if (varName != null) { //Update the value of the variable so that it can be used in the expression. vars[varName] = Convert.ToString(Xvalue); //Save the change VariableFileHandle.saveVariables(vars); p = new Parser(vars); double Yvalue = p.AnalyseTokens(Equation); //Copy the Equation over incase it has been modified. Equation = new List <Token>(eqnCopy); dataPoints.Add(new DataPoint(Xvalue, Yvalue)); } else { //This only occurs if only 1 variable has been specified. p = new Parser(vars); double Yvalue = p.AnalyseTokens(Equation); //If the equation specified is 'X=3' or 'x=3' then you want a vertical line. if (Y.ToLower() == "x") { flag = true; dataPoints.Add(new DataPoint(Yvalue, Xvalue)); } else { //otherwise draw a horizontal line. X = "x"; dataPoints.Add(new DataPoint(Xvalue, Yvalue)); } } } //Check if the dependent variable name in the equation matches the one given in the range. if (!(X is null)) { if (allTokens[varNameIndex].GetValue() != X) { throw new InvalidVariableNameInRangeException("Dependent variable " + X + " expected. " + allTokens[varNameIndex].GetValue() + " found instead."); } } if (flag) { X = Y; Y = "y"; } setMinAndMaxXandYValues(); printDataPoints(); }