e5e492b3cf03829b091022c8fb1339cfb4a893cf
[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 import serialization
19
20 # Hold the state of the calculator and its services
21 class CalculatorContext
22 auto_serializable
23
24 # Result of the last operation
25 var result: nullable Numeric = null
26
27 # Last operation pushed with `push_op`, to be executed on the next push
28 var last_op: nullable Char = null
29
30 # Value currently being entered
31 var current: nullable FlatBuffer = null
32
33 # Text to display on screen
34 fun display_text: String
35 do
36 var result = result
37 var last_op = last_op
38 var current = current
39
40 var buf = new FlatBuffer
41
42 if result != null and (current == null or last_op != '=') then
43 if last_op == '=' then buf.append "= "
44
45 buf.append result.to_s
46 buf.add ' '
47 end
48
49 if last_op != null and last_op != '=' then
50 buf.add last_op
51 buf.add ' '
52 end
53
54 if current != null then
55 buf.append current.to_s
56 buf.add ' '
57 end
58
59 return buf.to_s
60 end
61
62 # Push operation `op`, will usually execute the last operation
63 fun push_op(op: Char)
64 do
65 apply_last_op_if_any
66 if op == 'C' then
67 self.result = null
68 last_op = null
69 else
70 last_op = op # store for next push_op
71 end
72
73 # prepare next current
74 self.current = null
75 end
76
77 # Push a digit
78 fun push_digit(digit: Int)
79 do
80 var current = current
81 if current == null then current = new FlatBuffer
82 current.add digit.to_s.chars.first
83 self.current = current
84
85 if last_op == '=' then
86 self.result = null
87 last_op = null
88 end
89 end
90
91 # Switch entry mode from integer to decimal
92 fun switch_to_decimals
93 do
94 var current = current
95 if current == null then current = new FlatBuffer.from("0")
96 if not current.chars.has('.') then current.add '.'
97 self.current = current
98 end
99
100 # Execute the last operation it not null
101 protected fun apply_last_op_if_any
102 do
103 var op = last_op
104 var result = result
105 var current = current
106 self.current = null
107
108 if current == null then return
109
110 if op == null then
111 result = current.to_n
112 else if result != null then
113 if op == '+' then
114 result = result.add(current.to_n)
115 else if op == '-' then
116 result = result.sub(current.to_n)
117 else if op == '/' then
118 result = result.div(current.to_n)
119 else if op == '*' then
120 result = result.mul(current.to_n)
121 end
122 end
123
124 self.result = result
125 end
126 end
127
128 redef universal Float
129 redef fun to_s do return to_precision(6)
130 end