特に理由はありませんが、無性にJavaScriptで計算式を扱いたくなったので作ってみました。
整数と四則演算のみですが、とりあえず精神的に満たされたのでこれで終了です。
下のテキストボックスに適当に計算式を入れると計算します。ただそれだけ。
正しいのに計算してくれない場合があります。仕様ということで。
折角なので、コードも公開します。やっつけ感溢れる雑なコードです。使いたい人はご自由にどうぞ。動作の保証はしませんが。
function _g(id) {
return document.getElementById(id);
}
function Stack()
{
this.buff = [];
}
Stack.prototype.push = function(value) {
this.buff.push(value);
}
Stack.prototype.pop = function() {
if (this.buff.length == 0) {
return null;
}
n = this.buff.length - 1;
result = this.buff[n];
this.buff.splice(n, 1);
return result;
}
Stack.prototype.peek = function() {
if (this.buff.length == 0) return null;
return this.buff[this.buff.length - 1];
}
function calc(f) {
err="この式はだめだ(′Д`;)";
f = f.replace(/ | /g, "");
if (f.length == 0) {
return "";
}
token = [];
v = "";
s = false;
for (i = 0; i < f.length; i++) {
c = f[i];
if (c.match(/[0-9]/)) {
v = v + c;
s = false;
} else if ((c == "+" || c == "-") && s == true) {
v = (c == "-") ? "-" : v;
s = false;
} else {
switch(c) {
case "(":
case "+":
case "-":
case "*":
case "/":
s = true;
case ")":
if (v.length > 0) {
token.push(v);
v = "";
}
token.push(c);
break;
default:
return err;
}
}
}
if (v.length > 0) {
token.push(v);
}
rf = [];
st = new Stack();
for (i = 0; i < token.length; i++) {
t = token[i];
if (t.match(/[0-9]/)) {
rf.push(t);
} else if (t == ")") {
while(true) {
v = st.pop();
if (v == "(" || v == null) break;
rf.push(v);
}
} else if (t == "(") {
st.push(t);
} else {
while(true) {
v = st.peek();
if (v == null) {
st.push(t);
break;
}
if ((t == "+" || t == "-") && (v != "(" || v == ")")) rf.push(st.pop());
else if ((t == "*" || t == "/") && (v == "*" || v == "/")) rf.push(st.pop());
else {
st.push(t);
break;
}
}
}
}
while((t = st.pop()) != null) rf.push(t);
st = new Stack();
for (i = 0; i < rf.length; i++) {
t = rf[i];
if (isNaN((n = parseInt(t, 10)))) {
o2 = st.pop();
o1 = st.pop();
if (o1 == null || o2 == null) return err;
switch(t) {
case "+":
st.push(o1 + o2);
break;
case "-":
st.push(o1 - o2);
break;
case "*":
st.push(o1 * o2);
break;
case "/":
st.push(o1 / o2);
break;
}
} else {
st.push(n);
}
}
return st.pop();
}
