/** * Declare and define a function or constant. * * @param input * the user's raw input * @return the system message as String * @throws Exception * the exception (invalid declaration/definition) */ public string declare(string input) { if (input.IndexOf("=") == 0) { throw new Exception("empty declaration"); } if (input.IndexOf("=") == input.Count() - 1) { throw new Exception("empty definition"); } string declaration = Regex.Split(input, "=")[0].Trim(); string definition = Regex.Split(input, "=")[1]; if (Regex.IsMatch(declaration, "[a-zA-Z_]+[(][a-zA-Z_]+[)]")) { // it's a function string name = Regex.Split(declaration, "\\(|\\)")[0]; foreach (Function func in functions) { if (func.identifier == name) { throw new Exception("\"" + name + "\" is already declared!"); } } string var = Regex.Split(declaration, "\\(|\\)")[1]; if (String.IsNullOrEmpty(var)) { throw new Exception("\"" + var + "\" is an invalid variable"); } command("var " + var); Token[] deftokens = tokenize(definition); Stack <Token> stack = ArrayUtils.arrayToStack(deftokens); Dictionary <string, Token[]> map = new Dictionary <string, Token[]>(); functions.Remove(getFunction(name)); functions.Add(new Function(name, var, deftokens)); update(); return(name + "(" + var + ")=" + ArrayUtils.stringArray(NotationUtils.postfixToInfix(this, stack))); } else if (Regex.IsMatch(declaration, "[a-zA-Z_]+")) { // it's a constant Token[] deftokens = tokenize(definition); if (hasLockedToken(deftokens)) { throw new Exception("\"" + declaration + "\" contains locked token(s)"); } constant_defs[declaration] = deftokens; update(); return("\"" + declaration + "\" defined as \"" + ArrayUtils.stringArray(ArrayUtils.tokenArrayToStringArray(deftokens)) + "\""); } else { throw new Exception("\"" + declaration + "\" is an invalid declaration"); } }
/** * Calculate raw user's input. * * @param input * the user's input * @return the result as String * @throws Exception * the exception */ public string calculate(string input) { if (String.IsNullOrEmpty(input)) { throw new Exception("empty input"); } Token[] tokens = tokenize(input); ArrayUtils.printArray(ArrayUtils.tokenArrayToStringArray(tokens)); Stack <Token> stack = ArrayUtils.arrayToStack(tokens); Token[] ans = computePostfixStack(stack); return(ArrayUtils.stringArray(NotationUtils.postfixToInfix(this, ArrayUtils.arrayToStack(ans)))); }
/** * Returns an array of type Token from given user's input. The user's input * is split with my old regexes, converted to reversed prefix, and Populated * into a Token array.Exceptions will be caught in subsequent methods for * bad token input * * @param input * the user's raw input * @return the token[] result * @throws Exception * the exception */ public Token[] tokenize(string input) { string[] infix = format(input); Console.WriteLine("infix = "); ArrayUtils.printArray(infix); string[] postfix = NotationUtils.infixToPostfix(this, infix); Console.WriteLine("postfix = "); ArrayUtils.printArray(postfix); Token[] tokens = new Token[postfix.Count()]; for (int i = 0; i < postfix.Count(); i++) { string s = postfix[i]; if (isNumber(s)) { tokens[i] = new Token(TokenType.NUMBER, s, Double.Parse(s)); } else if (isVariable(s)) { tokens[i] = new Token(TokenType.VARIABLE, s); } else if (isConstant(s)) { tokens[i] = new Token(TokenType.CONSTANT, s, constants[s].dval); } else if (isFunction(s)) { tokens[i] = new Token(TokenType.FUNCTION, s); } else if (isOperator(s)) { tokens[i] = new Token(TokenType.OPERATOR, s); } else { throw new Exception(postfix[i] + " is a bad token (tokenizer)"); } } return(tokens); }
/** * Accepts line determined to be in command format. * * @param input * the input * @return the result/report as String * @throws Exception * the exception */ public string command(string input) { string cmd = Regex.Split(input, " ")[0], arg = Regex.Split(input, " ")[1]; switch (cmd) { case "var": variables.Add(arg); if (isConstant(arg)) { constants.Remove(arg); constant_defs.Remove(arg); } update(); return("\"" + arg + "\" declared as a variable"); case "print": if (isFunction(arg)) { Function f = getFunction(arg); return(f.identifier + "(" + f.variable + ") = " + ArrayUtils.stringArray(NotationUtils.postfixToInfix(this, ArrayUtils.arrayToStack(f.definition)))); } else if (isConstant(arg)) { return(arg + " = " + constants[arg]); } throw new Exception(arg + " is not a constant or function"); default: return("invalid command"); } }