[gnome-calculator/60-split-out-a-backend-library] gcalc: implement multiply group in a term



commit 1d6ec819b34310ec613adf3dc8089f9cd08509c6
Author: Daniel Espinosa Ortiz <esodan gmail com>
Date:   Fri Jan 4 14:01:32 2019 -0600

    gcalc: implement multiply group in a term

 gcalc/gcalc-parser.vala        |  2 +-
 gcalc/gcalc-term.vala          | 32 ++++++++++-----
 tests/gcalc-parsing.vala       | 88 ++++++++++++++++++++++++++++++++++++++++++
 tests/gcalc-solving-basic.vala | 76 ++++++++++++++++++++++++++++++++++++
 4 files changed, 188 insertions(+), 10 deletions(-)
---
diff --git a/gcalc/gcalc-parser.vala b/gcalc/gcalc-parser.vala
index 54049a48..1033dc16 100644
--- a/gcalc/gcalc-parser.vala
+++ b/gcalc/gcalc-parser.vala
@@ -399,7 +399,7 @@ public class GCalc.Parser : Object {
     if (current is Operator) {
       throw new ParserError.INVALID_TOKEN_ERROR ("Found an unexpected expression for a multiply operator");
     }
-    if ((current is Constant || current is Variable)
+    if ((current is Constant || current is Variable || current is Group)
         && current_parent is Term && top_parent is Polynomial) {
         current_parent.expressions.add (op);
         current = op;
diff --git a/gcalc/gcalc-term.vala b/gcalc/gcalc-term.vala
index bbd5d6e8..a1cf009b 100644
--- a/gcalc/gcalc-term.vala
+++ b/gcalc/gcalc-term.vala
@@ -56,15 +56,7 @@ public interface GCalc.Term : Object, Expression {
           first = false;
         } else if (current is Constant) {
           if (current_operator != null) {
-            if (current_operator is Minus) {
-              current = (current as Constant).multiply (e as Constant);
-            }
-            if (current_operator is Multiply) {
-              current = (current as Constant).multiply (e as Constant);
-            }
-            if (current_operator is Division) {
-              current = (current as Constant).divide (e as Constant);
-            }
+            current = evaluate_constants ((Constant) current, (Constant) e, current_operator);
           }
         }
       } else if (e is Group) {
@@ -72,6 +64,10 @@ public interface GCalc.Term : Object, Expression {
         if (current == null) {
           current = ev;
           first = false;
+        } else if (current is Constant&& ev is Constant) {
+          if (current_operator != null) {
+            current = evaluate_constants ((Constant) current, (Constant) ev, current_operator);
+          }
         }
       }
     }
@@ -80,6 +76,24 @@ public interface GCalc.Term : Object, Expression {
     }
     return current;
   }
+  public static Expression evaluate_constants (Constant c1, Constant c2, Operator op)
+    throws GLib.Error
+  {
+    Expression res = null;
+    if (op is Minus) {
+      res = (c1 as Constant).multiply (c2 as Constant);
+    }
+    if (op is Multiply) {
+      res = (c1 as Constant).multiply (c2 as Constant);
+    }
+    if (op is Division) {
+      res = (c1 as Constant).divide (c2 as Constant);
+    }
+    if (res == null) {
+      throw new TermError.INVALID_OPERATOR ("Unsupported operator in term's expression");
+    }
+    return res;
+  }
 }
 
 public errordomain GCalc.TermError {
diff --git a/tests/gcalc-parsing.vala b/tests/gcalc-parsing.vala
index 04b21d91..fbfb8220 100644
--- a/tests/gcalc-parsing.vala
+++ b/tests/gcalc-parsing.vala
@@ -612,6 +612,94 @@ class Tests {
         warning ("Error: %s", error.message);
       }
     });
+    Test.add_func ("/gcalc/parser/term/parenthesis/grouping/multiply",
+    ()=>{
+      try {
+        var parser = new Parser ();
+        var eqman = new GMathEquationManager ();
+        parser.parse ("5*(3+2)", eqman);
+        assert (eqman.equations.get_n_items () == 1);
+        var eq = eqman.equations.get_item (0) as MathEquation;
+        assert (eq != null);
+        assert (eq.expressions.get_n_items () == 1);
+        var p = eq.expressions.get_item (0) as Polynomial;
+        assert (p != null);
+        assert (p.expressions.get_n_items () == 1);
+        var t1 = p.expressions.get_item (0) as Term;
+        assert (t1 != null);
+        assert (t1.expressions.get_n_items () == 3);
+        var c1 = t1.expressions.get_item (0) as Constant;
+        assert (c1 != null);
+        var m1 = t1.expressions.get_item (1) as Multiply;
+        assert (m1 != null);
+        var g = t1.expressions.get_item (2) as Group;
+        assert (g != null);
+        assert (g.closed);
+        assert (g.expressions.get_n_items () == 1);
+        var pg = g.expressions.get_item (0) as Polynomial;
+        assert (pg != null);
+        assert (pg.expressions.get_n_items () == 2);
+        var tg1 = pg.expressions.get_item (0) as Term;
+        assert (tg1 != null);
+        assert (tg1.expressions.get_n_items () == 1);
+        var c2 = tg1.expressions.get_item (0) as Constant;
+        assert (c2 != null);
+        var tg2 = pg.expressions.get_item (1) as Term;
+        assert (tg2 != null);
+        assert (tg2.expressions.get_n_items () == 2);
+        message (tg2.to_string ());
+        var plus = tg2.expressions.get_item (0) as Plus;
+        assert (plus != null);
+        var c3 = tg2.expressions.get_item (1) as Constant;
+        assert (c3 != null);
+      } catch (GLib.Error error) {
+        warning ("Error: %s", error.message);
+      }
+    });
+    Test.add_func ("/gcalc/parser/term/parenthesis/grouping/multiply-inv",
+    ()=>{
+      try {
+        var parser = new Parser ();
+        var eqman = new GMathEquationManager ();
+        parser.parse ("(3+2)*5", eqman);
+        assert (eqman.equations.get_n_items () == 1);
+        var eq = eqman.equations.get_item (0) as MathEquation;
+        assert (eq != null);
+        assert (eq.expressions.get_n_items () == 1);
+        var p = eq.expressions.get_item (0) as Polynomial;
+        assert (p != null);
+        assert (p.expressions.get_n_items () == 1);
+        var t1 = p.expressions.get_item (0) as Term;
+        assert (t1 != null);
+        assert (t1.expressions.get_n_items () == 3);
+        var g = t1.expressions.get_item (0) as Group;
+        assert (g != null);
+        assert (g.closed);
+        assert (g.expressions.get_n_items () == 1);
+        var pg = g.expressions.get_item (0) as Polynomial;
+        assert (pg != null);
+        assert (pg.expressions.get_n_items () == 2);
+        var tg1 = pg.expressions.get_item (0) as Term;
+        assert (tg1 != null);
+        assert (tg1.expressions.get_n_items () == 1);
+        var c2 = tg1.expressions.get_item (0) as Constant;
+        assert (c2 != null);
+        var tg2 = pg.expressions.get_item (1) as Term;
+        assert (tg2 != null);
+        assert (tg2.expressions.get_n_items () == 2);
+        message (tg2.to_string ());
+        var plus = tg2.expressions.get_item (0) as Plus;
+        assert (plus != null);
+        var c3 = tg2.expressions.get_item (1) as Constant;
+        assert (c3 != null);
+        var m1 = t1.expressions.get_item (1) as Multiply;
+        assert (m1 != null);
+        var c1 = t1.expressions.get_item (2) as Constant;
+        assert (c1 != null);
+      } catch (GLib.Error error) {
+        warning ("Error: %s", error.message);
+      }
+    });
     return Test.run ();
   }
 }
diff --git a/tests/gcalc-solving-basic.vala b/tests/gcalc-solving-basic.vala
index 4037d2f9..9a1a979f 100644
--- a/tests/gcalc-solving-basic.vala
+++ b/tests/gcalc-solving-basic.vala
@@ -333,6 +333,82 @@ class Tests {
         warning ("Error: %s", e.message);
       }
     });
+    Test.add_func ("/gcalc/solve/group/multiply-term",
+    ()=>{
+      try {
+        var parser = new Parser ();
+        var eqman = new GMathEquationManager ();
+        parser.parse ("5*(3+2)", eqman);
+        assert (eqman.equations.get_n_items () == 1);
+        var eq = eqman.equations.get_item (0) as MathEquation;
+        assert (eq != null);
+        var e = eq.expressions.get_item (0) as Polynomial;
+        assert (e != null);
+        var res = e.evaluate () as Constant;
+        assert (res != null);
+        message ("Constant Result: %s", res.to_string ());
+        assert (res.real () == 25.0);
+      } catch (GLib.Error e) {
+        warning ("Error: %s", e.message);
+      }
+    });
+    Test.add_func ("/gcalc/solve/group/multiply-term/plug-constant",
+    ()=>{
+      try {
+        var parser = new Parser ();
+        var eqman = new GMathEquationManager ();
+        parser.parse ("5*(3+2)+1", eqman);
+        assert (eqman.equations.get_n_items () == 1);
+        var eq = eqman.equations.get_item (0) as MathEquation;
+        assert (eq != null);
+        var e = eq.expressions.get_item (0) as Polynomial;
+        assert (e != null);
+        var res = e.evaluate () as Constant;
+        assert (res != null);
+        message ("Constant Result: %s", res.to_string ());
+        assert (res.real () == 26.0);
+      } catch (GLib.Error e) {
+        warning ("Error: %s", e.message);
+      }
+    });
+    Test.add_func ("/gcalc/solve/group/multiply-term-inv",
+    ()=>{
+      try {
+        var parser = new Parser ();
+        var eqman = new GMathEquationManager ();
+        parser.parse ("(3+2)*5", eqman);
+        assert (eqman.equations.get_n_items () == 1);
+        var eq = eqman.equations.get_item (0) as MathEquation;
+        assert (eq != null);
+        var e = eq.expressions.get_item (0) as Polynomial;
+        assert (e != null);
+        var res = e.evaluate () as Constant;
+        assert (res != null);
+        message ("Constant Result: %s", res.to_string ());
+        assert (res.real () == 25.0);
+      } catch (GLib.Error e) {
+        warning ("Error: %s", e.message);
+      }
+    });
+    Test.add_func ("/gcalc/solve/group/complex",
+    ()=>{
+      try {
+        var parser = new Parser ();
+        var eqman = new GMathEquationManager ();
+        parser.parse ("(3+2)*5+1-3*(8-2)*7-(3)", eqman);
+        assert (eqman.equations.get_n_items () == 1);
+        var eq = eqman.equations.get_item (0) as MathEquation;
+        assert (eq != null);
+        var e = eq.expressions.get_item (0) as Polynomial;
+        assert (e != null);
+        var res = e.evaluate () as Constant;
+        assert (res != null);
+        message ("Constant Result: %s", res.to_string ());
+        assert (res.real () == -103.0);
+      } catch (GLib.Error e) {
+        warning ("Error: %s", e.message);
+      }
+    });
     return Test.run ();
   }
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]