Back to index

texmacs  1.0.7.15
evaluate_numeric.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : evaluate_numeric.cpp
00004 * DESCRIPTION: numeric operations
00005 * COPYRIGHT  : (C) 2006  Joris van der Hoeven
00006 *******************************************************************************
00007 * This software falls under the GNU general public license version 3 or later.
00008 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
00009 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
00010 ******************************************************************************/
00011 
00012 #include "evaluate_main.hpp"
00013 
00014 /******************************************************************************
00015 * Arithmetic operations
00016 ******************************************************************************/
00017 
00018 tree
00019 evaluate_plus_minus (tree t) {
00020   int i, n= N(t);
00021   if (n==0) return evaluate_error ("bad plus/minus");
00022   tree inc= evaluate (t[0]);
00023   if (is_double (inc)) {
00024     double acc= as_double (inc);
00025     if ((n==1) && is_func (t, MINUS))
00026       acc= -acc;
00027     for (i=1; i<n; i++) {
00028       tree inc= evaluate (t[i]);
00029       if (!is_double (inc))
00030        return evaluate_error ("bad plus/minus");
00031       if ((i == n-1) && is_func (t, MINUS))
00032        acc -= as_double (inc);
00033       else acc += as_double (inc);
00034     }
00035     return as_string (acc);
00036   }
00037   else if (is_anylen (inc)) {
00038     tree acc= as_tmlen (inc);
00039     if ((n==1) && is_func (t, MINUS))
00040       acc= tmlen_times (-1, acc);
00041     for (i=1; i<n; i++) {
00042       tree inc= evaluate (t[i]);
00043       if (!is_anylen (inc))
00044        return evaluate_error ("bad plus/minus");
00045       inc= as_tmlen (inc);
00046       if ((i == n-1) && is_func (t, MINUS))
00047        inc= tmlen_times (-1, inc);
00048       acc= tmlen_plus (acc, inc);
00049     }
00050     return acc;
00051   }
00052   else return evaluate_error ("bad plus/minus");
00053 }
00054 
00055 tree
00056 evaluate_times_over (tree t) {
00057   int i, n= N(t);
00058   if (n==0) return evaluate_error ("bad times/over");
00059   tree prod= evaluate (t[0]);
00060   if (is_double (prod));
00061   else if (is_anylen (prod)) prod= as_tmlen (prod);
00062   else if (is_percentage (prod)) prod= as_tree (as_percentage (prod));
00063   else return evaluate_error ("bad times/over");
00064   if ((n==1) && is_func (t, OVER)) {
00065     if (is_double (prod)) return as_string (1 / as_double (prod));
00066     else return evaluate_error ("bad times/over");
00067   }
00068   // cout << t << "\n";
00069   // cout << "  0\t" << prod << "\n";
00070   for (i=1; i<n; i++) {
00071     tree mul= evaluate (t[i]);
00072     if (is_double (mul)) {
00073       double _mul= as_double (mul);
00074       if ((i == n-1) && is_func (t, OVER))
00075        _mul= 1 / _mul;
00076       if (is_double (prod))
00077        prod= as_string (_mul * as_double (prod));
00078       else prod= tmlen_times (_mul, prod);
00079     }
00080     else if (is_anylen (mul)) {
00081       mul= as_tmlen (mul);
00082       if ((i == n-1) && is_func (t, OVER)) {
00083        if (!is_func (prod, TMLEN))
00084          return evaluate_error ("bad times/over");
00085        return tmlen_over (prod, mul);
00086       }
00087       if (is_double (prod))
00088        prod= tmlen_times (as_double (prod), mul);
00089       else return evaluate_error ("bad times/over");
00090     }
00091     else if (is_percentage (mul)) {
00092       double _mul= as_percentage (mul);
00093       if (is_double (prod))
00094        prod= as_string (_mul * as_double (prod));
00095       else prod= tmlen_times (_mul, prod);
00096     }
00097     else return evaluate_error ("bad times/over");
00098     // cout << "  " << i << "\t" << prod << "\n";
00099   }
00100   return prod;
00101 }
00102 
00103 tree
00104 evaluate_divide (tree t) {
00105   if (N(t) != 2) return evaluate_error ("bad divide");
00106   tree t1= evaluate (t[0]);
00107   tree t2= evaluate (t[1]);
00108   if (is_compound (t1) || is_compound (t2))
00109     return evaluate_error ("bad divide");
00110   if (is_int (t1->label) && (is_int (t2->label))) {
00111     int den= as_int (t2->label);
00112     if (den == 0) return evaluate_error ("division by zero");
00113     return as_string (as_int (t1->label) / den);
00114   }
00115   return evaluate_error ("bad divide");
00116 }
00117 
00118 tree
00119 evaluate_modulo (tree t) {
00120   if (N(t)!=2) return evaluate_error ("bad modulo");
00121   tree t1= evaluate (t[0]);
00122   tree t2= evaluate (t[1]);
00123   if (is_compound (t1) || is_compound (t2))
00124     return evaluate_error ("bad modulo");
00125   if (is_int (t1->label) && (is_int (t2->label))) {
00126     int den= as_int (t2->label);
00127     if (den == 0) return evaluate_error ("modulo zero");
00128     return as_string (as_int (t1->label) % den);
00129   }
00130   return evaluate_error ("bad modulo");
00131 }
00132 
00133 /******************************************************************************
00134 * Elementary functions
00135 ******************************************************************************/
00136 
00137 tree
00138 evaluate_math_sqrt (tree t) {
00139   if (N(t)!=1) return evaluate_error ("bad sqrt");
00140   tree t1= evaluate (t[0]);
00141   if (is_double (t1))
00142     return as_tree (sqrt (as_double (t1)));
00143   return evaluate_error ("bad sqrt");
00144 }
00145 
00146 tree
00147 evaluate_exp (tree t) {
00148   if (N(t)!=1) return evaluate_error ("bad exp");
00149   tree t1= evaluate (t[0]);
00150   if (is_double (t1))
00151     return as_tree (exp (as_double (t1)));
00152   return evaluate_error ("bad exp");
00153 }
00154 
00155 tree
00156 evaluate_log (tree t) {
00157   if (N(t)!=1) return evaluate_error ("bad log");
00158   tree t1= evaluate (t[0]);
00159   if (is_double (t1))
00160     return as_tree (log (as_double (t1)));
00161   return evaluate_error ("bad log");
00162 }
00163 
00164 tree
00165 evaluate_pow (tree t) {
00166   if (N(t)!=2) return evaluate_error ("bad pow");
00167   tree t1= evaluate (t[0]);
00168   tree t2= evaluate (t[1]);
00169   if (is_double (t1) && is_double (t2))
00170     return as_tree (pow (as_double (t1), as_double (t2)));
00171   return evaluate_error ("bad pow");
00172 }
00173 
00174 tree
00175 evaluate_cos (tree t) {
00176   if (N(t)!=1) return evaluate_error ("bad cos");
00177   tree t1= evaluate (t[0]);
00178   if (is_double (t1))
00179     return as_tree (cos (as_double (t1)));
00180   return evaluate_error ("bad cos");
00181 }
00182 
00183 tree
00184 evaluate_sin (tree t) {
00185   if (N(t)!=1) return evaluate_error ("bad sin");
00186   tree t1= evaluate (t[0]);
00187   if (is_double (t1))
00188     return as_tree (sin (as_double (t1)));
00189   return evaluate_error ("bad sin");
00190 }
00191 
00192 tree
00193 evaluate_tan (tree t) {
00194   if (N(t)!=1) return evaluate_error ("bad tan");
00195   tree t1= evaluate (t[0]);
00196   if (is_double (t1))
00197     return as_tree (tan (as_double (t1)));
00198   return evaluate_error ("bad tan");
00199 }