The compiler emits the right WAT op-name based on the operator.
In the compiler's chain loop, after emitting the next const, dispatch on op.
while (input_pos < input.len) {
const op: u8 = input[input_pos];
input_pos += 1;
appendStringLiteral(&wat_buffer, &wat_length, "i64.const ");
appendChar(&wat_buffer, &wat_length, input[input_pos]);
appendChar(&wat_buffer, &wat_length, '\n');
// YOU: emit "i64.add\n", "i64.sub\n", "i64.mul\n", or "i64.div_s\n".
// for anything else, printString("error").
input_pos += 1;
}
if (op == '+') {
appendStringLiteral(&wat_buffer, &wat_length, "i64.add\n");
} else if (op == '-') {
appendStringLiteral(&wat_buffer, &wat_length, "i64.sub\n");
} else if (op == '*') {
appendStringLiteral(&wat_buffer, &wat_length, "i64.mul\n");
} else if (op == '/') {
appendStringLiteral(&wat_buffer, &wat_length, "i64.div_s\n");
} else {
printString("error: unknown operator\n");
return;
}
Try "3+4*5" -> compiles to const 3, const 4, add, const 5, mul. VM runs it: 35. Same as the interpreter. Try "9-3-1", "8/2", your own.
We can only really test single-digit chains: the digit-extraction logic in the interpreter, the compiler's appendChar(input[input_pos]), and the VM's wat_buffer[wat_line_end - 1] all assume one-byte numbers. Multi-digit numbers come next.