open Bogue module W = Widget module L = Layout let calculator () = let stack = Stack.create () in Stack.push "0" stack ; let stack_show () = Stack.fold (fun acc number -> number ^ " " ^ acc) "" stack in let display = W.label "" in let update_display () = W.set_text display (stack_show ()) in let digit_pressed digit = match Stack.pop stack with | "0" -> Stack.push digit stack ; | number -> Stack.push (number ^ digit) stack ; update_display () in let push_clicked _ = Stack.push "0" stack ; update_display () in let swap_clicked _ = match Stack.length stack with | n when n >= 2 -> let y = Stack.pop stack in let x = Stack.pop stack in Stack.push y stack ; Stack.push x stack ; update_display () | _ -> () in let pop_clicked _ = match Stack.length stack with | 1 -> Stack.pop stack |> ignore ; Stack.push "0" stack ; update_display () | _ -> Stack.pop stack |> ignore ; update_display () in let digit_clicked digit = fun _ -> digit_pressed digit ; update_display () in let op_clicked op = fun _ -> match Stack.length stack with | n when n >= 2 -> let y = Stack.pop stack |> int_of_string in let x = Stack.pop stack |> int_of_string in Stack.push (op x y |> string_of_int) stack ; update_display () | _ -> () in let op_button name op = let button = W.button name in W.on_click ~click:(op_clicked op) button ; button in let push_button () = let button = W.button "PSH" in W.on_click ~click:push_clicked button ; button in let swap_button () = let button = W.button "SWP" in W.on_click ~click:swap_clicked button ; button in let pop_button () = let button = W.button "POP" in W.on_click ~click:pop_clicked button ; button in let digit_button digit = let button = W.button digit in W.on_click ~click:(digit_clicked digit) button ; button in let layout = L.tower ~align:Draw.Center [ L.resident ~w:400 display ; L.flat_of_w [ digit_button "1" ; digit_button "2" ; digit_button "3" ] ; L.flat_of_w [ digit_button "4" ; digit_button "5" ; digit_button "6" ] ; L.flat_of_w [ digit_button "7" ; digit_button "8" ; digit_button "9" ] ; L.flat_of_w [ digit_button "0" ] ; L.flat_of_w [ push_button () ; swap_button () ; pop_button () ] ; L.flat_of_w [ op_button "ADD" (+) ; op_button "MUL" ( * ) ; op_button "SUB" (-) ; op_button "DIV" (/) ] ; ] in let calculator = Bogue.make [] [layout] in update_display () ; Bogue.run calculator ;; let _ = calculator () ; Draw.quit()