include "ombcd.xin" declare #main-input has unbuffered declare #main-output has unbuffered macro int is (digit+) macro-end macro num is (["+-"]? ((int ("." int?)?) | ("." int))) macro-end global bcd nums variable initial-size 0 declare catch syntax-wrong define function push(value bcd x) as set new nums to x define bcd function pop() as local bcd x throw syntax-wrong when number of nums = 0 set x to nums remove nums return x define switch function rpn as local stream x repeat scan #current-input match blank* num => x push(bcd(x)) match blank* "+" push(pop()+pop()) match blank* "-" push(0-pop()+pop()) match blank* "*" push(pop()*pop()) match blank* "/" push(1/pop()*pop()) match blank* "%n" return true match any-text throw syntax-wrong again halt catch syntax-wrong do scan #current-input match any-text* "%n" done return false process repeat repeat scan #main-input match rpn local integer n set n to number of nums do when n = 1 output "d" % pop() || "%n" else when n > 1 throw syntax-wrong done match any-text* throw syntax-wrong again catch syntax-wrong output "error%n" clear nums again