[gnome-calculator/60-split-out-a-backend-library] gcalc: reimplementing equation parsing



commit a346522a3c1c64f784c2ab49d622d520f2937aa0
Author: Daniel Espinosa Ortiz <esodan gmail com>
Date:   Wed Jan 2 14:50:29 2019 -0600

    gcalc: reimplementing equation parsing
    
    This effort requires Gee and libvala, to take advantage
    of Vala's parser. Creates a new set of objects based
    on expressions

 gcalc/{gcalc-number.vala => gcalc-assign.vala} |  11 +-
 gcalc/gcalc-constant.vala                      |  24 +++
 gcalc/gcalc-expression-container.vala          |  55 +++++++
 gcalc/gcalc-expression.vala                    |   1 +
 gcalc/gcalc-function.vala                      |  24 +++
 gcalc/gcalc-gassign.vala                       |  26 ++++
 gcalc/gcalc-gconstant.vala                     |  44 ++++++
 gcalc/gcalc-gexpression.vala                   |   6 +-
 gcalc/gcalc-gfunction.vala                     |  33 +++++
 gcalc/gcalc-gmath-equation-manager.vala        |  27 ++++
 gcalc/gcalc-gmath-equation.vala                |  22 +++
 gcalc/gcalc-gpolynomial.vala                   |  23 +++
 gcalc/gcalc-gvariable.vala                     |  38 +++++
 gcalc/gcalc-math-equation-manager.vala         |   3 +-
 gcalc/gcalc-math-equation.vala                 |   6 +-
 gcalc/gcalc-parser.vala                        | 196 +++++++++++++++++++++++++
 gcalc/gcalc-polynomial.vala                    |  23 +++
 gcalc/gcalc-variable.vala                      |  25 ++++
 gcalc/meson.build                              |  16 ++
 meson.build                                    |  11 ++
 meson_options.txt                              |   3 +-
 tests/meson.build                              |  16 +-
 22 files changed, 618 insertions(+), 15 deletions(-)
---
diff --git a/gcalc/gcalc-number.vala b/gcalc/gcalc-assign.vala
similarity index 77%
rename from gcalc/gcalc-number.vala
rename to gcalc/gcalc-assign.vala
index b4cfd594..97495ebe 100644
--- a/gcalc/gcalc-number.vala
+++ b/gcalc/gcalc-assign.vala
@@ -1,6 +1,6 @@
-/*
- * Copyright (C) 2008-2012 Robert Ancell.
- * Copyright (C) 2018 Daniel Espinosa <esodan gmail com>
+/* gcalc-assign.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
@@ -14,6 +14,9 @@
 
  * 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.Assign : Object, Expression {}
 
-public class 
diff --git a/gcalc/gcalc-constant.vala b/gcalc/gcalc-constant.vala
new file mode 100644
index 00000000..e8707a25
--- /dev/null
+++ b/gcalc/gcalc-constant.vala
@@ -0,0 +1,24 @@
+/* gcalc-constant.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.Constant : Object, Expression {
+  public abstract void zero ();
+}
+
diff --git a/gcalc/gcalc-expression-container.vala b/gcalc/gcalc-expression-container.vala
new file mode 100644
index 00000000..fb0623d5
--- /dev/null
+++ b/gcalc/gcalc-expression-container.vala
@@ -0,0 +1,55 @@
+/* gcalc-expression-container.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.ExpressionContainer : Gee.ArrayList<Expression>, GLib.ListModel {
+  public Object? get_item (uint position) {
+    return (this as Gee.ArrayList<Expression>).@get ((int) position) as Object;
+  }
+  public Type get_item_type () {
+    return typeof (Expression);
+  }
+  public uint get_n_items () {
+    return (this as Gee.ArrayList<Expression>).size;
+  }
+  public Object? get_object (uint position) {
+    return get_item (position);
+  }
+  public Expression? find (Expression exp) {
+    foreach (Expression e in this) {
+      if (exp is Variable && e is Variable) {
+        if ((exp as Variable).name == (e as Variable).name) {
+          return e;
+        }
+      }
+    }
+    return null;
+  }
+  public Expression? find_named (string name) {
+    foreach (Expression e in this) {
+      if (e is Variable) {
+        if ((e as Variable).name == name) {
+          return e;
+        }
+      }
+    }
+    return null;
+  }
+}
+
diff --git a/gcalc/gcalc-expression.vala b/gcalc/gcalc-expression.vala
index c45547b6..0ea3554f 100644
--- a/gcalc/gcalc-expression.vala
+++ b/gcalc/gcalc-expression.vala
@@ -19,6 +19,7 @@
  *      Daniel Espinosa <esodan gmail com>
  */
 public interface GCalc.Expression : Object {
+  public abstract ExpressionContainer expressions { get; }
   public abstract string to_string ();
 }
 
diff --git a/gcalc/gcalc-function.vala b/gcalc/gcalc-function.vala
new file mode 100644
index 00000000..f63e359d
--- /dev/null
+++ b/gcalc/gcalc-function.vala
@@ -0,0 +1,24 @@
+/* gcalc-function.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.Function : Object, Expression {
+  public abstract string name { get; construct set; }
+}
+
diff --git a/gcalc/gcalc-gassign.vala b/gcalc/gcalc-gassign.vala
new file mode 100644
index 00000000..d69f691b
--- /dev/null
+++ b/gcalc/gcalc-gassign.vala
@@ -0,0 +1,26 @@
+/* gcalc-gassign.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.GAssign : GExpression, Assign {
+  public override string to_string () {
+    return "=";
+  }
+}
+
diff --git a/gcalc/gcalc-gconstant.vala b/gcalc/gcalc-gconstant.vala
new file mode 100644
index 00000000..f33a1d22
--- /dev/null
+++ b/gcalc/gcalc-gconstant.vala
@@ -0,0 +1,44 @@
+/* gcalc-gconstant.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.GConstant : GExpression, Constant {
+  private MPFR.Real real_value;
+
+  construct {
+    real_value.set_zero ();
+  }
+  public GConstant.integer (int val) {
+    real_value.set_signed_integer ((long) val);
+  }
+  public GConstant.unsigned_integer (uint val) {
+    real_value.set_unsigned_integer ((ulong) val);
+  }
+  public GConstant.@double (double val) {
+    real_value.set_double (val);
+  }
+
+  // Constant Interface
+  public void zero () { real_value.set_zero (); }
+  // Expression interface
+  public override string to_string () {
+    return ""; // FIXME: write down string representation
+  }
+}
+
diff --git a/gcalc/gcalc-gexpression.vala b/gcalc/gcalc-gexpression.vala
index 53614b6b..ec56fd68 100644
--- a/gcalc/gcalc-gexpression.vala
+++ b/gcalc/gcalc-gexpression.vala
@@ -18,8 +18,10 @@
  * Authors:
  *      Daniel Espinosa <esodan gmail com>
  */
-public class GCalc.GExpression : Object {
-  public string to_string () {
+public class GCalc.GExpression : Object, Expression {
+  ExpressionContainer exps = new ExpressionContainer ();
+  public ExpressionContainer expressions { get { return exps; } }
+  public new virtual string to_string () {
     return "";
   }
 }
diff --git a/gcalc/gcalc-gfunction.vala b/gcalc/gcalc-gfunction.vala
new file mode 100644
index 00000000..ab17b69f
--- /dev/null
+++ b/gcalc/gcalc-gfunction.vala
@@ -0,0 +1,33 @@
+/* gcalc-gfunction.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.GFunction : GExpression, Function {
+  public string name { get; construct set; }
+  construct {
+    name = "NoName";
+  }
+  public GFunction (string name) {
+    this.name = name;
+  }
+  public override string to_string () {
+    return name + " ()";
+  }
+}
+
diff --git a/gcalc/gcalc-gmath-equation-manager.vala b/gcalc/gcalc-gmath-equation-manager.vala
new file mode 100644
index 00000000..5bfc3c4e
--- /dev/null
+++ b/gcalc/gcalc-gmath-equation-manager.vala
@@ -0,0 +1,27 @@
+/* gcalc-gmath-equation-manager.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.GMathEquationManager : Object, MathEquationManager {
+  ExpressionContainer _equations = new ExpressionContainer ();
+  ExpressionContainer _functions = new ExpressionContainer ();
+  public ExpressionContainer equations { get { return _equations; } }
+  public ExpressionContainer functions { get { return _functions; } }
+}
+
diff --git a/gcalc/gcalc-gmath-equation.vala b/gcalc/gcalc-gmath-equation.vala
new file mode 100644
index 00000000..56c82981
--- /dev/null
+++ b/gcalc/gcalc-gmath-equation.vala
@@ -0,0 +1,22 @@
+/* gcalc-gmath-equation.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.GMathEquation : GExpression, MathEquation {}
+
diff --git a/gcalc/gcalc-gpolynomial.vala b/gcalc/gcalc-gpolynomial.vala
new file mode 100644
index 00000000..b3cf610d
--- /dev/null
+++ b/gcalc/gcalc-gpolynomial.vala
@@ -0,0 +1,23 @@
+/* gcalc-gpolynomial.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.GPolynomial : GExpression, Polynomial {
+}
+
diff --git a/gcalc/gcalc-gvariable.vala b/gcalc/gcalc-gvariable.vala
new file mode 100644
index 00000000..7a56c6d3
--- /dev/null
+++ b/gcalc/gcalc-gvariable.vala
@@ -0,0 +1,38 @@
+/* gcalc-gvariable.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.GVariable : GExpression, Variable {
+  private GLib.Value _value;
+
+  public string name { get; construct set; }
+  public GLib.Value value { get { return _value; } }
+
+  construct {
+    _value = GLib.Value (GLib.Type.DOUBLE);
+  }
+  public GVariable (string name) {
+    this.name = name;
+  }
+  // Expression
+  public override string to_string () {
+    return name;
+  }
+}
+
diff --git a/gcalc/gcalc-math-equation-manager.vala b/gcalc/gcalc-math-equation-manager.vala
index 43fa2441..97b085c1 100644
--- a/gcalc/gcalc-math-equation-manager.vala
+++ b/gcalc/gcalc-math-equation-manager.vala
@@ -19,6 +19,7 @@
  *      Daniel Espinosa <esodan gmail com>
  */
 public interface GCalc.MathEquationManager : Object {
-  public abstract GLib.ListModel equations { get; }
+  public abstract ExpressionContainer equations { get; }
+  public abstract ExpressionContainer functions { get; }
 }
 
diff --git a/gcalc/gcalc-math-equation.vala b/gcalc/gcalc-math-equation.vala
index 7c4f5fcd..238c3437 100644
--- a/gcalc/gcalc-math-equation.vala
+++ b/gcalc/gcalc-math-equation.vala
@@ -18,9 +18,5 @@
  * Authors:
  *      Daniel Espinosa <esodan gmail com>
  */
-public interface GCalc.MathEquation : Object {
-  public abstract Solver solver { get; }
-  public abstract string expresion { get; }
-  public abstract Result resolve ();
-}
+public interface GCalc.MathEquation : Object, Expression {}
 
diff --git a/gcalc/gcalc-parser.vala b/gcalc/gcalc-parser.vala
new file mode 100644
index 00000000..a37aa197
--- /dev/null
+++ b/gcalc/gcalc-parser.vala
@@ -0,0 +1,196 @@
+/* gcalc-gexpresion.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>
+ */
+using Vala;
+
+public class GCalc.Parser : Object {
+  public void parse (string str, MathEquationManager eqman) throws GLib.Error {
+    var context = new CodeContext ();
+    CodeContext.push (context);
+    SourceFileType type = SourceFileType.NONE;
+    var sf = new SourceFile (context, type, "gcalc://", str);
+    var scanner = new Vala.Scanner (sf);
+    var lines = str.split ("\n");
+    Vala.TokenType token = Vala.TokenType.NONE;
+    var expected = new Gee.ArrayList<Vala.TokenType> ();
+    Expression current = null;
+    while (token != Vala.TokenType.EOF) {
+      Vala.SourceLocation begin, end;
+      token = scanner.read_token (out begin, out end);
+      string n = token.to_string ();
+      n = n.replace ("`", "");
+      n = n.replace ("'", "");
+      string l = lines[begin.line];
+      n = l.substring (begin.column, end.column - begin.column);
+      if (expected.size != 0 && !expected.contains (token)) {
+        throw new ParserError.INVALID_TOKEN_ERROR ("Found an unexpected expression");
+      }
+      switch (token) {
+        case Vala.TokenType.IDENTIFIER:
+          var sfunc = eqman.functions.find_named (n);
+          if (sfunc != null) {
+            current = sfunc;
+            expected.clear ();
+            expected.add(Vala.TokenType.OPEN_PARENS);
+          } else if (n.down () == "def" && current == null) {
+            var f = new GFunction (n) as Expression;
+            eqman.functions.add (f);
+            current = f;
+            expected.clear ();
+            expected.add(Vala.TokenType.OPEN_PARENS);
+          } else if (n.down () == "def" && !(current is Function)) {
+            throw new ParserError.INVALID_TOKEN_ERROR ("Found an unexpected function definition expression");
+          } else {
+            var v = new GVariable (n) as Expression;
+            if (eqman.equations.find (v) == null) {
+              eqman.equations.add (v);
+            }
+            if (current == null) {
+              var ex = new GPolynomial ();
+              current = ex;
+              expected.clear ();
+              expected.add(Vala.TokenType.ASSIGN);
+            }
+            if (current is Assign) {
+              var ex = new GPolynomial ();
+              current.expressions.add (ex);
+              expected.clear ();
+              expected.add (Vala.TokenType.IDENTIFIER);
+              expected.add (Vala.TokenType.STAR);
+              expected.add (Vala.TokenType.PERCENT);
+              expected.add (Vala.TokenType.PLUS);
+              expected.add (Vala.TokenType.DIV);
+              expected.add (Vala.TokenType.MINUS);
+              expected.add (Vala.TokenType.INTEGER_LITERAL);
+              expected.add (Vala.TokenType.REAL_LITERAL);
+            }
+          }
+          break;
+        case Vala.TokenType.INTEGER_LITERAL:
+        case Vala.TokenType.REAL_LITERAL:
+          var iexp = new GConstant.@double (double.parse (n));
+          if (current is Polynomial) {
+            current.expressions.add (iexp);
+            expected.clear ();
+            expected.add (Vala.TokenType.STAR);
+            expected.add (Vala.TokenType.PERCENT);
+            expected.add (Vala.TokenType.PLUS);
+            expected.add (Vala.TokenType.DIV);
+            expected.add (Vala.TokenType.MINUS);
+          }
+          break;
+        case Vala.TokenType.CHARACTER_LITERAL:
+        case Vala.TokenType.STAR:
+        case Vala.TokenType.PERCENT:
+        case Vala.TokenType.PLUS:
+        case Vala.TokenType.DIV:
+        case Vala.TokenType.MINUS:
+          break;
+        case Vala.TokenType.ASSIGN:
+          if (current.expressions.get_n_items () > 1) {
+            throw new ParserError.INVALID_TOKEN_ERROR ("Found an unexpected expression");
+          }
+          if (expected.contains(token)) {
+            if (current is Variable) {
+              var expa = new GAssign ();
+              expa.expressions.add (current);
+              current = expa;
+              expected.clear ();
+              expected.add(Vala.TokenType.IDENTIFIER);
+              expected.add(Vala.TokenType.INTEGER_LITERAL);
+              expected.add(Vala.TokenType.REAL_LITERAL);
+            }
+          }
+          break;
+        case Vala.TokenType.OPEN_PARENS:
+          if (current is Function) {
+            var fexp = new GPolynomial ();
+            current = fexp;
+            expected.clear ();
+            expected.add(Vala.TokenType.IDENTIFIER);
+            expected.add(Vala.TokenType.INTEGER_LITERAL);
+            expected.add(Vala.TokenType.REAL_LITERAL);
+            expected.add(Vala.TokenType.CLOSE_PARENS);
+          }
+          break;
+        case Vala.TokenType.CLOSE_PARENS:
+          break;
+        case Vala.TokenType.STRING_LITERAL:
+        case Vala.TokenType.REGEX_LITERAL:
+        case Vala.TokenType.TEMPLATE_STRING_LITERAL:
+        case Vala.TokenType.VERBATIM_STRING_LITERAL:
+        case Vala.TokenType.ASSIGN_ADD:
+        case Vala.TokenType.ASSIGN_BITWISE_AND:
+        case Vala.TokenType.ASSIGN_BITWISE_OR:
+        case Vala.TokenType.ASSIGN_BITWISE_XOR:
+        case Vala.TokenType.ASSIGN_DIV:
+        case Vala.TokenType.ASSIGN_MUL:
+        case Vala.TokenType.ASSIGN_PERCENT:
+        case Vala.TokenType.ASSIGN_SHIFT_LEFT:
+        case Vala.TokenType.ASSIGN_SUB:
+        case Vala.TokenType.BITWISE_AND:
+        case Vala.TokenType.BITWISE_OR:
+        case Vala.TokenType.OP_AND:
+        case Vala.TokenType.OP_COALESCING:
+        case Vala.TokenType.OP_DEC:
+        case Vala.TokenType.OP_EQ:
+        case Vala.TokenType.OP_GE:
+        case Vala.TokenType.OP_GT:
+        case Vala.TokenType.OP_INC:
+        case Vala.TokenType.OP_LE:
+        case Vala.TokenType.OP_LT:
+        case Vala.TokenType.OP_NE:
+        case Vala.TokenType.OP_NEG:
+        case Vala.TokenType.OP_OR:
+        case Vala.TokenType.OP_PTR:
+        case Vala.TokenType.OP_SHIFT_LEFT:
+        // Carret?
+        case Vala.TokenType.CARRET:
+        // braces
+        case Vala.TokenType.CLOSE_BRACE:
+        case Vala.TokenType.CLOSE_BRACKET:
+        case Vala.TokenType.CLOSE_REGEX_LITERAL:
+        case Vala.TokenType.CLOSE_TEMPLATE:
+        case Vala.TokenType.OPEN_BRACE:
+        case Vala.TokenType.OPEN_BRACKET:
+        case Vala.TokenType.OPEN_REGEX_LITERAL:
+        case Vala.TokenType.OPEN_TEMPLATE:
+        //
+        case Vala.TokenType.SEMICOLON:
+        case Vala.TokenType.TILDE:
+        case Vala.TokenType.COLON:
+        case Vala.TokenType.COMMA:
+        case Vala.TokenType.DOUBLE_COLON:
+        case Vala.TokenType.DOT:
+        case Vala.TokenType.ELLIPSIS:
+        case Vala.TokenType.INTERR:
+        // Hash
+        case Vala.TokenType.HASH:
+          break;
+      }
+    }
+  }
+}
+
+public errordomain GCalc.ParserError {
+  INVALID_TOKEN_ERROR,
+  INVALID_EXPRESSION_ERROR
+}
+
diff --git a/gcalc/gcalc-polynomial.vala b/gcalc/gcalc-polynomial.vala
new file mode 100644
index 00000000..e8efae06
--- /dev/null
+++ b/gcalc/gcalc-polynomial.vala
@@ -0,0 +1,23 @@
+/* gcalc-polynomial.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.Polynomial : Object, Expression {
+}
+
diff --git a/gcalc/gcalc-variable.vala b/gcalc/gcalc-variable.vala
new file mode 100644
index 00000000..46b0bd5e
--- /dev/null
+++ b/gcalc/gcalc-variable.vala
@@ -0,0 +1,25 @@
+/* gcalc-variable.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.Variable : Object, Expression {
+  public abstract string name { get; construct set; }
+  public abstract GLib.Value value { get; }
+}
+
diff --git a/gcalc/meson.build b/gcalc/meson.build
index cb7bab62..80508bc2 100644
--- a/gcalc/meson.build
+++ b/gcalc/meson.build
@@ -39,15 +39,29 @@ configure_file(output : 'config.h',
        configuration : confh)
 
 sources = files([
+       'gcalc-assign.vala',
+       'gcalc-constant.vala',
        'gcalc-expression.vala',
+       'gcalc-expression-container.vala',
+       'gcalc-function.vala',
        'gcalc-error-result.vala',
        'gcalc-gexpression.vala',
+       'gcalc-gassign.vala',
+       'gcalc-gconstant.vala',
+       'gcalc-gfunction.vala',
+       'gcalc-gmath-equation.vala',
+       'gcalc-gmath-equation-manager.vala',
+       'gcalc-gpolynomial.vala',
        'gcalc-gresult.vala',
        'gcalc-gsolver.vala',
+       'gcalc-gvariable.vala',
        'gcalc-math-equation.vala',
        'gcalc-math-equation-manager.vala',
+       'gcalc-parser.vala',
+       'gcalc-polynomial.vala',
        'gcalc-result.vala',
        'gcalc-solver.vala',
+       'gcalc-variable.vala',
 ])
 
 
@@ -62,6 +76,8 @@ deps = [
        posix,
        libxml,
        libsoup,
+       vala_dep,
+       gee
 ]
 
 
diff --git a/meson.build b/meson.build
index 7b510605..3719af70 100644
--- a/meson.build
+++ b/meson.build
@@ -30,6 +30,17 @@ gmodule_export = dependency('gmodule-export-2.0')
 gobject = dependency('gobject-2.0', version: '>= ' + glib_min_version)
 libxml = dependency('libxml-2.0')
 libsoup = dependency('libsoup-2.4', version: '>= 2.42')
+gee = dependency('gee-0.8', version: '>= 0.20.0')
+
+# Vala compiler as expression parser
+vala_version = get_option ('vala-version')
+if vala_version == ''
+       vc = find_program('valac')
+       r = run_command(vc, '--api-version')
+       vala_version = r.stdout().strip()
+endif
+vala_dep_str = 'libvala-@0@'.format (vala_version)
+vala_dep = dependency(vala_dep_str)
 
 # Libraries
 cc = meson.get_compiler('c')
diff --git a/meson_options.txt b/meson_options.txt
index 579bba62..1daa8b3a 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -1 +1,2 @@
-option('disable-ui', type : 'boolean', value : false, description : 'Disable GTK+ program')
\ No newline at end of file
+option('disable-ui', type : 'boolean', value : false, description : 'Disable GTK+ program')
+option('vala-version', type: 'string', value : '', description : 'Use another version of Vala (only the 
latest is officially supported)')
\ No newline at end of file
diff --git a/tests/meson.build b/tests/meson.build
index 2cbecb79..5a584d47 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -54,9 +54,21 @@ endif
 test_main_interfaces_sources = [
   'gcalc-main-interfaces.vala',
 ]
+
+tests_deps = [
+  gio,
+  glib,
+  gobject,
+  libmath,
+  mpc,
+  mpfr,
+  posix,
+  gee,
+  inc_rooth_dep
+]
+
 test_interfaces = executable('gcalc-interfaces', test_main_interfaces_sources,
-  dependencies: gnome_calculator_tests_deps,
+  dependencies:tests_deps,
   link_with: [lib, lib_mpfrg],
-  include_directories: gnome_calculator_tests_includes,
 )
 test('gcalc-interfaces', test_interfaces)


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