-
Notifications
You must be signed in to change notification settings - Fork 0
/
runner.js
50 lines (40 loc) · 943 Bytes
/
runner.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
const operations = {
'sum': (a, b) => a + b,
'subtract': (a, b) => a - b,
'multiply': (a, b) => a * b,
'divide': (a, b) => a / b,
'pow': (a, b) => a ** b,
'log': console.log,
}
function id(a) {
return a
}
function push(stack, token) {
return [...stack, token]
}
function isNumber(token) {
return !isNaN(Number(token))
}
function throwNoOp(op) {
throw new Error(`unknown operation "${ op }"`)
}
function getOp(operation, operations) {
return operations[operation] || throwNoOp(operation)
}
function performOp(stack, token) {
return getOp(token, operations)(...stack)
}
function step(stack = [], token) {
return isNumber(token)
? push(stack, Number(token))
: push([], performOp(stack, token))
}
function tokenize(str) {
return str.split(/[\n ]+/).filter(id)
}
function interpret(tokens) {
return tokens.reduce(step, [])
}
module.exports = function run(code) {
return interpret(tokenize(code))
}