Stack program execution
Your task
A cutting table's controller works out how much material to feed by running a tiny stack program. tokens holds that program, one instruction per entry, and the stack starts empty. A token made only of digits is a value and is pushed. add pops two values and pushes their sum, mul pops two and pushes their product, dup pushes a copy of the top value, drop discards the top value, and swap exchanges the top two. Return the single value left on the stack once the whole program has run. Return -1 for a faulty program: an instruction finding fewer values than it needs, a token that is neither digits nor one of those five words, or a stack holding anything other than exactly one value at the end, which includes an empty program. Values are never negative and stay inside a 32 bit signed integer, so -1 is never a real result.
Examples
run_cutter_program(tokens: list[str]) -> intrun_cutter_program(["3", "4", "add"])7run_cutter_program(["5", "dup", "mul"])25run_cutter_program(["2", "3", "swap", "drop"])3