最終更新 2 hours ago

Calculator implementing Bogue

修正履歴 c5c932f947330d091848fb0f90612c64d930ae55

main.ml Raw Playground
1open Bogue
2
3module W = Widget
4module L = Layout
5
6
7let 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
91let _ =
92 calculator () ;
93 Draw.quit()
94