[gnome-calculator/60-split-out-a-backend-library] gcalc: implement Variable evaluation



commit 8098aba02904475d911ce11a4927a0beb80655b3
Author: Daniel Espinosa Ortiz <esodan gmail com>
Date:   Sat Jan 5 23:18:29 2019 -0600

    gcalc: implement Variable evaluation

 gcalc/gcalc-assign.vala        | 26 ++++++++++++++++++++-
 gcalc/gcalc-gvariable.vala     |  5 ++--
 gcalc/gcalc-variable.vala      | 26 ++++++++++++++++++++-
 tests/gcalc-solving-basic.vala | 52 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 104 insertions(+), 5 deletions(-)
---
diff --git a/gcalc/gcalc-assign.vala b/gcalc/gcalc-assign.vala
index 3aa81630..11d9dba3 100644
--- a/gcalc/gcalc-assign.vala
+++ b/gcalc/gcalc-assign.vala
@@ -18,5 +18,29 @@
  * Authors:
  *      Daniel Espinosa <esodan gmail com>
  */
-public interface GCalc.Assign : Object, Expression, Operator, BinaryOperator {}
+public interface GCalc.Assign : Object, Expression, Operator, BinaryOperator {
+  public Expression evaluate () throws GLib.Error {
+    if (expressions.get_n_items () != 2) {
+      throw new AssigError.INVALID_STRUCTURE_ERROR ("Invalid number of expressions in assign");
+    }
+    var v = expressions.get_item (0) as Variable;
+    if (v == null) {
+      throw new AssigError.INVALID_STRUCTURE_ERROR ("Invalid variable object in assign");
+    }
+    var p = expressions.get_item (1) as Polynomial;
+    if (p == null) {
+      throw new AssigError.INVALID_STRUCTURE_ERROR ("Invalid polynomial object in assign");
+    }
+    var ca = p.evaluate () as Constant;
+    if (ca == null) {
+      throw new AssigError.INVALID_STRUCTURE_ERROR ("Invalid polynomial evaluation in assign; should a 
constant no Variable update was done");
+    }
+    v.@value = ca;
+    return v.@value;
+  }
+}
+
+public errordomain GCalc.AssigError {
+  INVALID_STRUCTURE_ERROR
+}
 
diff --git a/gcalc/gcalc-gvariable.vala b/gcalc/gcalc-gvariable.vala
index 4257a066..30329b1c 100644
--- a/gcalc/gcalc-gvariable.vala
+++ b/gcalc/gcalc-gvariable.vala
@@ -19,13 +19,12 @@
  *      Daniel Espinosa <esodan gmail com>
  */
 public class GCalc.GVariable : GExpression, Variable, Hashable {
-  private GLib.Value _value;
 
   public string name { get; construct set; }
-  public GLib.Value value { get { return _value; } }
+  public Constant value { get; set; }
 
   construct {
-    _value = GLib.Value (GLib.Type.DOUBLE);
+    _value = new GConstant.@double (0.0);
   }
   public GVariable (string name) {
     this.name = name;
diff --git a/gcalc/gcalc-variable.vala b/gcalc/gcalc-variable.vala
index 46b0bd5e..a427a89f 100644
--- a/gcalc/gcalc-variable.vala
+++ b/gcalc/gcalc-variable.vala
@@ -20,6 +20,30 @@
  */
 public interface GCalc.Variable : Object, Expression {
   public abstract string name { get; construct set; }
-  public abstract GLib.Value value { get; }
+  public abstract Constant @value { get; set; }
+  public virtual Expression evaluate () throws GLib.Error {
+    if (parent == null) {
+      throw new VariableError.INVALID_PARENT ("Can't access to Variable's expression definition. Invalid 
parent. Expected Assign operator");
+    }
+    if (parent.expressions.get_n_items () != 2) {
+      throw new VariableError.INVALID_EXPRESSION_DEFINITION ("Can't access to Variable's expression 
definition. Expression not found");
+    }
+    var e = parent.expressions.get_item (1) as Polynomial;
+    if (e == null) {
+      throw new VariableError.INVALID_EXPRESSION_DEFINITION ("Can't access to Variable's expression 
definition. Unexpected object type");
+    }
+    var exp = e.evaluate () as Constant;
+    if (exp == null) {
+      throw new VariableError.EVALUATION_FAIL ("Variable evaluation fail. Variable's value not updated");
+    }
+    @value = exp;
+    return exp;
+  }
+}
+
+public errordomain GCalc.VariableError {
+  INVALID_PARENT,
+  INVALID_EXPRESSION_DEFINITION,
+  EVALUATION_FAIL
 }
 
diff --git a/tests/gcalc-solving-basic.vala b/tests/gcalc-solving-basic.vala
index 267f91b4..7fd57746 100644
--- a/tests/gcalc-solving-basic.vala
+++ b/tests/gcalc-solving-basic.vala
@@ -1030,6 +1030,58 @@ class Tests {
         warning ("Error: %s", e.message);
       }
     });
+    Test.add_func ("/gcalc/solve/variable/constant",
+    ()=>{
+      try {
+        var parser = new GParser ();
+        var eqman = new GMathEquationManager ();
+        parser.parse ("x=3", eqman);
+        assert (eqman.equations.get_n_items () == 1);
+        var eq = eqman.equations.get_item (0) as MathEquation;
+        assert (eq != null);
+        var a = eq.expressions.get_item (0) as Assign;
+        assert (a != null);
+        var res1 = a.evaluate () as Constant;
+        assert (res1 != null);
+        message ("Constant Result: %s", res1.to_string ());
+        assert (res1.real () == 3.0);
+        assert (a.expressions.get_n_items () == 2);
+        var v = a.expressions.get_item (0) as Variable;
+        assert (v != null);
+        var res2 = v.evaluate () as Constant;
+        assert (res2 != null);
+        message ("Constant Result: %s", res2.to_string ());
+        assert (res2.real () == 3.0);
+      } catch (GLib.Error e) {
+        warning ("Error: %s", e.message);
+      }
+    });
+    Test.add_func ("/gcalc/solve/variable/complex/polynomial",
+    ()=>{
+      try {
+        var parser = new GParser ();
+        var eqman = new GMathEquationManager ();
+        parser.parse ("x=3*4/cos(0)+(4+5)/(1+sin(0))*4", eqman);
+        assert (eqman.equations.get_n_items () == 1);
+        var eq = eqman.equations.get_item (0) as MathEquation;
+        assert (eq != null);
+        var a = eq.expressions.get_item (0) as Assign;
+        assert (a != null);
+        var res1 = a.evaluate () as Constant;
+        assert (res1 != null);
+        message ("Constant Result: %s", res1.to_string ());
+        assert (res1.real () == 48.0);
+        assert (a.expressions.get_n_items () == 2);
+        var v = a.expressions.get_item (0) as Variable;
+        assert (v != null);
+        var res2 = v.evaluate () as Constant;
+        assert (res2 != null);
+        message ("Constant Result: %s", res2.to_string ());
+        assert (res2.real () == 48.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]