Last active
February 7, 2022 14:41
-
-
Save ikasoba/7aee6109f37482d1bd91820a237dedfb to your computer and use it in GitHub Desktop.
順序なし、整数のみの計算式の文字列を実行します(evalの計算だけ版のようなもの)。実数はフリーズします
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const calc=((raw)=>{ | |
let s=[] | |
const sw = (addIndex,v,f)=>new class { | |
cases=new Map(); | |
def=null; | |
c(v,f){ | |
this.cases.set(v,f) | |
return this | |
} | |
d(f){ | |
this.def=f | |
return this | |
} | |
eval(_f=()=>{}){ | |
_f(this,v) | |
for (const [k,f] of this.cases.entries()){ | |
let r; | |
if ((typeof k == "string" && v.startsWith(k)) || (k instanceof RegExp && (r=v.match(k)))){ | |
addIndex(k.length!=null ? k.length : r[0]?.length) | |
return f(r) | |
} | |
} | |
if (this.def)return this.def() | |
} | |
}().eval(f); | |
for (let i=0;i<raw.length;){ | |
const t=sw((v)=>i+=v,raw.slice(i),(s)=> | |
s.c(/^[0-9]+/,(v)=>parseInt(v[0])).c(/^[+\-*/]/,(v)=>v[0]) | |
) | |
if (t)s.push(t) | |
} | |
let stack=[] | |
for (let i=0;i<s.length;i++){ | |
if (typeof s[i] == "number")stack.push(s[i]); | |
if (s[i]=="*")stack.push(stack.pop()*s[i+=1]); | |
else if (s[i]=="/")stack.push(stack.pop()/s[i+=1]); | |
else if (s[i]=="+")stack.push(stack.pop()+s[i+=1]); | |
else if (s[i]=="-")stack.push(stack.pop()-s[i+=1]); | |
} | |
return stack.pop() | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment