PLACE
spec
solutions
TXL

RPN Calculator in TXL

...

tokens  number "[+-]?.\d+" | "[+-]?\d+(.\d*)?"  end tokens

define program  [empty]  end define

define input  [input_content] [newline]  end define

define input_content
  [blank] | [expr] | [error]
end define

define expr
  [blank] [number] [blank]
| [expr] [space] [expr] [space] [op] [blank]
end define

define op  '+ | '- | '* | '/  end define

define blank  [opt space]  end define

define error  [repeat token+]  end define

rule main
  replace [program]  e [empty]
  construct maybe_input [opt input]  _ [get]
  deconstruct not maybe_input
  deconstruct maybe_input  content [input_content] _ [newline]
  construct _ [input_content]  content [doblank] [doexpr] [doerror]
  by e
end rule

function doblank
  match [input_content]  e [blank]
end function

function doexpr
  replace [input_content]  e [expr]
  construct r [expr]  e [evalrpn]
  deconstruct r  _ [blank] n [number] _ [blank]
  by  n [+ 0] [put]
end function

rule evalrpn
  replace [expr]  e [expr]
  construct r [expr]  e [add] [subtract] [multiply] [divide]
  where not r [= e]
  by r
end rule

rule add
  replace [expr]
  _ [blank] x [number] _ [space] y [number] _ [space] + _ [blank]
  by x [+ y]
end rule

rule subtract
  replace [expr]
  _ [blank] x [number] _ [space] y [number] _ [space] - _ [blank]
  by x [- y]
end rule

rule multiply
  replace [expr]
  _ [blank] x [number] _ [space] y [number] _ [space] * _ [blank]
  by x [* y]
end rule

rule divide
  replace [expr]
  _ [blank] x [number] _ [space] y [number] _ [space] / _ [blank]
  by x [/ y]
end rule

function doerror
  construct s [input_content] 'error
  replace [input_content]  e [error]  by s [put]
end function

boykobbatgmaildotcom