module Calculator where calculator env = template num := [] haveDot := False stack := [] in let digit n = do num := n:num dot = do num := '.' : num haveDot := True enter = do if num /= [] then if not haveDot then dot digit '0' stack := read (reverse num) : stack num := [] haveDot := False op f = do enter case stack of a:b:rest -> stack := f b a : rest redraw _ -> err clear = do num := [] haveDot := False stack := [] redraw redraw = do env.putStr "\n# " forall n <- reverse stack do env.putStr (show n ++ " ") env.putStr (reverse num) err = do env.putChar '\BEL' redraw input c = action env.putChar c case c of ' ' -> enter 'c' -> clear '+' -> op (+) '-' -> op (-) '*' -> op (*) '/' -> op (/) '\n' -> redraw 'q' -> env.quit '.' -> dot c | isDigit c -> digit c _ -> err init = action env.putStr "\nWelcome to O'Calc v0.00001\n" redraw in struct ..Prog struct Prog = init :: Action input :: Char -> Action run prog env = do p <- prog env p.init env.setReader p.input main = run calculator