js-calc/calc.js

138 lines
2.5 KiB
JavaScript

const answer = document.getElementById('answer');
function cls()
{
answer.value = '';
}
function append(c)
{
answer.value += c;
}
function lex()
{
var lexed = [];
var builder = "";
var flush = ()=>{
if(builder.length > 0)
{
lexed.push(builder);
builder = "";
}
}
var val = answer.value;
for(i=0;i<val.length;i++)
{
switch(val.at(i))
{
case '.':
case '(':
case ')':
case '^':
case '-':
case '*':
case '/':
case '+':
{
flush();
lexed.push(val.at(i));
}
break;
default:
builder += val.at(i);
break;
}
}
flush();
return lexed;
}
function parse_value(d)
{
if(d.i < d.lexed.length && d.lexed[d.i] == '(')
{
d.i++;
var v= parse_add(d);
d.i++;
return v;
}
j = parseInt(d.lexed[d.i++]);
if(d.lexed[d.i] == '.')
{
d.i++;
j= parseFloat(`${j}.${d.lexed[d.i++]}`);
}
return j;
}
function parse_pow(d)
{
var r = parse_value(d);
while(d.i<d.lexed.length && d.lexed[d.i] == "^")
{
d.i++;
var l = parse_value(d);
r= Math.pow(r,l);
}
return r;
}
function parse_times(d)
{
var r = parse_pow(d);
while(d.i<d.lexed.length && (d.lexed[d.i] == "*" || d.lexed[d.i] == "/"))
{
if(d.i<d.lexed.length && d.lexed[d.i] == "*")
{
d.i++;
var l = parse_pow(d);
r *= l;
}
if(d.i<d.lexed.length && d.lexed[d.i] == "/")
{
d.i++;
var l = parse_pow(d);
r /= l;
}
}
return r;
}
function parse_add(d)
{
var r = parse_times(d);
while(d.i<d.lexed.length && (d.lexed[d.i] == "+" || d.lexed[d.i] == "-"))
{
if(d.i<d.lexed.length && d.lexed[d.i] == "+")
{
d.i++;
var l = parse_times(d);
r += l;
}
if(d.i<d.lexed.length && d.lexed[d.i] == "-")
{
d.i++;
var k = r;
var l = parse_times(d);
r -= l;
}
}
return r;
}
function calculate()
{
var lexed = lex();
var d = {
i: 0,
lexed: lexed
}
answer.value = parse_add(d).toString();
}