main.ml
· 2.9 KiB · OCaml
Raw
Playground
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 make_button name action =
let button = W.button name in
W.on_click ~click:action button ;
button in
let op_button name op = make_button name @@ op_clicked op in
let push_button = make_button "PSH" push_clicked in
let swap_button = make_button "SWP" swap_clicked in
let pop_button = make_button "POP" pop_clicked in
let digit_button digit = make_button digit @@ digit_clicked digit in
let (//) x y =
match x, y with
| (_, 0) -> 0
| (x, y) -> x / y 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()
| 1 | open Bogue |
| 2 | |
| 3 | module W = Widget |
| 4 | module L = Layout |
| 5 | |
| 6 | |
| 7 | let calculator () = |
| 8 | let stack = Stack.create () in |
| 9 | Stack.push "0" stack ; |
| 10 | |
| 11 | let stack_show () = |
| 12 | Stack.fold (fun acc number -> number ^ " " ^ acc) "" stack in |
| 13 | |
| 14 | let display = W.label "" in |
| 15 | let update_display () = |
| 16 | W.set_text display (stack_show ()) in |
| 17 | |
| 18 | let digit_pressed digit = |
| 19 | match Stack.pop stack with |
| 20 | | "0" -> Stack.push digit stack ; |
| 21 | | number -> Stack.push (number ^ digit) stack ; |
| 22 | update_display () in |
| 23 | |
| 24 | let push_clicked _ = |
| 25 | Stack.push "0" stack ; |
| 26 | update_display () in |
| 27 | |
| 28 | let swap_clicked _ = |
| 29 | match Stack.length stack with |
| 30 | | n when n >= 2 -> |
| 31 | let y = Stack.pop stack in |
| 32 | let x = Stack.pop stack in |
| 33 | Stack.push y stack ; |
| 34 | Stack.push x stack ; |
| 35 | update_display () |
| 36 | | _ -> () in |
| 37 | |
| 38 | let pop_clicked _ = |
| 39 | match Stack.length stack with |
| 40 | | 1 -> |
| 41 | Stack.pop stack |> ignore ; |
| 42 | Stack.push "0" stack ; |
| 43 | update_display () |
| 44 | | _ -> |
| 45 | Stack.pop stack |> ignore ; |
| 46 | update_display () in |
| 47 | |
| 48 | let digit_clicked digit = fun _ -> |
| 49 | digit_pressed digit ; |
| 50 | update_display () in |
| 51 | |
| 52 | let op_clicked op = fun _ -> |
| 53 | match Stack.length stack with |
| 54 | | n when n >= 2 -> |
| 55 | let y = Stack.pop stack |> int_of_string in |
| 56 | let x = Stack.pop stack |> int_of_string in |
| 57 | Stack.push (op x y |> string_of_int) stack ; |
| 58 | update_display () |
| 59 | | _ -> () in |
| 60 | |
| 61 | let make_button name action = |
| 62 | let button = W.button name in |
| 63 | W.on_click ~click:action button ; |
| 64 | button in |
| 65 | |
| 66 | let op_button name op = make_button name @@ op_clicked op in |
| 67 | let push_button = make_button "PSH" push_clicked in |
| 68 | let swap_button = make_button "SWP" swap_clicked in |
| 69 | let pop_button = make_button "POP" pop_clicked in |
| 70 | let digit_button digit = make_button digit @@ digit_clicked digit in |
| 71 | |
| 72 | let (//) x y = |
| 73 | match x, y with |
| 74 | | (_, 0) -> 0 |
| 75 | | (x, y) -> x / y in |
| 76 | |
| 77 | let layout = L.tower ~align:Draw.Center [ |
| 78 | L.resident ~w:400 display ; |
| 79 | L.flat_of_w [ digit_button "1" ; digit_button "2" ; digit_button "3" ] ; |
| 80 | L.flat_of_w [ digit_button "4" ; digit_button "5" ; digit_button "6" ] ; |
| 81 | L.flat_of_w [ digit_button "7" ; digit_button "8" ; digit_button "9" ] ; |
| 82 | L.flat_of_w [ digit_button "0" ] ; |
| 83 | L.flat_of_w [ push_button; swap_button; pop_button] ; |
| 84 | L.flat_of_w [ op_button "ADD" (+) ; op_button "MUL" ( * ) ; op_button "SUB" (-) ; op_button "DIV" (//) ] ; |
| 85 | ] in |
| 86 | |
| 87 | let calculator = Bogue.make [] [layout] in |
| 88 | update_display () ; |
| 89 | Bogue.run calculator ;; |
| 90 | |
| 91 | let _ = |
| 92 | calculator () ; |
| 93 | Draw.quit() |
| 94 |