[gnome-calculator/60-split-out-a-backend-library] gcalc: added Term object



commit 4afbeec0ba17e4840bee93a6557c2023226dd9b5
Author: Daniel Espinosa Ortiz <esodan gmail com>
Date:   Thu Jan 3 09:25:42 2019 -0600

    gcalc: added Term object
    
    Constructing an equation, we have polynomial formed by terms.
    This commit add support for them.

 gcalc/gcalc-gterm.vala           | 22 ++++++++++
 gcalc/gcalc-parser.vala          | 92 ++++++++++++++++++----------------------
 gcalc/gcalc-term.vala            | 22 ++++++++++
 gcalc/meson.build                |  2 +
 tests/gcalc-main-interfaces.vala | 34 ++++++++++-----
 5 files changed, 112 insertions(+), 60 deletions(-)
---
diff --git a/gcalc/gcalc-gterm.vala b/gcalc/gcalc-gterm.vala
new file mode 100644
index 00000000..3998c7f8
--- /dev/null
+++ b/gcalc/gcalc-gterm.vala
@@ -0,0 +1,22 @@
+/* gcalc-gterm.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.GTerm : GExpression, Term {}
+
diff --git a/gcalc/gcalc-parser.vala b/gcalc/gcalc-parser.vala
index d8b6f8fa..634566b7 100644
--- a/gcalc/gcalc-parser.vala
+++ b/gcalc/gcalc-parser.vala
@@ -38,6 +38,7 @@ public class GCalc.Parser : Object {
     var expected = new Gee.ArrayList<Vala.TokenType> ();
     Expression current = null;
     Expression current_parent = null;
+    Expression top_parent = null;
     var eq = new GMathEquation ();
     while (token != Vala.TokenType.EOF) {
       Vala.SourceLocation begin, end;
@@ -152,17 +153,13 @@ public class GCalc.Parser : Object {
               expected.add(Vala.TokenType.PLUS);
               expected.add(Vala.TokenType.MINUS);
               message ("Adding new variable named: '%s'", (current as Variable).name);
-            } else {
-              if (current is Polynomial && current.expressions.get_n_items () == 0) {
-                current.expressions.add (v);
-                current = v;
+            } else if (current is Polynomial) {
+                var t = new GTerm ();
+                t.expressions.add (v);
+                current.expressions.add (t);
+                current_parent = current;
+                current = t;
                 expected.clear ();
-              } else if (current is BinaryOperator) {
-                current.expressions.add (v);
-                current = current_parent;
-              } else {
-                throw new ParserError.INVALID_TOKEN_ERROR ("Found an unexpected variable without operator");
-              }
             }
           }
           break;
@@ -172,20 +169,22 @@ public class GCalc.Parser : Object {
           if (!double.try_parse (n, out res)) {
             throw new ParserError.INVALID_TOKEN_ERROR ("Found an unexpected expression for a constant");
           }
-          var iexp = new GConstant.@double (double.parse (n));
+          var cexp = new GConstant.@double (double.parse (n));
           if (current == null) {
-            current = new GPolynomial ();
-            eq.expressions.add (current);
-          }
-          if (current is Polynomial) {
-            current.expressions.add (iexp);
+            var exp = new GPolynomial ();
+            eq.expressions.add (exp);
+            var t = new GTerm ();
+            exp.expressions.add (t);
+            t.expressions.add (cexp);
+            current = cexp;
+            current_parent = t;
+            top_parent = exp;
+          } else if ((current is Operator || current is Term) && current_parent is Term && top_parent is 
Polynomial) {
+            current_parent.expressions.add (cexp);
             expected.clear ();
-            current_parent = current;
-            current = iexp;
-          }
-          if (current is BinaryOperator) {
-            current.expressions.add (iexp);
             current = current_parent;
+            current_parent = top_parent;
+            top_parent = null;
           }
           break;
         case Vala.TokenType.PERCENT:
@@ -200,35 +199,26 @@ public class GCalc.Parser : Object {
           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;
-            exp.expressions.add (opp);
-            current_parent = exp;
+            current_parent = t;
+            top_parent = exp;
             eq.expressions.add (exp);
             expected.clear ();
-          } else {
-            if (current is Variable || current is Constant) {
-              if (current_parent == null) {
-                var exp = new GPolynomial ();
-                exp.expressions.add (opp);
-                eq.expressions.add (exp);
-                opp.expressions.add (current);
-                current = opp;
-                current_parent = exp;
-              } else {
-                var i = current_parent.expressions.index_of (current);
-                if (!(current_parent is Polynomial)) {
-                  throw new ParserError.INVALID_TOKEN_ERROR ("Found an unexpected expression for a plus 
operator: parent is not a Polynomial");
-                }
-                opp.expressions.add (current);
-                current_parent.expressions.@set (i, opp);
-                current = opp;
-              }
-            }
-            if (current is Polynomial) { // FIXME: Add the concept of term
-              current.expressions.add (opp);
-              current_parent = current;
-              current = opp;
-            }
+          } else if (current_parent is Polynomial && current is Term) {
+            current.expressions.add (opp);
+            top_parent = current_parent;
+            current_parent = current;
+            current = opp;
+          } else if (current is Constant && 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;
           }
           break;
         case Vala.TokenType.DIV:
@@ -247,8 +237,11 @@ public class GCalc.Parser : Object {
             expa.expressions.add (current);
             var exp = new GPolynomial ();
             expa.expressions.add (exp);
-            current = exp;
-            current_parent = expa;
+            var t = new GTerm ();
+            exp.expressions.add (t);
+            current = t;
+            current_parent = t;
+            top_parent = exp;
             expected.clear ();
           }
           break;
@@ -319,7 +312,6 @@ public class GCalc.Parser : Object {
         // Hash
         case Vala.TokenType.HASH:
           throw new ParserError.INVALID_TOKEN_ERROR ("Found an unexpected expression");
-          break;
       }
     }
     eqman.equations.add (eq);
diff --git a/gcalc/gcalc-term.vala b/gcalc/gcalc-term.vala
new file mode 100644
index 00000000..db11643b
--- /dev/null
+++ b/gcalc/gcalc-term.vala
@@ -0,0 +1,22 @@
+/* gcalc-term.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.Term : Object, Expression {}
+
diff --git a/gcalc/meson.build b/gcalc/meson.build
index f80f82f0..e9351bc2 100644
--- a/gcalc/meson.build
+++ b/gcalc/meson.build
@@ -57,6 +57,7 @@ sources = files([
        'gcalc-gpolynomial.vala',
        'gcalc-gresult.vala',
        'gcalc-gsolver.vala',
+       'gcalc-gterm.vala',
        'gcalc-gvariable.vala',
        'gcalc-math-equation.vala',
        'gcalc-math-equation-manager.vala',
@@ -66,6 +67,7 @@ sources = files([
        'gcalc-polynomial.vala',
        'gcalc-result.vala',
        'gcalc-solver.vala',
+       'gcalc-term.vala',
        'gcalc-variable.vala',
 ])
 
diff --git a/tests/gcalc-main-interfaces.vala b/tests/gcalc-main-interfaces.vala
index 6e4c3731..99d43475 100644
--- a/tests/gcalc-main-interfaces.vala
+++ b/tests/gcalc-main-interfaces.vala
@@ -36,7 +36,10 @@ class Tests {
         var p = eq.expressions.get_item (0) as Polynomial;
         assert (p != null);
         assert (p.expressions.get_n_items () == 1);
-        var c = p.expressions.get_item (0) as Constant;
+        var t = p.expressions.get_item (0) as Term;
+        assert (t != null);
+        assert (t.expressions.get_n_items () == 1);
+        var c = t.expressions.get_item (0) as Constant;
         assert (c != null);
       } catch (GLib.Error error) {
         warning ("Error: %s", error.message);
@@ -55,7 +58,10 @@ class Tests {
         var p = eq.expressions.get_item (0) as Polynomial;
         assert (p != null);
         assert (p.expressions.get_n_items () == 1);
-        var c = p.expressions.get_item (0) as Constant;
+        var t = p.expressions.get_item (0) as Term;
+        assert (t != null);
+        assert (t.expressions.get_n_items () == 1);
+        var c = t.expressions.get_item (0) as Constant;
         assert (c != null);
       } catch (GLib.Error error) {
         warning ("Error: %s", error.message);
@@ -91,7 +97,10 @@ class Tests {
         var p = assign.expressions.get_item (1) as Polynomial;
         assert (p != null);
         assert (p.expressions.get_n_items () == 1);
-        var c = p.expressions.get_item (0) as Constant;
+        var t = p.expressions.get_item (0) as Term;
+        assert (t != null);
+        assert (t.expressions.get_n_items () == 1);
+        var c = t.expressions.get_item (0) as Constant;
         assert (c != null);
       } catch (GLib.Error error) {
         warning ("Error: %s", error.message);
@@ -108,14 +117,19 @@ class Tests {
         assert (eq != null);
         assert (eq.expressions.get_n_items () == 1);
         var p = eq.expressions.get_item (0) as Polynomial;
-        assert (p.expressions.get_n_items () == 1);
-        message ("%s", p.expressions.get_item (0).get_type ().name ());
-        var plus = p.expressions.get_item (0) as Plus;
-        assert (plus != null);
-        assert (plus.expressions.get_n_items () == 2);
-        var c1 = plus.expressions.get_item (0) as Constant;
+        assert (p != null);
+        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 () == 1);
+        var c1 = t1.expressions.get_item (0) as Constant;
         assert (c1 != null);
-        var c2 = plus.expressions.get_item (1) as Constant;
+        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 Constant;
         assert (c2 != null);
       } catch (GLib.Error error) {
         warning ("Error: %s", error.message);


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