var context = new CalculatorContext
- redef fun signal( sender, user_data )
+ redef fun signal(sender, op)
do
- var after_point = context.after_point
- if after_point == null then
- after_point = 0
- else
- after_point = (after_point.abs)
- end
-
- if user_data isa Char then # is an operation
- var c = user_data
- if c == '.' then
- but_dot.sensitive= false
+ if op isa Char then # is an operation
+ if op == '.' then
+ but_dot.sensitive = false
context.switch_to_decimals
- lbl_disp.text = "{context.current.to_i}."
else
- but_dot.sensitive= true
- context.push_op( c )
-
- var s = context.result.to_precision_native(6)
- var index : nullable Int = null
- for i in s.length.times do
- var chiffre = s.chars[i]
- if chiffre == '0' and index == null then
- index = i
- else if chiffre != '0' then
- index = null
- end
- end
- if index != null then
- s = s.substring(0, index)
- if s.chars[s.length-1] == ',' then s = s.substring(0, s.length-1)
- end
- lbl_disp.text = s
+ but_dot.sensitive = true
+ context.push_op op
end
- else if user_data isa Int then # is a number
- var n = user_data
- context.push_digit( n )
- lbl_disp.text = context.current.to_precision_native(after_point)
+ else if op isa Int then # is a number
+ context.push_digit op
end
+
+ lbl_disp.text = context.display_text
end
init
module calculator_logic
class CalculatorContext
- var result : nullable Float = null
+ var result: nullable Numeric = null
- var last_op : nullable Char = null
+ var last_op: nullable Char = null
- var current : nullable Float = null
- var after_point : nullable Int = null
+ var current: nullable FlatBuffer = null
+ fun display_text: String
+ do
+ var result = result
+ var last_op = last_op
+ var current = current
+
+ var buf = new FlatBuffer
+
+ if result != null and (current == null or last_op != '=') then
+ if last_op == '=' then buf.append "= "
+
+ buf.append result.to_s
+ buf.add ' '
+ end
+
+ if last_op != null and last_op != '=' then
+ buf.add last_op
+ buf.add ' '
+ end
+
+ if current != null then
+ buf.append current.to_s
+ buf.add ' '
+ end
+
+ return buf.to_s
+ end
fun push_op( op : Char )
do
apply_last_op_if_any
if op == 'C' then
- self.result = 0.0
+ self.result = null
last_op = null
else
last_op = op # store for next push_op
end
# prepare next current
- after_point = null
- current = null
+ self.current = null
end
fun push_digit( digit : Int )
do
var current = current
- if current == null then current = 0.0
+ if current == null then current = new FlatBuffer
+ current.add digit.to_s.chars.first
+ self.current = current
- var after_point = after_point
- if after_point == null then
- current = current * 10.0 + digit.to_f
- else
- current = current + digit.to_f * 10.0.pow(after_point.to_f)
- self.after_point -= 1
+ if last_op == '=' then
+ self.result = null
+ last_op = null
end
-
- self.current = current
end
fun switch_to_decimals
do
- if self.current == null then current = 0.0
- if after_point != null then return
-
- after_point = -1
+ var current = current
+ if current == null then current = new FlatBuffer.from("0")
+ if not current.chars.has('.') then current.add '.'
+ self.current = current
end
fun apply_last_op_if_any
var op = last_op
var result = result
- if result == null then result = 0.0
var current = current
- if current == null then current = 0.0
+ if current == null then current = new FlatBuffer
if op == null then
- result = current
+ result = current.to_n
else if op == '+' then
- result = result + current
+ result = result.add(current.to_n)
else if op == '-' then
- result = result - current
+ result = result.sub(current.to_n)
else if op == '/' then
- result = result / current
+ result = result.div(current.to_n)
else if op == '*' then
- result = result * current
+ result = result.mul(current.to_n)
end
self.result = result
self.current = null
end
end
+
+redef universal Float
+ redef fun to_s do return to_precision(6)
+end
context.push_op( '*' )
context.push_digit( 2 )
context.push_op( '=' )
-var r = context.result.to_precision( 2 )
-assert r == "30.00" else print r
+var r = context.result
+assert r == "30.00" else print r or else "-"
context = new CalculatorContext
context.push_digit( 1 )
context.push_op( '*' )
context.push_digit( 3 )
context.push_op( '=' )
-r = context.result.to_precision( 2 )
-assert r == "42.30" else print r
+r = context.result
+assert r == "42.30" else print r or else "-"
context.push_op( '+' )
context.push_digit( 1 )
context.push_digit( 1 )
context.push_op( '=' )
-r = context.result.to_precision( 2 )
-assert r == "53.30" else print r
+r = context.result
+assert r == "53.30" else print r or else "-"
context = new CalculatorContext
context.push_digit( 4 )
context.push_op( '/' )
context.push_digit( 3 )
context.push_op( '=' )
-r = context.result.to_precision( 2 )
-assert r == "14.10" else print r
+r = context.result
+assert r == "14.10" else print r or else "-"
#test multiple decimals
context = new CalculatorContext
context.push_op( '+' )
context.push_digit( 1 )
context.push_op( '=' )
-r = context.result.to_precision( 3 )
-assert r == "51.123" else print r
+r = context.result
+assert r == "51.123" else print r or else "-"
#test 'C' button
context = new CalculatorContext
context.push_digit( 0 )
context.push_op( '=' )
context.push_op( 'C' )
-r = context.result.to_precision( 1 )
-assert r == "0.0" else print r
+r = context.result
+assert r == "0.0" else print r or else "-"