[gnome-calculator/60-split-out-a-backend-library] gcalc: add new library for math parsing/solving
- From: Daniel Espinosa Ortiz <despinosa src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-calculator/60-split-out-a-backend-library] gcalc: add new library for math parsing/solving
- Date: Mon, 7 Jan 2019 00:10:51 +0000 (UTC)
commit 3e9eda2d49b2937ce04a4c4b2147c484573d1e96
Author: Daniel Espinosa Ortiz <esodan gmail com>
Date: Sun Jan 6 17:17:14 2019 -0600
gcalc: add new library for math parsing/solving
Fix issue #60
This new library is independent from the internal one.
GCalc provides following features:
* Parse complicated constant equations
* Parse pre-defined functions (equivalent to the ones in Calculator)
* Parse complicated equations with pre-defined functions in them
* Parsing expressions to an Object Oriented tree representation using GObject classes
* Define arbitrary variables using complicated expressions, with both other variables or constants
* Evaluate expressions using defined variables
* Uses MPC as back end for calculation so complex numbers will be available soon
* No Gtk+ dependencies
.gitlab-ci.yml | 6 +-
gcalc/gcalc-assign.vala | 46 +
gcalc/gcalc-binary-operator.vala | 22 +
gcalc/gcalc-constant.vala | 31 +
gcalc/gcalc-division.vala | 22 +
gcalc/gcalc-error-result.vala | 24 +
gcalc/gcalc-expression-container.vala | 77 ++
gcalc/gcalc-expression-hash-map.vala | 36 +
gcalc/gcalc-expression.vala | 30 +
gcalc/gcalc-function-acos.vala | 55 ++
gcalc/gcalc-function-acosh.vala | 55 ++
gcalc/gcalc-function-asin.vala | 55 ++
gcalc/gcalc-function-asinh.vala | 55 ++
gcalc/gcalc-function-atan.vala | 55 ++
gcalc/gcalc-function-atanh.vala | 55 ++
gcalc/gcalc-function-cos.vala | 55 ++
gcalc/gcalc-function-cosh.vala | 55 ++
gcalc/gcalc-function-exp.vala | 55 ++
gcalc/gcalc-function-log.vala | 55 ++
gcalc/gcalc-function-sin.vala | 55 ++
gcalc/gcalc-function-sinh.vala | 55 ++
gcalc/gcalc-function-sqrt.vala | 55 ++
gcalc/gcalc-function-tan.vala | 55 ++
gcalc/gcalc-function-tanh.vala | 55 ++
gcalc/gcalc-function.vala | 40 +
gcalc/gcalc-gassign.vala | 46 +
gcalc/gcalc-gconstant.vala | 125 +++
gcalc/gcalc-gdivision.vala | 26 +
gcalc/gcalc-gerror-result.vala | 35 +
gcalc/gcalc-gexpression.vala | 43 +
gcalc/gcalc-gfunction.vala | 60 ++
gcalc/gcalc-ggroup.vala | 54 ++
gcalc/gcalc-gmath-equation-manager.vala | 46 +
gcalc/gcalc-gmath-equation.vala | 38 +
gcalc/gcalc-gminus.vala | 26 +
gcalc/gcalc-gmultiply.vala | 26 +
gcalc/gcalc-gparser.vala | 503 +++++++++++
gcalc/gcalc-gplus.vala | 26 +
gcalc/gcalc-gpolynomial.vala | 33 +
gcalc/gcalc-gpow.vala | 26 +
gcalc/gcalc-gresult.vala | 32 +
gcalc/gcalc-group.vala | 45 +
gcalc/gcalc-gsolver.vala | 47 ++
gcalc/gcalc-gterm.vala | 33 +
gcalc/gcalc-gvariable.vala | 42 +
gcalc/gcalc-hashable.vala | 24 +
gcalc/gcalc-math-equation-manager.vala | 40 +
gcalc/gcalc-math-equation.vala | 24 +
gcalc/gcalc-minus.vala | 22 +
gcalc/gcalc-multiply.vala | 22 +
gcalc/gcalc-operator.vala | 22 +
gcalc/gcalc-plus.vala | 22 +
gcalc/gcalc-polynomial.vala | 61 ++
gcalc/gcalc-pow.vala | 22 +
gcalc/gcalc-result.vala | 25 +
gcalc/gcalc-solver.vala | 28 +
gcalc/gcalc-term.vala | 127 +++
gcalc/gcalc-variable.vala | 56 ++
gcalc/gcalc.deps.in | 3 +
gcalc/gcalc.pc.in | 13 +
gcalc/meson.build | 187 +++++
gcalc/mpfr-glue.vala | 28 +
gcalc/namespace-info.vala.in | 24 +
lib/meson.build | 3 +-
lib/mpfr-glue.vala | 2 +-
meson.build | 25 +-
meson_options.txt | 3 +
org.gnome.Calculator.json | 117 ++-
search-provider/meson.build | 5 +-
src/meson.build | 6 +-
tests/gcalc-parsing.vala | 1076 ++++++++++++++++++++++++
tests/gcalc-solving-basic.vala | 1401 +++++++++++++++++++++++++++++++
tests/meson.build | 48 +-
vapi/mpc.vapi | 20 +-
74 files changed, 5863 insertions(+), 64 deletions(-)
---
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 4ecbd503..b1cfc045 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -2,12 +2,12 @@
image: ubuntu:rolling
before_script:
- apt-get update
- - apt-get install -q -y --no-install-recommends meson valac gcc gettext itstool libgtk-3-dev
libgtksourceview-4-dev libmpc-dev libmpfr-dev libsoup2.4-dev libxml2-dev
+ - apt-get install -q -y --no-install-recommends meson valac gcc gettext itstool libgtk-3-dev
libgtksourceview-4-dev libmpc-dev libmpfr-dev libsoup2.4-dev libxml2-dev libgee-0.8-dev libvala-0.42
.before_script_template: &fedora_before_script
image: fedora:latest
before_script:
- - dnf install -y meson vala itstool gtk3-devel gtksourceview4-devel libmpc-devel mpfr-devel
libsoup-devel libxml2-devel
+ - dnf install -y meson vala itstool gtk3-devel gtksourceview4-devel libmpc-devel mpfr-devel
libsoup-devel libxml2-devel libgee-devel vala-devel
.build_template: &meson_build
stage: build
@@ -54,4 +54,4 @@ test:fedora:
dependencies:
- build:fedora
<<: *fedora_before_script
- <<: *meson_test
+ <<: *meson_test
\ No newline at end of file
diff --git a/gcalc/gcalc-assign.vala b/gcalc/gcalc-assign.vala
new file mode 100644
index 00000000..11d9dba3
--- /dev/null
+++ b/gcalc/gcalc-assign.vala
@@ -0,0 +1,46 @@
+/* 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
+ * 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.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-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-constant.vala b/gcalc/gcalc-constant.vala
new file mode 100644
index 00000000..15d1c644
--- /dev/null
+++ b/gcalc/gcalc-constant.vala
@@ -0,0 +1,31 @@
+/* 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 double real ();
+ public abstract double imag ();
+ public abstract void zero ();
+ public abstract Constant add (Constant c);
+ public abstract Constant multiply (Constant c);
+ public abstract Constant divide (Constant c);
+ public abstract Constant neg ();
+ public abstract Constant pow (Constant c);
+}
+
diff --git a/gcalc/gcalc-division.vala b/gcalc/gcalc-division.vala
new file mode 100644
index 00000000..68d29bee
--- /dev/null
+++ b/gcalc/gcalc-division.vala
@@ -0,0 +1,22 @@
+/* gcalc-division.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.Division : Object, Expression, Operator, BinaryOperator {}
+
diff --git a/gcalc/gcalc-error-result.vala b/gcalc/gcalc-error-result.vala
new file mode 100644
index 00000000..365c3d54
--- /dev/null
+++ b/gcalc/gcalc-error-result.vala
@@ -0,0 +1,24 @@
+/* gcalc-error-result.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.ErrorResult : Object, Result {
+ public abstract string message { get; }
+}
+
diff --git a/gcalc/gcalc-expression-container.vala b/gcalc/gcalc-expression-container.vala
new file mode 100644
index 00000000..2521b389
--- /dev/null
+++ b/gcalc/gcalc-expression-container.vala
@@ -0,0 +1,77 @@
+/* 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 weak Expression parent { get; set; }
+ public new void add (Expression exp) {
+ (this as Gee.ArrayList<Expression>).add (exp);
+ exp.parent = parent;
+ }
+ public new Expression remove_at (int index) {
+ var r = (this as Gee.ArrayList<Expression>).remove_at (index);
+ if (r != null) {
+ r.parent = null;
+ }
+ return r;
+ }
+ public new Expression remove (Expression exp) {
+ var i = (this as Gee.ArrayList<Expression>).index_of (exp);
+ return remove_at (i);
+ }
+ // 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;
+ }
+ }
+ if (e is Function) {
+ if ((e as Function).name == name) {
+ return e;
+ }
+ }
+ }
+ return null;
+ }
+}
+
diff --git a/gcalc/gcalc-expression-hash-map.vala b/gcalc/gcalc-expression-hash-map.vala
new file mode 100644
index 00000000..06e8a793
--- /dev/null
+++ b/gcalc/gcalc-expression-hash-map.vala
@@ -0,0 +1,36 @@
+/* gcalc-expression-hash-table.vala
+ *
+ * Copyright (C) 2019 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.ExpressionHashMap : Gee.HashMap<uint,Expression> {
+ public weak Expression parent { get; set; }
+ public void add (Expression exp)
+ requires (exp is Hashable)
+ {
+ (this as Gee.HashMap<uint,Expression>).set (((Hashable) exp).hash (), exp);
+ exp.parent = parent;
+ }
+ public void remove (Expression exp) {
+ (this as Gee.HashMap<uint,Expression>).unset (((Hashable) exp).hash ());
+ }
+ public Expression find_named (string name) {
+ return (this as Gee.HashMap<uint,Expression>).@get (name.hash ());
+ }
+}
+
diff --git a/gcalc/gcalc-expression.vala b/gcalc/gcalc-expression.vala
new file mode 100644
index 00000000..6b83c5d5
--- /dev/null
+++ b/gcalc/gcalc-expression.vala
@@ -0,0 +1,30 @@
+/* gcalc-expresion.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.Expression : Object {
+ public abstract weak Expression parent { get; set; }
+ public abstract ExpressionContainer expressions { get; }
+ public abstract string to_string ();
+ public abstract Result solve ();
+}
+
+public interface GCalc.ErrorExpression : Object, Expression {
+}
+
diff --git a/gcalc/gcalc-function-acos.vala b/gcalc/gcalc-function-acos.vala
new file mode 100644
index 00000000..4cdeac66
--- /dev/null
+++ b/gcalc/gcalc-function-acos.vala
@@ -0,0 +1,55 @@
+/* gcalc-function-acos.vala
+ *
+ * Copyright (C) 2019 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.GFunctionAcos : GFunction {
+
+ construct {
+ name = "acos";
+ n_params = 1;
+ param_types.add (new GConstant ());
+ }
+
+ public override Expression evaluate () throws GLib.Error
+ {
+ verify_params ();
+ GConstant c = null;
+ var exp = expressions.get_item (0) as Expression;
+ if (exp == null) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid parameter type. Expected %s",
typeof(Expression).name ());
+ }
+ var ev = exp.solve ();
+ if (ev is ErrorResult) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).message);
+ }
+ if (ev is Result) {
+ c = ((Result) ev).expression as GConstant;
+ }
+ if (c == null) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid expression in result");
+ }
+ var p1 = MPC.Complex (1000);
+ p1.set (c.get_complex ());
+ var res = MPC.Complex (1000);
+ res.acos (p1);
+ var nc = new GConstant.internal_complex (res);
+ return nc as Expression;
+ }
+}
+
diff --git a/gcalc/gcalc-function-acosh.vala b/gcalc/gcalc-function-acosh.vala
new file mode 100644
index 00000000..00d39d0d
--- /dev/null
+++ b/gcalc/gcalc-function-acosh.vala
@@ -0,0 +1,55 @@
+/* gcalc-function-acosh.vala
+ *
+ * Copyright (C) 2019 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.GFunctionAcosh : GFunction {
+
+ construct {
+ name = "acosh";
+ n_params = 1;
+ param_types.add (new GConstant ());
+ }
+
+ public override Expression evaluate () throws GLib.Error
+ {
+ verify_params ();
+ GConstant c = null;
+ var exp = expressions.get_item (0) as Expression;
+ if (exp == null) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid parameter type. Expected %s",
typeof(Expression).name ());
+ }
+ var ev = exp.solve ();
+ if (ev is ErrorResult) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).message);
+ }
+ if (ev is Result) {
+ c = ((Result) ev).expression as GConstant;
+ }
+ if (c == null) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid expression in result");
+ }
+ var p1 = MPC.Complex (1000);
+ p1.set (c.get_complex ());
+ var res = MPC.Complex (1000);
+ res.acosh (p1);
+ var nc = new GConstant.internal_complex (res);
+ return nc as Expression;
+ }
+}
+
diff --git a/gcalc/gcalc-function-asin.vala b/gcalc/gcalc-function-asin.vala
new file mode 100644
index 00000000..a8d9ce27
--- /dev/null
+++ b/gcalc/gcalc-function-asin.vala
@@ -0,0 +1,55 @@
+/* gcalc-function-asin.vala
+ *
+ * Copyright (C) 2019 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.GFunctionAsin : GFunction {
+
+ construct {
+ name = "asin";
+ n_params = 1;
+ param_types.add (new GConstant ());
+ }
+
+ public override Expression evaluate () throws GLib.Error
+ {
+ verify_params ();
+ GConstant c = null;
+ var exp = expressions.get_item (0) as Expression;
+ if (exp == null) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid parameter type. Expected %s",
typeof(Expression).name ());
+ }
+ var ev = exp.solve ();
+ if (ev is ErrorResult) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).message);
+ }
+ if (ev is Result) {
+ c = ((Result) ev).expression as GConstant;
+ }
+ if (c == null) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid expression in result");
+ }
+ var p1 = MPC.Complex (1000);
+ p1.set (c.get_complex ());
+ var res = MPC.Complex (1000);
+ res.asin (p1);
+ var nc = new GConstant.internal_complex (res);
+ return nc as Expression;
+ }
+}
+
diff --git a/gcalc/gcalc-function-asinh.vala b/gcalc/gcalc-function-asinh.vala
new file mode 100644
index 00000000..4bcbf877
--- /dev/null
+++ b/gcalc/gcalc-function-asinh.vala
@@ -0,0 +1,55 @@
+/* gcalc-function-asinh.vala
+ *
+ * Copyright (C) 2019 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.GFunctionAsinh : GFunction {
+
+ construct {
+ name = "asinh";
+ n_params = 1;
+ param_types.add (new GConstant ());
+ }
+
+ public override Expression evaluate () throws GLib.Error
+ {
+ verify_params ();
+ GConstant c = null;
+ var exp = expressions.get_item (0) as Expression;
+ if (exp == null) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid parameter type. Expected %s",
typeof(Expression).name ());
+ }
+ var ev = exp.solve ();
+ if (ev is ErrorResult) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).message);
+ }
+ if (ev is Result) {
+ c = ((Result) ev).expression as GConstant;
+ }
+ if (c == null) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid expression in result");
+ }
+ var p1 = MPC.Complex (1000);
+ p1.set (c.get_complex ());
+ var res = MPC.Complex (1000);
+ res.asinh (p1);
+ var nc = new GConstant.internal_complex (res);
+ return nc as Expression;
+ }
+}
+
diff --git a/gcalc/gcalc-function-atan.vala b/gcalc/gcalc-function-atan.vala
new file mode 100644
index 00000000..5af108b5
--- /dev/null
+++ b/gcalc/gcalc-function-atan.vala
@@ -0,0 +1,55 @@
+/* gcalc-function-atan.vala
+ *
+ * Copyright (C) 2019 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.GFunctionAtan : GFunction {
+
+ construct {
+ name = "atan";
+ n_params = 1;
+ param_types.add (new GConstant ());
+ }
+
+ public override Expression evaluate () throws GLib.Error
+ {
+ verify_params ();
+ GConstant c = null;
+ var exp = expressions.get_item (0) as Expression;
+ if (exp == null) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid parameter type. Expected %s",
typeof(Expression).name ());
+ }
+ var ev = exp.solve ();
+ if (ev is ErrorResult) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).message);
+ }
+ if (ev is Result) {
+ c = ((Result) ev).expression as GConstant;
+ }
+ if (c == null) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid expression in result");
+ }
+ var p1 = MPC.Complex (1000);
+ p1.set (c.get_complex ());
+ var res = MPC.Complex (1000);
+ res.atan (p1);
+ var nc = new GConstant.internal_complex (res);
+ return nc as Expression;
+ }
+}
+
diff --git a/gcalc/gcalc-function-atanh.vala b/gcalc/gcalc-function-atanh.vala
new file mode 100644
index 00000000..2bc32229
--- /dev/null
+++ b/gcalc/gcalc-function-atanh.vala
@@ -0,0 +1,55 @@
+/* gcalc-function-atanh.vala
+ *
+ * Copyright (C) 2019 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.GFunctionAtanh : GFunction {
+
+ construct {
+ name = "atanh";
+ n_params = 1;
+ param_types.add (new GConstant ());
+ }
+
+ public override Expression evaluate () throws GLib.Error
+ {
+ verify_params ();
+ GConstant c = null;
+ var exp = expressions.get_item (0) as Expression;
+ if (exp == null) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid parameter type. Expected %s",
typeof(Expression).name ());
+ }
+ var ev = exp.solve ();
+ if (ev is ErrorResult) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).message);
+ }
+ if (ev is Result) {
+ c = ((Result) ev).expression as GConstant;
+ }
+ if (c == null) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid expression in result");
+ }
+ var p1 = MPC.Complex (1000);
+ p1.set (c.get_complex ());
+ var res = MPC.Complex (1000);
+ res.atanh (p1);
+ var nc = new GConstant.internal_complex (res);
+ return nc as Expression;
+ }
+}
+
diff --git a/gcalc/gcalc-function-cos.vala b/gcalc/gcalc-function-cos.vala
new file mode 100644
index 00000000..ab5828e1
--- /dev/null
+++ b/gcalc/gcalc-function-cos.vala
@@ -0,0 +1,55 @@
+/* gcalc-function-cos.vala
+ *
+ * Copyright (C) 2019 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.GFunctionCos : GFunction {
+
+ construct {
+ name = "cos";
+ n_params = 1;
+ param_types.add (new GConstant ());
+ }
+
+ public override Expression evaluate () throws GLib.Error
+ {
+ verify_params ();
+ GConstant c = null;
+ var exp = expressions.get_item (0) as Expression;
+ if (exp == null) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid parameter type. Expected %s",
typeof(Expression).name ());
+ }
+ var ev = exp.solve ();
+ if (ev is ErrorResult) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).message);
+ }
+ if (ev is Result) {
+ c = ((Result) ev).expression as GConstant;
+ }
+ if (c == null) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid expression in result");
+ }
+ var p1 = MPC.Complex (1000);
+ p1.set (c.get_complex ());
+ var res = MPC.Complex (1000);
+ res.cos (p1);
+ var nc = new GConstant.internal_complex (res);
+ return nc as Expression;
+ }
+}
+
diff --git a/gcalc/gcalc-function-cosh.vala b/gcalc/gcalc-function-cosh.vala
new file mode 100644
index 00000000..e051ce82
--- /dev/null
+++ b/gcalc/gcalc-function-cosh.vala
@@ -0,0 +1,55 @@
+/* gcalc-function-cosh.vala
+ *
+ * Copyright (C) 2019 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.GFunctionCosh : GFunction {
+
+ construct {
+ name = "cosh";
+ n_params = 1;
+ param_types.add (new GConstant ());
+ }
+
+ public override Expression evaluate () throws GLib.Error
+ {
+ verify_params ();
+ GConstant c = null;
+ var exp = expressions.get_item (0) as Expression;
+ if (exp == null) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid parameter type. Expected %s",
typeof(Expression).name ());
+ }
+ var ev = exp.solve ();
+ if (ev is ErrorResult) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).message);
+ }
+ if (ev is Result) {
+ c = ((Result) ev).expression as GConstant;
+ }
+ if (c == null) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid expression in result");
+ }
+ var p1 = MPC.Complex (1000);
+ p1.set (c.get_complex ());
+ var res = MPC.Complex (1000);
+ res.cosh (p1);
+ var nc = new GConstant.internal_complex (res);
+ return nc as Expression;
+ }
+}
+
diff --git a/gcalc/gcalc-function-exp.vala b/gcalc/gcalc-function-exp.vala
new file mode 100644
index 00000000..1cf135b1
--- /dev/null
+++ b/gcalc/gcalc-function-exp.vala
@@ -0,0 +1,55 @@
+/* gcalc-function-exp.vala
+ *
+ * Copyright (C) 2019 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.GFunctionExp : GFunction {
+
+ construct {
+ name = "exp";
+ n_params = 1;
+ param_types.add (new GConstant ());
+ }
+
+ public override Expression evaluate () throws GLib.Error
+ {
+ verify_params ();
+ GConstant c = null;
+ var exp = expressions.get_item (0) as Expression;
+ if (exp == null) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid parameter type. Expected %s",
typeof(Expression).name ());
+ }
+ var ev = exp.solve ();
+ if (ev is ErrorResult) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).message);
+ }
+ if (ev is Result) {
+ c = ((Result) ev).expression as GConstant;
+ }
+ if (c == null) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid expression in result");
+ }
+ var p1 = MPC.Complex (1000);
+ p1.set (c.get_complex ());
+ var res = MPC.Complex (1000);
+ res.exp (p1);
+ var nc = new GConstant.internal_complex (res);
+ return nc as Expression;
+ }
+}
+
diff --git a/gcalc/gcalc-function-log.vala b/gcalc/gcalc-function-log.vala
new file mode 100644
index 00000000..de57efe8
--- /dev/null
+++ b/gcalc/gcalc-function-log.vala
@@ -0,0 +1,55 @@
+/* gcalc-function-log.vala
+ *
+ * Copyright (C) 2019 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.GFunctionLog : GFunction {
+
+ construct {
+ name = "log";
+ n_params = 1;
+ param_types.add (new GConstant ());
+ }
+
+ public override Expression evaluate () throws GLib.Error
+ {
+ verify_params ();
+ GConstant c = null;
+ var exp = expressions.get_item (0) as Expression;
+ if (exp == null) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid parameter type. Expected %s",
typeof(Expression).name ());
+ }
+ var ev = exp.solve ();
+ if (ev is ErrorResult) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).message);
+ }
+ if (ev is Result) {
+ c = ((Result) ev).expression as GConstant;
+ }
+ if (c == null) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid expression in result");
+ }
+ var p1 = MPC.Complex (1000);
+ p1.set (c.get_complex ());
+ var res = MPC.Complex (1000);
+ res.log (p1);
+ var nc = new GConstant.internal_complex (res);
+ return nc as Expression;
+ }
+}
+
diff --git a/gcalc/gcalc-function-sin.vala b/gcalc/gcalc-function-sin.vala
new file mode 100644
index 00000000..5a288a0b
--- /dev/null
+++ b/gcalc/gcalc-function-sin.vala
@@ -0,0 +1,55 @@
+/* gcalc-function-sin.vala
+ *
+ * Copyright (C) 2019 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.GFunctionSin : GFunction {
+
+ construct {
+ name = "sin";
+ n_params = 1;
+ param_types.add (new GConstant ());
+ }
+
+ public override Expression evaluate () throws GLib.Error
+ {
+ verify_params ();
+ GConstant c = null;
+ var exp = expressions.get_item (0) as Expression;
+ if (exp == null) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid parameter type. Expected %s",
typeof(Expression).name ());
+ }
+ var ev = exp.solve ();
+ if (ev is ErrorResult) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).message);
+ }
+ if (ev is Result) {
+ c = ((Result) ev).expression as GConstant;
+ }
+ if (c == null) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid expression in result");
+ }
+ var p1 = MPC.Complex (1000);
+ p1.set (c.get_complex ());
+ var res = MPC.Complex (1000);
+ res.sin (p1);
+ var nc = new GConstant.internal_complex (res);
+ return nc as Expression;
+ }
+}
+
diff --git a/gcalc/gcalc-function-sinh.vala b/gcalc/gcalc-function-sinh.vala
new file mode 100644
index 00000000..92c796ef
--- /dev/null
+++ b/gcalc/gcalc-function-sinh.vala
@@ -0,0 +1,55 @@
+/* gcalc-function-sinh.vala
+ *
+ * Copyright (C) 2019 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.GFunctionSinh : GFunction {
+
+ construct {
+ name = "sinh";
+ n_params = 1;
+ param_types.add (new GConstant ());
+ }
+
+ public override Expression evaluate () throws GLib.Error
+ {
+ verify_params ();
+ GConstant c = null;
+ var exp = expressions.get_item (0) as Expression;
+ if (exp == null) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid parameter type. Expected %s",
typeof(Expression).name ());
+ }
+ var ev = exp.solve ();
+ if (ev is ErrorResult) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).message);
+ }
+ if (ev is Result) {
+ c = ((Result) ev).expression as GConstant;
+ }
+ if (c == null) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid expression in result");
+ }
+ var p1 = MPC.Complex (1000);
+ p1.set (c.get_complex ());
+ var res = MPC.Complex (1000);
+ res.sinh (p1);
+ var nc = new GConstant.internal_complex (res);
+ return nc as Expression;
+ }
+}
+
diff --git a/gcalc/gcalc-function-sqrt.vala b/gcalc/gcalc-function-sqrt.vala
new file mode 100644
index 00000000..0291cd8f
--- /dev/null
+++ b/gcalc/gcalc-function-sqrt.vala
@@ -0,0 +1,55 @@
+/* gcalc-function-sqrt.vala
+ *
+ * Copyright (C) 2019 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.GFunctionSqrt : GFunction {
+
+ construct {
+ name = "sqrt";
+ n_params = 1;
+ param_types.add (new GConstant ());
+ }
+
+ public override Expression evaluate () throws GLib.Error
+ {
+ verify_params ();
+ GConstant c = null;
+ var exp = expressions.get_item (0) as Expression;
+ if (exp == null) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid parameter type. Expected %s",
typeof(Expression).name ());
+ }
+ var ev = exp.solve ();
+ if (ev is ErrorResult) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).message);
+ }
+ if (ev is Result) {
+ c = ((Result) ev).expression as GConstant;
+ }
+ if (c == null) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid expression in result");
+ }
+ var p1 = MPC.Complex (1000);
+ p1.set (c.get_complex ());
+ var res = MPC.Complex (1000);
+ res.sqrt (p1);
+ var nc = new GConstant.internal_complex (res);
+ return nc as Expression;
+ }
+}
+
diff --git a/gcalc/gcalc-function-tan.vala b/gcalc/gcalc-function-tan.vala
new file mode 100644
index 00000000..3793076b
--- /dev/null
+++ b/gcalc/gcalc-function-tan.vala
@@ -0,0 +1,55 @@
+/* gcalc-function-tan.vala
+ *
+ * Copyright (C) 2019 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.GFunctionTan : GFunction {
+
+ construct {
+ name = "tan";
+ n_params = 1;
+ param_types.add (new GConstant ());
+ }
+
+ public override Expression evaluate () throws GLib.Error
+ {
+ verify_params ();
+ GConstant c = null;
+ var exp = expressions.get_item (0) as Expression;
+ if (exp == null) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid parameter type. Expected %s",
typeof(Expression).name ());
+ }
+ var ev = exp.solve ();
+ if (ev is ErrorResult) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).message);
+ }
+ if (ev is Result) {
+ c = ((Result) ev).expression as GConstant;
+ }
+ if (c == null) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid expression in result");
+ }
+ var p1 = MPC.Complex (1000);
+ p1.set (c.get_complex ());
+ var res = MPC.Complex (1000);
+ res.tan (p1);
+ var nc = new GConstant.internal_complex (res);
+ return nc as Expression;
+ }
+}
+
diff --git a/gcalc/gcalc-function-tanh.vala b/gcalc/gcalc-function-tanh.vala
new file mode 100644
index 00000000..831157ba
--- /dev/null
+++ b/gcalc/gcalc-function-tanh.vala
@@ -0,0 +1,55 @@
+/* gcalc-function-tanh.vala
+ *
+ * Copyright (C) 2019 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.GFunctionTanh : GFunction {
+
+ construct {
+ name = "tanh";
+ n_params = 1;
+ param_types.add (new GConstant ());
+ }
+
+ public override Expression evaluate () throws GLib.Error
+ {
+ verify_params ();
+ GConstant c = null;
+ var exp = expressions.get_item (0) as Expression;
+ if (exp == null) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid parameter type. Expected %s",
typeof(Expression).name ());
+ }
+ var ev = exp.solve ();
+ if (ev is ErrorResult) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid expression: %s", ((ErrorResult) ev).message);
+ }
+ if (ev is Result) {
+ c = ((Result) ev).expression as GConstant;
+ }
+ if (c == null) {
+ throw new FunctionError.INVOCATION_ERROR ("Invalid expression in result");
+ }
+ var p1 = MPC.Complex (1000);
+ p1.set (c.get_complex ());
+ var res = MPC.Complex (1000);
+ res.tanh (p1);
+ var nc = new GConstant.internal_complex (res);
+ return nc as Expression;
+ }
+}
+
diff --git a/gcalc/gcalc-function.vala b/gcalc/gcalc-function.vala
new file mode 100644
index 00000000..9c6f9f8a
--- /dev/null
+++ b/gcalc/gcalc-function.vala
@@ -0,0 +1,40 @@
+/* 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 ExpressionContainer param_types { get; }
+ public abstract string name { get; construct set; }
+ public abstract uint n_params { get; construct set; }
+ public abstract bool closed { get; set; }
+ public abstract Expression evaluate () throws GLib.Error;
+ public virtual bool verify_params () throws GLib.Error {
+ if (expressions.get_n_items () != n_params) {
+ throw new FunctionError.INVALID_PARAMETERS_ERROR ("Invalid number of parameters. Required %u,
provided: %u",
+ n_params, expressions.get_n_items ());
+ }
+ return true;
+ }
+}
+
+public errordomain GCalc.FunctionError {
+ INVALID_PARAMETERS_ERROR,
+ INVOCATION_ERROR
+}
+
diff --git a/gcalc/gcalc-gassign.vala b/gcalc/gcalc-gassign.vala
new file mode 100644
index 00000000..91bf4bd9
--- /dev/null
+++ b/gcalc/gcalc-gassign.vala
@@ -0,0 +1,46 @@
+/* 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, Operator, BinaryOperator, Assign {
+ public override string to_string () {
+ 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) {
+ res = new GErrorResult ("Invalid expression in Assignment: %s".printf (e.message));
+ }
+ return res;
+ }
+}
+
diff --git a/gcalc/gcalc-gconstant.vala b/gcalc/gcalc-gconstant.vala
new file mode 100644
index 00000000..88ea0bc3
--- /dev/null
+++ b/gcalc/gcalc-gconstant.vala
@@ -0,0 +1,125 @@
+/* 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 MPC.Complex _complex = MPC.Complex (1000);
+
+ internal unowned MPC.Complex get_complex () { return _complex; }
+
+ construct {
+ _complex.set_double (0.0);
+ }
+ internal GConstant.internal_complex (MPC.Complex complex) {
+ _complex.set (complex);
+ }
+ public GConstant.integer (int val) {
+ _complex.set_double (val);
+ }
+ public GConstant.unsigned_integer (uint val) {
+ _complex.set_double (val);
+ }
+ public GConstant.@double (double val) {
+ _complex.set_double (val);
+ }
+ public GConstant.complex (double real, double imag) {
+ _complex.set_double (real, imag);
+ }
+
+ // Constant Interface
+ public double real () {
+ return _complex.get_real_double ();
+ }
+ public double imag () {
+ return _complex.get_imag_double ();
+ }
+ public void zero () {
+ MPFR.Real r = MPFR.Real (1000);
+ r.set_zero ();
+ _complex.set_mpreal (r);
+ }
+ public Constant add (Constant c)
+ requires (c is GConstant)
+ {
+ var res = MPC.Complex (1000);
+ var p1 = MPC.Complex (1000);
+ p1.set ((c as GConstant).get_complex ());
+ res.add (_complex, p1);
+ var nc = new GConstant.internal_complex (res);
+ return nc as Constant;
+ }
+ public Constant subtract (Constant c)
+ requires (c is GConstant)
+ {
+ var res = MPC.Complex (1000);
+ var p1 = MPC.Complex (1000);
+ p1.set ((c as GConstant).get_complex ());
+ res.subtract (_complex, p1);
+ var nc = new GConstant.internal_complex (res);
+ return nc as Constant;
+ }
+ public Constant multiply (Constant c)
+ requires (c is GConstant)
+ {
+ var res = MPC.Complex (1000);
+ var p1 = MPC.Complex (1000);
+ p1.set ((c as GConstant).get_complex ());
+ res.multiply (_complex, p1);
+ var nc = new GConstant.internal_complex (res);
+ return nc as Constant;
+ }
+ public Constant divide (Constant c)
+ requires (c is GConstant)
+ {
+ var res = MPC.Complex (1000);
+ var p1 = MPC.Complex (1000);
+ p1.set ((c as GConstant).get_complex ());
+ res.divide (_complex, p1);
+ var nc = new GConstant.internal_complex (res);
+ return nc as Constant;
+ }
+ public Constant neg ()
+ {
+ var res = MPC.Complex (1000);
+ res.neg (_complex);
+ var nc = new GConstant.internal_complex (res);
+ return nc as Constant;
+ }
+ public Constant pow (Constant c)
+ requires (c is GConstant)
+ {
+ var res = MPC.Complex (1000);
+ var p1 = MPC.Complex (1000);
+ p1.set ((c as GConstant).get_complex ());
+ res.power (_complex, p1);
+ var nc = new GConstant.internal_complex (res);
+ return nc as Constant;
+ }
+ // Expression interface
+ public override string to_string () {
+ if (imag () != 0.0) {
+ return MPC.Complex.to_string (10, 10, _complex);
+ }
+ return "%g".printf (real ());
+ }
+ public override Result solve () {
+ return new GResult (this) as Result;
+ }
+}
+
diff --git a/gcalc/gcalc-gdivision.vala b/gcalc/gcalc-gdivision.vala
new file mode 100644
index 00000000..9832cd0b
--- /dev/null
+++ b/gcalc/gcalc-gdivision.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.GDivision : GExpression, Operator, BinaryOperator, Division {
+ public override string to_string () {
+ return "/";
+ }
+}
+
diff --git a/gcalc/gcalc-gerror-result.vala b/gcalc/gcalc-gerror-result.vala
new file mode 100644
index 00000000..9cb43886
--- /dev/null
+++ b/gcalc/gcalc-gerror-result.vala
@@ -0,0 +1,35 @@
+/* gcalc-gerror-result.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.GErrorResult : Object, Result, ErrorResult {
+ private string msg = "";
+ private Expression _expression;
+
+ public GErrorResult (string msg) {
+ this.msg = msg;
+ _expression = new GErrorExpression ();
+ }
+ // 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
new file mode 100644
index 00000000..ea35587f
--- /dev/null
+++ b/gcalc/gcalc-gexpression.vala
@@ -0,0 +1,43 @@
+/* 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>
+ */
+public class GCalc.GExpression : Object, Expression {
+ ExpressionContainer exps = new ExpressionContainer ();
+ construct {
+ exps.parent = this;
+ }
+ // Expression
+ public weak Expression parent { get; set; }
+ public ExpressionContainer expressions { get { return exps; } }
+ public new virtual string to_string () {
+ string s = "";
+ foreach (Expression e in expressions) {
+ s += e.to_string ();
+ }
+ return s;
+ }
+ public new virtual Result solve () {
+ return new GErrorResult ("Invalid expression");
+ }
+}
+
+
+public class GCalc.GErrorExpression : GExpression, ErrorExpression {}
+
diff --git a/gcalc/gcalc-gfunction.vala b/gcalc/gcalc-gfunction.vala
new file mode 100644
index 00000000..bfb29479
--- /dev/null
+++ b/gcalc/gcalc-gfunction.vala
@@ -0,0 +1,60 @@
+/* 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, Hashable {
+ ExpressionContainer _param_types = new ExpressionContainer ();
+
+ public ExpressionContainer param_types { get { return _param_types; } }
+ public uint n_params { get; construct set; }
+ public string name { get; construct set; }
+ public bool closed { get; set; }
+
+ construct {
+ name = "NoName";
+ }
+ public GFunction.with_name (string name, int nparams) {
+ this.name = name;
+ n_params = nparams;
+ }
+ public override string to_string () {
+ 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 {
+ return new GErrorExpression ();
+ }
+ // Hashable
+ public uint hash () {
+ return name.hash ();
+ }
+}
+
diff --git a/gcalc/gcalc-ggroup.vala b/gcalc/gcalc-ggroup.vala
new file mode 100644
index 00000000..b9e7b074
--- /dev/null
+++ b/gcalc/gcalc-ggroup.vala
@@ -0,0 +1,54 @@
+/* gcalc-ggroup.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.GGroup : GExpression, Group {
+ public Group.Level level { get; set; }
+ public bool closed { get; set; }
+ public override string to_string () {
+ string s = "";
+ switch (level) {
+ case ONE:
+ s = "(";
+ break;
+ case TWO:
+ s = "[";
+ break;
+ case THREE:
+ s = "{";
+ break;
+ }
+ foreach (Expression e in expressions) {
+ s += e.to_string ();
+ }
+ switch (level) {
+ case ONE:
+ s += ")";
+ break;
+ case TWO:
+ s += "]";
+ break;
+ case THREE:
+ s += "}";
+ break;
+ }
+ return s;
+ }
+}
+
diff --git a/gcalc/gcalc-gmath-equation-manager.vala b/gcalc/gcalc-gmath-equation-manager.vala
new file mode 100644
index 00000000..c0733d35
--- /dev/null
+++ b/gcalc/gcalc-gmath-equation-manager.vala
@@ -0,0 +1,46 @@
+/* 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; } }
+
+ construct {
+ // Initialize default Functions
+ functions.add (new GFunctionSqrt ());
+ functions.add (new GFunctionExp ());
+ functions.add (new GFunctionLog ());
+ functions.add (new GFunctionSin ());
+ functions.add (new GFunctionCos ());
+ functions.add (new GFunctionTan ());
+ functions.add (new GFunctionAsin ());
+ functions.add (new GFunctionAcos ());
+ functions.add (new GFunctionAtan ());
+ functions.add (new GFunctionSinh ());
+ functions.add (new GFunctionCosh ());
+ functions.add (new GFunctionTanh ());
+ functions.add (new GFunctionAsinh ());
+ functions.add (new GFunctionAcosh ());
+ functions.add (new GFunctionAtanh ());
+ }
+}
+
diff --git a/gcalc/gcalc-gmath-equation.vala b/gcalc/gcalc-gmath-equation.vala
new file mode 100644
index 00000000..50d1157f
--- /dev/null
+++ b/gcalc/gcalc-gmath-equation.vala
@@ -0,0 +1,38 @@
+/* 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 {
+ ExpressionHashMap _variables = new ExpressionHashMap ();
+ public ExpressionHashMap variables { get { return _variables; } }
+ public override Result solve () {
+ Result res = null;
+ if (expressions.get_n_items () == 0) {
+ return new GErrorResult ("No expressions found in equation");
+ }
+ var e = expressions.get_item (0) as Expression;
+ if (e == null) {
+ res = new GErrorResult ("Invalid expression in equation");
+ } else {
+ res = e.solve ();
+ }
+ return res;
+ }
+}
+
diff --git a/gcalc/gcalc-gminus.vala b/gcalc/gcalc-gminus.vala
new file mode 100644
index 00000000..0cc90ea3
--- /dev/null
+++ b/gcalc/gcalc-gminus.vala
@@ -0,0 +1,26 @@
+/* gcalc-gminus.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.GMinus : GExpression, Operator, BinaryOperator, Minus {
+ public override string to_string () {
+ return "-";
+ }
+}
+
diff --git a/gcalc/gcalc-gmultiply.vala b/gcalc/gcalc-gmultiply.vala
new file mode 100644
index 00000000..384b092c
--- /dev/null
+++ b/gcalc/gcalc-gmultiply.vala
@@ -0,0 +1,26 @@
+/* gcalc-gmultiply.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.GMultiply : GExpression, Operator, BinaryOperator, Multiply {
+ public override string to_string () {
+ return "*";
+ }
+}
+
diff --git a/gcalc/gcalc-gparser.vala b/gcalc/gcalc-gparser.vala
new file mode 100644
index 00000000..e6918870
--- /dev/null
+++ b/gcalc/gcalc-gparser.vala
@@ -0,0 +1,503 @@
+/* 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.GParser : Object {
+ Expression current = null;
+ Expression current_parent = null;
+ Expression top_parent = null;
+ Gee.ArrayList<Vala.TokenType> expected = new Gee.ArrayList<Vala.TokenType> ();
+
+ 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);
+ string[] lines;
+ if ("\n" in str) {
+ lines = str.split ("\n");
+ } else {
+ lines = new string [0];
+ lines[0] = str;
+ }
+ Vala.TokenType token = Vala.TokenType.NONE;
+ GMathEquation eq = new GMathEquation ();
+ current = null;
+ current_parent = null;
+ top_parent = null;
+ while (token != Vala.TokenType.EOF) {
+ Vala.SourceLocation begin, end;
+ token = scanner.read_token (out begin, out end);
+ if (token == Vala.TokenType.EOF) {
+ break;
+ }
+ string n = token.to_string ();
+ n = n.replace ("`", "");
+ n = n.replace ("'", "");
+ string l = lines[begin.line - 1];
+ message ("Token: '%s' : Line: %d Column begin: %d Column end: %d Text: '%s'", n, begin.line,
begin.column, end.column, l);
+ n = l.substring (begin.column - 1, end.column - begin.column + 1);
+ message ("Token text: '%s'", n);
+ if (expected.size != 0 && !expected.contains (token)) {
+ throw new ParserError.INVALID_TOKEN_ERROR ("Found an unexpected expression");
+ }
+ switch (token) {
+ case Vala.TokenType.ABSTRACT:
+ case Vala.TokenType.AS:
+ case Vala.TokenType.ASYNC:
+ case Vala.TokenType.BASE:
+ case Vala.TokenType.BREAK:
+ case Vala.TokenType.CASE:
+ case Vala.TokenType.CATCH:
+ case Vala.TokenType.CLASS:
+ case Vala.TokenType.CONST:
+ case Vala.TokenType.CONSTRUCT:
+ case Vala.TokenType.CONTINUE:
+ case Vala.TokenType.DEFAULT:
+ case Vala.TokenType.DELEGATE:
+ case Vala.TokenType.DELETE:
+ case Vala.TokenType.DO:
+ case Vala.TokenType.DYNAMIC:
+ case Vala.TokenType.ELSE:
+ case Vala.TokenType.ENUM:
+ case Vala.TokenType.ENSURES:
+ case Vala.TokenType.ERRORDOMAIN:
+ case Vala.TokenType.EXTERN:
+ case Vala.TokenType.FALSE:
+ case Vala.TokenType.FINALLY:
+ case Vala.TokenType.FOR:
+ case Vala.TokenType.FOREACH:
+ case Vala.TokenType.GET:
+ case Vala.TokenType.IF:
+ case Vala.TokenType.IN:
+ case Vala.TokenType.INLINE:
+ case Vala.TokenType.INTERFACE:
+ case Vala.TokenType.INTERNAL:
+ case Vala.TokenType.IS:
+ case Vala.TokenType.LOCK:
+ case Vala.TokenType.NAMESPACE:
+ case Vala.TokenType.NEW:
+ case Vala.TokenType.NULL:
+ case Vala.TokenType.OUT:
+ case Vala.TokenType.OVERRIDE:
+ case Vala.TokenType.OWNED:
+ case Vala.TokenType.PARAMS:
+ case Vala.TokenType.PRIVATE:
+ case Vala.TokenType.PROTECTED:
+ case Vala.TokenType.PUBLIC:
+ case Vala.TokenType.REF:
+ case Vala.TokenType.REQUIRES:
+ case Vala.TokenType.RETURN:
+ case Vala.TokenType.SEALED:
+ case Vala.TokenType.SET:
+ case Vala.TokenType.SIGNAL:
+ case Vala.TokenType.SIZEOF:
+ case Vala.TokenType.STATIC:
+ case Vala.TokenType.STRUCT:
+ case Vala.TokenType.SWITCH:
+ case Vala.TokenType.THIS:
+ case Vala.TokenType.THROW:
+ case Vala.TokenType.THROWS:
+ case Vala.TokenType.TRUE:
+ case Vala.TokenType.TRY:
+ case Vala.TokenType.TYPEOF:
+ case Vala.TokenType.UNOWNED:
+ case Vala.TokenType.USING:
+ case Vala.TokenType.VAR:
+ case Vala.TokenType.VIRTUAL:
+ case Vala.TokenType.VOID:
+ case Vala.TokenType.VOLATILE:
+ case Vala.TokenType.WEAK:
+ case Vala.TokenType.WHILE:
+ case Vala.TokenType.YIELD:
+ case Vala.TokenType.IDENTIFIER:
+ Expression sfunc = eqman.functions.find_named (n);
+ if (sfunc != null) {
+ sfunc = Object.new (sfunc.get_type ()) as Expression;
+ if (current == null) {
+ var exp = new GPolynomial ();
+ eq.expressions.add (exp);
+ var t = new GTerm ();
+ exp.expressions.add (t);
+ t.expressions.add (sfunc);
+ current = sfunc;
+ current_parent = t;
+ 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 (current is Term && current_parent is Polynomial) {
+ current.expressions.add (sfunc);
+ current_parent = current;
+ current = sfunc;
+ top_parent = current_parent.parent;
+ expected.clear ();
+ }
+ } else if (n.down () == "def" && current == null) {
+ // FIXME: implement function definition
+ } 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;
+ var sv = eqman.find_variable (n) as Variable;
+ if (sv == null) {
+ sv = eq.variables.find_named (n) as Variable;
+ if (sv == null) {
+ eq.variables.add (v);
+ } else {
+ ((Variable) v).bind = sv;
+ }
+ } else {
+ ((Variable) v).bind = sv;
+ }
+ if (current == null) {
+ var exp = new GPolynomial ();
+ eq.expressions.add (exp);
+ var t = new GTerm ();
+ exp.expressions.add (t);
+ t.expressions.add (v);
+ current = v;
+ current_parent = v.parent;
+ top_parent = current_parent.parent;
+ expected.clear ();
+ } else if (current is Operator && current_parent is Term && top_parent is Polynomial) {
+ current_parent.expressions.add (v);
+ current = v;
+ expected.clear ();
+ } else if (current is Term) {
+ current.expressions.add (v);
+ 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 ();
+ }
+ }
+ break;
+ case Vala.TokenType.INTEGER_LITERAL:
+ case Vala.TokenType.REAL_LITERAL:
+ double res = 0;
+ if (!double.try_parse (n, out res)) {
+ throw new ParserError.INVALID_TOKEN_ERROR ("Found an unexpected expression for a constant");
+ }
+ var cexp = new GConstant.@double (double.parse (n));
+ if (current == null) {
+ var exp = new GPolynomial ();
+ eq.expressions.add (exp);
+ var t = new GTerm ();
+ exp.expressions.add (t);
+ t.expressions.add (cexp);
+ current = cexp;
+ current_parent = t;
+ top_parent = exp;
+ } else if ((current is Operator || current is Term) && current_parent is Term && top_parent is
Polynomial) {
+ current_parent.expressions.add (cexp);
+ expected.clear ();
+ current = cexp;
+ } else if (current is Term && current_parent is Polynomial && (top_parent is Group || top_parent
is Function)) {
+ current.expressions.add (cexp);
+ top_parent = current_parent;
+ current_parent = current;
+ current = cexp;
+ expected.clear ();
+ }
+ break;
+ case Vala.TokenType.PERCENT:
+ case Vala.TokenType.CHARACTER_LITERAL:
+ break;
+ case Vala.TokenType.STAR:
+ var op = new GMultiply ();
+ process_term_operator (op, eq);
+ break;
+ case Vala.TokenType.PLUS:
+ var opp = new GPlus ();
+ process_operator (opp, eq);
+ break;
+ case Vala.TokenType.DIV:
+ var op = new GDivision ();
+ process_term_operator (op, eq);
+ break;
+ case Vala.TokenType.MINUS:
+ var opp = new GMinus ();
+ process_operator (opp, eq);
+ break;
+ case Vala.TokenType.ASSIGN:
+ if (current == null) {
+ throw new ParserError.INVALID_TOKEN_ERROR ("Found an unexpected expression for an assignment");
+ } else if (current is Polynomial) {
+ throw new ParserError.INVALID_TOKEN_ERROR ("Found an unexpected expression: can't set a value to
a polynomial");
+ } else if (current is Variable) {
+ bool removed = false;
+ if (current.parent != null) {
+ if (current.parent is Term) {
+ var t = current.parent;
+ if (t.parent != null) {
+ if (t.parent is Polynomial) {
+ var p = t.parent;
+ if (p.parent != null) {
+ if (p.parent is MathEquation) {
+ eq.expressions.remove (p);
+ p.expressions.remove (t);
+ removed = true;
+ }
+ }
+ }
+ }
+ }
+ }
+ if (!removed) {
+ throw new ParserError.INVALID_EXPRESSION_ERROR ("Found an unexpected expression for an
assignment. Assignment should be done on variables");
+ }
+ var expa = new GAssign ();
+ eq.expressions.add (expa);
+ expa.expressions.add (current);
+ var exp = new GPolynomial ();
+ expa.expressions.add (exp);
+ var t = new GTerm ();
+ exp.expressions.add (t);
+ current = t;
+ current_parent = t;
+ top_parent = exp;
+ expected.clear ();
+ }
+ break;
+ case Vala.TokenType.OPEN_PARENS:
+ if (current == null) {
+ var exp = new GPolynomial ();
+ eq.expressions.add (exp);
+ var t = new GTerm ();
+ exp.expressions.add (t);
+ var g = new GGroup ();
+ t.expressions.add (g);
+ var exp2 = new GPolynomial ();
+ var t2 = new GTerm ();
+ exp2.expressions.add (t2);
+ g.expressions.add (exp2);
+ current = t2;
+ current_parent = exp2;
+ top_parent = g;
+ } else if (current is Function) {
+ message ("Function Open parens");
+ var fexp = new GPolynomial ();
+ var t = new GTerm ();
+ fexp.expressions.add (t);
+ current.expressions.add (fexp);
+ top_parent = current;
+ current = t;
+ current_parent = fexp;
+ expected.clear ();
+ } else if (current is Operator && current_parent is Term && top_parent is Polynomial) {
+ var g = new GGroup ();
+ current_parent.expressions.add (g);
+ var exp = new GPolynomial ();
+ g.expressions.add (exp);
+ var t = new GTerm ();
+ exp.expressions.add (t);
+ current = t;
+ current_parent = exp;
+ top_parent = g;
+ }
+ break;
+ case Vala.TokenType.CLOSE_PARENS:
+ if (current == null) {
+ throw new ParserError.INVALID_TOKEN_ERROR ("Found an unexpected expression while closing
parenthesis");
+ }
+ bool foundp = false;
+ var par = current;
+ while (par != null) {
+ if (par is Group) {
+ if (!((Group) par).closed) {
+ foundp = true;
+ ((Group) par).closed = true;
+ break;
+ }
+ }
+ if (par is Function) {
+ if (!((Function) par).closed) {
+ foundp = true;
+ ((Function) par).closed = true;
+ break;
+ }
+ }
+ par = par.parent;
+ }
+ if (foundp) {
+ current = par;
+ current_parent = par.parent; // Term
+ top_parent = current_parent.parent;
+ }
+ break;
+ case Vala.TokenType.CARRET:
+ var op = new GPow ();
+ if (current == null) {
+ throw new ParserError.INVALID_TOKEN_ERROR ("Found an unexpected expression trying power
expression");
+ } else {
+ process_term_operator (op, eq);
+ }
+ break;
+ // braces
+ case Vala.TokenType.CLOSE_BRACE:
+ case Vala.TokenType.CLOSE_BRACKET:
+ case Vala.TokenType.OPEN_BRACE:
+ case Vala.TokenType.OPEN_BRACKET:
+ break;
+ case Vala.TokenType.STRING_LITERAL:
+ message ("Found string literal");
+ break;
+ 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:
+ // templates and regex
+ case Vala.TokenType.CLOSE_REGEX_LITERAL:
+ case Vala.TokenType.CLOSE_TEMPLATE:
+ 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:
+ throw new ParserError.INVALID_TOKEN_ERROR ("Found an unexpected expression");
+ }
+ }
+ eqman.equations.add (eq);
+ }
+ private void process_operator (Operator opp, GMathEquation eq) throws GLib.Error {
+ if (current is BinaryOperator) {
+ throw new ParserError.INVALID_TOKEN_ERROR ("Found an unexpected expression for a plus operator");
+ }
+ if (current == null) {
+ var exp = new GPolynomial ();
+ var t = new GTerm ();
+ t.expressions.add (opp);
+ exp.expressions.add (t);
+ current = opp;
+ current_parent = t;
+ top_parent = exp;
+ eq.expressions.add (exp);
+ expected.clear ();
+ } else if (current_parent is Polynomial && current is Term) {
+ current.expressions.add (opp);
+ top_parent = current_parent;
+ current_parent = current;
+ current = opp;
+ expected.clear ();
+ } else if ((current is Constant || current is Variable)
+ && current_parent is Term && top_parent is Polynomial) {
+ // New term
+ var t = new GTerm ();
+ t.expressions.add (opp);
+ top_parent.expressions.add (t);
+ current = opp;
+ current_parent = t;
+ expected.clear ();
+ } 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);
+ top_parent.expressions.add (t);
+ current = opp;
+ current_parent = t;
+ top_parent = current_parent.parent;
+ expected.clear ();
+ } else if (current is Variable && current_parent == null) {
+ // New Polynomial
+ var exp = new GPolynomial ();
+ eq.expressions.add (exp);
+ var t = new GTerm ();
+ exp.expressions.add (t);
+ t.expressions.add (current);
+ var t2 = new GTerm ();
+ exp.expressions.add (t2);
+ t2.expressions.add (opp);
+ current = opp;
+ current_parent = t2;
+ top_parent = exp;
+ expected.clear ();
+ }
+ }
+ private void process_term_operator (Operator op, GMathEquation eq) throws GLib.Error {
+ 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 || current is Function)
+ && current_parent is Term && top_parent is Polynomial) {
+ current_parent.expressions.add (op);
+ current = op;
+ expected.clear ();
+ } else if (current is Variable && current_parent == null) {
+ // New Polynomial
+ var exp = new GPolynomial ();
+ eq.expressions.add (exp);
+ var t = new GTerm ();
+ exp.expressions.add (t);
+ t.expressions.add (current);
+ t.expressions.add (op);
+ current = op;
+ current_parent = t;
+ top_parent = exp;
+ expected.clear ();
+ }
+ }
+}
+
+public errordomain GCalc.ParserError {
+ INVALID_TOKEN_ERROR,
+ INVALID_EXPRESSION_ERROR
+}
+
diff --git a/gcalc/gcalc-gplus.vala b/gcalc/gcalc-gplus.vala
new file mode 100644
index 00000000..86ba9443
--- /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-gpolynomial.vala b/gcalc/gcalc-gpolynomial.vala
new file mode 100644
index 00000000..aa232263
--- /dev/null
+++ b/gcalc/gcalc-gpolynomial.vala
@@ -0,0 +1,33 @@
+/* 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 {
+ public override Result solve () {
+ Result res = null;
+ try {
+ var e = evaluate ();
+ res = new GResult (e) as Result;
+ } catch (GLib.Error err) {
+ res = new GErrorResult ("Polynomial solving fails: %s".printf (err.message));
+ }
+ return res;
+ }
+}
+
diff --git a/gcalc/gcalc-gpow.vala b/gcalc/gcalc-gpow.vala
new file mode 100644
index 00000000..c21cb561
--- /dev/null
+++ b/gcalc/gcalc-gpow.vala
@@ -0,0 +1,26 @@
+/* gcalc-gpow.vala
+ *
+ * Copyright (C) 2019 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.GPow : GExpression, Operator, Pow {
+ public override string to_string () {
+ return "^";
+ }
+}
+
diff --git a/gcalc/gcalc-gresult.vala b/gcalc/gcalc-gresult.vala
new file mode 100644
index 00000000..20bd8369
--- /dev/null
+++ b/gcalc/gcalc-gresult.vala
@@ -0,0 +1,32 @@
+/* gcalc-gresult.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.GResult : Object, Result {
+ private Expression _expression;
+ public GResult (Expression exp) {
+ _expression = exp;
+ }
+ // Result
+ public string to_string () {
+ return expression.to_string ();
+ }
+ public Expression expression { get { return _expression; } }
+}
+
diff --git a/gcalc/gcalc-group.vala b/gcalc/gcalc-group.vala
new file mode 100644
index 00000000..cfe4c994
--- /dev/null
+++ b/gcalc/gcalc-group.vala
@@ -0,0 +1,45 @@
+/* gcalc-group.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.Group : Object, Expression {
+ public enum Level {
+ ONE,
+ TWO,
+ THREE
+ }
+ public abstract Level level { get; set; }
+ public abstract bool closed { get; set; }
+ public virtual Expression evaluate () throws GLib.Error {
+ if (expressions.get_n_items () == 0) {
+ throw new GroupError.INVALID_POLYNOMIAL ("No internal polynomial in group");
+ }
+ var e = expressions.get_item (0) as Polynomial;
+ if (e == null) {
+ throw new GroupError.INVALID_POLYNOMIAL ("Invalid internal polynomial in group");
+ }
+ return e.evaluate ();
+ }
+}
+
+public errordomain GCalc.GroupError {
+ INVALID_POLYNOMIAL,
+ INVALID_INTERNAL_TERM,
+}
+
diff --git a/gcalc/gcalc-gsolver.vala b/gcalc/gcalc-gsolver.vala
new file mode 100644
index 00000000..6694b8f5
--- /dev/null
+++ b/gcalc/gcalc-gsolver.vala
@@ -0,0 +1,47 @@
+/* gcalc-solver.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 GCalc;
+
+public class GCalc.GSolver : Object, Solver {
+ construct {
+ equation_manager = new GMathEquationManager ();
+ }
+ // Sover
+ public MathEquationManager equation_manager { get; set; }
+ public Result solve (string str) throws GLib.Error {
+ var p = new GParser ();
+ Result res;
+ try {
+ p.parse (str, equation_manager);
+ if (equation_manager.equations.get_n_items () == 0) {
+ return new GErrorResult ("No equations found after parsing");
+ }
+ var eq = equation_manager.equations.get_item (0) as MathEquation;
+ if (eq == null) {
+ return new GErrorResult ("No equations found after parsing");
+ }
+ res = eq.solve ();
+ } catch (GLib.Error e) {
+ res = new GErrorResult ("Solving fails: %s".printf (e.message));
+ }
+ return res;
+ }
+}
diff --git a/gcalc/gcalc-gterm.vala b/gcalc/gcalc-gterm.vala
new file mode 100644
index 00000000..1402273c
--- /dev/null
+++ b/gcalc/gcalc-gterm.vala
@@ -0,0 +1,33 @@
+/* gcalc-gterm.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.GTerm : GExpression, Term {
+ public override Result solve () {
+ Result res = null;
+ try {
+ var e = evaluate ();
+ res = new GResult (e) as Result;
+ } catch (GLib.Error err) {
+ res = new GErrorResult ("Term evaluation fails: %s".printf (err.message));
+ }
+ return res;
+ }
+}
+
diff --git a/gcalc/gcalc-gvariable.vala b/gcalc/gcalc-gvariable.vala
new file mode 100644
index 00000000..bd9b3a3d
--- /dev/null
+++ b/gcalc/gcalc-gvariable.vala
@@ -0,0 +1,42 @@
+/* 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, Hashable {
+
+ public string name { get; construct set; }
+ public Constant value { get; set; }
+ public Variable bind { get; set; }
+
+ construct {
+ _value = new GConstant.@double (0.0);
+ }
+ public GVariable (string name) {
+ this.name = name;
+ }
+ // Expression
+ public override string to_string () {
+ return name;
+ }
+ // Hashable
+ public uint hash () {
+ return name.hash ();
+ }
+}
+
diff --git a/gcalc/gcalc-hashable.vala b/gcalc/gcalc-hashable.vala
new file mode 100644
index 00000000..9d147607
--- /dev/null
+++ b/gcalc/gcalc-hashable.vala
@@ -0,0 +1,24 @@
+/* gcalc-hashable.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.Hashable : Object {
+ public abstract uint hash ();
+}
+
diff --git a/gcalc/gcalc-math-equation-manager.vala b/gcalc/gcalc-math-equation-manager.vala
new file mode 100644
index 00000000..5bc076cd
--- /dev/null
+++ b/gcalc/gcalc-math-equation-manager.vala
@@ -0,0 +1,40 @@
+/* gcalc-math-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 interface GCalc.MathEquationManager : Object {
+ public abstract ExpressionContainer equations { get; }
+ public abstract ExpressionContainer functions { get; }
+ public virtual Variable find_variable (string name) {
+ Variable res = null;
+ foreach (Expression e in equations) {
+ var eq = e as MathEquation;
+ if (e == null) {
+ continue;
+ }
+ var v = eq.variables.find_named (name) as Variable;
+ if (v != null) {
+ res = v;
+ break;
+ }
+ }
+ return res;
+ }
+}
+
diff --git a/gcalc/gcalc-math-equation.vala b/gcalc/gcalc-math-equation.vala
new file mode 100644
index 00000000..f76a3032
--- /dev/null
+++ b/gcalc/gcalc-math-equation.vala
@@ -0,0 +1,24 @@
+/* gcalc-math-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 interface GCalc.MathEquation : Object, Expression {
+ public abstract ExpressionHashMap variables { get; }
+}
+
diff --git a/gcalc/gcalc-minus.vala b/gcalc/gcalc-minus.vala
new file mode 100644
index 00000000..0722fd80
--- /dev/null
+++ b/gcalc/gcalc-minus.vala
@@ -0,0 +1,22 @@
+/* gcalc-minus.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.Minus : Object, Expression, Operator, BinaryOperator {}
+
diff --git a/gcalc/gcalc-multiply.vala b/gcalc/gcalc-multiply.vala
new file mode 100644
index 00000000..bde0f5be
--- /dev/null
+++ b/gcalc/gcalc-multiply.vala
@@ -0,0 +1,22 @@
+/* gcalc-multiply.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.Multiply : Object, Expression, Operator, BinaryOperator {}
+
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-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/gcalc-polynomial.vala b/gcalc/gcalc-polynomial.vala
new file mode 100644
index 00000000..dd52e225
--- /dev/null
+++ b/gcalc/gcalc-polynomial.vala
@@ -0,0 +1,61 @@
+/* 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 {
+ public virtual Expression evaluate () throws GLib.Error {
+ Term current = null;
+ Expression res = null;
+ for (uint i = 0; i < expressions.get_n_items (); i++) {
+ var e = expressions.get_item (i) as Term;
+ if (e == null) {
+ continue;
+ }
+ if (current == null) {
+ current = (Term) e;
+ if (i+1 < expressions.get_n_items ()) {
+ continue;
+ }
+ var er = ((Term) e).evaluate ();
+ if (res == null) {
+ res = er;
+ break;
+ }
+ if (res is Constant && er is Constant) {
+ res = ((Constant) res).add ((Constant) er);
+ break;
+ }
+ }
+ var re = current.add ((Term) e);
+ current = null;
+ if (res == null) {
+ res = re;
+ } else if (res is Constant && re is Constant) {
+ res = ((Constant) res).add ((Constant) re);
+ }
+ if (res != null) {
+ }
+ }
+ if (res == null) {
+ return new GErrorExpression ();
+ }
+ return res;
+ }
+}
+
diff --git a/gcalc/gcalc-pow.vala b/gcalc/gcalc-pow.vala
new file mode 100644
index 00000000..39e2d84b
--- /dev/null
+++ b/gcalc/gcalc-pow.vala
@@ -0,0 +1,22 @@
+/* gcalc-pow.vala
+ *
+ * Copyright (C) 2019 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.Pow : Object, Expression, Operator {}
+
diff --git a/gcalc/gcalc-result.vala b/gcalc/gcalc-result.vala
new file mode 100644
index 00000000..a1bfcb7a
--- /dev/null
+++ b/gcalc/gcalc-result.vala
@@ -0,0 +1,25 @@
+/* gcalc-result.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.Result : Object {
+ public abstract string to_string ();
+ public abstract Expression expression { get; }
+}
+
diff --git a/gcalc/gcalc-solver.vala b/gcalc/gcalc-solver.vala
new file mode 100644
index 00000000..49d7bff6
--- /dev/null
+++ b/gcalc/gcalc-solver.vala
@@ -0,0 +1,28 @@
+/* gcalc-solver.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.Solver : Object {
+ public abstract MathEquationManager equation_manager { get; set; }
+ public abstract Result solve (string str) throws GLib.Error;
+}
+
+public errordomain GCalc.SolverError {
+ EXPRESSION_ERROR
+}
diff --git a/gcalc/gcalc-term.vala b/gcalc/gcalc-term.vala
new file mode 100644
index 00000000..db69629b
--- /dev/null
+++ b/gcalc/gcalc-term.vala
@@ -0,0 +1,127 @@
+/* gcalc-term.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.Term : Object, Expression {
+ public virtual Expression add (Term t) throws GLib.Error {
+ if (t.expressions.get_n_items () == 0) {
+ return new GConstant.@double (1.0);
+ }
+ Expression res = new GErrorExpression ();
+ var e = evaluate ();
+ var e2 = t.evaluate ();
+ if (e is Constant && e2 is Constant) {
+ res = ((Constant) e).add ((Constant) e2);
+ }
+ return res;
+ }
+ public virtual Expression evaluate () throws GLib.Error {
+ message ("Evaluating term: %s", this.to_string ());
+ Expression current = null;
+ Operator current_operator = null;
+ bool first = true;
+ foreach (Expression e in expressions) {
+ 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");
+ }
+ if (e is Minus && first) {
+ var c = new GConstant.@double (-1.0);
+ current = c;
+ first = false;
+ }
+ message ("Setting current operator to: %s", e.get_type ().name());
+ current_operator = e as Operator;
+ continue;
+ } else if (e is Constant) {
+ if (current == null) {
+ current = e;
+ first = false;
+ } else if (current is Constant) {
+ if (current_operator != null) {
+ current = evaluate_constants ((Constant) current, (Constant) e, current_operator);
+ }
+ }
+ } else if (e is Group) {
+ var ev = ((Group) 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);
+ }
+ }
+ } 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);
+ }
+ }
+ } else if (e is Variable) {
+ message ("Evaluating Variable '%s'", (e as Variable).name);
+ var ev = (e as Variable).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);
+ }
+ }
+ }
+ }
+ if (current == null) {
+ throw new TermError.EVALUATION_FAIL ("Evaluation fail on Term");
+ }
+ return current;
+ }
+ public static Expression evaluate_constants (Constant c1, Constant c2, Operator op)
+ throws GLib.Error
+ {
+ Expression res = null;
+ if (op is Minus) {
+ res = (c1 as Constant).multiply (c2 as Constant);
+ }
+ if (op is Multiply) {
+ res = (c1 as Constant).multiply (c2 as Constant);
+ }
+ if (op is Division) {
+ res = (c1 as Constant).divide (c2 as Constant);
+ }
+ if (op is Pow) {
+ res = (c1 as Constant).pow (c2 as Constant);
+ }
+ if (res == null) {
+ throw new TermError.INVALID_OPERATOR ("Unsupported operator in term's expression");
+ }
+ return res;
+ }
+}
+
+public errordomain GCalc.TermError {
+ INVALID_OPERATOR,
+ EVALUATION_FAIL,
+}
+
diff --git a/gcalc/gcalc-variable.vala b/gcalc/gcalc-variable.vala
new file mode 100644
index 00000000..7f1f62da
--- /dev/null
+++ b/gcalc/gcalc-variable.vala
@@ -0,0 +1,56 @@
+/* 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 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 ();
+ }
+ 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;
+ message ("Variable '%s' evaluated to: %s", name, @value.to_string ());
+ return exp;
+ }
+}
+
+public errordomain GCalc.VariableError {
+ INVALID_PARENT,
+ INVALID_EXPRESSION_DEFINITION,
+ EVALUATION_FAIL
+}
+
diff --git a/gcalc/gcalc.deps.in b/gcalc/gcalc.deps.in
new file mode 100644
index 00000000..23d423ce
--- /dev/null
+++ b/gcalc/gcalc.deps.in
@@ -0,0 +1,3 @@
+gio-2.0
+gee-0.8
+libvala-@VALA_API_VERSION@
diff --git a/gcalc/gcalc.pc.in b/gcalc/gcalc.pc.in
new file mode 100644
index 00000000..faaae0bb
--- /dev/null
+++ b/gcalc/gcalc.pc.in
@@ -0,0 +1,13 @@
+prefix=@prefix@
+exec_prefix=${prefix}
+libdir=@libdir@
+datadir=@prefix@/share
+includedir=@prefix@/include
+
+Name: libgcalc
+Description: GNOME Calculator Libray
+URL: http://live.gnome.org/
+Version: @PROJECT_VERSION@
+Requires: gio-2.0 >= 2.50
+Libs: -L${libdir} -lgcalc-@API_VERSION@
+Cflags: -I${includedir}/gcalc-@API_VERSION@
diff --git a/gcalc/meson.build b/gcalc/meson.build
new file mode 100644
index 00000000..06517e27
--- /dev/null
+++ b/gcalc/meson.build
@@ -0,0 +1,187 @@
+PROJECT_NAME='gcalc'
+API_VERSION='1'
+VERSIONED_PROJECT_NAME=PROJECT_NAME+'-'+API_VERSION
+CAMEL_CASE_NAME='GCalc'
+VERSIONED_CAMEL_CASE_NAME=CAMEL_CASE_NAME+'-'+API_VERSION
+vapidir = join_paths (get_option('datadir'),'vala','vapi')
+GIR_NAME= VERSIONED_CAMEL_CASE_NAME+'.gir'
+TYPELIB_NAME= VERSIONED_CAMEL_CASE_NAME+'.typelib'
+VAPI_NAME = VERSIONED_PROJECT_NAME+'.vapi'
+
+conf = configuration_data()
+conf.set('prefix', get_option('prefix'))
+conf.set('libdir', '${exec_prefix}/'+get_option ('libdir'))
+conf.set('PROJECT_NAME', PROJECT_NAME)
+conf.set('PROJECT_VERSION', meson.project_version ())
+conf.set('API_VERSION', API_VERSION)
+conf.set('VALA_API_VERSION', vala_version)
+
+configure_file(input : 'gcalc.pc.in',
+ output : 'gcalc-@0@.pc'.format(API_VERSION),
+ configuration : conf,
+ install : true,
+ install_dir : join_paths(get_option('libdir'), 'pkgconfig'))
+
+configure_file(input : 'gcalc.deps.in',
+ output : 'gcalc-@0@.deps'.format(API_VERSION),
+ configuration : conf,
+ install : true,
+ install_dir : vapidir)
+
+nsinfo = configure_file(input : 'namespace-info.vala.in',
+ output : 'namespace-info.vala',
+ configuration : conf)
+namespaceinfo_dep = declare_dependency (sources : nsinfo)
+
+confh = configuration_data ()
+confh.set_quoted('PACKAGE_LOCALE_DIR', join_paths(get_option('prefix'), get_option('datadir'), 'locale'))
+confh.set_quoted('GETTEXT_PACKAGE', 'GCalc')
+configure_file(output : 'config.h',
+ configuration : confh)
+
+
+lib_mpfrg_sources = files([
+ 'mpfr-glue.vala'
+])
+
+lib_mpfrg = static_library ('mpfrg',
+ lib_mpfrg_sources,
+ vala_header: 'mpfrg.h',
+ vala_vapi: 'mpfrg.vapi',
+ dependencies: [
+ gio,
+ mpc,
+ mpfr,
+ ],
+ install: false,
+)
+
+sources = files([
+ 'gcalc-assign.vala',
+ 'gcalc-binary-operator.vala',
+ 'gcalc-constant.vala',
+ 'gcalc-division.vala',
+ 'gcalc-expression.vala',
+ 'gcalc-expression-container.vala',
+ 'gcalc-expression-hash-map.vala',
+ 'gcalc-function.vala',
+ 'gcalc-function-acos.vala',
+ 'gcalc-function-acosh.vala',
+ 'gcalc-function-asin.vala',
+ 'gcalc-function-asinh.vala',
+ 'gcalc-function-atan.vala',
+ 'gcalc-function-atanh.vala',
+ 'gcalc-function-cos.vala',
+ 'gcalc-function-cosh.vala',
+ 'gcalc-function-exp.vala',
+ 'gcalc-function-log.vala',
+ 'gcalc-function-sin.vala',
+ 'gcalc-function-sinh.vala',
+ 'gcalc-function-sqrt.vala',
+ 'gcalc-function-tan.vala',
+ 'gcalc-function-tanh.vala',
+ 'gcalc-error-result.vala',
+ 'gcalc-gexpression.vala',
+ 'gcalc-gassign.vala',
+ 'gcalc-gconstant.vala',
+ 'gcalc-gdivision.vala',
+ 'gcalc-gerror-result.vala',
+ 'gcalc-gfunction.vala',
+ 'gcalc-gmath-equation.vala',
+ 'gcalc-gmath-equation-manager.vala',
+ 'gcalc-gminus.vala',
+ 'gcalc-gmultiply.vala',
+ 'gcalc-gparser.vala',
+ 'gcalc-gplus.vala',
+ 'gcalc-gpolynomial.vala',
+ 'gcalc-gpow.vala',
+ 'gcalc-gresult.vala',
+ 'gcalc-group.vala',
+ 'gcalc-ggroup.vala',
+ 'gcalc-gsolver.vala',
+ 'gcalc-gterm.vala',
+ 'gcalc-gvariable.vala',
+ 'gcalc-hashable.vala',
+ 'gcalc-math-equation.vala',
+ 'gcalc-math-equation-manager.vala',
+ 'gcalc-minus.vala',
+ 'gcalc-multiply.vala',
+ 'gcalc-operator.vala',
+ 'gcalc-plus.vala',
+ 'gcalc-polynomial.vala',
+ 'gcalc-pow.vala',
+ 'gcalc-result.vala',
+ 'gcalc-solver.vala',
+ 'gcalc-term.vala',
+ 'gcalc-variable.vala',
+])
+
+
+inc_libh = include_directories ('.')
+inc_libh_dep = declare_dependency (include_directories : inc_libh)
+
+deps = [
+ gio,
+ namespaceinfo_dep,
+ inc_libh_dep,
+ inc_rooth_dep,
+ posix,
+ libxml,
+ libsoup,
+ vala_dep,
+ libmath,
+ gee
+]
+
+# LT_VERSION for ABI related changes
+# From: https://autotools.io/libtool/version.html
+# This rules applies to Meson 0.43
+# Increase the current value whenever an interface has been added, removed or changed.
+# Always increase revision value whenever an interface has been added, removed or changed.
+# Increase the age value only if the changes made to the ABI are backward compatible.
+# Set version to the value of subtract age from current
+# Reset current and version to 1 and, age and version to 0 if library's name is changed
+LT_CURRENT='0'
+LT_REVISION='0'
+LT_AGE='0'
+LT_VERSION='0'
+lib = library(VERSIONED_PROJECT_NAME,
+ sources,
+ version : LT_VERSION,
+ soversion : LT_VERSION+'.'+LT_AGE+'.'+LT_REVISION,
+ vala_header : PROJECT_NAME+'.h',
+ vala_vapi : VAPI_NAME,
+ vala_gir : GIR_NAME,
+ dependencies : deps,
+ vala_args: [
+ '--vapidir='+vapi_dir,
+ '--pkg=mpc',
+ '--pkg=mpfr'
+ ],
+ c_args : [
+ '-include',
+ meson.current_build_dir() + '/config.h',
+ ],
+ link_with: [ lib_mpfrg ],
+ install : true,
+ install_dir : [
+ true,
+ join_paths (get_option('includedir'), 'gcalc-@0@'.format (API_VERSION), 'gcalc'),
+ vapidir,
+ true
+ ])
+
+g_ir_compiler = find_program('g-ir-compiler', required: false)
+if g_ir_compiler.found() and not get_option('disable-introspection')
+custom_target('typelib',
+ command: [
+ g_ir_compiler,
+ '--shared-library', 'lib'+PROJECT_NAME+'-@0@.so'.format (API_VERSION),
+ '--output', '@OUTPUT@',
+ join_paths(meson.current_build_dir(), GIR_NAME)
+ ],
+ output: TYPELIB_NAME,
+ depends: lib,
+ install: true,
+ install_dir: join_paths(get_option('libdir'), 'girepository-1.0'))
+endif
\ No newline at end of file
diff --git a/gcalc/mpfr-glue.vala b/gcalc/mpfr-glue.vala
new file mode 100644
index 00000000..9e801748
--- /dev/null
+++ b/gcalc/mpfr-glue.vala
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2016 Phillip Wood <phillip wood dunelm org uk>
+ *
+ * GNOME Calculator - mpfr-glue.vala
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Phillip Wood <phillip wood dunelm org uk>
+ */
+
+namespace MPFRG
+{
+ [Compact]
+ public class RealRef {
+ public MPFR.Real val;
+ }
+}
diff --git a/gcalc/namespace-info.vala.in b/gcalc/namespace-info.vala.in
new file mode 100644
index 00000000..01b7b864
--- /dev/null
+++ b/gcalc/namespace-info.vala.in
@@ -0,0 +1,24 @@
+/* -*- Mode: vala; indent-tabs-mode: nil; c-basic-offset: 2; tab-width: 2 -*- */
+/* Attr.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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors:
+ * Daniel Espinosa <esodan gmail com>
+ */
+[CCode (gir_namespace = "GCalc", gir_version = "@API_VERSION@", cheader_filename = "gcalc/@PROJECT_NAME@.h")]
+namespace GCalc {}
diff --git a/lib/meson.build b/lib/meson.build
index bc1b9792..7cc854f6 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -1,5 +1,4 @@
libcalculator_sources = [
- 'mpfr-glue.vala',
'currency.vala',
'equation.vala',
'equation-lexer.vala',
@@ -33,6 +32,7 @@ libcalculator_deps = [
mpc,
mpfr,
posix,
+ inc_libh_dep
]
libcalculator = static_library('calculator', libcalculator_sources,
@@ -40,5 +40,6 @@ libcalculator = static_library('calculator', libcalculator_sources,
c_args: libcalculator_c_flags,
vala_args: libcalculator_vala_flags,
include_directories: config_h_dir,
+ link_with: [ lib_mpfrg ],
install: false,
)
diff --git a/lib/mpfr-glue.vala b/lib/mpfr-glue.vala
index e52c0f6f..9e801748 100644
--- a/lib/mpfr-glue.vala
+++ b/lib/mpfr-glue.vala
@@ -19,7 +19,7 @@
* Authors: Phillip Wood <phillip wood dunelm org uk>
*/
-namespace MPFR
+namespace MPFRG
{
[Compact]
public class RealRef {
diff --git a/meson.build b/meson.build
index 11ebd68e..1050d8f1 100644
--- a/meson.build
+++ b/meson.build
@@ -4,6 +4,9 @@ project('gnome-calculator', ['c', 'vala'],
license: 'GPLv3+',
)
+inc_rooth = include_directories ('.')
+inc_rooth_dep = declare_dependency (include_directories : inc_rooth)
+
gnome = import('gnome')
i18n = import('i18n')
@@ -25,10 +28,19 @@ gio = dependency('gio-2.0', version: '>= ' + glib_min_version)
glib = dependency('glib-2.0', version: '>= ' + glib_min_version)
gmodule_export = dependency('gmodule-export-2.0')
gobject = dependency('gobject-2.0', version: '>= ' + glib_min_version)
-gtk = dependency('gtk+-3.0', version: '>= 3.19.3')
-gtksourceview = dependency('gtksourceview-4', version: '>= 4.0.2')
-libsoup = dependency('libsoup-2.4', version: '>= 2.42')
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')
@@ -63,10 +75,15 @@ config_h_dir = include_directories('.')
meson.add_install_script('meson_post_install.py')
# Subdirs
+subdir('gcalc')
+if not get_option ('disable-ui')
+gtk = dependency('gtk+-3.0', version: '>= 3.19.3')
+gtksourceview = dependency('gtksourceview-4', version: '>= 4.0.2')
subdir('data')
subdir('lib')
subdir('src')
subdir('search-provider')
-subdir('tests')
subdir('help')
subdir('po')
+endif
+subdir('tests')
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644
index 00000000..96472bb7
--- /dev/null
+++ b/meson_options.txt
@@ -0,0 +1,3 @@
+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)')
+option('disable-introspection', type : 'boolean', value : false, description : 'Disable GObject
Introspection Typelib generation')
\ No newline at end of file
diff --git a/org.gnome.Calculator.json b/org.gnome.Calculator.json
index b5826475..7ffbafd7 100644
--- a/org.gnome.Calculator.json
+++ b/org.gnome.Calculator.json
@@ -1,74 +1,103 @@
{
- "app-id": "org.gnome.Calculator",
- "runtime": "org.gnome.Platform",
- "runtime-version": "master",
- "sdk": "org.gnome.Sdk",
- "command": "gnome-calculator",
- "tags": ["nightly"],
- "desktop-file-name-prefix": "(Nightly) ",
- "finish-args": [
- /* X11 + XShm access */
- "--share=ipc", "--socket=x11",
- /* Wayland access */
+ "app-id" : "org.gnome.Calculator",
+ "runtime" : "org.gnome.Sdk",
+ "runtime-version" : "master",
+ "sdk" : "org.gnome.Sdk",
+ "command" : "gnome-calculator",
+ "tags" : [
+ "nightly"
+ ],
+ "desktop-file-name-prefix" : "(Nightly) ",
+ "finish-args" : [
+ "--share=ipc",
+ "--socket=x11",
"--socket=wayland",
- /* Needs to talk to the network to get currency data */
"--share=network",
- /* Needed for dconf to work */
- "--filesystem=xdg-run/dconf", "--filesystem=~/.config/dconf:ro",
- "--talk-name=ca.desrt.dconf", "--env=DCONF_USER_CONFIG_DIR=.config/dconf"
+ "--filesystem=xdg-run/dconf",
+ "--filesystem=~/.config/dconf:ro",
+ "--talk-name=ca.desrt.dconf",
+ "--env=DCONF_USER_CONFIG_DIR=.config/dconf"
],
"build-options" : {
- "cflags": "-O2 -g -w",
- "cxxflags": "-O2 -g -w"
+ "cflags" : "-O2 -g -w",
+ "cxxflags" : "-O2 -g -w",
+ "env" : {
+ }
},
- "cleanup": ["/include", "/lib/pkgconfig",
- "/share/pkgconfig", "/share/aclocal",
- "/man", "/share/man", "/share/gtk-doc",
- "/share/vala", "*.la", "*.a",
- "/bin/gcalccmd",
- "/lib/girepository-1.0", "/share/info", "/share/gtksourceview-4",
- "/share/doc", "/share/gir-1.0"
+ "cleanup" : [
+ "/include",
+ "/lib/pkgconfig",
+ "/share/pkgconfig",
+ "/share/aclocal",
+ "/man",
+ "/share/man",
+ "/share/gtk-doc",
+ "/share/vala",
+ "*.la",
+ "*.a",
+ "/bin/gcalccmd",
+ "/lib/girepository-1.0",
+ "/share/info",
+ "/share/gtksourceview-4",
+ "/share/doc",
+ "/share/gir-1.0"
],
- "modules": [
+ "modules" : [
{
- "name": "mpfr",
- "sources": [
+ "name" : "mpfr",
+ "sources" : [
{
- "type": "archive",
- "url": "http://www.mpfr.org/mpfr-4.0.1/mpfr-4.0.1.tar.xz",
- "sha256": "67874a60826303ee2fb6affc6dc0ddd3e749e9bfcb4c8655e3953d0458a6e16e"
+ "type" : "archive",
+ "url" : "http://www.mpfr.org/mpfr-4.0.1/mpfr-4.0.1.tar.xz",
+ "sha256" : "67874a60826303ee2fb6affc6dc0ddd3e749e9bfcb4c8655e3953d0458a6e16e"
}
]
},
{
- "name": "mpc",
+ "name" : "mpc",
"config-opts" : [
"--with-mpfr=/app"
],
- "sources": [
+ "sources" : [
{
- "type": "archive",
- "url": "https://ftp.gnu.org/gnu/mpc/mpc-1.1.0.tar.gz",
- "sha256": "6985c538143c1208dcb1ac42cedad6ff52e267b47e5f970183a3e75125b43c2e"
+ "type" : "archive",
+ "url" : "https://ftp.gnu.org/gnu/mpc/mpc-1.1.0.tar.gz",
+ "sha256" : "6985c538143c1208dcb1ac42cedad6ff52e267b47e5f970183a3e75125b43c2e"
}
]
},
{
- "name": "gtksourceview",
- "sources": [
+ "name" : "gtksourceview",
+ "sources" : [
{
- "type": "git",
- "url": "https://gitlab.gnome.org/GNOME/gtksourceview.git"
+ "type" : "git",
+ "url" : "https://gitlab.gnome.org/GNOME/gtksourceview.git"
}
]
},
{
- "name": "gnome-calculator",
- "buildsystem": "meson",
- "sources": [
+ "name" : "gee",
+ "config-opts" : [
+ "--disable-introspection"
+ ],
+ "sources" : [
+ {
+ "type" : "archive",
+ "url" : "https://download.gnome.org/sources/libgee/0.20/libgee-0.20.1.tar.xz",
+ "sha256" : "bb2802d29a518e8c6d2992884691f06ccfcc25792a5686178575c7111fea4630"
+ }
+ ]
+ },
+ {
+ "name" : "gnome-calculator",
+ "buildsystem" : "meson",
+ "config-opts" : [
+ "-Ddisable-introspection=true"
+ ],
+ "sources" : [
{
- "type": "git",
- "url": "https://gitlab.gnome.org/GNOME/gnome-calculator.git"
+ "type" : "git",
+ "url" : "https://gitlab.gnome.org/GNOME/gnome-calculator.git"
}
]
}
diff --git a/search-provider/meson.build b/search-provider/meson.build
index 00c6f84a..9ddf53fb 100644
--- a/search-provider/meson.build
+++ b/search-provider/meson.build
@@ -11,6 +11,7 @@ search_provider_deps = [
mpc,
mpfr,
posix,
+ inc_libh_dep
]
search_provider_vala_flags = [
@@ -30,7 +31,7 @@ search_provider_includes = [
# The executable
executable('gnome-calculator-search-provider', search_provider_sources,
dependencies: search_provider_deps,
- link_with: libcalculator,
+ link_with: [libcalculator, lib_mpfrg],
install_dir: get_option('libexecdir'),
include_directories: search_provider_includes,
vala_args: search_provider_vala_flags,
@@ -52,4 +53,4 @@ configure_file(
configuration: dbusconf,
install: true,
install_dir: join_paths(get_option('datadir'), 'dbus-1', 'services'),
-)
+)
\ No newline at end of file
diff --git a/src/meson.build b/src/meson.build
index 5f374d85..7172149b 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -27,6 +27,7 @@ gnome_calculator_deps = [
mpc,
mpfr,
posix,
+ inc_libh_dep
]
gnome_calculator_vala_flags = [
@@ -47,10 +48,10 @@ gnome_calculator_includes = [
executable('gnome-calculator', gnome_calculator_sources,
dependencies: gnome_calculator_deps,
- link_with: libcalculator,
include_directories: gnome_calculator_includes,
vala_args: gnome_calculator_vala_flags,
c_args: gnome_calculator_c_flags,
+ link_with: [libcalculator, lib_mpfrg],
install: true,
)
@@ -69,6 +70,7 @@ gcalccmd_deps = [
mpc,
mpfr,
posix,
+ inc_libh_dep
]
gcalccmd_vala_flags = [
@@ -83,7 +85,7 @@ gcalccmd_includes = [
executable('gcalccmd', gcalccmd_sources,
dependencies: gcalccmd_deps,
- link_with: libcalculator,
+ link_with: [libcalculator, lib_mpfrg],
include_directories: gcalccmd_includes,
vala_args: gcalccmd_vala_flags,
install: true,
diff --git a/tests/gcalc-parsing.vala b/tests/gcalc-parsing.vala
new file mode 100644
index 00000000..e71e8380
--- /dev/null
+++ b/tests/gcalc-parsing.vala
@@ -0,0 +1,1076 @@
+/* -*- Mode: Vala; indent-tabs-mode: nil; c-basic-offset: 2; tab-width: 2 -*- */
+/*
+ * GCalc Unit Tests
+ * Copyright (C) Daniel Espinosa Ortiz 2018 <esodan gmail com>
+ *
+ * libgda 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * libgda 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 program. If not, see <http://www.gnu.org/licenses/>.
+ */
+using GCalc;
+
+class Tests {
+ static int main (string[] args)
+ {
+ GLib.Intl.setlocale (GLib.LocaleCategory.ALL, "");
+ Test.init (ref args);
+ Test.add_func ("/gcalc/parser/constant/integer",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("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 != null);
+ assert (p.expressions.get_n_items () == 1);
+ var t = p.expressions.get_item (0) as Term;
+ assert (t != null);
+ assert (t.expressions.get_n_items () == 1);
+ var c = t.expressions.get_item (0) as Constant;
+ assert (c != null);
+ } catch (GLib.Error error) {
+ warning ("Error: %s", error.message);
+ }
+ });
+ Test.add_func ("/gcalc/parser/constant/double",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("10.3", 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 != null);
+ assert (p.expressions.get_n_items () == 1);
+ var t = p.expressions.get_item (0) as Term;
+ assert (t != null);
+ assert (t.expressions.get_n_items () == 1);
+ var c = t.expressions.get_item (0) as Constant;
+ assert (c != null);
+ } catch (GLib.Error error) {
+ warning ("Error: %s", error.message);
+ }
+ });
+ Test.add_func ("/gcalc/parser/assign/error",
+ ()=>{
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ try {
+ parser.parse ("=", eqman);
+ assert_not_reached ();
+ } catch (GLib.Error error) {
+ message ("Error catched correctly: %s", error.message);
+ }
+ });
+ Test.add_func ("/gcalc/parser/assign/variable/constant",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("var=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 assign = eq.expressions.get_item (0) as Assign;
+ assert (assign != null);
+ assert (assign.expressions.get_n_items () == 2);
+ var v = assign.expressions.get_item (0) as Variable;
+ assert (v != null);
+ assert (v.name == "var");
+ var p = assign.expressions.get_item (1) as Polynomial;
+ assert (p != null);
+ assert (p.expressions.get_n_items () == 1);
+ var t = p.expressions.get_item (0) as Term;
+ assert (t != null);
+ assert (t.expressions.get_n_items () == 1);
+ var c = t.expressions.get_item (0) as Constant;
+ assert (c != null);
+ } catch (GLib.Error error) {
+ warning ("Error: %s", error.message);
+ }
+ });
+ Test.add_func ("/gcalc/parser/term/plus/constant",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ 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 != null);
+ assert (p.expressions.get_n_items () == 2);
+ var t1 = p.expressions.get_item (0) as Term;
+ assert (t1 != null);
+ assert (t1.expressions.get_n_items () == 1);
+ var c1 = t1.expressions.get_item (0) as Constant;
+ assert (c1 != null);
+ var t2 = p.expressions.get_item (1) as Term;
+ assert (t2 != null);
+ assert (t2.expressions.get_n_items () == 2);
+ var plus = t2.expressions.get_item (0) as Plus;
+ assert (plus != null);
+ var c2 = t2.expressions.get_item (1) as Constant;
+ assert (c2 != null);
+ } catch (GLib.Error error) {
+ warning ("Error: %s", error.message);
+ }
+ });
+ Test.add_func ("/gcalc/parser/term/plus/variables",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("A+B", 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 != null);
+ assert (p.expressions.get_n_items () == 2);
+ var t1 = p.expressions.get_item (0) as Term;
+ assert (t1 != null);
+ assert (t1.expressions.get_n_items () == 1);
+ var c1 = t1.expressions.get_item (0) as Variable;
+ assert (c1 != null);
+ var t2 = p.expressions.get_item (1) as Term;
+ assert (t2 != null);
+ assert (t2.expressions.get_n_items () == 2);
+ var plus = t2.expressions.get_item (0) as Plus;
+ assert (plus != null);
+ var c2 = t2.expressions.get_item (1) as Variable;
+ assert (c2 != null);
+ } catch (GLib.Error error) {
+ warning ("Error: %s", error.message);
+ }
+ });
+ Test.add_func ("/gcalc/parser/term/plus/variables+constant",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("A+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 != null);
+ assert (p.expressions.get_n_items () == 2);
+ var t1 = p.expressions.get_item (0) as Term;
+ assert (t1 != null);
+ assert (t1.expressions.get_n_items () == 1);
+ var c1 = t1.expressions.get_item (0) as Variable;
+ assert (c1 != null);
+ var t2 = p.expressions.get_item (1) as Term;
+ assert (t2 != null);
+ assert (t2.expressions.get_n_items () == 2);
+ var plus = t2.expressions.get_item (0) as Plus;
+ assert (plus != null);
+ var c2 = t2.expressions.get_item (1) as Constant;
+ assert (c2 != null);
+ } catch (GLib.Error error) {
+ warning ("Error: %s", error.message);
+ }
+ });
+ Test.add_func ("/gcalc/parser/term/plus/constant+variable",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("1+B", 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 != null);
+ assert (p.expressions.get_n_items () == 2);
+ var t1 = p.expressions.get_item (0) as Term;
+ assert (t1 != null);
+ assert (t1.expressions.get_n_items () == 1);
+ var c1 = t1.expressions.get_item (0) as Constant;
+ assert (c1 != null);
+ var t2 = p.expressions.get_item (1) as Term;
+ assert (t2 != null);
+ assert (t2.expressions.get_n_items () == 2);
+ var plus = t2.expressions.get_item (0) as Plus;
+ assert (plus != null);
+ var c2 = t2.expressions.get_item (1) as Variable;
+ assert (c2 != null);
+ } catch (GLib.Error error) {
+ warning ("Error: %s", error.message);
+ }
+ });
+ Test.add_func ("/gcalc/parser/term/complex/constant+variable",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("-1+B+3+A", 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 != null);
+ message ("Terms: %u", p.expressions.get_n_items ());
+ assert (p.expressions.get_n_items () == 4);
+ var t1 = p.expressions.get_item (0) as Term;
+ assert (t1 != null);
+ assert (t1.expressions.get_n_items () == 2);
+ var minus = t1.expressions.get_item (0) as Minus;
+ assert (minus != null);
+ var c1 = t1.expressions.get_item (1) as Constant;
+ assert (c1 != null);
+ var t2 = p.expressions.get_item (1) as Term;
+ assert (t2 != null);
+ assert (t2.expressions.get_n_items () == 2);
+ var plus = t2.expressions.get_item (0) as Plus;
+ assert (plus != null);
+ var c2 = t2.expressions.get_item (1) as Variable;
+ assert (c2 != null);
+ var t3 = p.expressions.get_item (2) as Term;
+ assert (t3 != null);
+ assert (t3.expressions.get_n_items () == 2);
+ var plus2 = t3.expressions.get_item (0) as Plus;
+ assert (plus2 != null);
+ var c3 = t3.expressions.get_item (1) as Constant;
+ assert (c3 != null);
+ var t4 = p.expressions.get_item (3) as Term;
+ assert (t4 != null);
+ assert (t4.expressions.get_n_items () == 2);
+ var plus3 = t4.expressions.get_item (0) as Plus;
+ assert (plus3 != null);
+ var c4 = t4.expressions.get_item (1) as Variable;
+ assert (c4 != null);
+ } catch (GLib.Error error) {
+ warning ("Error: %s", error.message);
+ }
+ });
+ Test.add_func ("/gcalc/parser/term/complex/constant+variable/combined-operators",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("-1+B+3-A", 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 != null);
+ message ("Terms: %u", p.expressions.get_n_items ());
+ assert (p.expressions.get_n_items () == 4);
+ var t1 = p.expressions.get_item (0) as Term;
+ assert (t1 != null);
+ assert (t1.expressions.get_n_items () == 2);
+ var minus = t1.expressions.get_item (0) as Minus;
+ assert (minus != null);
+ var c1 = t1.expressions.get_item (1) as Constant;
+ assert (c1 != null);
+ var t2 = p.expressions.get_item (1) as Term;
+ assert (t2 != null);
+ assert (t2.expressions.get_n_items () == 2);
+ var plus = t2.expressions.get_item (0) as Plus;
+ assert (plus != null);
+ var c2 = t2.expressions.get_item (1) as Variable;
+ assert (c2 != null);
+ var t3 = p.expressions.get_item (2) as Term;
+ assert (t3 != null);
+ assert (t3.expressions.get_n_items () == 2);
+ var plus2 = t3.expressions.get_item (0) as Plus;
+ assert (plus2 != null);
+ var c3 = t3.expressions.get_item (1) as Constant;
+ assert (c3 != null);
+ var t4 = p.expressions.get_item (3) as Term;
+ assert (t4 != null);
+ assert (t4.expressions.get_n_items () == 2);
+ var minus2 = t4.expressions.get_item (0) as Minus;
+ assert (minus2 != null);
+ var c4 = t4.expressions.get_item (1) as Variable;
+ assert (c4 != null);
+ } catch (GLib.Error error) {
+ warning ("Error: %s", error.message);
+ }
+ });
+ Test.add_func ("/gcalc/parser/term/multiply/constant",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ 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 != null);
+ assert (p.expressions.get_n_items () == 1);
+ var t1 = p.expressions.get_item (0) as Term;
+ assert (t1 != null);
+ assert (t1.expressions.get_n_items () == 3);
+ var c1 = t1.expressions.get_item (0) as Constant;
+ assert (c1 != null);
+ var m = t1.expressions.get_item (1) as Multiply;
+ assert (m != null);
+ var c2 = t1.expressions.get_item (2) as Constant;
+ assert (c2 != null);
+ } catch (GLib.Error error) {
+ warning ("Error: %s", error.message);
+ }
+ });
+ Test.add_func ("/gcalc/parser/term/multiply/variable",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("A*B", 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 != null);
+ message ("Terms: %u", p.expressions.get_n_items ());
+ assert (p.expressions.get_n_items () == 1);
+ var t1 = p.expressions.get_item (0) as Term;
+ assert (t1 != null);
+ assert (t1.expressions.get_n_items () == 3);
+ var c1 = t1.expressions.get_item (0) as Variable;
+ assert (c1 != null);
+ var m = t1.expressions.get_item (1) as Multiply;
+ assert (m != null);
+ var c2 = t1.expressions.get_item (2) as Variable;
+ assert (c2 != null);
+ } catch (GLib.Error error) {
+ warning ("Error: %s", error.message);
+ }
+ });
+ Test.add_func ("/gcalc/parser/term/complex/constant*variable",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("-1*B+3*A", 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 != null);
+ message ("Terms: %u", p.expressions.get_n_items ());
+ assert (p.expressions.get_n_items () == 2);
+ var t1 = p.expressions.get_item (0) as Term;
+ assert (t1 != null);
+ assert (t1.expressions.get_n_items () == 4);
+ var minus = t1.expressions.get_item (0) as Minus;
+ assert (minus != null);
+ var c1 = t1.expressions.get_item (1) as Constant;
+ assert (c1 != null);
+ var m1 = t1.expressions.get_item (2) as Multiply;
+ assert (m1 != null);
+ var c2 = t1.expressions.get_item (3) as Variable;
+ assert (c2 != null);
+ var t2 = p.expressions.get_item (1) as Term;
+ assert (t2 != null);
+ assert (t2.expressions.get_n_items () == 4);
+ var plus = t2.expressions.get_item (0) as Plus;
+ assert (plus != null);
+ var c3 = t2.expressions.get_item (1) as Constant;
+ assert (c3 != null);
+ var m2 = t2.expressions.get_item (2) as Multiply;
+ assert (m2 != null);
+ var c4 = t2.expressions.get_item (3) as Variable;
+ assert (c4 != null);
+ } catch (GLib.Error error) {
+ warning ("Error: %s", error.message);
+ }
+ });
+ Test.add_func ("/gcalc/parser/term/division/constant",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ 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 != null);
+ assert (p.expressions.get_n_items () == 1);
+ var t1 = p.expressions.get_item (0) as Term;
+ assert (t1 != null);
+ assert (t1.expressions.get_n_items () == 3);
+ var c1 = t1.expressions.get_item (0) as Constant;
+ assert (c1 != null);
+ var m = t1.expressions.get_item (1) as Division;
+ assert (m != null);
+ var c2 = t1.expressions.get_item (2) as Constant;
+ assert (c2 != null);
+ } catch (GLib.Error error) {
+ warning ("Error: %s", error.message);
+ }
+ });
+ Test.add_func ("/gcalc/parser/term/division/variable",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("A/B", 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 != null);
+ message ("Terms: %u", p.expressions.get_n_items ());
+ assert (p.expressions.get_n_items () == 1);
+ var t1 = p.expressions.get_item (0) as Term;
+ assert (t1 != null);
+ assert (t1.expressions.get_n_items () == 3);
+ var c1 = t1.expressions.get_item (0) as Variable;
+ assert (c1 != null);
+ var m = t1.expressions.get_item (1) as Division;
+ assert (m != null);
+ var c2 = t1.expressions.get_item (2) as Variable;
+ assert (c2 != null);
+ } catch (GLib.Error error) {
+ warning ("Error: %s", error.message);
+ }
+ });
+ Test.add_func ("/gcalc/parser/term/complex/multiply-division/constant-variable",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("-1/B+3*A/5", 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 != null);
+ message ("Terms: %u", p.expressions.get_n_items ());
+ assert (p.expressions.get_n_items () == 2);
+ var t1 = p.expressions.get_item (0) as Term;
+ assert (t1 != null);
+ assert (t1.expressions.get_n_items () == 4);
+ var minus = t1.expressions.get_item (0) as Minus;
+ assert (minus != null);
+ var c1 = t1.expressions.get_item (1) as Constant;
+ assert (c1 != null);
+ var m1 = t1.expressions.get_item (2) as Division;
+ assert (m1 != null);
+ var c2 = t1.expressions.get_item (3) as Variable;
+ assert (c2 != null);
+ var t2 = p.expressions.get_item (1) as Term;
+ assert (t2 != null);
+ assert (t2.expressions.get_n_items () == 6);
+ var plus = t2.expressions.get_item (0) as Plus;
+ assert (plus != null);
+ var c3 = t2.expressions.get_item (1) as Constant;
+ assert (c3 != null);
+ var m2 = t2.expressions.get_item (2) as Multiply;
+ assert (m2 != null);
+ var c4 = t2.expressions.get_item (3) as Variable;
+ assert (c4 != null);
+ var m3 = t2.expressions.get_item (4) as Division;
+ assert (m3 != null);
+ var c5 = t2.expressions.get_item (5) as Constant;
+ assert (c5 != null);
+ } catch (GLib.Error error) {
+ warning ("Error: %s", error.message);
+ }
+ });
+ Test.add_func ("/gcalc/parser/constant/to_string",
+ ()=>{
+ Constant c = new GConstant.@double (-1.0) as Constant;
+ assert ("-1" in c.to_string ());
+ });
+ Test.add_func ("/gcalc/parser/term/parenthesis",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("(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 != null);
+ assert (p.expressions.get_n_items () == 1);
+ var t = p.expressions.get_item (0) as Term;
+ assert (t != null);
+ assert (t.expressions.get_n_items () == 1);
+ var g = t.expressions.get_item (0) as Group;
+ assert (g != null);
+ assert (g.closed);
+ assert (g.expressions.get_n_items () == 1);
+ var p1 = g.expressions.get_item (0) as Polynomial;
+ assert (p1 != null);
+ assert (p1.expressions.get_n_items () == 1);
+ var t1 = p1.expressions.get_item (0) as Term;
+ assert (t1 != null);
+ assert (t1.expressions.get_n_items () == 1);
+ var c = t1.expressions.get_item (0) as Constant;
+ assert (c != null);
+ } catch (GLib.Error error) {
+ warning ("Error: %s", error.message);
+ }
+ });
+ Test.add_func ("/gcalc/parser/term/parenthesis/errors",
+ ()=>{
+ var parser = new GParser ();
+ var eqman1 = new GMathEquationManager ();
+ try {
+ parser.parse ("(", eqman1);
+ } catch (GLib.Error error) {
+ message ("Correctly catched grouping error: %s", error.message);
+ }
+ var eqman2 = new GMathEquationManager ();
+ try {
+ parser.parse ("1)", eqman2);
+ } catch (GLib.Error error) {
+ message ("Correctly catched grouping error: %s", error.message);
+ }
+ var eqman3 = new GMathEquationManager ();
+ try {
+ parser.parse ("(1))", eqman3);
+ } catch (GLib.Error error) {
+ message ("Correctly catched grouping error: %s", error.message);
+ }
+ var eqman4 = new GMathEquationManager ();
+ try {
+ parser.parse ("(((1))))", eqman4);
+ } catch (GLib.Error error) {
+ message ("Correctly catched grouping error: %s", error.message);
+ }
+ });
+ Test.add_func ("/gcalc/parser/term/parenthesis/grouping",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ 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 != null);
+ assert (p.expressions.get_n_items () == 2);
+ var t1 = p.expressions.get_item (0) as Term;
+ assert (t1 != null);
+ assert (t1.expressions.get_n_items () == 1);
+ var g1 = t1.expressions.get_item (0) as Group;
+ assert (g1 != null);
+ assert (g1.closed);
+ assert (g1.expressions.get_n_items () == 1);
+ var p1 = g1.expressions.get_item (0) as Polynomial;
+ assert (p1 != null);
+ assert (p1.expressions.get_n_items () == 1);
+ var t11 = p1.expressions.get_item (0) as Term;
+ assert (t11 != null);
+ assert (t11.expressions.get_n_items () == 1);
+ var c1 = t11.expressions.get_item (0) as Constant;
+ assert (c1 != null);
+ var t2 = p.expressions.get_item (1) as Term;
+ assert (t2 != null);
+ assert (t2.expressions.get_n_items () == 2);
+ var plus = t2.expressions.get_item (0) as Plus;
+ assert (plus != null);
+ var g2 = t2.expressions.get_item (1) as Group;
+ assert (g2 != null);
+ assert (g2.closed);
+ assert (g2.expressions.get_n_items () == 1);
+ var p2 = g2.expressions.get_item (0) as Polynomial;
+ assert (p2 != null);
+ assert (p2.expressions.get_n_items () == 1);
+ var t21 = p1.expressions.get_item (0) as Term;
+ assert (t21 != null);
+ assert (t21.expressions.get_n_items () == 1);
+ var c2 = t21.expressions.get_item (0) as Constant;
+ assert (c2 != null);
+ } catch (GLib.Error error) {
+ warning ("Error: %s", error.message);
+ }
+ });
+ Test.add_func ("/gcalc/parser/term/parenthesis/grouping/multiply",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("5*(3+2)", 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 != null);
+ assert (p.expressions.get_n_items () == 1);
+ var t1 = p.expressions.get_item (0) as Term;
+ assert (t1 != null);
+ assert (t1.expressions.get_n_items () == 3);
+ var c1 = t1.expressions.get_item (0) as Constant;
+ assert (c1 != null);
+ var m1 = t1.expressions.get_item (1) as Multiply;
+ assert (m1 != null);
+ var g = t1.expressions.get_item (2) as Group;
+ assert (g != null);
+ assert (g.closed);
+ assert (g.expressions.get_n_items () == 1);
+ var pg = g.expressions.get_item (0) as Polynomial;
+ assert (pg != null);
+ assert (pg.expressions.get_n_items () == 2);
+ var tg1 = pg.expressions.get_item (0) as Term;
+ assert (tg1 != null);
+ assert (tg1.expressions.get_n_items () == 1);
+ var c2 = tg1.expressions.get_item (0) as Constant;
+ assert (c2 != null);
+ var tg2 = pg.expressions.get_item (1) as Term;
+ assert (tg2 != null);
+ assert (tg2.expressions.get_n_items () == 2);
+ message (tg2.to_string ());
+ var plus = tg2.expressions.get_item (0) as Plus;
+ assert (plus != null);
+ var c3 = tg2.expressions.get_item (1) as Constant;
+ assert (c3 != null);
+ } catch (GLib.Error error) {
+ warning ("Error: %s", error.message);
+ }
+ });
+ Test.add_func ("/gcalc/parser/term/parenthesis/grouping/multiply-inv",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("(3+2)*5", 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 != null);
+ assert (p.expressions.get_n_items () == 1);
+ var t1 = p.expressions.get_item (0) as Term;
+ assert (t1 != null);
+ assert (t1.expressions.get_n_items () == 3);
+ var g = t1.expressions.get_item (0) as Group;
+ assert (g != null);
+ assert (g.closed);
+ assert (g.expressions.get_n_items () == 1);
+ var pg = g.expressions.get_item (0) as Polynomial;
+ assert (pg != null);
+ assert (pg.expressions.get_n_items () == 2);
+ var tg1 = pg.expressions.get_item (0) as Term;
+ assert (tg1 != null);
+ assert (tg1.expressions.get_n_items () == 1);
+ var c2 = tg1.expressions.get_item (0) as Constant;
+ assert (c2 != null);
+ var tg2 = pg.expressions.get_item (1) as Term;
+ assert (tg2 != null);
+ assert (tg2.expressions.get_n_items () == 2);
+ message (tg2.to_string ());
+ var plus = tg2.expressions.get_item (0) as Plus;
+ assert (plus != null);
+ var c3 = tg2.expressions.get_item (1) as Constant;
+ assert (c3 != null);
+ var m1 = t1.expressions.get_item (1) as Multiply;
+ assert (m1 != null);
+ var c1 = t1.expressions.get_item (2) as Constant;
+ assert (c1 != null);
+ } catch (GLib.Error error) {
+ warning ("Error: %s", error.message);
+ }
+ });
+ Test.add_func ("/gcalc/parser/function/defaults",
+ ()=>{
+ var eqman = new GMathEquationManager ();
+ assert (eqman.functions.get_n_items () > 0);
+ assert (eqman.functions.find_named ("sin") != null);
+ assert (eqman.functions.find_named ("cos") != null);
+ assert (eqman.functions.find_named ("tan") != null);
+ assert (eqman.functions.find_named ("asin") != null);
+ assert (eqman.functions.find_named ("acos") != null);
+ assert (eqman.functions.find_named ("atan") != null);
+ assert (eqman.functions.find_named ("sinh") != null);
+ assert (eqman.functions.find_named ("cosh") != null);
+ assert (eqman.functions.find_named ("tanh") != null);
+ assert (eqman.functions.find_named ("asinh") != null);
+ assert (eqman.functions.find_named ("acosh") != null);
+ assert (eqman.functions.find_named ("atanh") != null);
+ assert (eqman.functions.find_named ("exp") != null);
+ assert (eqman.functions.find_named ("log") != null);
+ assert (eqman.functions.find_named ("sqrt") != null);
+ });
+ Test.add_func ("/gcalc/parser/function/unique",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ 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);
+ assert (eq.expressions.get_n_items () == 1);
+ var p = eq.expressions.get_item (0) as Polynomial;
+ assert (p != null);
+ assert (p.expressions.get_n_items () == 1);
+ var t = p.expressions.get_item (0) as Term;
+ assert (t != null);
+ assert (t.expressions.get_n_items () == 1);
+ var f = t.expressions.get_item (0) as Function;
+ assert (f != null);
+ assert (f.expressions.get_n_items () == 1);
+ var p1 = f.expressions.get_item (0) as Polynomial;
+ assert (p1 != null);
+ var t1 =p1.expressions.get_item (0) as Term;
+ assert (t1 != null);
+ message ("Terms: %u", t1.expressions.get_n_items ());
+ assert (t1.expressions.get_n_items () == 1);
+ var c = t1.expressions.get_item (0) as Constant;
+ assert (c != null);
+ } catch (GLib.Error error) {
+ warning ("Error: %s", error.message);
+ }
+ });
+ Test.add_func ("/gcalc/parser/pow/unique",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("3^3", 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 != null);
+ assert (p.expressions.get_n_items () == 1);
+ var t = p.expressions.get_item (0) as Term;
+ assert (t != null);
+ assert (t.expressions.get_n_items () == 3);
+ var c1 = t.expressions.get_item (0) as Constant;
+ assert (c1 != null);
+ var pw = t.expressions.get_item (1) as Pow;
+ assert (pw != null);
+ var c2 = t.expressions.get_item (2) as Constant;
+ assert (c2 != null);
+ } catch (GLib.Error error) {
+ warning ("Error: %s", error.message);
+ }
+ });
+ Test.add_func ("/gcalc/parser/pow/polynomial",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("3^(3+5*3)", 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 != null);
+ assert (p.expressions.get_n_items () == 1);
+ var t = p.expressions.get_item (0) as Term;
+ assert (t != null);
+ assert (t.expressions.get_n_items () == 3);
+ var c1 = t.expressions.get_item (0) as Constant;
+ assert (c1 != null);
+ var pw = t.expressions.get_item (1) as Pow;
+ assert (pw != null);
+ var g = t.expressions.get_item (2) as Group;
+ assert (g != null);
+ assert (g.expressions.get_n_items () == 1);
+ var p1 = g.expressions.get_item (0) as Polynomial;
+ assert (p1 != null);
+ } catch (GLib.Error error) {
+ warning ("Error: %s", error.message);
+ }
+ });
+ Test.add_func ("/gcalc/parser/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);
+ 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);
+ assert (t.expressions.get_n_items () == 1);
+ var c = t.expressions.get_item (0) as Constant;
+ assert (c != null);
+ } catch (GLib.Error error) {
+ warning ("Error: %s", error.message);
+ }
+ });
+ Test.add_func ("/gcalc/parser/variable/polynomial",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("x=3*4*cos(0)+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 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 () == 2);
+ var t1 = e.expressions.get_item (0) as Term;
+ assert (t1 != null);
+ assert (t1.expressions.get_n_items () == 5);
+ var c1 = t1.expressions.get_item (0) as Constant;
+ assert (c1 != null);
+ var m1 = t1.expressions.get_item (1) as Multiply;
+ assert (m1 != null);
+ var c2 = t1.expressions.get_item (2) as Constant;
+ assert (c2 != null);
+ var m2 = t1.expressions.get_item (3) as Multiply;
+ assert (m2 != null);
+ var f1 = t1.expressions.get_item (4) as Function;
+ assert (f1 != null);
+ var t2 = e.expressions.get_item (1) as Term;
+ assert (t2 != null);
+ assert (t2.expressions.get_n_items () == 2);
+ var pl = t2.expressions.get_item (0) as Plus;
+ assert (pl != null);
+ var c3 = t2.expressions.get_item (1) as Constant;
+ assert (c3 != null);
+ } catch (GLib.Error error) {
+ warning ("Error: %s", error.message);
+ }
+ });
+ Test.add_func ("/gcalc/parser/variable/lookup/equation",
+ ()=>{
+ 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 v = eq.variables.find_named ("x");
+ assert (v != null);
+ } catch (GLib.Error error) {
+ warning ("Error: %s", error.message);
+ }
+ });
+ Test.add_func ("/gcalc/parser/variables/lookup/equation",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("x=3", eqman);
+ parser.parse ("y=x", eqman);
+ assert (eqman.equations.get_n_items () == 2);
+ var eq = eqman.equations.get_item (0) as MathEquation;
+ assert (eq != null);
+ var v = eq.variables.find_named ("x");
+ assert (v != null);
+ var eq2 = eqman.equations.get_item (1) as MathEquation;
+ assert (eq2 != null);
+ var v2 = eq2.variables.find_named ("y");
+ assert (v2 != null);
+ var v3 = eq2.variables.find_named ("x");
+ assert (v3 == null);
+ assert (eqman.find_variable ("x") != null);
+ assert (eqman.find_variable ("y") != null);
+ } catch (GLib.Error error) {
+ warning ("Error: %s", error.message);
+ }
+ });
+ Test.add_func ("/gcalc/parser/variable/equations",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("x=3", eqman);
+ parser.parse ("x", eqman);
+ assert (eqman.equations.get_n_items () == 2);
+ var eq = eqman.equations.get_item (0) as MathEquation;
+ assert (eq != null);
+ 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.to_string ());
+ assert (eq2.expressions.get_n_items () == 1);
+ var e2 = eq2.expressions.get_item (0) 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 v2 = t2.expressions.get_item (0) as Variable;
+ assert (v2 != null);
+ } catch (GLib.Error error) {
+ warning ("Error: %s", error.message);
+ }
+ });
+ Test.add_func ("/gcalc/parser/variable/equations/asigments",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("x=3", eqman);
+ parser.parse ("y=x", eqman);
+ assert (eqman.equations.get_n_items () == 2);
+ var eq = eqman.equations.get_item (0) as MathEquation;
+ assert (eq != null);
+ 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.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);
+ } catch (GLib.Error error) {
+ 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
new file mode 100644
index 00000000..bb64f9ee
--- /dev/null
+++ b/tests/gcalc-solving-basic.vala
@@ -0,0 +1,1401 @@
+/* -*- Mode: Vala; indent-tabs-mode: nil; c-basic-offset: 2; tab-width: 2 -*- */
+/*
+ * GCalc Unit Tests
+ * Copyright (C) Daniel Espinosa Ortiz 2018 <esodan gmail com>
+ *
+ * libgda 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * libgda 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 program. If not, see <http://www.gnu.org/licenses/>.
+ */
+using GCalc;
+
+class Tests {
+ static int main (string[] args)
+ {
+ GLib.Intl.setlocale (GLib.LocaleCategory.ALL, "");
+ Test.init (ref args);
+ Test.add_func ("/gcalc/solve/constant/add",
+ ()=>{
+ var c1 = new GConstant.@double (3.0);
+ var c2 = new GConstant.@double (3.0);
+ var c3 = c1.add (c2);
+ assert (c3 != null);
+ message (c3.to_string ());
+ assert (c3.real () == 6.0);
+ });
+ Test.add_func ("/gcalc/solve/constant/subtract",
+ ()=>{
+ var c1 = new GConstant.@double (9.0);
+ var c2 = new GConstant.@double (3.0);
+ var c3 = c1.subtract (c2);
+ assert (c3 != null);
+ message (c3.to_string ());
+ assert (c3.real () == 6.0);
+ });
+ Test.add_func ("/gcalc/solve/constant/multiply",
+ ()=>{
+ var c1 = new GConstant.@double (3.0);
+ var c2 = new GConstant.@double (3.0);
+ var c3 = c1.multiply (c2);
+ assert (c3 != null);
+ message (c3.to_string ());
+ assert (c3.real () == 9.0);
+ });
+ Test.add_func ("/gcalc/solve/constant/devide",
+ ()=>{
+ var c1 = new GConstant.@double (9.0);
+ var c2 = new GConstant.@double (3.0);
+ var c3 = c1.divide (c2);
+ assert (c3 != null);
+ message (c3.to_string ());
+ assert (c3.real () == 3.0);
+ });
+ Test.add_func ("/gcalc/solve/constant/negation",
+ ()=>{
+ var c1 = new GConstant.@double (9.0);
+ var c3 = c1.neg ();
+ assert (c3 != null);
+ message (c3.to_string ());
+ assert (c3.real () == -9.0);
+ });
+ Test.add_func ("/gcalc/solve/constant/complex",
+ ()=>{
+ var c1 = new GConstant.complex (10.0, 15.0);
+ var c3 = c1.neg ();
+ assert (c3 != null);
+ message (c3.to_string ());
+ assert (c3.real () == -10.0);
+ assert (c3.imag () == -15.0);
+ });
+ Test.add_func ("/gcalc/solve/constant",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("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 t = e.expressions.get_item (0) as Term;
+ assert (t != null);
+ var c = t.expressions.get_item (0) as Constant;
+ assert (c != null);
+ var res = c.solve ();
+ assert (res != null);
+ assert (res.expression != null);
+ var rc = res.expression as Constant;
+ assert (rc != null);
+ message ("Constant Result: %s", rc.to_string ());
+ assert (rc.real () == 1.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/term/constant",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("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 t = e.expressions.get_item (0) as Term;
+ var res = t.solve ();
+ assert (res != null);
+ assert (res.expression != null);
+ message ("Result type: %s", res.expression.get_type ().name ());
+ assert (!(res is ErrorResult));
+ var rc = res.expression as Constant;
+ assert (rc != null);
+ message ("Constant Result: %s", rc.to_string ());
+ assert (rc.real () == 1.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/term/constant/multiply",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("3*5", 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 t = e.expressions.get_item (0) as Term;
+ var res = t.solve ();
+ assert (res != null);
+ assert (res.expression != null);
+ message ("Result type: %s", res.expression.get_type ().name ());
+ assert (!(res is ErrorResult));
+ var rc = res.expression as Constant;
+ assert (rc != null);
+ message ("Constant Result: %s", rc.to_string ());
+ assert (rc.real () == 15.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/term/constant/division",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("15/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 t = e.expressions.get_item (0) as Term;
+ var res = t.solve ();
+ assert (res != null);
+ assert (res.expression != null);
+ message ("Result type: %s", res.expression.get_type ().name ());
+ assert (!(res is ErrorResult));
+ var rc = res.expression as Constant;
+ assert (rc != null);
+ message ("Constant Result: %s", rc.to_string ());
+ assert (rc.real () == 5.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/term/add/constant",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ 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);
+ var e = eq.expressions.get_item (0) as Polynomial;
+ assert (e != null);
+ var t1 = e.expressions.get_item (0) as Term;
+ var t2 = e.expressions.get_item (1) as Term;
+ var res = t1.add (t2);
+ assert (res != null);
+ message (res.get_type ().name ());
+ var c = res as Constant;
+ assert (c != null);
+ message (c.to_string ());
+ assert (c.real () == 2.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/term/add/constant-multiple",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("1+1-9+8-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 ();
+ assert (res != null);
+ message (res.get_type ().name ());
+ var c = res as Constant;
+ assert (c != null);
+ message (c.to_string ());
+ assert (c.real () == -2.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/term/add-mult-div/constant-multiple",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("15/3+18/6-27/9+4*2-3*2", 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 ();
+ assert (res != null);
+ message (res.get_type ().name ());
+ var c = res as Constant;
+ assert (c != null);
+ message (c.to_string ());
+ assert (c.real () == 7.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/group/constant",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("(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 t = e.expressions.get_item (0) as Term;
+ assert (t != null);
+ var g = t.expressions.get_item (0) as Group;
+ assert (g != null);
+ var res = g.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/group/multiple-levels/1",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("(((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/group/multiple-levels/multiply",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("(((1)))*((((5))))", 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/group/multiple-levels/add",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("(((1)))+((((5))))", 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 () == 6.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/group/constant/basic-polynomial",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("(1+2)", 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 t = e.expressions.get_item (0) as Term;
+ assert (t != null);
+ var g = t.expressions.get_item (0) as Group;
+ assert (g != null);
+ var res = g.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/group/constant/polynomial",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("(2*8-10/5)", 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 t = e.expressions.get_item (0) as Term;
+ assert (t != null);
+ var g = t.expressions.get_item (0) as Group;
+ assert (g != null);
+ var res = g.evaluate () as Constant;
+ assert (res != null);
+ message ("Constant Result: %s", res.to_string ());
+ assert (res.real () == 14.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/group/multiple/2",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("(2)+(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 () == 5.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/group/multiply-term",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("5*(3+2)", 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 () == 25.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/group/multiply-term/plug-constant",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("5*(3+2)+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 () == 26.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/group/multiply-term-inv",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("(3+2)*5", 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 () == 25.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/group/complex",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("(3+2)*5+1-3*(8-2)*7-(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 () == -103.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/function/sqrt",
+ ()=>{
+ try {
+ var c1 = new GConstant.@double (9.0);
+ var f = new GFunctionSqrt ();
+ f.expressions.add (c1);
+ var c2 = f.evaluate () as Constant;
+ assert (c2 != null);
+ message (c2.to_string ());
+ assert (c2.real () == 3.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/function/exp",
+ ()=>{
+ try {
+ var c1 = new GConstant.@double (0.0);
+ var f = new GFunctionExp ();
+ f.expressions.add (c1);
+ var c2 = f.evaluate () as Constant;
+ assert (c2 != null);
+ message (c2.to_string ());
+ assert (c2.real () == 1.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/function/log",
+ ()=>{
+ try {
+ var c1 = new GConstant.@double (1.0);
+ var f = new GFunctionLog ();
+ f.expressions.add (c1);
+ var c2 = f.evaluate () as Constant;
+ assert (c2 != null);
+ message (c2.to_string ());
+ assert (c2.real () == 0.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/function/sin",
+ ()=>{
+ try {
+ var c1 = new GConstant.@double (0.0);
+ var f = new GFunctionSin ();
+ f.expressions.add (c1);
+ var c2 = f.evaluate () as Constant;
+ assert (c2 != null);
+ message (c2.to_string ());
+ assert (c2.real () == 0.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/function/cos",
+ ()=>{
+ try {
+ var c1 = new GConstant.@double (0.0);
+ var f = new GFunctionCos ();
+ f.expressions.add (c1);
+ var c2 = f.evaluate () as Constant;
+ assert (c2 != null);
+ message (c2.to_string ());
+ assert (c2.real () == 1.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/function/tan",
+ ()=>{
+ try {
+ var c1 = new GConstant.@double (0.0);
+ var f = new GFunctionTan ();
+ f.expressions.add (c1);
+ var c2 = f.evaluate () as Constant;
+ assert (c2 != null);
+ message (c2.to_string ());
+ assert (c2.real () == 0.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/function/asin",
+ ()=>{
+ try {
+ var c1 = new GConstant.@double (0.0);
+ var f = new GFunctionAsin ();
+ f.expressions.add (c1);
+ var c2 = f.evaluate () as Constant;
+ assert (c2 != null);
+ message (c2.to_string ());
+ assert (c2.real () == 0.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/function/acos",
+ ()=>{
+ try {
+ var c1 = new GConstant.@double (1.0);
+ var f = new GFunctionAcos ();
+ f.expressions.add (c1);
+ var c2 = f.evaluate () as Constant;
+ assert (c2 != null);
+ message (c2.to_string ());
+ assert (c2.real () == 0.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/function/atan",
+ ()=>{
+ try {
+ var c1 = new GConstant.@double (0.0);
+ var f = new GFunctionAtan ();
+ f.expressions.add (c1);
+ var c2 = f.evaluate () as Constant;
+ assert (c2 != null);
+ message (c2.to_string ());
+ assert (c2.real () == 0.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/function/sinh",
+ ()=>{
+ try {
+ var c1 = new GConstant.@double (0.0);
+ var f = new GFunctionSinh ();
+ f.expressions.add (c1);
+ var c2 = f.evaluate () as Constant;
+ assert (c2 != null);
+ message (c2.to_string ());
+ assert (c2.real () == 0.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/function/cosh",
+ ()=>{
+ try {
+ var c1 = new GConstant.@double (0.0);
+ var f = new GFunctionCosh ();
+ f.expressions.add (c1);
+ var c2 = f.evaluate () as Constant;
+ assert (c2 != null);
+ message (c2.to_string ());
+ assert (c2.real () == 1.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/function/tanh",
+ ()=>{
+ try {
+ var c1 = new GConstant.@double (0.0);
+ var f = new GFunctionTanh ();
+ f.expressions.add (c1);
+ var c2 = f.evaluate () as Constant;
+ assert (c2 != null);
+ message (c2.to_string ());
+ assert (c2.real () == 0.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/function/asinh",
+ ()=>{
+ try {
+ var c1 = new GConstant.@double (0.0);
+ var f = new GFunctionAsinh ();
+ f.expressions.add (c1);
+ var c2 = f.evaluate () as Constant;
+ assert (c2 != null);
+ message (c2.to_string ());
+ assert (c2.real () == 0.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/function/acosh",
+ ()=>{
+ try {
+ var c1 = new GConstant.@double (1.0);
+ var f = new GFunctionAcosh ();
+ f.expressions.add (c1);
+ var c2 = f.evaluate () as Constant;
+ assert (c2 != null);
+ message (c2.to_string ());
+ assert (c2.real () == 0.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/function/atanh",
+ ()=>{
+ try {
+ var c1 = new GConstant.@double (0.0);
+ var f = new GFunctionAtanh ();
+ f.expressions.add (c1);
+ var c2 = f.evaluate () as Constant;
+ assert (c2 != null);
+ message (c2.to_string ());
+ assert (c2.real () == 0.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/function/unique",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ 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 t = e.expressions.get_item (0) as Term;
+ assert (t != null);
+ var f = t.expressions.get_item (0) as Function;
+ assert (f != null);
+ assert (f.closed);
+ var res = f.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/unique/evaluated-polynomial",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ 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 GParser ();
+ 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 GParser ();
+ 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 GParser ();
+ 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 GParser ();
+ 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 GParser ();
+ 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 GParser ();
+ 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 GParser ();
+ 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 GParser ();
+ 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 GParser ();
+ 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/complex1",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("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 () == -7.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/function/polynomial/group",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("(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 () == 1.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/function/polynomial/complex2",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("5*6+tan(0)+tan(0)/2*8+2*cos(0)-9/cos(0)+(1/(cos(0)+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 () == 23.5);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/pow",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("3^3", 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 () == 27.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/pow/polynomial/constants",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("2^(3+5)", 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 () == 256.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/pow/polynomial/function",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("2^(3+5*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 () == 256.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/pow/polynomial/terms",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("2^(3+5*cos(0))+5*3-3^(sin(0)+5/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 () == 28.0);
+ } catch (GLib.Error e) {
+ 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);
+ }
+ });
+ Test.add_func ("/gcalc/solve/equation/solve/variable",
+ ()=>{
+ 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 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);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/equations/solve/variable",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("x=3", eqman);
+ parser.parse ("x", eqman);
+ assert (eqman.equations.get_n_items () == 2);
+ 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);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/equations/solve/variable/assignment",
+ ()=>{
+ try {
+ var parser = new GParser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("x=3", eqman);
+ parser.parse ("y=x", eqman);
+ assert (eqman.equations.get_n_items () == 2);
+ 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);
+ } catch (GLib.Error e) {
+ 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);
+ }
+ });
+ Test.add_func ("/gcalc/solve/equations/solve/variables/polynomial/complex",
+ ()=>{
+ 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);
+ parser.parse ("x+2*y-z/(z+2*y)", eqman);
+ assert (eqman.equations.get_n_items () == 4);
+ 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);
+ var eq4 = eqman.equations.get_item (3) as MathEquation;
+ assert (eq4 != null);
+ message ("Evaluating Eq4...");
+ var res4 = eq4.solve ();
+ if (res4 is ErrorResult) {
+ warning ("Error: %s", (res4 as ErrorResult).message);
+ }
+ assert (res4.expression != null);
+ message ("Result Type: %s", res4.expression.get_type ().name ());
+ assert (res4.expression is Constant);
+ message ("Result: %s", res4.expression.to_string ());
+ var c4 = res4.expression as Constant;
+ assert (c4 != null);
+ assert (c4.real () == 8.16);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ return Test.run ();
+ }
+}
diff --git a/tests/meson.build b/tests/meson.build
index 808c85e3..eb459673 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -1,14 +1,17 @@
+if not get_option ('disable-ui')
+
# Common
gnome_calculator_tests_deps = [
+ gtk,
+ gtksourceview,
gio,
glib,
gobject,
- gtk,
- gtksourceview,
libmath,
mpc,
mpfr,
posix,
+ inc_rooth_dep
]
gnome_calculator_tests_includes = [
@@ -16,12 +19,13 @@ gnome_calculator_tests_includes = [
]
# Tests
+
test_equation_sources = [
'test-equation.vala',
]
test_equation = executable('test-equation', test_equation_sources,
dependencies: gnome_calculator_tests_deps,
- link_with: libcalculator,
+ link_with: [libcalculator, lib_mpfrg],
include_directories: gnome_calculator_tests_includes,
)
test('Equation test', test_equation)
@@ -31,7 +35,7 @@ test_number_sources = [
]
test_number = executable('test-number', test_number_sources,
dependencies: gnome_calculator_tests_deps,
- link_with: libcalculator,
+ link_with: [libcalculator, lib_mpfrg],
include_directories: gnome_calculator_tests_includes,
)
test('Number test', test_number)
@@ -41,7 +45,41 @@ test_serializer_sources = [
]
test_serializer = executable('test-serializer', test_serializer_sources,
dependencies: gnome_calculator_tests_deps,
- link_with: libcalculator,
+ link_with: [libcalculator, lib_mpfrg],
include_directories: gnome_calculator_tests_includes,
)
test('Serializer test', test_serializer)
+endif
+
+tests_deps = [
+ gio,
+ glib,
+ gobject,
+ libmath,
+ mpc,
+ mpfr,
+ posix,
+ gee,
+ inc_rooth_dep
+]
+
+test_parsing_sources = [
+ 'gcalc-parsing.vala',
+]
+
+test_parsing = executable('gcalc-parsing', test_parsing_sources,
+ dependencies:tests_deps,
+ link_with: [lib, lib_mpfrg],
+)
+test('gcalc-parsing', test_parsing)
+
+
+test_solve_basic_sources = [
+ 'gcalc-solving-basic.vala',
+]
+
+test_solve_basic = executable('gcalc-solve-basic', test_solve_basic_sources,
+ dependencies:tests_deps,
+ link_with: [lib, lib_mpfrg],
+)
+test('gcalc-solve-basic', test_solve_basic)
diff --git a/vapi/mpc.vapi b/vapi/mpc.vapi
index d34521bb..bc818344 100644
--- a/vapi/mpc.vapi
+++ b/vapi/mpc.vapi
@@ -49,6 +49,8 @@ namespace MPC {
public struct Complex {
[CCode (cname="mpc_init2")]
public Complex (MPFR.Precision prec);
+ [CCode (cname="mpc_set_prec")]
+ public void set_prec (MPFR.Precision prec);
public int @set (Complex op, Round rnd = Round.NEAREST);
[CCode (cname="mpc_set_ui_ui")]
public int set_unsigned_integer (ulong re, ulong im = 0, Round rnd = Round.NEAREST);
@@ -66,9 +68,9 @@ namespace MPC {
[CCode (cname="mpc_set_d_d")]
public int set_double (double re, double im = 0, Round rnd = Round.NEAREST);
[CCode (cname="mpc_realref")]
- public unowned MPFR.RealRef get_real ();
+ public unowned MPFRG.RealRef get_real ();
[CCode (cname="mpc_imagref")]
- public unowned MPFR.RealRef get_imag ();
+ public unowned MPFRG.RealRef get_imag ();
public bool is_zero () { var res = cmp_si_si (0, 0); return inex_re (res) == 0 && inex_im (res) ==
0; }
public bool is_equal (Complex c) { var res = cmp (c); return inex_re (res) == 0 && inex_im (res) ==
0; }
public int cmp (Complex op2);
@@ -119,5 +121,19 @@ namespace MPC {
public int asinh (Complex op, Round rnd = Round.NEAREST);
public int acosh (Complex op, Round rnd = Round.NEAREST);
public int atanh (Complex op, Round rnd = Round.NEAREST);
+
+ public double get_real_double () {
+ var r = MPFR.Real (1000);
+ r.set (get_real ().val);
+ return r.get_double ();
+ }
+ public double get_imag_double () {
+ var i = MPFR.Real (1000);
+ i.set (get_imag ().val);
+ return i.get_double ();
+ }
+
+ [CCode (cname="mpc_get_str")]
+ public static string to_string (int @base, size_t digits, Complex op, Round rnd = Round.NEAREST);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]