[gnome-calculator/60-split-out-a-backend-library] gcalc: added support for minus operator



commit 53ffc1d5d2a7d151f62c25d41d8697d398ef0dea
Author: Daniel Espinosa Ortiz <esodan gmail com>
Date:   Thu Jan 3 10:22:34 2019 -0600

    gcalc: added support for minus operator

 gcalc/gcalc-gminus.vala          |  26 ++++++++++
 gcalc/gcalc-gplus.vala           |   2 +-
 gcalc/gcalc-minus.vala           |  22 +++++++++
 gcalc/gcalc-parser.vala          | 102 +++++++++++++++++++++------------------
 gcalc/meson.build                |   4 +-
 tests/gcalc-main-interfaces.vala |  52 +++++++++++++++++++-
 6 files changed, 156 insertions(+), 52 deletions(-)
---
diff --git a/gcalc/gcalc-gminus.vala b/gcalc/gcalc-gminus.vala
new file mode 100644
index 00000000..0cc90ea3
--- /dev/null
+++ b/gcalc/gcalc-gminus.vala
@@ -0,0 +1,26 @@
+/* gcalc-gminus.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.GMinus : GExpression, Operator, BinaryOperator, Minus {
+  public override string to_string () {
+    return "-";
+  }
+}
+
diff --git a/gcalc/gcalc-gplus.vala b/gcalc/gcalc-gplus.vala
index 1ceb031f..86ba9443 100644
--- a/gcalc/gcalc-gplus.vala
+++ b/gcalc/gcalc-gplus.vala
@@ -20,7 +20,7 @@
  */
 public class GCalc.GPlus : GExpression, Operator, BinaryOperator, Plus {
   public override string to_string () {
-    return "*";
+    return "+";
   }
 }
 
diff --git a/gcalc/gcalc-minus.vala b/gcalc/gcalc-minus.vala
new file mode 100644
index 00000000..0722fd80
--- /dev/null
+++ b/gcalc/gcalc-minus.vala
@@ -0,0 +1,22 @@
+/* gcalc-minus.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.Minus : Object, Expression, Operator, BinaryOperator {}
+
diff --git a/gcalc/gcalc-parser.vala b/gcalc/gcalc-parser.vala
index ae805d97..fa0d46ff 100644
--- a/gcalc/gcalc-parser.vala
+++ b/gcalc/gcalc-parser.vala
@@ -21,6 +21,11 @@
 using Vala;
 
 public class GCalc.Parser : Object {
+  Expression current = null;
+  Expression current_parent = null;
+  Expression top_parent = null;
+  Gee.ArrayList<Vala.TokenType> expected = new Gee.ArrayList<Vala.TokenType> ();
+
   public void parse (string str, MathEquationManager eqman) throws GLib.Error {
     var context = new CodeContext ();
     CodeContext.push (context);
@@ -35,11 +40,7 @@ public class GCalc.Parser : Object {
       lines[0] = str;
     }
     Vala.TokenType token = Vala.TokenType.NONE;
-    var expected = new Gee.ArrayList<Vala.TokenType> ();
-    Expression current = null;
-    Expression current_parent = null;
-    Expression top_parent = null;
-    var eq = new GMathEquation ();
+    GMathEquation eq = new GMathEquation ();
     while (token != Vala.TokenType.EOF) {
       Vala.SourceLocation begin, end;
       token = scanner.read_token (out begin, out end);
@@ -188,53 +189,13 @@ public class GCalc.Parser : Object {
         case Vala.TokenType.STAR:
           break;
         case Vala.TokenType.PLUS:
-          if (current is BinaryOperator) {
-            throw new ParserError.INVALID_TOKEN_ERROR ("Found an unexpected expression for a plus operator");
-          }
           var opp = new GPlus ();
-          if (current == null) {
-            var exp = new GPolynomial ();
-            var t = new GTerm ();
-            t.expressions.add (opp);
-            exp.expressions.add (t);
-            current = opp;
-            current_parent = t;
-            top_parent = exp;
-            eq.expressions.add (exp);
-            expected.clear ();
-          } else if (current_parent is Polynomial && current is Term) {
-            current.expressions.add (opp);
-            top_parent = current_parent;
-            current_parent = current;
-            current = opp;
-            expected.clear ();
-          } else if ((current is Constant || current is Variable)
-                     && current_parent is Term && top_parent is Polynomial) {
-            // New term
-            var t = new GTerm ();
-            t.expressions.add (opp);
-            top_parent.expressions.add (t);
-            current = opp;
-            current_parent = t;
-            expected.clear ();
-          }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);
-            var t2 = new GTerm ();
-            exp.expressions.add (t2);
-            t2.expressions.add (opp);
-            current = opp;
-            current_parent = t2;
-            top_parent = exp;
-            expected.clear ();
-          }
+          process_operator (opp, eq);
           break;
         case Vala.TokenType.DIV:
         case Vala.TokenType.MINUS:
+          var opp = new GMinus ();
+          process_operator (opp, eq);
           break;
         case Vala.TokenType.ASSIGN:
           if (current == null) {
@@ -328,6 +289,51 @@ public class GCalc.Parser : Object {
     }
     eqman.equations.add (eq);
   }
+  private void process_operator (Operator opp, GMathEquation eq) throws GLib.Error {
+    if (current is BinaryOperator) {
+      throw new ParserError.INVALID_TOKEN_ERROR ("Found an unexpected expression for a plus operator");
+    }
+    if (current == null) {
+      var exp = new GPolynomial ();
+      var t = new GTerm ();
+      t.expressions.add (opp);
+      exp.expressions.add (t);
+      current = opp;
+      current_parent = t;
+      top_parent = exp;
+      eq.expressions.add (exp);
+      expected.clear ();
+    } else if (current_parent is Polynomial && current is Term) {
+      current.expressions.add (opp);
+      top_parent = current_parent;
+      current_parent = current;
+      current = opp;
+      expected.clear ();
+    } else if ((current is Constant || current is Variable)
+               && current_parent is Term && top_parent is Polynomial) {
+      // New term
+      var t = new GTerm ();
+      t.expressions.add (opp);
+      top_parent.expressions.add (t);
+      current = opp;
+      current_parent = t;
+      expected.clear ();
+    }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);
+      var t2 = new GTerm ();
+      exp.expressions.add (t2);
+      t2.expressions.add (opp);
+      current = opp;
+      current_parent = t2;
+      top_parent = exp;
+      expected.clear ();
+    }
+  }
 }
 
 public errordomain GCalc.ParserError {
diff --git a/gcalc/meson.build b/gcalc/meson.build
index e9351bc2..8476dbd7 100644
--- a/gcalc/meson.build
+++ b/gcalc/meson.build
@@ -53,6 +53,7 @@ sources = files([
        'gcalc-gfunction.vala',
        'gcalc-gmath-equation.vala',
        'gcalc-gmath-equation-manager.vala',
+       'gcalc-gminus.vala',
        'gcalc-gplus.vala',
        'gcalc-gpolynomial.vala',
        'gcalc-gresult.vala',
@@ -61,6 +62,7 @@ sources = files([
        'gcalc-gvariable.vala',
        'gcalc-math-equation.vala',
        'gcalc-math-equation-manager.vala',
+       'gcalc-minus.vala',
        'gcalc-operator.vala',
        'gcalc-parser.vala',
        'gcalc-plus.vala',
@@ -156,4 +158,4 @@ custom_target('typelib',
        depends: lib,
        install: true,
        install_dir: join_paths(get_option('libdir'), 'girepository-1.0'))
-endif
+endif
\ No newline at end of file
diff --git a/tests/gcalc-main-interfaces.vala b/tests/gcalc-main-interfaces.vala
index 89279370..e805d8e7 100644
--- a/tests/gcalc-main-interfaces.vala
+++ b/tests/gcalc-main-interfaces.vala
@@ -238,8 +238,10 @@ class Tests {
         assert (p.expressions.get_n_items () == 4);
         var t1 = p.expressions.get_item (0) as Term;
         assert (t1 != null);
-        assert (t1.expressions.get_n_items () == 1);
-        var c1 = t1.expressions.get_item (0) as Constant;
+        assert (t1.expressions.get_n_items () == 2);
+        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 t2 = p.expressions.get_item (1) as Term;
         assert (t2 != null);
@@ -266,6 +268,52 @@ class Tests {
         warning ("Error: %s", error.message);
       }
     });
+    Test.add_func ("/gcalc/parser/term/complex/constant+variable/combined-operators",
+    ()=>{
+      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 () == 4);
+        var t1 = p.expressions.get_item (0) as Term;
+        assert (t1 != null);
+        assert (t1.expressions.get_n_items () == 2);
+        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 t2 = p.expressions.get_item (1) as Term;
+        assert (t2 != null);
+        assert (t2.expressions.get_n_items () == 2);
+        var plus = t2.expressions.get_item (0) as Plus;
+        assert (plus != null);
+        var c2 = t2.expressions.get_item (1) as Variable;
+        assert (c2 != null);
+        var t3 = p.expressions.get_item (2) as Term;
+        assert (t3 != null);
+        assert (t3.expressions.get_n_items () == 2);
+        var plus2 = t3.expressions.get_item (0) as Plus;
+        assert (plus2 != null);
+        var c3 = t3.expressions.get_item (1) as Constant;
+        assert (c3 != null);
+        var t4 = p.expressions.get_item (3) as Term;
+        assert (t4 != null);
+        assert (t4.expressions.get_n_items () == 2);
+        var minus2 = t4.expressions.get_item (0) as Minus;
+        assert (minus2 != null);
+        var c4 = t4.expressions.get_item (1) 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]