Давайте сделаем это максимально простым.eval
принимает выражение e
-
const eval = e =>
// if the expression is an object ...
Object (e) === e
// apply the operator to the evaluated operands ...
? apply (e.op, eval (e.left), eval (e.right))
// otherwise the expression is already a primitive
: e
apply
тоже просто -
const env =
{ '+': (a, b) => a + b
, '-': (a, b) => a - b
, '*': (a, b) => a * b
, '/': (a, b) => a / b
}
const apply = (f, ...args) =>
{ if (env[f] === undefined)
throw Error (`unknown operator: ${f}`)
else
return env[f] (...args)
}
Попробуйте и посмотрите -
eval (op1)
// 101
eval (op2)
// 20
eval ({ left: 10, op: '^', right: 2 })
// unknown operator: ^
Развернитефрагмент ниже для проверки результатов в вашем собственном браузере -
const env =
{ '+': (a, b) => a + b
, '-': (a, b) => a - b
, '*': (a, b) => a * b
, '/': (a, b) => a / b
}
const eval = e =>
Object (e) === e
? apply (e.op, eval (e.left), eval (e.right))
: e
const apply = (f, ...args) =>
{ if (env[f] === undefined)
throw Error (`unknown operator: ${f}`)
else
return env[f] (...args)
}
const op1 =
{ left: 5, op: '-', right: { left: 3, op: '*', right: { left: 8, op: '-', right: { left: 200, op: '/', right: 5 } } } }
const op2 =
{ left: { left: 10, op: '*', right: { left: 2, op: '+', right: 1, }, }, op: '+', right: { left: 5, op: '*', right: { left: 1, op: '-', right: { left: 1, op: '+', right: 2 } } } }
console .log
( eval (op1) // 101
, eval (op2) // 20
)