[gnome-calculator/60-split-out-a-backend-library] gcalc: improving evaluation/solving error generation



commit 994c359a329747c135f3d045530f91981178e871
Author: Daniel Espinosa Ortiz <esodan gmail com>
Date:   Sun Jan 6 11:10:47 2019 -0600

    gcalc: improving evaluation/solving error generation
    
    * Fixed variable assignment evaluation from expression with
      variables

 gcalc/gcalc-error-result.vala   |   4 +-
 gcalc/gcalc-function-acos.vala  |   2 +-
 gcalc/gcalc-function-acosh.vala |   2 +-
 gcalc/gcalc-function-asin.vala  |   2 +-
 gcalc/gcalc-function-asinh.vala |   2 +-
 gcalc/gcalc-function-atan.vala  |   2 +-
 gcalc/gcalc-function-atanh.vala |   2 +-
 gcalc/gcalc-function-cos.vala   |   2 +-
 gcalc/gcalc-function-cosh.vala  |   2 +-
 gcalc/gcalc-function-exp.vala   |   2 +-
 gcalc/gcalc-function-log.vala   |   2 +-
 gcalc/gcalc-function-sin.vala   |   2 +-
 gcalc/gcalc-function-sinh.vala  |   2 +-
 gcalc/gcalc-function-sqrt.vala  |   2 +-
 gcalc/gcalc-function-tan.vala   |   2 +-
 gcalc/gcalc-function-tanh.vala  |   2 +-
 gcalc/gcalc-gassign.vala        |  16 +++-
 gcalc/gcalc-gerror-result.vala  |  10 ++-
 gcalc/gcalc-gexpression.vala    |   3 +-
 gcalc/gcalc-gmath-equation.vala |   6 +-
 gcalc/gcalc-gparser.vala        |   5 +-
 gcalc/gcalc-gpolynomial.vala    |   3 +-
 gcalc/gcalc-gresult.vala        |   9 ---
 gcalc/gcalc-gsolver.vala        |   9 +--
 gcalc/gcalc-gterm.vala          |   3 +-
 gcalc/gcalc-polynomial.vala     |   6 --
 gcalc/gcalc-result.vala         |   2 -
 gcalc/gcalc-term.vala           |  18 +----
 gcalc/gcalc-variable.vala       |   3 +
 tests/gcalc-parsing.vala        |  70 +++++++++++++++++
 tests/gcalc-solving-basic.vala  | 169 ++++++++++++++++++++++++++++++++++++++--
 31 files changed, 285 insertions(+), 81 deletions(-)
---
diff --git a/gcalc/gcalc-error-result.vala b/gcalc/gcalc-error-result.vala
index c4fef72c..365c3d54 100644
--- a/gcalc/gcalc-error-result.vala
+++ b/gcalc/gcalc-error-result.vala
@@ -18,7 +18,7 @@
  * Authors:
  *      Daniel Espinosa <esodan gmail com>
  */
-public interface GCalc.ErrorResult : Object {
-  public abstract string to_string ();
+public interface GCalc.ErrorResult : Object, Result {
+  public abstract string message { get; }
 }
 
diff --git a/gcalc/gcalc-function-acos.vala b/gcalc/gcalc-function-acos.vala
index 98197443..4cdeac66 100644
--- a/gcalc/gcalc-function-acos.vala
+++ b/gcalc/gcalc-function-acos.vala
@@ -36,7 +36,7 @@ public class GCalc.GFunctionAcos : GFunction {
     }
     var ev = exp.solve ();
     if (ev is ErrorResult) {
-       throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).to_string ());
+       throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).message);
     }
     if (ev is Result) {
       c = ((Result) ev).expression as GConstant;
diff --git a/gcalc/gcalc-function-acosh.vala b/gcalc/gcalc-function-acosh.vala
index fd0121ad..00d39d0d 100644
--- a/gcalc/gcalc-function-acosh.vala
+++ b/gcalc/gcalc-function-acosh.vala
@@ -36,7 +36,7 @@ public class GCalc.GFunctionAcosh : GFunction {
     }
     var ev = exp.solve ();
     if (ev is ErrorResult) {
-       throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).to_string ());
+       throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).message);
     }
     if (ev is Result) {
       c = ((Result) ev).expression as GConstant;
diff --git a/gcalc/gcalc-function-asin.vala b/gcalc/gcalc-function-asin.vala
index b35a75c6..a8d9ce27 100644
--- a/gcalc/gcalc-function-asin.vala
+++ b/gcalc/gcalc-function-asin.vala
@@ -36,7 +36,7 @@ public class GCalc.GFunctionAsin : GFunction {
     }
     var ev = exp.solve ();
     if (ev is ErrorResult) {
-       throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).to_string ());
+       throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).message);
     }
     if (ev is Result) {
       c = ((Result) ev).expression as GConstant;
diff --git a/gcalc/gcalc-function-asinh.vala b/gcalc/gcalc-function-asinh.vala
index ffca07dc..4bcbf877 100644
--- a/gcalc/gcalc-function-asinh.vala
+++ b/gcalc/gcalc-function-asinh.vala
@@ -36,7 +36,7 @@ public class GCalc.GFunctionAsinh : GFunction {
     }
     var ev = exp.solve ();
     if (ev is ErrorResult) {
-       throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).to_string ());
+       throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).message);
     }
     if (ev is Result) {
       c = ((Result) ev).expression as GConstant;
diff --git a/gcalc/gcalc-function-atan.vala b/gcalc/gcalc-function-atan.vala
index e38a7301..5af108b5 100644
--- a/gcalc/gcalc-function-atan.vala
+++ b/gcalc/gcalc-function-atan.vala
@@ -36,7 +36,7 @@ public class GCalc.GFunctionAtan : GFunction {
     }
     var ev = exp.solve ();
     if (ev is ErrorResult) {
-       throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).to_string ());
+       throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).message);
     }
     if (ev is Result) {
       c = ((Result) ev).expression as GConstant;
diff --git a/gcalc/gcalc-function-atanh.vala b/gcalc/gcalc-function-atanh.vala
index f0901865..2bc32229 100644
--- a/gcalc/gcalc-function-atanh.vala
+++ b/gcalc/gcalc-function-atanh.vala
@@ -36,7 +36,7 @@ public class GCalc.GFunctionAtanh : GFunction {
     }
     var ev = exp.solve ();
     if (ev is ErrorResult) {
-       throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).to_string ());
+       throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).message);
     }
     if (ev is Result) {
       c = ((Result) ev).expression as GConstant;
diff --git a/gcalc/gcalc-function-cos.vala b/gcalc/gcalc-function-cos.vala
index 7cc336cf..ab5828e1 100644
--- a/gcalc/gcalc-function-cos.vala
+++ b/gcalc/gcalc-function-cos.vala
@@ -36,7 +36,7 @@ public class GCalc.GFunctionCos : GFunction {
     }
     var ev = exp.solve ();
     if (ev is ErrorResult) {
-       throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).to_string ());
+       throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).message);
     }
     if (ev is Result) {
       c = ((Result) ev).expression as GConstant;
diff --git a/gcalc/gcalc-function-cosh.vala b/gcalc/gcalc-function-cosh.vala
index beb7a81a..e051ce82 100644
--- a/gcalc/gcalc-function-cosh.vala
+++ b/gcalc/gcalc-function-cosh.vala
@@ -36,7 +36,7 @@ public class GCalc.GFunctionCosh : GFunction {
     }
     var ev = exp.solve ();
     if (ev is ErrorResult) {
-       throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).to_string ());
+       throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).message);
     }
     if (ev is Result) {
       c = ((Result) ev).expression as GConstant;
diff --git a/gcalc/gcalc-function-exp.vala b/gcalc/gcalc-function-exp.vala
index 135d04e7..1cf135b1 100644
--- a/gcalc/gcalc-function-exp.vala
+++ b/gcalc/gcalc-function-exp.vala
@@ -36,7 +36,7 @@ public class GCalc.GFunctionExp : GFunction {
     }
     var ev = exp.solve ();
     if (ev is ErrorResult) {
-       throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).to_string ());
+       throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).message);
     }
     if (ev is Result) {
       c = ((Result) ev).expression as GConstant;
diff --git a/gcalc/gcalc-function-log.vala b/gcalc/gcalc-function-log.vala
index 36a33ab8..de57efe8 100644
--- a/gcalc/gcalc-function-log.vala
+++ b/gcalc/gcalc-function-log.vala
@@ -36,7 +36,7 @@ public class GCalc.GFunctionLog : GFunction {
     }
     var ev = exp.solve ();
     if (ev is ErrorResult) {
-       throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).to_string ());
+       throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).message);
     }
     if (ev is Result) {
       c = ((Result) ev).expression as GConstant;
diff --git a/gcalc/gcalc-function-sin.vala b/gcalc/gcalc-function-sin.vala
index f16c3c6c..5a288a0b 100644
--- a/gcalc/gcalc-function-sin.vala
+++ b/gcalc/gcalc-function-sin.vala
@@ -36,7 +36,7 @@ public class GCalc.GFunctionSin : GFunction {
     }
     var ev = exp.solve ();
     if (ev is ErrorResult) {
-       throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).to_string ());
+       throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).message);
     }
     if (ev is Result) {
       c = ((Result) ev).expression as GConstant;
diff --git a/gcalc/gcalc-function-sinh.vala b/gcalc/gcalc-function-sinh.vala
index 30ef98eb..92c796ef 100644
--- a/gcalc/gcalc-function-sinh.vala
+++ b/gcalc/gcalc-function-sinh.vala
@@ -36,7 +36,7 @@ public class GCalc.GFunctionSinh : GFunction {
     }
     var ev = exp.solve ();
     if (ev is ErrorResult) {
-       throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).to_string ());
+       throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).message);
     }
     if (ev is Result) {
       c = ((Result) ev).expression as GConstant;
diff --git a/gcalc/gcalc-function-sqrt.vala b/gcalc/gcalc-function-sqrt.vala
index 9dfd72ca..0291cd8f 100644
--- a/gcalc/gcalc-function-sqrt.vala
+++ b/gcalc/gcalc-function-sqrt.vala
@@ -36,7 +36,7 @@ public class GCalc.GFunctionSqrt : GFunction {
     }
     var ev = exp.solve ();
     if (ev is ErrorResult) {
-       throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).to_string ());
+       throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).message);
     }
     if (ev is Result) {
       c = ((Result) ev).expression as GConstant;
diff --git a/gcalc/gcalc-function-tan.vala b/gcalc/gcalc-function-tan.vala
index 0e74db06..3793076b 100644
--- a/gcalc/gcalc-function-tan.vala
+++ b/gcalc/gcalc-function-tan.vala
@@ -36,7 +36,7 @@ public class GCalc.GFunctionTan : GFunction {
     }
     var ev = exp.solve ();
     if (ev is ErrorResult) {
-       throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).to_string ());
+       throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).message);
     }
     if (ev is Result) {
       c = ((Result) ev).expression as GConstant;
diff --git a/gcalc/gcalc-function-tanh.vala b/gcalc/gcalc-function-tanh.vala
index 8c34ed0d..831157ba 100644
--- a/gcalc/gcalc-function-tanh.vala
+++ b/gcalc/gcalc-function-tanh.vala
@@ -36,7 +36,7 @@ public class GCalc.GFunctionTanh : GFunction {
     }
     var ev = exp.solve ();
     if (ev is ErrorResult) {
-       throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).to_string ());
+       throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).message);
     }
     if (ev is Result) {
       c = ((Result) ev).expression as GConstant;
diff --git a/gcalc/gcalc-gassign.vala b/gcalc/gcalc-gassign.vala
index 4ecf7252..91bf4bd9 100644
--- a/gcalc/gcalc-gassign.vala
+++ b/gcalc/gcalc-gassign.vala
@@ -20,15 +20,25 @@
  */
 public class GCalc.GAssign : GExpression, Operator, BinaryOperator, Assign {
   public override string to_string () {
-    return "=";
+    if (expressions.get_n_items () != 2) {
+      return "Invalid Assigment structure";
+    }
+    var v = expressions.get_item (0) as Variable;
+    if (v == null) {
+      return "Invalid Assigment structure. No variable is set";
+    }
+    var e = expressions.get_item (1) as Expression;
+    if (e == null) {
+      return "Invalid Assigment structure. No variable's definition is set";
+    }
+    return v.to_string ()+"="+e.to_string ();
   }
   public override Result solve () {
     Result res = null;
     try {
       res = new GResult (evaluate ());
     } catch (GLib.Error e) {
-      var err = new GErrorResult ("Invalid expression");
-      return new GResult.with_error (new GErrorExpression (), err as ErrorResult);
+      res = new GErrorResult ("Invalid expression in Assignment: %s".printf (e.message));
     }
     return res;
   }
diff --git a/gcalc/gcalc-gerror-result.vala b/gcalc/gcalc-gerror-result.vala
index f99f1699..9cb43886 100644
--- a/gcalc/gcalc-gerror-result.vala
+++ b/gcalc/gcalc-gerror-result.vala
@@ -18,12 +18,18 @@
  * Authors:
  *      Daniel Espinosa <esodan gmail com>
  */
-public class GCalc.GErrorResult : Object, ErrorResult {
+public class GCalc.GErrorResult : Object, Result, ErrorResult {
   private string msg = "";
+  private Expression _expression;
+
   public GErrorResult (string msg) {
     this.msg = msg;
+    _expression = new GErrorExpression ();
   }
-  // ErrorResult
+  // Result
+  public Expression expression { get { return _expression; } }
   public string to_string () { return msg; }
+  // ErrorResult
+  public string message { get { return msg; } }
 }
 
diff --git a/gcalc/gcalc-gexpression.vala b/gcalc/gcalc-gexpression.vala
index 10685a8a..ea35587f 100644
--- a/gcalc/gcalc-gexpression.vala
+++ b/gcalc/gcalc-gexpression.vala
@@ -34,8 +34,7 @@ public class GCalc.GExpression : Object, Expression {
     return s;
   }
   public new virtual Result solve () {
-    var e = new GErrorResult ("Invalid expression");
-    return new GResult.with_error (new GErrorExpression (), e as ErrorResult);
+    return new GErrorResult ("Invalid expression");
   }
 }
 
diff --git a/gcalc/gcalc-gmath-equation.vala b/gcalc/gcalc-gmath-equation.vala
index 2dc1585c..50d1157f 100644
--- a/gcalc/gcalc-gmath-equation.vala
+++ b/gcalc/gcalc-gmath-equation.vala
@@ -24,13 +24,11 @@ public class GCalc.GMathEquation : GExpression, MathEquation {
   public override Result solve () {
     Result res = null;
     if (expressions.get_n_items () == 0) {
-      var err = new GErrorResult ("No expressions found in equation");
-      return new GResult.with_error ((Expression) new GErrorExpression (), (ErrorResult) err) as Result;
+      return new GErrorResult ("No expressions found in equation");
     }
     var e = expressions.get_item (0) as Expression;
     if (e == null) {
-      var err = new GErrorResult ("Invalid expression in equation");
-      return new GResult.with_error ((Expression) new GErrorExpression (), (ErrorResult) err) as Result;
+      res = new GErrorResult ("Invalid expression in equation");
     } else {
       res = e.solve ();
     }
diff --git a/gcalc/gcalc-gparser.vala b/gcalc/gcalc-gparser.vala
index c0eca992..e6918870 100644
--- a/gcalc/gcalc-gparser.vala
+++ b/gcalc/gcalc-gparser.vala
@@ -173,7 +173,6 @@ public class GCalc.GParser : Object {
               ((Variable) v).bind = sv;
             }
             if (current == null) {
-              message ("Trying to Add a polynomial in a variable");
               var exp = new GPolynomial ();
               eq.expressions.add (exp);
               var t = new GTerm ();
@@ -183,7 +182,6 @@ public class GCalc.GParser : Object {
               current_parent = v.parent;
               top_parent = current_parent.parent;
               expected.clear ();
-              message ("Created initial variable");
             } else if (current is Operator && current_parent is Term && top_parent is Polynomial) {
                 current_parent.expressions.add (v);
                 current = v;
@@ -193,6 +191,9 @@ public class GCalc.GParser : Object {
                 current = v;
                 current_parent = v.parent;
                 top_parent = current_parent.parent;
+                message (current.get_type ().name ());
+                message (current_parent.get_type ().name ());
+                message (top_parent.get_type ().name ());
                 expected.clear ();
             }
           }
diff --git a/gcalc/gcalc-gpolynomial.vala b/gcalc/gcalc-gpolynomial.vala
index fa038d81..aa232263 100644
--- a/gcalc/gcalc-gpolynomial.vala
+++ b/gcalc/gcalc-gpolynomial.vala
@@ -25,8 +25,7 @@ public class GCalc.GPolynomial : GExpression, Polynomial {
       var e = evaluate ();
       res = new GResult (e) as Result;
     } catch (GLib.Error err) {
-      var nerr = new GErrorResult (err.message);
-      res = new GResult.with_error ((Expression) new GErrorExpression (), (ErrorResult) nerr) as Result;
+      res = new GErrorResult ("Polynomial solving fails: %s".printf (err.message));
     }
     return res;
   }
diff --git a/gcalc/gcalc-gresult.vala b/gcalc/gcalc-gresult.vala
index 3d9998f4..20bd8369 100644
--- a/gcalc/gcalc-gresult.vala
+++ b/gcalc/gcalc-gresult.vala
@@ -20,22 +20,13 @@
  */
 public class GCalc.GResult : Object, Result {
   private Expression _expression;
-  private ErrorResult _error;
   public GResult (Expression exp) {
     _expression = exp;
-    _error = null;
   }
-  public GResult.with_error (Expression exp, ErrorResult error) {
-    _expression = exp;
-    _error = error;
-  }
-
   // Result
-  public bool is_valid { get { return _error == null; } }
   public string to_string () {
     return expression.to_string ();
   }
   public Expression expression { get { return _expression; } }
-  public ErrorResult error { get { return _error; } }
 }
 
diff --git a/gcalc/gcalc-gsolver.vala b/gcalc/gcalc-gsolver.vala
index 7ca51dc8..6694b8f5 100644
--- a/gcalc/gcalc-gsolver.vala
+++ b/gcalc/gcalc-gsolver.vala
@@ -32,18 +32,15 @@ public class GCalc.GSolver : Object, Solver {
     try {
       p.parse (str, equation_manager);
       if (equation_manager.equations.get_n_items () == 0) {
-        var err = new GErrorResult ("No equations found after parsing");
-        res = new GResult.with_error ((Expression) new GErrorExpression (), (ErrorResult) err) as Result;
+        return new GErrorResult ("No equations found after parsing");
       }
       var eq = equation_manager.equations.get_item (0) as MathEquation;
       if (eq == null) {
-        var err = new GErrorResult ("No equations found after parsing");
-        res = new GResult.with_error ((Expression) new GErrorExpression (), (ErrorResult) err) as Result;
+        return new GErrorResult ("No equations found after parsing");
       }
       res = eq.solve ();
     } catch (GLib.Error e) {
-      var err = new GErrorResult (e.message);
-      res = new GResult.with_error ((Expression) new GErrorExpression (), (ErrorResult) err) as Result;
+      res = new GErrorResult ("Solving fails: %s".printf (e.message));
     }
     return res;
   }
diff --git a/gcalc/gcalc-gterm.vala b/gcalc/gcalc-gterm.vala
index b96c45c5..1402273c 100644
--- a/gcalc/gcalc-gterm.vala
+++ b/gcalc/gcalc-gterm.vala
@@ -25,8 +25,7 @@ public class GCalc.GTerm : GExpression, Term {
       var e = evaluate ();
       res = new GResult (e) as Result;
     } catch (GLib.Error err) {
-      var nerr = new GErrorResult (err.message);
-      res = new GResult.with_error ((Expression) new GErrorExpression (), (ErrorResult) nerr) as Result;
+      res = new GErrorResult ("Term evaluation fails: %s".printf (err.message));
     }
     return res;
   }
diff --git a/gcalc/gcalc-polynomial.vala b/gcalc/gcalc-polynomial.vala
index e00e5c7d..dd52e225 100644
--- a/gcalc/gcalc-polynomial.vala
+++ b/gcalc/gcalc-polynomial.vala
@@ -22,11 +22,9 @@ public interface GCalc.Polynomial : Object, Expression {
   public virtual Expression evaluate () throws GLib.Error {
     Term current = null;
     Expression res = null;
-    message ("Terms: %u", expressions.get_n_items ());
     for (uint i = 0; i < expressions.get_n_items (); i++) {
       var e = expressions.get_item (i) as Term;
       if (e == null) {
-        message ("No Term: %s", e.get_type ().name ());
         continue;
       }
       if (current == null) {
@@ -40,22 +38,18 @@ public interface GCalc.Polynomial : Object, Expression {
           break;
         }
         if (res is Constant && er is Constant) {
-          message ("Adding: %s + %s", res.to_string (), er.to_string ());
           res = ((Constant) res).add ((Constant) er);
           break;
         }
       }
       var re = current.add ((Term) e);
       current = null;
-      message ("Current Terms Sum: %s", re.to_string ());
       if (res == null) {
         res = re;
       } else if (res is Constant && re is Constant) {
-        message ("Adding: %s + %s", res.to_string (), re.to_string ());
         res = ((Constant) res).add ((Constant) re);
       }
       if (res != null) {
-        message ("Current Sum: %s", res.to_string ());
       }
     }
     if (res == null) {
diff --git a/gcalc/gcalc-result.vala b/gcalc/gcalc-result.vala
index 7bb82b7b..a1bfcb7a 100644
--- a/gcalc/gcalc-result.vala
+++ b/gcalc/gcalc-result.vala
@@ -19,9 +19,7 @@
  *      Daniel Espinosa <esodan gmail com>
  */
 public interface GCalc.Result : Object {
-  public abstract bool is_valid { get; }
   public abstract string to_string ();
   public abstract Expression expression { get; }
-  public abstract ErrorResult error { get; }
 }
 
diff --git a/gcalc/gcalc-term.vala b/gcalc/gcalc-term.vala
index 6f06d77e..db69629b 100644
--- a/gcalc/gcalc-term.vala
+++ b/gcalc/gcalc-term.vala
@@ -37,7 +37,7 @@ public interface GCalc.Term : Object, Expression {
     Operator current_operator = null;
     bool first = true;
     foreach (Expression e in expressions) {
-      message ("Evaluation Expression in term: %s", e.to_string ());
+      message ("Evaluating Expression in term: %s", e.to_string ());
       if (e is Operator) {
         if (!(e is Minus || e is Plus) && first) {
           throw new TermError.INVALID_OPERATOR ("Incorrect position for operator in expression");
@@ -81,21 +81,7 @@ public interface GCalc.Term : Object, Expression {
         }
       } else if (e is Variable) {
         message ("Evaluating Variable '%s'", (e as Variable).name);
-        var par = e.parent;
-        while (par != null) {
-          if (par is MathEquation) {
-            break;
-          }
-          par = par.parent;
-        }
-        if (par == null) {
-          throw new TermError.EVALUATION_FAIL ("Variable's equation definition not found");
-        }
-        var res = ((MathEquation) par).solve ();
-        if (res.error != null) {
-          throw new TermError.EVALUATION_FAIL ("Variable evaluation fail: %s", res.error.to_string ());
-        }
-        var ev = res.expression;
+        var ev = (e as Variable).evaluate ();
         if (current == null) {
           current = ev;
           first = false;
diff --git a/gcalc/gcalc-variable.vala b/gcalc/gcalc-variable.vala
index d9fdeae6..7f1f62da 100644
--- a/gcalc/gcalc-variable.vala
+++ b/gcalc/gcalc-variable.vala
@@ -22,6 +22,8 @@ public interface GCalc.Variable : Object, Expression {
   public abstract string name { get; construct set; }
   public abstract Constant @value { get; set; }
   public abstract Variable bind { get; set; }
+  public virtual bool binded { get { return bind != null; } }
+
   public virtual Expression evaluate () throws GLib.Error {
     if (bind != null) {
       return bind.evaluate ();
@@ -41,6 +43,7 @@ public interface GCalc.Variable : Object, Expression {
       throw new VariableError.EVALUATION_FAIL ("Variable evaluation fail. Variable's value not updated");
     }
     @value = exp;
+    message ("Variable '%s' evaluated to: %s", name, @value.to_string ());
     return exp;
   }
 }
diff --git a/tests/gcalc-parsing.vala b/tests/gcalc-parsing.vala
index 9342d2df..e71e8380 100644
--- a/tests/gcalc-parsing.vala
+++ b/tests/gcalc-parsing.vala
@@ -1001,6 +1001,76 @@ class Tests {
         warning ("Error: %s", error.message);
       }
     });
+    Test.add_func ("/gcalc/parser/variable/equations/asigments/polynomial/variables",
+    ()=>{
+      try {
+        var parser = new GParser ();
+        var eqman = new GMathEquationManager ();
+        parser.parse ("x=3", eqman);
+        parser.parse ("y=x", eqman);
+        parser.parse ("z=x+y", eqman);
+        assert (eqman.equations.get_n_items () == 3);
+        var eq = eqman.equations.get_item (0) as MathEquation;
+        assert (eq != null);
+        message ("Eq1: %s", eq.to_string ());
+        assert (eq.expressions.get_n_items () == 1);
+        var a = eq.expressions.get_item (0) as Assign;
+        assert (a != null);
+        assert (a.expressions.get_n_items () == 2);
+        var v = a.expressions.get_item (0) as Variable;
+        assert (v != null);
+        var e = a.expressions.get_item (1) as Polynomial;
+        assert (e != null);
+        assert (e.expressions.get_n_items () == 1);
+        var t = e.expressions.get_item (0) as Term;
+        assert (t != null);
+        var c = t.expressions.get_item (0) as Constant;
+        assert (c != null);
+        var eq2 = eqman.equations.get_item (1) as MathEquation;
+        assert (eq2 != null);
+        message ("Eq2: %s", eq2.to_string ());
+        assert (eq2.expressions.get_n_items () == 1);
+        var a2 = eq2.expressions.get_item (0) as Assign;
+        assert (a2 != null);
+        assert (a2.expressions.get_n_items () == 2);
+        var v2 = a2.expressions.get_item (0) as Variable;
+        assert (v2 != null);
+        var e2 = a2.expressions.get_item (1) as Polynomial;
+        assert (e2 != null);
+        assert (e2.expressions.get_n_items () == 1);
+        var t2 = e2.expressions.get_item (0) as Term;
+        assert (t2 != null);
+        var v3 = t2.expressions.get_item (0) as Variable;
+        assert (v3 != null);
+        var eq3 = eqman.equations.get_item (2) as MathEquation;
+        assert (eq3 != null);
+        message ("Eq3: %s", eq3.to_string ());
+        assert (eq3.expressions.get_n_items () == 1);
+        var a3 = eq3.expressions.get_item (0) as Assign;
+        assert (a3 != null);
+        assert (a3.expressions.get_n_items () == 2);
+        var v4 = a3.expressions.get_item (0) as Variable;
+        assert (v4 != null);
+        var e3 = a3.expressions.get_item (1) as Polynomial;
+        assert (e3 != null);
+        message ("Termns in Polynomial3: %u", e3.expressions.get_n_items ());
+        assert (e3.expressions.get_n_items () == 2);
+        var t3 = e3.expressions.get_item (0) as Term;
+        assert (t3 != null);
+        assert (t3.expressions.get_n_items () == 1);
+        var v5 = t3.expressions.get_item (0) as Variable;
+        assert (v5 != null);
+        var t4 = e3.expressions.get_item (1) as Term;
+        assert (t4 != null);
+        assert (t4.expressions.get_n_items () == 2);
+        var plus = t4.expressions.get_item (0) as Plus;
+        assert (plus != null);
+        var v6 = t4.expressions.get_item (1) as Variable;
+        assert (v6 != null);
+      } catch (GLib.Error error) {
+        warning ("Error: %s", error.message);
+      }
+    });
     return Test.run ();
   }
 }
diff --git a/tests/gcalc-solving-basic.vala b/tests/gcalc-solving-basic.vala
index 28978422..95917b23 100644
--- a/tests/gcalc-solving-basic.vala
+++ b/tests/gcalc-solving-basic.vala
@@ -118,7 +118,7 @@ class Tests {
         assert (res != null);
         assert (res.expression != null);
         message ("Result type: %s", res.expression.get_type ().name ());
-        assert (res.is_valid);
+        assert (!(res is ErrorResult));
         var rc = res.expression as Constant;
         assert (rc != null);
         message ("Constant Result: %s", rc.to_string ());
@@ -143,7 +143,7 @@ class Tests {
         assert (res != null);
         assert (res.expression != null);
         message ("Result type: %s", res.expression.get_type ().name ());
-        assert (res.is_valid);
+        assert (!(res is ErrorResult));
         var rc = res.expression as Constant;
         assert (rc != null);
         message ("Constant Result: %s", rc.to_string ());
@@ -168,7 +168,7 @@ class Tests {
         assert (res != null);
         assert (res.expression != null);
         message ("Result type: %s", res.expression.get_type ().name ());
-        assert (res.is_valid);
+        assert (!(res is ErrorResult));
         var rc = res.expression as Constant;
         assert (rc != null);
         message ("Constant Result: %s", rc.to_string ());
@@ -1093,7 +1093,7 @@ class Tests {
         assert (eq != null);
         var res = eq.solve ();
         if (res is ErrorResult) {
-          warning ("Error: %s", res.error.to_string ());
+          warning ("Error: %s", (res as ErrorResult).message);
         }
         assert (res.expression != null);
         assert (res.expression is Constant);
@@ -1117,7 +1117,7 @@ class Tests {
         assert (eq != null);
         var res = eq.solve ();
         if (res is ErrorResult) {
-          warning ("Error: %s", res.error.to_string ());
+          warning ("Error: %s", (res as ErrorResult).message);
         }
         assert (res.expression != null);
         assert (res.expression is Constant);
@@ -1129,7 +1129,7 @@ class Tests {
         assert (eq2 != null);
         var res2 = eq2.solve ();
         if (res2 is ErrorResult) {
-          warning ("Error: %s", res2.error.to_string ());
+          warning ("Error: %s", (res2 as ErrorResult).message);
         }
         assert (res2.expression != null);
         assert (res2.expression is Constant);
@@ -1153,7 +1153,7 @@ class Tests {
         assert (eq != null);
         var res = eq.solve ();
         if (res is ErrorResult) {
-          warning ("Error: %s", res.error.to_string ());
+          warning ("Error: %s", (res as ErrorResult).message);
         }
         assert (res.expression != null);
         assert (res.expression is Constant);
@@ -1165,7 +1165,7 @@ class Tests {
         assert (eq2 != null);
         var res2 = eq2.solve ();
         if (res2 is ErrorResult) {
-          warning ("Error: %s", res2.error.to_string ());
+          warning ("Error: %s", (res2 as ErrorResult).message);
         }
         assert (res2.expression != null);
         assert (res2.expression is Constant);
@@ -1177,6 +1177,159 @@ class Tests {
         warning ("Error: %s", e.message);
       }
     });
+    Test.add_func ("/gcalc/solve/equations/solve/variable/assignment/polynomial",
+    ()=>{
+      try {
+        var parser = new GParser ();
+        var eqman = new GMathEquationManager ();
+        parser.parse ("x=3", eqman);
+        parser.parse ("y=x", eqman);
+        parser.parse ("z=y+x", eqman);
+        assert (eqman.equations.get_n_items () == 3);
+        var eq = eqman.equations.get_item (0) as MathEquation;
+        assert (eq != null);
+        var res = eq.solve ();
+        if (res is ErrorResult) {
+          warning ("Error: %s", (res as ErrorResult).message);
+        }
+        assert (res.expression != null);
+        assert (res.expression is Constant);
+        message ("Result: %s", res.expression.to_string ());
+        var c = res.expression as Constant;
+        assert (c != null);
+        assert (c.real () == 3.0);
+        var eq2 = eqman.equations.get_item (0) as MathEquation;
+        assert (eq2 != null);
+        var res2 = eq2.solve ();
+        if (res2 is ErrorResult) {
+          warning ("Error: %s", (res2 as ErrorResult).message);
+        }
+        assert (res2.expression != null);
+        assert (res2.expression is Constant);
+        message ("Result: %s", res2.expression.to_string ());
+        var c2 = res2.expression as Constant;
+        assert (c2 != null);
+        assert (c2.real () == 3.0);
+        var eq3 = eqman.equations.get_item (2) as MathEquation;
+        assert (eq3 != null);
+        message ("Evaluating Eq3...");
+        var res3 = eq3.solve ();
+        if (res3 is ErrorResult) {
+          warning ("Error: %s", (res3 as ErrorResult).message);
+        }
+        assert (res3.expression != null);
+        message ("Result Type: %s", res3.expression.get_type ().name ());
+        assert (res3.expression is Constant);
+        message ("Result: %s", res3.expression.to_string ());
+        var c3 = res3.expression as Constant;
+        assert (c3 != null);
+        assert (c3.real () == 6.0);
+      } catch (GLib.Error e) {
+        warning ("Error: %s", e.message);
+      }
+    });
+    Test.add_func ("/gcalc/solve/equations/solve/variable/assignment/polynomial/complex1",
+    ()=>{
+      try {
+        var parser = new GParser ();
+        var eqman = new GMathEquationManager ();
+        parser.parse ("x=3", eqman);
+        parser.parse ("y=x", eqman);
+        parser.parse ("z=y+x*3+9/y*2*x", eqman);
+        assert (eqman.equations.get_n_items () == 3);
+        var eq = eqman.equations.get_item (0) as MathEquation;
+        assert (eq != null);
+        var res = eq.solve ();
+        if (res is ErrorResult) {
+          warning ("Error: %s", (res as ErrorResult).message);
+        }
+        assert (res.expression != null);
+        assert (res.expression is Constant);
+        message ("Result: %s", res.expression.to_string ());
+        var c = res.expression as Constant;
+        assert (c != null);
+        assert (c.real () == 3.0);
+        var eq2 = eqman.equations.get_item (0) as MathEquation;
+        assert (eq2 != null);
+        var res2 = eq2.solve ();
+        if (res2 is ErrorResult) {
+          warning ("Error: %s", (res2 as ErrorResult).message);
+        }
+        assert (res2.expression != null);
+        assert (res2.expression is Constant);
+        message ("Result: %s", res2.expression.to_string ());
+        var c2 = res2.expression as Constant;
+        assert (c2 != null);
+        assert (c2.real () == 3.0);
+        var eq3 = eqman.equations.get_item (2) as MathEquation;
+        assert (eq3 != null);
+        message ("Evaluating Eq3...");
+        var res3 = eq3.solve ();
+        if (res3 is ErrorResult) {
+          warning ("Error: %s", (res3 as ErrorResult).message);
+        }
+        assert (res3.expression != null);
+        message ("Result Type: %s", res3.expression.get_type ().name ());
+        assert (res3.expression is Constant);
+        message ("Result: %s", res3.expression.to_string ());
+        var c3 = res3.expression as Constant;
+        assert (c3 != null);
+        assert (c3.real () == 30.0);
+      } catch (GLib.Error e) {
+        warning ("Error: %s", e.message);
+      }
+    });
+    Test.add_func ("/gcalc/solve/equations/solve/variable/assignment/polynomial/complex2",
+    ()=>{
+      try {
+        var parser = new GParser ();
+        var eqman = new GMathEquationManager ();
+        parser.parse ("x=3", eqman);
+        parser.parse ("y=x", eqman);
+        parser.parse ("z=y+x*3+9/y*2*x-((x-2*y)/(x+2-y))", eqman);
+        assert (eqman.equations.get_n_items () == 3);
+        var eq = eqman.equations.get_item (0) as MathEquation;
+        assert (eq != null);
+        var res = eq.solve ();
+        if (res is ErrorResult) {
+          warning ("Error: %s", (res as ErrorResult).message);
+        }
+        assert (res.expression != null);
+        assert (res.expression is Constant);
+        message ("Result: %s", res.expression.to_string ());
+        var c = res.expression as Constant;
+        assert (c != null);
+        assert (c.real () == 3.0);
+        var eq2 = eqman.equations.get_item (0) as MathEquation;
+        assert (eq2 != null);
+        var res2 = eq2.solve ();
+        if (res2 is ErrorResult) {
+          warning ("Error: %s", (res2 as ErrorResult).message);
+        }
+        assert (res2.expression != null);
+        assert (res2.expression is Constant);
+        message ("Result: %s", res2.expression.to_string ());
+        var c2 = res2.expression as Constant;
+        assert (c2 != null);
+        assert (c2.real () == 3.0);
+        var eq3 = eqman.equations.get_item (2) as MathEquation;
+        assert (eq3 != null);
+        message ("Evaluating Eq3...");
+        var res3 = eq3.solve ();
+        if (res3 is ErrorResult) {
+          warning ("Error: %s", (res3 as ErrorResult).message);
+        }
+        assert (res3.expression != null);
+        message ("Result Type: %s", res3.expression.get_type ().name ());
+        assert (res3.expression is Constant);
+        message ("Result: %s", res3.expression.to_string ());
+        var c3 = res3.expression as Constant;
+        assert (c3 != null);
+        assert (c3.real () == 31.5);
+      } 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]