examples/calculator: revamp style of the calculator code
[nit.git] / examples / calculator / src / calculator_logic.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Business logic of a calculator
16 module calculator_logic
17
18 # Hold the state of the calculator and its services
19 class CalculatorContext
20 # Result of the last operation
21 var result: nullable Numeric = null
22
23 # Last operation pushed with `push_op`, to be executed on the next push
24 var last_op: nullable Char = null
25
26 # Value currently being entered
27 var current: nullable FlatBuffer = null
28
29 # Text to display on screen
30 fun display_text: String
31 do
32 var result = result
33 var last_op = last_op
34 var current = current
35
36 var buf = new FlatBuffer
37
38 if result != null and (current == null or last_op != '=') then
39 if last_op == '=' then buf.append "= "
40
41 buf.append result.to_s
42 buf.add ' '
43 end
44
45 if last_op != null and last_op != '=' then
46 buf.add last_op
47 buf.add ' '
48 end
49
50 if current != null then
51 buf.append current.to_s
52 buf.add ' '
53 end
54
55 return buf.to_s
56 end
57
58 # Push operation `op`, will usually execute the last operation
59 fun push_op(op: Char)
60 do
61 apply_last_op_if_any
62 if op == 'C' then
63 self.result = null
64 last_op = null
65 else
66 last_op = op # store for next push_op
67 end
68
69 # prepare next current
70 self.current = null
71 end
72
73 # Push a digit
74 fun push_digit(digit: Int)
75 do
76 var current = current
77 if current == null then current = new FlatBuffer
78 current.add digit.to_s.chars.first
79 self.current = current
80
81 if last_op == '=' then
82 self.result = null
83 last_op = null
84 end
85 end
86
87 # Switch entry mode from integer to decimal
88 fun switch_to_decimals
89 do
90 var current = current
91 if current == null then current = new FlatBuffer.from("0")
92 if not current.chars.has('.') then current.add '.'
93 self.current = current
94 end
95
96 # Execute the last operation it not null
97 protected fun apply_last_op_if_any
98 do
99 var op = last_op
100
101 var result = result
102
103 var current = current
104 if current == null then current = new FlatBuffer
105
106 if op == null then
107 result = current.to_n
108 else if op == '+' then
109 result = result.add(current.to_n)
110 else if op == '-' then
111 result = result.sub(current.to_n)
112 else if op == '/' then
113 result = result.div(current.to_n)
114 else if op == '*' then
115 result = result.mul(current.to_n)
116 end
117
118 self.result = result
119 self.current = null
120 end
121 end
122
123 redef universal Float
124 redef fun to_s do return to_precision(6)
125 end