[gnome-calculator/60-split-out-a-backend-library] gcalc: implemented function sqrt()
- 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 function sqrt()
- Date: Fri, 4 Jan 2019 21:22:19 +0000 (UTC)
commit cb6e4d694ab985cdd2c947e74120206ae16127ee
Author: Daniel Espinosa Ortiz <esodan gmail com>
Date: Fri Jan 4 15:21:45 2019 -0600
gcalc: implemented function sqrt()
gcalc/gcalc-function-sqrt.vala | 53 +++++++++++++++++++++++++++++++++
gcalc/gcalc-function.vala | 16 ++++++++++
gcalc/gcalc-gexpression.vala | 2 +-
gcalc/gcalc-gfunction.vala | 16 ++++++++--
gcalc/gcalc-gmath-equation-manager.vala | 5 ++++
gcalc/gcalc-parser.vala | 9 +-----
gcalc/meson.build | 1 +
tests/gcalc-solving-basic.vala | 14 +++++++++
8 files changed, 105 insertions(+), 11 deletions(-)
---
diff --git a/gcalc/gcalc-function-sqrt.vala b/gcalc/gcalc-function-sqrt.vala
new file mode 100644
index 00000000..fa337023
--- /dev/null
+++ b/gcalc/gcalc-function-sqrt.vala
@@ -0,0 +1,53 @@
+/* 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.GFunctionSqrt : GFunction {
+ public GFunctionSqrt () {
+ base ("sqrt", 1);
+ param_types.add (new GConstant ());
+ }
+
+ public override Expression call () throws GLib.Error
+ {
+ verify_params ();
+ GConstant c = null;
+ var exp = parameters.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).to_string ());
+ }
+ 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.vala b/gcalc/gcalc-function.vala
index f63e359d..4ca01b92 100644
--- a/gcalc/gcalc-function.vala
+++ b/gcalc/gcalc-function.vala
@@ -19,6 +19,22 @@
* Daniel Espinosa <esodan gmail com>
*/
public interface GCalc.Function : Object, Expression {
+ public abstract ExpressionContainer parameters { get; }
+ public abstract ExpressionContainer param_types { get; }
public abstract string name { get; construct set; }
+ public abstract uint n_params { get; construct set; }
+ public abstract Expression call () throws GLib.Error;
+ public virtual bool verify_params () throws GLib.Error {
+ if (parameters.get_n_items () != n_params) {
+ throw new FunctionError.INVALID_PARAMETERS_ERROR ("Invalid number of parameters. Required %u,
provided: %u",
+ n_params, parameters.get_n_items ());
+ }
+ return true;
+ }
+}
+
+public errordomain GCalc.FunctionError {
+ INVALID_PARAMETERS_ERROR,
+ INVOCATION_ERROR
}
diff --git a/gcalc/gcalc-gexpression.vala b/gcalc/gcalc-gexpression.vala
index 5ca735c6..10685a8a 100644
--- a/gcalc/gcalc-gexpression.vala
+++ b/gcalc/gcalc-gexpression.vala
@@ -35,7 +35,7 @@ public class GCalc.GExpression : Object, Expression {
}
public new virtual Result solve () {
var e = new GErrorResult ("Invalid expression");
- return new GResult.with_error (this, e as ErrorResult);
+ return new GResult.with_error (new GErrorExpression (), e as ErrorResult);
}
}
diff --git a/gcalc/gcalc-gfunction.vala b/gcalc/gcalc-gfunction.vala
index ab17b69f..2cda8938 100644
--- a/gcalc/gcalc-gfunction.vala
+++ b/gcalc/gcalc-gfunction.vala
@@ -19,15 +19,27 @@
* Daniel Espinosa <esodan gmail com>
*/
public class GCalc.GFunction : GExpression, Function {
+ ExpressionContainer _parameters = new ExpressionContainer ();
+ ExpressionContainer _param_types = new ExpressionContainer ();
+
+ public ExpressionContainer parameters { get { return _parameters; } }
+ public ExpressionContainer param_types { get { return _param_types; } }
+ public uint n_params { get; construct set; }
public string name { get; construct set; }
+
construct {
name = "NoName";
}
- public GFunction (string name) {
+ public GFunction (string name, int nparams) {
this.name = name;
+ n_params = nparams;
}
public override string to_string () {
- return name + " ()";
+ return name + "()";
+ }
+
+ public new virtual Expression call () throws GLib.Error {
+ return new GErrorExpression ();
}
}
diff --git a/gcalc/gcalc-gmath-equation-manager.vala b/gcalc/gcalc-gmath-equation-manager.vala
index 104aaea7..8d1007fb 100644
--- a/gcalc/gcalc-gmath-equation-manager.vala
+++ b/gcalc/gcalc-gmath-equation-manager.vala
@@ -25,5 +25,10 @@ public class GCalc.GMathEquationManager : Object, MathEquationManager {
public ExpressionContainer equations { get { return _equations; } }
public ExpressionContainer functions { get { return _functions; } }
public ExpressionContainer variables { get { return _variables; } }
+
+ construct {
+ // Initialize default Functions
+ functions.add (new GFunctionSqrt ());
+ }
}
diff --git a/gcalc/gcalc-parser.vala b/gcalc/gcalc-parser.vala
index 1033dc16..89c76d4f 100644
--- a/gcalc/gcalc-parser.vala
+++ b/gcalc/gcalc-parser.vala
@@ -127,14 +127,13 @@ public class GCalc.Parser : Object {
case Vala.TokenType.WHILE:
case Vala.TokenType.YIELD:
case Vala.TokenType.IDENTIFIER:
- message ("Found an identifier");
var sfunc = eqman.functions.find_named (n);
if (sfunc != null) {
current = sfunc;
expected.clear ();
expected.add(Vala.TokenType.OPEN_PARENS);
} else if (n.down () == "def" && current == null) {
- var f = new GFunction (n) as Expression;
+ var f = new GFunction (n, 1) as Expression; // FIXME: Requires more work to identify parameters
eqman.functions.add (f);
current = f;
expected.clear ();
@@ -142,10 +141,8 @@ public class GCalc.Parser : Object {
} else if (n.down () == "def" && current is Function) {
throw new ParserError.INVALID_TOKEN_ERROR ("Found an unexpected function definition expression");
} else {
- message ("Searching variable: %s", n);
var v = new GVariable (n) as Expression;
if (eqman.variables.find_named (n) == null) {
- message ("Adding new variable named: '%s'", (v as Variable).name);
eqman.variables.add (v);
}
if (current == null) {
@@ -245,10 +242,6 @@ public class GCalc.Parser : Object {
var fexp = new GPolynomial ();
current = fexp;
expected.clear ();
- expected.add (Vala.TokenType.IDENTIFIER);
- expected.add (Vala.TokenType.INTEGER_LITERAL);
- expected.add (Vala.TokenType.REAL_LITERAL);
- expected.add (Vala.TokenType.CLOSE_PARENS);
} else if (current is Operator && current_parent is Term && top_parent is Polynomial) {
var g = new GGroup ();
current_parent.expressions.add (g);
diff --git a/gcalc/meson.build b/gcalc/meson.build
index 42101824..a97375eb 100644
--- a/gcalc/meson.build
+++ b/gcalc/meson.build
@@ -46,6 +46,7 @@ sources = files([
'gcalc-expression.vala',
'gcalc-expression-container.vala',
'gcalc-function.vala',
+ 'gcalc-function-sqrt.vala',
'gcalc-error-result.vala',
'gcalc-gexpression.vala',
'gcalc-gassign.vala',
diff --git a/tests/gcalc-solving-basic.vala b/tests/gcalc-solving-basic.vala
index a3603861..c4eb27c6 100644
--- a/tests/gcalc-solving-basic.vala
+++ b/tests/gcalc-solving-basic.vala
@@ -466,6 +466,20 @@ class Tests {
warning ("Error: %s", e.message);
}
});
+ Test.add_func ("/gcalc/solve/function/sqrt",
+ ()=>{
+ try {
+ var c1 = new GConstant.@double (9.0);
+ var fsqrt = new GFunctionSqrt ();
+ fsqrt.parameters.add (c1);
+ var c2 = fsqrt.call () as Constant;
+ assert (c2 != null);
+ message (c2.to_string ());
+ assert (c2.real () == 3.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]