[gnome-calculator/60-split-out-a-backend-library] gcalc: implemented evaluating function in a term



commit 991e57c1ed038e000f11dec0e337ab401f0ac661
Author: Daniel Espinosa Ortiz <esodan gmail com>
Date:   Fri Jan 4 17:45:27 2019 -0600

    gcalc: implemented evaluating function in a term

 gcalc/gcalc-gfunction.vala     |  14 ++-
 gcalc/gcalc-parser.vala        |   8 +-
 gcalc/gcalc-term.vala          |  12 ++-
 tests/gcalc-solving-basic.vala | 210 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 240 insertions(+), 4 deletions(-)
---
diff --git a/gcalc/gcalc-gfunction.vala b/gcalc/gcalc-gfunction.vala
index 34eabbd1..b2d1ba93 100644
--- a/gcalc/gcalc-gfunction.vala
+++ b/gcalc/gcalc-gfunction.vala
@@ -34,7 +34,19 @@ public class GCalc.GFunction : GExpression, Function {
     n_params = nparams;
   }
   public override string to_string () {
-    return name + "()";
+    string s = name + "(";
+    for (uint i = 0; i < expressions.get_n_items (); i++) {
+      var e = expressions.get_item (i) as Expression;
+      if (e == null) {
+        continue;
+      }
+      s += e.to_string ();
+      if (i + 1 < expressions.get_n_items ()) {
+        s += ",";
+      }
+    }
+    s += ")";
+    return s;
   }
 
   public new virtual Expression evaluate () throws GLib.Error {
diff --git a/gcalc/gcalc-parser.vala b/gcalc/gcalc-parser.vala
index 2e82a72c..07a1acfe 100644
--- a/gcalc/gcalc-parser.vala
+++ b/gcalc/gcalc-parser.vala
@@ -140,6 +140,10 @@ public class GCalc.Parser : Object {
               top_parent = exp;
               expected.clear ();
               expected.add(Vala.TokenType.OPEN_PARENS);
+            } else if (current is Operator && current_parent is Term && top_parent is Polynomial) {
+                current_parent.expressions.add (sfunc);
+                current = sfunc;
+                expected.clear ();
             }
           } else if (n.down () == "def" && current == null) {
             // FIXME: implement function definition
@@ -379,7 +383,7 @@ public class GCalc.Parser : Object {
       current = opp;
       current_parent = t;
       expected.clear ();
-    } else if (current is Group && current_parent is Term && top_parent is Polynomial) {
+    } else if ((current is Group || current is Function) && current_parent is Term && top_parent is 
Polynomial) {
       // New term
       var t = new GTerm ();
       t.expressions.add (opp);
@@ -408,7 +412,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 || current is Group)
+    if ((current is Constant || current is Variable || current is Group || current is Function)
         && 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 a1cf009b..6cc3e136 100644
--- a/gcalc/gcalc-term.vala
+++ b/gcalc/gcalc-term.vala
@@ -64,7 +64,17 @@ public interface GCalc.Term : Object, Expression {
         if (current == null) {
           current = ev;
           first = false;
-        } else if (current is Constant&& ev is Constant) {
+        } else if (current is Constant && ev is Constant) {
+          if (current_operator != null) {
+            current = evaluate_constants ((Constant) current, (Constant) ev, current_operator);
+          }
+        }
+      } else if (e is Function) {
+        var ev = ((Function) e).evaluate ();
+        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);
           }
diff --git a/tests/gcalc-solving-basic.vala b/tests/gcalc-solving-basic.vala
index e693d712..0983c14a 100644
--- a/tests/gcalc-solving-basic.vala
+++ b/tests/gcalc-solving-basic.vala
@@ -700,6 +700,216 @@ class Tests {
         warning ("Error: %s", e.message);
       }
     });
+    Test.add_func ("/gcalc/solve/function/unique/evaluated-polynomial",
+    ()=>{
+      try {
+        var parser = new Parser ();
+        var eqman = new GMathEquationManager ();
+        parser.parse ("sin(0)", 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 () == 0.0);
+      } catch (GLib.Error e) {
+        warning ("Error: %s", e.message);
+      }
+    });
+    Test.add_func ("/gcalc/solve/function/term/mul",
+    ()=>{
+      try {
+        var parser = new Parser ();
+        var eqman = new GMathEquationManager ();
+        parser.parse ("cos(0)*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 () == 3.0);
+      } catch (GLib.Error e) {
+        warning ("Error: %s", e.message);
+      }
+    });
+    Test.add_func ("/gcalc/solve/function/term/mul-inv",
+    ()=>{
+      try {
+        var parser = new Parser ();
+        var eqman = new GMathEquationManager ();
+        parser.parse ("3*cos(0)", 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 () == 3.0);
+      } catch (GLib.Error e) {
+        warning ("Error: %s", e.message);
+      }
+    });
+    Test.add_func ("/gcalc/solve/function/term/div",
+    ()=>{
+      try {
+        var parser = new Parser ();
+        var eqman = new GMathEquationManager ();
+        parser.parse ("3/cos(0)", 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 () == 3.0);
+      } catch (GLib.Error e) {
+        warning ("Error: %s", e.message);
+      }
+    });
+    Test.add_func ("/gcalc/solve/function/term/div-inv",
+    ()=>{
+      try {
+        var parser = new Parser ();
+        var eqman = new GMathEquationManager ();
+        parser.parse ("cos(0)/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 () == 1.0);
+      } catch (GLib.Error e) {
+        warning ("Error: %s", e.message);
+      }
+    });
+    Test.add_func ("/gcalc/solve/function/polynomial",
+    ()=>{
+      try {
+        var parser = new Parser ();
+        var eqman = new GMathEquationManager ();
+        parser.parse ("cos(0)+4", 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 () == 5.0);
+      } catch (GLib.Error e) {
+        warning ("Error: %s", e.message);
+      }
+    });
+    Test.add_func ("/gcalc/solve/function/polynomial-inv",
+    ()=>{
+      try {
+        var parser = new Parser ();
+        var eqman = new GMathEquationManager ();
+        parser.parse ("4+cos(0)", 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 () == 5.0);
+      } catch (GLib.Error e) {
+        warning ("Error: %s", e.message);
+      }
+    });
+    Test.add_func ("/gcalc/solve/function/polynomial/functions",
+    ()=>{
+      try {
+        var parser = new Parser ();
+        var eqman = new GMathEquationManager ();
+        parser.parse ("cos(0)+sin(0)", 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 () == 1.0);
+      } catch (GLib.Error e) {
+        warning ("Error: %s", e.message);
+      }
+    });
+    Test.add_func ("/gcalc/solve/function/polynomial/constan+func",
+    ()=>{
+      try {
+        var parser = new Parser ();
+        var eqman = new GMathEquationManager ();
+        parser.parse ("1+cos(0)", 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 () == 2.0);
+      } catch (GLib.Error e) {
+        warning ("Error: %s", e.message);
+      }
+    });
+    Test.add_func ("/gcalc/solve/function/polynomial/constan-func",
+    ()=>{
+      try {
+        var parser = new Parser ();
+        var eqman = new GMathEquationManager ();
+        parser.parse ("4-cos(0)", 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 () == 3.0);
+      } catch (GLib.Error e) {
+        warning ("Error: %s", e.message);
+      }
+    });
+    Test.add_func ("/gcalc/solve/function/polynomial/complex",
+    ()=>{
+      try {
+        var parser = new Parser ();
+        var eqman = new GMathEquationManager ();
+        parser.parse ("9/3+5+2*cos(0)-9/cos(0)", eqman);
+        assert (eqman.equations.get_n_items () == 1);
+        var eq = eqman.equations.get_item (0) as MathEquation;
+        assert (eq != null);
+        message ("Equation: %s", eq.to_string ());
+        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 () == 10.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]