There are quite a few accumulator-based programming languages featured in challenges across the site, but it's a little tiring to have to write almost identical code for each one. So in this challenge you will write a program which can generate interpreters from an input.
How does this work? Let us take this example:
[a ** 3, b * 2, c + 15, d = 0, e / 8]
This is not the only input format allowed. You are allowed to take input as an array of directives, an array of strings or even an entire string composed of these directives. Each directive looks similar to this:
[a, *, 3]
In this case, the a
command multiplies (+
means add, -
means subtract, *
means multiply, /
means divide, **
means exponentiate and =
means assignment) the accumulator by 3
(the third element). So with the aforementioned input, we end up with this schema:
the command `a` cubes the accumulator
the command `b` doubles the accumulator
the command `c` adds 15 to the accumulator
the command `d` assigns the accumulator to 0
the command `e` divides the accumulator by 8
This means that typing the command cabdcbbe
will output 7.5, because: (these rules apply to all generated "languages")
- the accumulator is automatically initialized to 0 at the beginning of a program
- the accumulator is implicitly outputted at the end of a command
(0 + 15)**3*2
is disregarded because d reassigns the accumulator to zero(0 + 15)*2*2/8 = 7.5
When given an array of directives, your program should output a complete program in your favorite language (might be the one you write your answer in, but not necessarily) which takes a valid program in the newly generated language and outputs the accumulator at the end of it. If I were using JavaScript and were passed the array we discussed, my program might output
const program = prompt();
let acc = 0;
for (const command of program) {
if (command === 'a') {
acc = acc ** 3;
} else if (command === 'b') {
acc = acc * 2;
} else if (command === 'c') {
acc = acc + 15;
} else if (command === 'd') {
acc = 0;
} else if (command === 'e') {
acc = acc / 8;
}
}
alert(acc);
now, for some more rules:
- the input will always be valid. No destructive operators will be entered (such as a / 0 which divides the accumulator by zero.
- each command will perform only one operation on the accumulator, so there will be no command which multiplies the accumulator by 3, squares it and adds 5 to it all in one go.
- each command is one letter long.
- the shortest answer in bytes wins. [code-golf rules]
- the interpreter should read the program from STDIN or from a file.
- on TIO, you may pre-define the input array in the header section, but your program should obviously be able to handle any valid input.
- you only need to support the six operators mentioned previously.
- commands can involve floating point numbers and not only integers
- you may replace the operators but you must then state which ones you changed
- you may output a float even if all operators yield integers. You may not truncate outputs however
+
,-
,*
,/
,**
and=
the only operators we have to support? \$\endgroup\$^
rather than**
? \$\endgroup\$