From 18f81a336db495b5e468837caf8560c14aea6a19 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Alexis=20Laferri=C3=A8re?= Date: Sun, 1 May 2016 15:11:14 -0400 Subject: [PATCH] calculator: extend the calculator logic with scientific operators MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Alexis Laferrière --- examples/calculator/src/calculator_logic.nit | 90 ++++++++++++++++++++------ 1 file changed, 71 insertions(+), 19 deletions(-) diff --git a/examples/calculator/src/calculator_logic.nit b/examples/calculator/src/calculator_logic.nit index 46f9ca3..775e8e3 100644 --- a/examples/calculator/src/calculator_logic.nit +++ b/examples/calculator/src/calculator_logic.nit @@ -24,33 +24,35 @@ class CalculatorContext # Result of the last operation var result: nullable Numeric = null - # Last operation pushed with `push_op`, to be executed on the next push + # Last operation pushed with `push_op` var last_op: nullable Text = null + # Is `last_op` an unary operation or a '='? + var last_op_was_unary = false + # Value currently being entered var current: nullable String = null # Text to display on screen 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 "= " + var last_op = last_op + var result = result + if result != null then + if last_op_was_unary then buf.append "{last_op or else "?"} " buf.append result.to_s buf.add ' ' end - if last_op != null and last_op != "=" then + if last_op != null and not last_op_was_unary then buf.append last_op buf.add ' ' end + var current = current if current != null then buf.append current.to_s buf.add ' ' @@ -62,30 +64,74 @@ class CalculatorContext # Push operation `op`, will usually execute the last operation fun push_op(op: Text) do + # Constants + # TODO Protect constants to preserve full precision and to forbid appending extra digits + if op == "π" then + if last_op_was_unary then clear + current = pi.to_s + return + else if op == "e" then + if last_op_was_unary then clear + current = 2.718282.to_s + return + + # Clear screen + else if op == "C" then + clear + return + end + + # For all operators, apply pending operators apply_last_op_if_any - if op == "C" then - self.result = null - last_op = null + + var result = self.result or else 0 + + last_op = op + last_op_was_unary = true + + # Unary operators + if op == "√" then + self.result = result.to_f.sqrt + else if op == "x²" then + self.result = result.to_f.pow(2.0) + else if op == "x!" then + self.result = result.to_i.factorial + else if op == "sin" then + self.result = result.to_f.sin + else if op == "cos" then + self.result = result.to_f.cos + else if op == "tan" then + self.result = result.to_f.tan + + # = + else if op == "=" then + current = null + + # Binary operators else - last_op = op # store for next push_op + self.result = result # Set as same or 0 + last_op_was_unary = false + current = null end + end - # prepare next current - self.current = null + # Clear all state + private fun clear + do + result = null + last_op = null + current = null end # Push a digit fun push_digit(digit: Int) do + if last_op_was_unary then clear + var current = current if current == null then current = "" current += digit.to_s self.current = current - - if last_op == "=" then - self.result = null - last_op = null - end end # Switch entry mode from integer to decimal @@ -118,6 +164,12 @@ class CalculatorContext result = result.div(current.to_n) else if op == "*" or op == "×" then result = result.mul(current.to_n) + else if op == "%" then + result = result.to_i % current.to_i + else if op == "xⁿ" then + result = result.to_f.pow(current.to_f) + else if op == "log" then + result = result.to_f.log_base(current.to_f) end end -- 1.7.9.5