[gnome-calculator/60-split-out-a-backend-library] gcalc: implemented power operator
- From: Daniel Espinosa Ortiz <despinosa src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-calculator/60-split-out-a-backend-library] gcalc: implemented power operator
- Date: Sat, 5 Jan 2019 03:18:11 +0000 (UTC)
commit ddfa9f57e2b851f92c2306cc4f73cba856c91671
Author: Daniel Espinosa Ortiz <esodan gmail com>
Date: Fri Jan 4 20:51:48 2019 -0600
gcalc: implemented power operator
gcalc/gcalc-constant.vala | 1 +
gcalc/gcalc-gconstant.vala | 10 ++++++
gcalc/gcalc-gpow.vala | 26 ++++++++++++++
gcalc/gcalc-parser.vala | 26 +++++++++-----
gcalc/gcalc-pow.vala | 22 ++++++++++++
gcalc/gcalc-term.vala | 3 ++
gcalc/meson.build | 2 ++
tests/gcalc-parsing.vala | 55 +++++++++++++++++++++++++++++
tests/gcalc-solving-basic.vala | 80 ++++++++++++++++++++++++++++++++++++++++++
9 files changed, 217 insertions(+), 8 deletions(-)
---
diff --git a/gcalc/gcalc-constant.vala b/gcalc/gcalc-constant.vala
index d7d1b6b1..15d1c644 100644
--- a/gcalc/gcalc-constant.vala
+++ b/gcalc/gcalc-constant.vala
@@ -26,5 +26,6 @@ public interface GCalc.Constant : Object, Expression {
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-gconstant.vala b/gcalc/gcalc-gconstant.vala
index 9d54b4f0..88ea0bc3 100644
--- a/gcalc/gcalc-gconstant.vala
+++ b/gcalc/gcalc-gconstant.vala
@@ -101,6 +101,16 @@ public class GCalc.GConstant : GExpression, Constant {
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) {
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-parser.vala b/gcalc/gcalc-parser.vala
index 55f0050f..7e4e167e 100644
--- a/gcalc/gcalc-parser.vala
+++ b/gcalc/gcalc-parser.vala
@@ -284,14 +284,18 @@ public class GCalc.Parser : Object {
var par = current;
while (par != null) {
if (par is Group) {
- foundp = true;
- ((Group) par).closed = true;
- break;
+ if (!((Group) par).closed) {
+ foundp = true;
+ ((Group) par).closed = true;
+ break;
+ }
}
if (par is Function) {
- foundp = true;
- ((Function) par).closed = true;
- break;
+ if (!((Function) par).closed) {
+ foundp = true;
+ ((Function) par).closed = true;
+ break;
+ }
}
par = par.parent;
}
@@ -301,6 +305,14 @@ public class GCalc.Parser : Object {
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:
@@ -338,8 +350,6 @@ public class GCalc.Parser : Object {
case Vala.TokenType.OP_OR:
case Vala.TokenType.OP_PTR:
case Vala.TokenType.OP_SHIFT_LEFT:
- // Carret?
- case Vala.TokenType.CARRET:
// templates and regex
case Vala.TokenType.CLOSE_REGEX_LITERAL:
case Vala.TokenType.CLOSE_TEMPLATE:
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-term.vala b/gcalc/gcalc-term.vala
index 6cc3e136..ba2554d8 100644
--- a/gcalc/gcalc-term.vala
+++ b/gcalc/gcalc-term.vala
@@ -99,6 +99,9 @@ public interface GCalc.Term : Object, Expression {
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");
}
diff --git a/gcalc/meson.build b/gcalc/meson.build
index e9d48f3f..f94054be 100644
--- a/gcalc/meson.build
+++ b/gcalc/meson.build
@@ -74,6 +74,7 @@ sources = files([
'gcalc-gmultiply.vala',
'gcalc-gplus.vala',
'gcalc-gpolynomial.vala',
+ 'gcalc-gpow.vala',
'gcalc-gresult.vala',
'gcalc-group.vala',
'gcalc-ggroup.vala',
@@ -88,6 +89,7 @@ sources = files([
'gcalc-parser.vala',
'gcalc-plus.vala',
'gcalc-polynomial.vala',
+ 'gcalc-pow.vala',
'gcalc-result.vala',
'gcalc-solver.vala',
'gcalc-term.vala',
diff --git a/tests/gcalc-parsing.vala b/tests/gcalc-parsing.vala
index 1631f2d2..b9b90d00 100644
--- a/tests/gcalc-parsing.vala
+++ b/tests/gcalc-parsing.vala
@@ -757,6 +757,61 @@ class Tests {
warning ("Error: %s", error.message);
}
});
+ Test.add_func ("/gcalc/parser/pow/unique",
+ ()=>{
+ try {
+ var parser = new Parser ();
+ 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 Parser ();
+ 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);
+ }
+ });
return Test.run ();
}
}
diff --git a/tests/gcalc-solving-basic.vala b/tests/gcalc-solving-basic.vala
index f067e0e9..3116dee1 100644
--- a/tests/gcalc-solving-basic.vala
+++ b/tests/gcalc-solving-basic.vala
@@ -950,6 +950,86 @@ class Tests {
warning ("Error: %s", e.message);
}
});
+ Test.add_func ("/gcalc/solve/pow",
+ ()=>{
+ try {
+ var parser = new Parser ();
+ 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 Parser ();
+ 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 Parser ();
+ 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 Parser ();
+ 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);
+ }
+ });
return Test.run ();
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]