[gnumeric] Expr: localize the code to simplify "if".
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] Expr: localize the code to simplify "if".
- Date: Mon, 26 Mar 2012 01:15:38 +0000 (UTC)
commit 61786551e57f0b997874519753e911af8b07c9c8
Author: Morten Welinder <terra gnome org>
Date: Sun Mar 25 21:13:23 2012 -0400
Expr: localize the code to simplify "if".
Prepare for more expression rewrites for import/export.
ChangeLog | 2 +
plugins/openoffice/ChangeLog | 6 ++++
plugins/openoffice/openoffice-read.c | 50 ++++++++++++++++++---------------
src/expr.c | 41 +++++++++++++++++++++++++++
src/expr.h | 2 +
5 files changed, 78 insertions(+), 23 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 5143eae..4c5a342 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,7 @@
2012-03-25 Morten Welinder <terra gnome org>
+ * src/expr.c (gnm_expr_simplify_if): New function.
+
* src/rangefunc.c (gnm_range_covar_pop): Rename from
gnm_range_covar.
(gnm_range_covar_est): New function.
diff --git a/plugins/openoffice/ChangeLog b/plugins/openoffice/ChangeLog
index e026d84..d7d746a 100644
--- a/plugins/openoffice/ChangeLog
+++ b/plugins/openoffice/ChangeLog
@@ -1,3 +1,9 @@
+2012-03-25 Morten Welinder <terra gnome org>
+
+ * openoffice-read.c (odf_func_chisqdist_handler): Simplify (at the
+ expense of speed). If we need a pile of these, they need to be
+ simple.
+
2012-03-25 Andreas J. Guelzow <aguelzow pyrshep ca>
* openoffice-read.c (odf_adjust_offsets_col): new
diff --git a/plugins/openoffice/openoffice-read.c b/plugins/openoffice/openoffice-read.c
index 3c75c0c..d6b7325 100644
--- a/plugins/openoffice/openoffice-read.c
+++ b/plugins/openoffice/openoffice-read.c
@@ -10267,37 +10267,41 @@ odf_func_chisqdist_handler (G_GNUC_UNUSED GnmConventions const *convs, Workbook
return gnm_expr_new_funcall (f, args);
}
case 3: {
- GSList * link = g_slist_nth ((GSList *) args, 2);
- GnmExpr const *expr = link->data;
+ GnmExpr const *arg0 = args->data;
+ GnmExpr const *arg1 = args->next->data;
+ GnmExpr const *arg2 = args->next->next->data;
GnmFunc *fd_if;
GnmFunc *fd_pchisq;
GnmFunc *fd_dchisq;
- GnmExpr const *expr_pchisq;
- GnmExpr const *expr_dchisq;
+ GnmExpr const *expr_pchisq;
+ GnmExpr const *expr_dchisq;
+ GnmExpr const *res, *simp;
- args = (GnmExprList *) g_slist_remove_link ((GSList *) args, link);
- g_slist_free (link);
-
- if (GNM_EXPR_GET_OPER (expr) == GNM_EXPR_OP_FUNCALL) {
- if (go_ascii_strcase_equal (expr->func.func->name, "TRUE")) {
- fd_pchisq = gnm_func_lookup_or_add_placeholder ("R.PCHISQ", scope, FALSE);
- gnm_expr_free (expr);
- return gnm_expr_new_funcall (fd_pchisq, args);
- }
- if (go_ascii_strcase_equal (expr->func.func->name, "FALSE")) {
- fd_dchisq = gnm_func_lookup_or_add_placeholder ("R.DCHISQ", scope, FALSE);
- gnm_expr_free (expr);
- return gnm_expr_new_funcall (fd_dchisq, args);
- }
- }
fd_if = gnm_func_lookup_or_add_placeholder ("IF", scope, FALSE);
fd_pchisq = gnm_func_lookup_or_add_placeholder ("R.PCHISQ", scope, FALSE);
fd_dchisq = gnm_func_lookup_or_add_placeholder ("R.DCHISQ", scope, FALSE);
expr_pchisq = gnm_expr_new_funcall2
- (fd_pchisq, gnm_expr_copy (g_slist_nth_data ((GSList *) args, 0)),
- gnm_expr_copy (g_slist_nth_data ((GSList *) args, 1)));
- expr_dchisq = gnm_expr_new_funcall (fd_dchisq, args);
- return gnm_expr_new_funcall3 (fd_if, expr, expr_pchisq, expr_dchisq);
+ (fd_pchisq,
+ gnm_expr_copy (arg0),
+ gnm_expr_copy (arg1));
+ expr_dchisq = gnm_expr_new_funcall2
+ (fd_dchisq,
+ arg0,
+ arg1);
+ res = gnm_expr_new_funcall3
+ (fd_if,
+ arg2,
+ expr_pchisq,
+ expr_dchisq);
+
+ simp = gnm_expr_simplify_if (res);
+ if (simp) {
+ gnm_expr_free (res);
+ res = simp;
+ }
+
+ g_slist_free (args);
+ return res;
}
default:
break;
diff --git a/src/expr.c b/src/expr.c
index 13488bf..7b02652 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -1560,6 +1560,47 @@ gnm_expr_eval (GnmExpr const *expr, GnmEvalPos const *pos,
return value_new_error (pos, _("Unknown evaluation error"));
}
+
+GnmExpr const *
+gnm_expr_simplify_if (GnmExpr const *expr)
+{
+ static GnmFunc *f_if = NULL;
+ GnmExpr const *cond;
+ gboolean c;
+
+ g_return_val_if_fail (expr != NULL, NULL);
+
+ if (GNM_EXPR_GET_OPER (expr) != GNM_EXPR_OP_FUNCALL)
+ return NULL;
+
+ if (!f_if)
+ f_if = gnm_func_lookup ("if", NULL);
+
+ if (expr->func.func != f_if || expr->func.argc != 3)
+ return NULL;
+
+ cond = expr->func.argv[0];
+ if (GNM_EXPR_GET_OPER (cond) == GNM_EXPR_OP_CONSTANT) {
+ GnmValue const *condval = cond->constant.value;
+ gboolean err;
+ c = value_get_as_bool (condval, &err);
+ if (err)
+ return NULL;
+ } else if (GNM_EXPR_GET_OPER (cond) == GNM_EXPR_OP_FUNCALL) {
+ if (cond->func.func != gnm_func_lookup ("true", NULL))
+ c = TRUE;
+ else if (cond->func.func != gnm_func_lookup ("false", NULL))
+ c = FALSE;
+ else
+ return NULL;
+ } else
+ return NULL;
+
+ return gnm_expr_copy (expr->func.argv[c ? 1 : 2]);
+}
+
+
+
/*
* Converts a parsed tree into its string representation
* assuming that we are evaluating at col, row
diff --git a/src/expr.h b/src/expr.h
index bc1b164..8ca0edf 100644
--- a/src/expr.h
+++ b/src/expr.h
@@ -101,6 +101,8 @@ gboolean gnm_expr_contains_subtotal (GnmExpr const *expr);
GnmValue *gnm_expr_eval (GnmExpr const *expr, GnmEvalPos const *pos,
GnmExprEvalFlags flags);
+GnmExpr const *gnm_expr_simplify_if (GnmExpr const *expr);
+
/*****************************************************************************/
#define gnm_expr_list_append(l,e) g_slist_append ((l), (gpointer)(e))
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]