Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- function importPackage(pack) {
- for (var x in pack) {
- global[x] = pack[x];
- }
- }
- var exceptions = (function () {
- function MyException(message) { this.message = message }
- MyException.prototype = Error.prototype;
- MyException.prototype.name = "MyException";
- function MakeException(name) { this.name = name }
- MakeException.prototype = MyException.prototype;
- function exceptionFactory(name, newMess) {
- var result = function () {
- MyException.call(this, newMess.apply(null, arguments));
- }
- result.prototype = new MakeException(name);
- return result;
- }
- var OddClosingParenthesisException = exceptionFactory(
- "OddClosingParenthesisException",
- function (expr, ind) {
- return ("Odd closing bracket at position: " + ind + "\n" + expr);
- }
- );
- var MissingClosingParenthesisException = exceptionFactory(
- "MissingClosingParenthesisException",
- function (expr, ind) {
- return ("Expected closing bracket before position: " + ind + "\n" + expr);
- }
- );
- var MissingOpeationParenthesisException = exceptionFactory(
- "MissingOpeationParenthesisException",
- function (expr, op, ind, mode) {
- var ending = op + "' at position: " + ind + "\n" + expr;
- if (!mode) {
- return ("Opening bracket expected before operation '" + ending);
- } else {
- return ("Closing bracket expected after operation '" + ending);
- }
- }
- );
- var MissingOperandException = exceptionFactory(
- "MissingOperandException",
- function (expr, op, ind) {
- return ("Overflow operands for operation '" + op + "' at position: " + ind + "\n" + expr );
- }
- );
- var OddOperandException = exceptionFactory(
- "OddOperandException",
- function (expr, op, ind) {
- return ("Too many operands for operation '" + op + "' at position: " + ind + "\n" + expr);
- }
- );
- var UnknownIdentifierException = exceptionFactory(
- "UnknownIdentifierException",
- function (expr, id, ind) {
- return ("Unknown identifier '" + id + "' at position: " + ind + "\n" + expr);
- }
- );
- var UnknownSymbolException = exceptionFactory(
- "UnknownSymbolException",
- function (expr, ind) {
- return ("Unknown symbol '" + expr.charAt(ind) + "' at position: " + ind + "\n" + expr);
- }
- );
- var MissingOperationException = exceptionFactory(
- "MissingOperationException",
- function (expr, ind, where) {
- var reason = "";
- if (!where) {
- reason = "Expected operation after opening bracket at position ";
- } else {
- reason = "Expected operation before closing bracket at position ";
- }
- return (reason + ind + "\n" + expr);
- }
- );
- var OddSuffixException = exceptionFactory(
- "OddSuffixException",
- function (expr, ind) {
- return ("Unexpected suffix after correct expression at position: " + ind + "\n" + expr);
- }
- );
- return {
- "MyException": MyException,
- "OddClosingParenthesisException": OddClosingParenthesisException,
- "MissingClosingParenthesisException": MissingClosingParenthesisException,
- "MissingOperandException": MissingOperandException,
- "UnknownIdentifierException": UnknownIdentifierException,
- "UnknownSymbolException": UnknownSymbolException,
- "MissingOperationException": MissingOperationException,
- "OddSuffixException": OddSuffixException,
- "OddOperandException": OddOperandException,
- "MissingOpeationParenthesisException": MissingOpeationParenthesisException
- }
- })();
- var expression = (function () {
- importPackage(exceptions);
- function myNew(constructor, args) {
- var tmp = Object.create(constructor.prototype);
- constructor.apply(tmp, args);
- return tmp;
- }
- var VARIABLES = {"x": 0, "y": 1, "z": 2};
- function Const(x) {
- this.getValue = function () { return x }
- }
- Const.prototype.toString = function () { return this.getValue().toString() }
- Const.prototype.prefix = Const.prototype.toString;
- Const.prototype.evaluate = function () { return this.getValue() }
- function Variable(s) {
- var ind = VARIABLES[s];
- this.getName = function () { return s }
- this.getInd = function () { return ind }
- }
- Variable.prototype.toString = function () { return this.getName() }
- Variable.prototype.prefix = Variable.prototype.toString;
- Variable.prototype.evaluate = function () { return arguments[this.getInd()] }
- function Operation() {
- var operands = [].slice.call(arguments);
- this.getOperands = function () { return operands }
- }
- Operation.prototype.toString = function () {
- return this.getOperands().join(" ") + " " + this.getSymbol();
- }
- Operation.prototype.prefix = function () {
- return "(" + this.getSymbol() + " " + this.getOperands().map(function (value) { return value.prefix() }).join(" ") + ")";
- }
- Operation.prototype.evaluate = function () {
- var args = arguments;
- var res = this.getOperands().map(function(value) { return value.evaluate.apply(value, args) });
- return this._action.apply(null, res);
- }
- function flag(a) {
- return (a instanceof Const || a instanceof Variable || a instanceof Operation);
- }
- function DefineOperation(action, symbol) {
- this._action = action;
- this.getSymbol = function () {
- return symbol;
- }
- }
- DefineOperation.prototype = Operation.prototype;
- function operationFactory(action, symbol) {
- var result = function () {
- var args = arguments;
- Operation.apply(this, args);
- }
- result.prototype = new DefineOperation(action, symbol);
- return result;
- }
- var Add = operationFactory(
- function (a, b) { return a + b },
- "+"
- );
- var Subtract = operationFactory(
- function (a, b) { return a - b },
- "-"
- );
- var Multiply = operationFactory(
- function (a, b) { return a * b },
- "*"
- );
- var Divide = operationFactory(
- function (a, b) { return a / b },
- "/"
- );
- var Negate = operationFactory(
- function (a) { return -a },
- "negate"
- );
- var ArcTan = operationFactory(
- function (a) { return Math.atan(a) },
- "atan"
- );
- var Exp = operationFactory(
- function (a) {return Math.exp(a) },
- "exp"
- );
- var OP = {
- "+": Add,
- "-": Subtract,
- "*": Multiply,
- "/": Divide,
- "negate": Negate,
- "atan": ArcTan,
- "exp": Exp
- };
- var ARGS_COUNT = {
- "+": 2,
- "-": 2,
- "*": 2,
- "/": 2,
- "negate": 1,
- "atan": 1,
- "exp": 1
- };
- var expr = "";
- var ind = 0;
- var stack = [];
- var index = [];
- function skipWhiteSpace() {
- while (ind < expr.length && /\s/.test(expr.charAt(ind))) {
- ind++;
- }
- }
- function parsePrefix(s) {
- var balance = 0;
- ind = 0;
- expr = s;
- stack = [];
- skipWhiteSpace();
- if (ind === expr.length) {
- throw new MyException("Empty input");
- }
- var mode = 0;
- while (true) {
- skipWhiteSpace();
- if (ind >= expr.length) {
- break;
- }
- if (expr.charAt(ind) === ")") {
- balance--;
- if (balance < 0) {
- throw new OddClosingParenthesisException(expr, ind);
- }
- var tempInd = undefined;
- var curOperation = undefined;
- var operands = [];
- while ((stack[stack.length - 1] !== "(") && !(stack[stack.length - 1] in OP)) {
- operands.push(stack.pop());
- index.pop();
- }
- if (stack[stack.length - 1] === "(") {
- throw new MissingOperationException(expr, index.pop(), mode);
- }
- curOperation = stack.pop();
- tempInd = index.pop();
- if (stack.pop() !== "(") {
- throw new MissingOpeationParenthesisException(expr, curOperation, index.pop(), mode);
- }
- index.pop()
- if (operands.length > ARGS_COUNT[curOperation]) {
- throw new OddOperandException(expr, curOperation, tempInd);
- } else if (operands.length < ARGS_COUNT[curOperation]) {
- throw new MissingOperandException(expr, curOperation, tempInd);
- } else {
- stack.push(myNew(OP[curOperation], operands.reverse()));
- }
- ind++;
- if (balance === 0) {
- break;
- }
- continue;
- }
- index.push(ind);
- if (expr.charAt(ind) === "(") {
- stack.push("(");
- ind++;
- balance++;
- continue;
- }
- var curNumber = "";
- if (expr.charAt(ind) === "-") {
- curNumber += "-";
- ind++;
- }
- while (ind < expr.length && /\d/.test(expr.charAt(ind))) {
- curNumber += expr.charAt(ind++);
- }
- if (curNumber !== "" && curNumber !== "-") {
- stack.push(new Const(parseInt(curNumber)));
- continue;
- } else {
- if (curNumber === "-") {
- ind--;
- }
- }
- var curOp = undefined;
- var curId;
- if (expr.charAt(ind) in OP) {
- curOp = expr.charAt(ind);
- ind++;
- } else {
- curId = "";
- if (!(/[A-Za-z]/.test(expr.charAt(ind)))) {
- throw new UnknownSymbolException(expr, ind);
- }
- while (ind < expr.length && /\w/.test(expr.charAt(ind))) {
- curId += expr.charAt(ind++);
- }
- if (curId in OP) {
- curOp = curId;
- }
- }
- if (curOp !== undefined) {
- stack.push(curOp);
- } else if (curId in VARIABLES) {
- stack.push(new Variable(curId));
- if (balance === 0) {
- break;
- }
- } else {
- throw new UnknownIdentifierException(expr, curId, index.pop());
- }
- }
- skipWhiteSpace();
- if (ind !== expr.length) {
- throw new OddSuffixException(expr, ind);
- } else if (balance > 0) {
- throw new MissingClosingParenthesisException(expr, ind);
- } else if (stack.length > 1) {
- throw new MissingOpeationParenthesisException(expr, stack[0], index[0], mode);
- }
- var res = stack.pop();
- if (!flag(res)) {
- throw new MissingOpeationParenthesisException(expr, res, index.pop(), mode);
- }
- return res;
- }
- return {
- "Const": Const,
- "Variable": Variable,
- "Add": Add,
- "Subtract": Subtract,
- "Multiply": Multiply,
- "Divide": Divide,
- "Negate": Negate,
- "parsePrefix": parsePrefix,
- "ArcTan": ArcTan,
- "Exp": Exp
- }
- })();
- importPackage(expression);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement