Skip to content

Instantly share code, notes, and snippets.

@huozhi
Created February 25, 2017 04:44
Show Gist options
  • Save huozhi/cdc42a4d7e81e8986d7358716e45c545 to your computer and use it in GitHub Desktop.
Save huozhi/cdc42a4d7e81e8986d7358716e45c545 to your computer and use it in GitHub Desktop.
calculate expression
var isNumber = (val) => /[0-9]/.test(val)
var isAlpha = (val) => /[a-z]/.test(val)
var isEmpty = (arr) => arr.length === 0
var top = (stack) => stack[stack.length - 1]
var calculate = function(str) {
var i = 0
var snum = []
var sop = []
var prior = (val) => {
if (isNumber(val)) {
return 0
} else if (isAlpha(val)) {
return 1
} else if (/\+|-/.test(val)) {
return 2
} else if (/\*|\//.test(val)) {
return 3
}
return -1
}
var evaluate = (a, b, op) => {
switch (op) {
case '+': return parseInt(a + b, 10)
case '-': return parseInt(a - b, 10)
case '*': return parseInt(a * b, 10)
case '/': return parseInt(a / b, 10)
}
}
var evaluateNext = () => {
let op = sop.pop()
let b = snum.pop()
let a = snum.pop()
snum.push(evaluate(a, b, op))
}
while (i < str.length) {
let ch = str[i]
if (/\s/.test(ch)) {
i++
continue
}
if (isNumber(ch)) {
let num = ''
while (isNumber(str[i])) {
num += str[i]
i++
}
snum.push(parseInt(num, 10))
} else if (ch === '(') {
sop.push('(')
i++
} else if (ch === ')') {
while (top(sop) !== '(') {
evaluateNext()
}
sop.pop()
i++
} else {
if (isEmpty(sop) || prior(top(sop)) < prior(ch)) {
sop.push(ch)
} else {
while (!isEmpty(sop) && prior(top(sop)) >= prior(ch)) {
evaluateNext()
}
sop.push(ch)
}
i++
}
}
while (!isEmpty(sop)) {
evaluateNext()
}
return top(snum)
}
var test = (str) => {
console.log(calculate(str), parseInt(eval(str), 10))
}
test('1 + 2 * 3')
test('1 + 2 + 3')
test('(1 + 2 * 6) * 3 / 7 - 4')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment