[gnome-calculator/60-split-out-a-backend-library] gcalc: add support for multiply operator parsing



commit b0cc1a5071ec5729b1f922f230f02b83ad372d2b
Author: Daniel Espinosa Ortiz <esodan gmail com>
Date:   Thu Jan 3 10:55:04 2019 -0600

    gcalc: add support for multiply operator parsing

 gcalc/gcalc-gmultiply.vala       | 26 ++++++++++++
 gcalc/gcalc-multiply.vala        | 22 ++++++++++
 gcalc/gcalc-parser.vala          | 28 +++++++++---
 gcalc/meson.build                |  2 +
 tests/gcalc-main-interfaces.vala | 92 ++++++++++++++++++++++++++++++++++++++++
 5 files changed, 165 insertions(+), 5 deletions(-)
---
diff --git a/gcalc/gcalc-gmultiply.vala b/gcalc/gcalc-gmultiply.vala
new file mode 100644
index 00000000..50d2a004
--- /dev/null
+++ b/gcalc/gcalc-gmultiply.vala
@@ -0,0 +1,26 @@
+/* gcalc-gmultiply.vala
+ *
+ * Copyright (C) 2018  Daniel Espinosa <esodan gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *      Daniel Espinosa <esodan gmail com>
+ */
+public class GCalc.GMultiply : GExpression, Operator, BinaryOperator, Multiply {
+  public override string to_string () {
+    return "+";
+  }
+}
+
diff --git a/gcalc/gcalc-multiply.vala b/gcalc/gcalc-multiply.vala
new file mode 100644
index 00000000..bde0f5be
--- /dev/null
+++ b/gcalc/gcalc-multiply.vala
@@ -0,0 +1,22 @@
+/* gcalc-multiply.vala
+ *
+ * Copyright (C) 2018  Daniel Espinosa <esodan gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *      Daniel Espinosa <esodan gmail com>
+ */
+public interface GCalc.Multiply : Object, Expression, Operator, BinaryOperator {}
+
diff --git a/gcalc/gcalc-parser.vala b/gcalc/gcalc-parser.vala
index fa0d46ff..175b3bcd 100644
--- a/gcalc/gcalc-parser.vala
+++ b/gcalc/gcalc-parser.vala
@@ -145,15 +145,12 @@ public class GCalc.Parser : Object {
             message ("Searching variable: %s", n);
             var v = new GVariable (n) as Expression;
             if (eqman.variables.find_named (n) == null) {
+              message ("Adding new variable named: '%s'", (v as Variable).name);
               eqman.variables.add (v);
             }
             if (current == null) {
               current = v;
               expected.clear ();
-              expected.add(Vala.TokenType.ASSIGN);
-              expected.add(Vala.TokenType.PLUS);
-              expected.add(Vala.TokenType.MINUS);
-              message ("Adding new variable named: '%s'", (current as Variable).name);
             } else if (current is Operator && current_parent is Term && top_parent is Polynomial) {
                 current_parent.expressions.add (v);
                 current = v;
@@ -187,6 +184,27 @@ public class GCalc.Parser : Object {
         case Vala.TokenType.CHARACTER_LITERAL:
           break;
         case Vala.TokenType.STAR:
+          var op = new GMultiply ();
+          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)
+              && current_parent is Term && top_parent is Polynomial) {
+              current_parent.expressions.add (op);
+              current = op;
+          } else if (current is Variable && current_parent == null) {
+            // New Polynomial
+            var exp = new GPolynomial ();
+            eq.expressions.add (exp);
+            var t = new GTerm ();
+            exp.expressions.add (t);
+            t.expressions.add (current);
+            t.expressions.add (op);
+            current = op;
+            current_parent = t;
+            top_parent = exp;
+            expected.clear ();
+          }
           break;
         case Vala.TokenType.PLUS:
           var opp = new GPlus ();
@@ -318,7 +336,7 @@ public class GCalc.Parser : Object {
       current = opp;
       current_parent = t;
       expected.clear ();
-    }if (current is Variable && current_parent == null) {
+    } else if (current is Variable && current_parent == null) {
       // New Polynomial
       var exp = new GPolynomial ();
       eq.expressions.add (exp);
diff --git a/gcalc/meson.build b/gcalc/meson.build
index 8476dbd7..62a6d29c 100644
--- a/gcalc/meson.build
+++ b/gcalc/meson.build
@@ -54,6 +54,7 @@ sources = files([
        'gcalc-gmath-equation.vala',
        'gcalc-gmath-equation-manager.vala',
        'gcalc-gminus.vala',
+       'gcalc-gmultiply.vala',
        'gcalc-gplus.vala',
        'gcalc-gpolynomial.vala',
        'gcalc-gresult.vala',
@@ -63,6 +64,7 @@ sources = files([
        'gcalc-math-equation.vala',
        'gcalc-math-equation-manager.vala',
        'gcalc-minus.vala',
+       'gcalc-multiply.vala',
        'gcalc-operator.vala',
        'gcalc-parser.vala',
        'gcalc-plus.vala',
diff --git a/tests/gcalc-main-interfaces.vala b/tests/gcalc-main-interfaces.vala
index e805d8e7..af8030f8 100644
--- a/tests/gcalc-main-interfaces.vala
+++ b/tests/gcalc-main-interfaces.vala
@@ -314,6 +314,98 @@ class Tests {
         warning ("Error: %s", error.message);
       }
     });
+    Test.add_func ("/gcalc/parser/term/multiply/constant",
+    ()=>{
+      try {
+        var parser = new Parser ();
+        var eqman = new GMathEquationManager ();
+        parser.parse ("1*1", 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 m = t1.expressions.get_item (1) as Multiply;
+        assert (m != null);
+        var c2 = t1.expressions.get_item (2) as Constant;
+        assert (c2 != null);
+      } catch (GLib.Error error) {
+        warning ("Error: %s", error.message);
+      }
+    });
+    Test.add_func ("/gcalc/parser/term/multiply/variable",
+    ()=>{
+      try {
+        var parser = new Parser ();
+        var eqman = new GMathEquationManager ();
+        parser.parse ("A*B", 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);
+        message ("Terms: %u", p.expressions.get_n_items ());
+        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 Variable;
+        assert (c1 != null);
+        var m = t1.expressions.get_item (1) as Multiply;
+        assert (m != null);
+        var c2 = t1.expressions.get_item (2) as Variable;
+        assert (c2 != null);
+      } catch (GLib.Error error) {
+        warning ("Error: %s", error.message);
+      }
+    });
+    Test.add_func ("/gcalc/parser/term/complex/constant*variable",
+    ()=>{
+      try {
+        var parser = new Parser ();
+        var eqman = new GMathEquationManager ();
+        parser.parse ("-1*B+3*A", 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);
+        message ("Terms: %u", p.expressions.get_n_items ());
+        assert (p.expressions.get_n_items () == 2);
+        var t1 = p.expressions.get_item (0) as Term;
+        assert (t1 != null);
+        assert (t1.expressions.get_n_items () == 4);
+        var minus = t1.expressions.get_item (0) as Minus;
+        assert (minus != null);
+        var c1 = t1.expressions.get_item (1) as Constant;
+        assert (c1 != null);
+        var m1 = t1.expressions.get_item (2) as Multiply;
+        assert (m1 != null);
+        var c2 = t1.expressions.get_item (3) as Variable;
+        assert (c2 != null);
+        var t2 = p.expressions.get_item (1) as Term;
+        assert (t2 != null);
+        var plus = t2.expressions.get_item (0) as Plus;
+        assert (plus != null);
+        var c3 = t2.expressions.get_item (1) as Constant;
+        assert (c3 != null);
+        var m2 = t2.expressions.get_item (2) as Multiply;
+        assert (m2 != null);
+        var c4 = t2.expressions.get_item (3) as Variable;
+        assert (c4 != null);
+      } catch (GLib.Error error) {
+        warning ("Error: %s", error.message);
+      }
+    });
     return Test.run ();
   }
 }


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