[gnome-calculator/60-split-out-a-backend-library] gcalc: implemented parse contant sums



commit 5f7670267d2c3230103b8038c645515752a671eb
Author: Daniel Espinosa Ortiz <esodan gmail com>
Date:   Wed Jan 2 18:20:00 2019 -0600

    gcalc: implemented parse contant sums

 gcalc/gcalc-assign.vala          |  2 +-
 gcalc/gcalc-binary-operator.vala | 22 ++++++++++++++++
 gcalc/gcalc-gassign.vala         |  2 +-
 gcalc/gcalc-gplus.vala           | 26 +++++++++++++++++++
 gcalc/gcalc-operator.vala        | 22 ++++++++++++++++
 gcalc/gcalc-parser.vala          | 56 ++++++++++++++++++++++++++++++++++++++--
 gcalc/gcalc-plus.vala            | 22 ++++++++++++++++
 gcalc/meson.build                |  4 +++
 tests/gcalc-main-interfaces.vala | 26 ++++++++++++++++++-
 9 files changed, 177 insertions(+), 5 deletions(-)
---
diff --git a/gcalc/gcalc-assign.vala b/gcalc/gcalc-assign.vala
index 97495ebe..3aa81630 100644
--- a/gcalc/gcalc-assign.vala
+++ b/gcalc/gcalc-assign.vala
@@ -18,5 +18,5 @@
  * Authors:
  *      Daniel Espinosa <esodan gmail com>
  */
-public interface GCalc.Assign : Object, Expression {}
+public interface GCalc.Assign : Object, Expression, Operator, BinaryOperator {}
 
diff --git a/gcalc/gcalc-binary-operator.vala b/gcalc/gcalc-binary-operator.vala
new file mode 100644
index 00000000..4541fac6
--- /dev/null
+++ b/gcalc/gcalc-binary-operator.vala
@@ -0,0 +1,22 @@
+/* gcalc-binary-operator.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.BinaryOperator : Object, Expression, Operator {}
+
diff --git a/gcalc/gcalc-gassign.vala b/gcalc/gcalc-gassign.vala
index d69f691b..a11068de 100644
--- a/gcalc/gcalc-gassign.vala
+++ b/gcalc/gcalc-gassign.vala
@@ -18,7 +18,7 @@
  * Authors:
  *      Daniel Espinosa <esodan gmail com>
  */
-public class GCalc.GAssign : GExpression, Assign {
+public class GCalc.GAssign : GExpression, Operator, BinaryOperator, Assign {
   public override string to_string () {
     return "=";
   }
diff --git a/gcalc/gcalc-gplus.vala b/gcalc/gcalc-gplus.vala
new file mode 100644
index 00000000..1ceb031f
--- /dev/null
+++ b/gcalc/gcalc-gplus.vala
@@ -0,0 +1,26 @@
+/* gcalc-gplus.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.GPlus : GExpression, Operator, BinaryOperator, Plus {
+  public override string to_string () {
+    return "*";
+  }
+}
+
diff --git a/gcalc/gcalc-operator.vala b/gcalc/gcalc-operator.vala
new file mode 100644
index 00000000..a41b8d88
--- /dev/null
+++ b/gcalc/gcalc-operator.vala
@@ -0,0 +1,22 @@
+/* gcalc-operator.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.Operator : Object, Expression {}
+
diff --git a/gcalc/gcalc-parser.vala b/gcalc/gcalc-parser.vala
index 2ccd9948..d8b6f8fa 100644
--- a/gcalc/gcalc-parser.vala
+++ b/gcalc/gcalc-parser.vala
@@ -149,12 +149,19 @@ public class GCalc.Parser : Object {
               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 Polynomial) {
+              if (current is Polynomial && current.expressions.get_n_items () == 0) {
                 current.expressions.add (v);
                 current = v;
                 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");
               }
             }
           }
@@ -173,13 +180,57 @@ public class GCalc.Parser : Object {
           if (current is Polynomial) {
             current.expressions.add (iexp);
             expected.clear ();
+            current_parent = current;
             current = iexp;
           }
+          if (current is BinaryOperator) {
+            current.expressions.add (iexp);
+            current = current_parent;
+          }
           break;
+        case Vala.TokenType.PERCENT:
         case Vala.TokenType.CHARACTER_LITERAL:
+          break;
         case Vala.TokenType.STAR:
-        case Vala.TokenType.PERCENT:
+          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 ();
+            current = opp;
+            exp.expressions.add (opp);
+            current_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;
+            }
+          }
+          break;
         case Vala.TokenType.DIV:
         case Vala.TokenType.MINUS:
           break;
@@ -267,6 +318,7 @@ public class GCalc.Parser : Object {
         case Vala.TokenType.INTERR:
         // Hash
         case Vala.TokenType.HASH:
+          throw new ParserError.INVALID_TOKEN_ERROR ("Found an unexpected expression");
           break;
       }
     }
diff --git a/gcalc/gcalc-plus.vala b/gcalc/gcalc-plus.vala
new file mode 100644
index 00000000..f52c0acc
--- /dev/null
+++ b/gcalc/gcalc-plus.vala
@@ -0,0 +1,22 @@
+/* gcalc-plus.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.Plus : Object, Expression, Operator, BinaryOperator {}
+
diff --git a/gcalc/meson.build b/gcalc/meson.build
index 92fee1ee..f80f82f0 100644
--- a/gcalc/meson.build
+++ b/gcalc/meson.build
@@ -40,6 +40,7 @@ configure_file(output : 'config.h',
 
 sources = files([
        'gcalc-assign.vala',
+       'gcalc-binary-operator.vala',
        'gcalc-constant.vala',
        'gcalc-expression.vala',
        'gcalc-expression-container.vala',
@@ -52,13 +53,16 @@ sources = files([
        'gcalc-gfunction.vala',
        'gcalc-gmath-equation.vala',
        'gcalc-gmath-equation-manager.vala',
+       'gcalc-gplus.vala',
        'gcalc-gpolynomial.vala',
        'gcalc-gresult.vala',
        'gcalc-gsolver.vala',
        'gcalc-gvariable.vala',
        'gcalc-math-equation.vala',
        'gcalc-math-equation-manager.vala',
+       'gcalc-operator.vala',
        'gcalc-parser.vala',
+       'gcalc-plus.vala',
        'gcalc-polynomial.vala',
        'gcalc-result.vala',
        'gcalc-solver.vala',
diff --git a/tests/gcalc-main-interfaces.vala b/tests/gcalc-main-interfaces.vala
index 6633160a..6e4c3731 100644
--- a/tests/gcalc-main-interfaces.vala
+++ b/tests/gcalc-main-interfaces.vala
@@ -72,7 +72,7 @@ class Tests {
         message ("Error catched correctly: %s", error.message);
       }
     });
-    Test.add_func ("/gcalc/parser/constant/variable",
+    Test.add_func ("/gcalc/parser/assign/variable/constant",
     ()=>{
       try {
         var parser = new Parser ();
@@ -97,6 +97,30 @@ class Tests {
         warning ("Error: %s", error.message);
       }
     });
+    Test.add_func ("/gcalc/parser/binaryoperator/plus/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.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 (c1 != null);
+        var c2 = plus.expressions.get_item (1) as Constant;
+        assert (c2 != 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]