genie-math.c

     
   1  //! @file genie-math.c
   2  //! @author J. Marcel van der Veer
   3  
   4  //! @section Copyright
   5  //!
   6  //! This file is part of Algol68G - an Algol 68 compiler-interpreter.
   7  //! Copyright 2001-2026 J. Marcel van der Veer [algol68g@algol68genie.nl].
   8  
   9  //! @section License
  10  //!
  11  //! This program is free software; you can redistribute it and/or modify it 
  12  //! under the terms of the GNU General Public License as published by the 
  13  //! Free Software Foundation; either version 3 of the License, or 
  14  //! (at your option) any later version.
  15  //!
  16  //! This program is distributed in the hope that it will be useful, but 
  17  //! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
  18  //! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 
  19  //! more details. You should have received a copy of the GNU General Public 
  20  //! License along with this program. If not, see [http://www.gnu.org/licenses/].
  21  
  22  //! @section Synopsis
  23  //!
  24  //! Math interpreter routines.
  25  
  26  #include "a68g.h"
  27  #include "a68g-double.h"
  28  #include "a68g-genie.h"
  29  #include "a68g-mp.h"
  30  #include "a68g-prelude.h"
  31  
  32  
  33  //! @brief Whether value is finite
  34  
  35  void genie_is_finite_real (NODE_T * p)
  36  {
  37    A68G_REAL z;
  38    POP_OBJECT (p, &z, A68G_REAL);
  39    BOOL_T w = a68g_finite_real (VALUE (&z));
  40    PUSH_VALUE (p, w, A68G_BOOL);
  41  }
  42  
  43  
  44  //! @brief Whether value is finite
  45  
  46  void genie_is_finite_mp (NODE_T * p)
  47  {
  48    MOID_T *m = LHS_MODE (SUB (p));
  49    int size = SIZE (m);
  50    MP_T *z = (MP_T *) STACK_OFFSET (-size);
  51    A68G_SP -= size;
  52    CHECK_INIT (p, (UNSIGNED_T) MP_STATUS (z) & INIT_MASK, m);
  53    BOOL_T w = A68G_FINITE_MP (z);
  54    PUSH_VALUE (p, w, A68G_BOOL);
  55  }
  56  
  57  
  58  //! @brief Whether value is infinite
  59  
  60  void genie_is_infinite_real (NODE_T * p)
  61  {
  62    A68G_REAL z;
  63    POP_OBJECT (p, &z, A68G_REAL);
  64    DOUBLE_T v = VALUE (&z);
  65    BOOL_T w = (v == a68g_minus_inf_real ()) || (v == a68g_plus_inf_real ());
  66    PUSH_VALUE (p, w, A68G_BOOL);
  67  }
  68  
  69  
  70  //! @brief Whether value is finite
  71  
  72  void genie_is_infinite_mp (NODE_T * p)
  73  {
  74    MOID_T *m = LHS_MODE (SUB (p));
  75    int size = SIZE (m);
  76    MP_T *z = (MP_T *) STACK_OFFSET (-size);
  77    A68G_SP -= size;
  78    CHECK_INIT (p, (UNSIGNED_T) MP_STATUS (z) & INIT_MASK, m);
  79    BOOL_T w = A68G_INF_MP (z);
  80    PUSH_VALUE (p, w, A68G_BOOL);
  81  }
  82  
  83  
  84  //! @brief Whether value is +inf 
  85  
  86  void genie_is_plus_inf_real (NODE_T * p)
  87  {
  88    A68G_REAL z;
  89    POP_OBJECT (p, &z, A68G_REAL);
  90    BOOL_T w = VALUE (&z) == a68g_plus_inf_real ();
  91    PUSH_VALUE (p, w, A68G_BOOL);
  92  }
  93  
  94  
  95  //! @brief Whether value is +inf 
  96  
  97  void genie_is_plus_inf_mp (NODE_T * p)
  98  {
  99    MOID_T *m = LHS_MODE (SUB (p));
 100    int size = SIZE (m);
 101    MP_T *z = (MP_T *) STACK_OFFSET (-size);
 102    A68G_SP -= size;
 103    CHECK_INIT (p, (UNSIGNED_T) MP_STATUS (z) & INIT_MASK, m);
 104    BOOL_T w = (A68G_PLUS_INF_MP (z) ? A68G_TRUE : A68G_FALSE);
 105    PUSH_VALUE (p, w, A68G_BOOL);
 106  }
 107  
 108  
 109  //! @brief Whether value is -inf 
 110  
 111  void genie_is_minus_inf_real (NODE_T * p)
 112  {
 113    A68G_REAL z;
 114    POP_OBJECT (p, &z, A68G_REAL);
 115    BOOL_T w = VALUE (&z) == a68g_minus_inf_real ();
 116    PUSH_VALUE (p, w, A68G_BOOL);
 117  }
 118  
 119  
 120  //! @brief Whether value is -inf 
 121  
 122  void genie_is_minus_inf_mp (NODE_T * p)
 123  {
 124    MOID_T *m = LHS_MODE (SUB (p));
 125    int size = SIZE (m);
 126    MP_T *z = (MP_T *) STACK_OFFSET (-size);
 127    A68G_SP -= size;
 128    CHECK_INIT (p, (UNSIGNED_T) MP_STATUS (z) & INIT_MASK, m);
 129    BOOL_T w = (A68G_MINUS_INF_MP (z) ? A68G_TRUE : A68G_FALSE);
 130    PUSH_VALUE (p, w, A68G_BOOL);
 131  }
 132  
 133  
 134  //! @brief Whether value is NaN 
 135  
 136  void genie_is_nan_real (NODE_T * p)
 137  {
 138    A68G_REAL z;
 139    POP_OBJECT (p, &z, A68G_REAL);
 140    BOOL_T w = a68g_isnan_real (VALUE (&z));
 141    PUSH_VALUE (p, w, A68G_BOOL);
 142  }
 143  
 144  
 145  //! @brief Whether value is NaN 
 146  
 147  void genie_is_nan_mp (NODE_T * p)
 148  {
 149    MOID_T *m = LHS_MODE (SUB (p));
 150    int size = SIZE (m);
 151    MP_T *z = (MP_T *) STACK_OFFSET (-size);
 152    A68G_SP -= size;
 153    CHECK_INIT (p, (UNSIGNED_T) MP_STATUS (z) & INIT_MASK, m);
 154    BOOL_T w = (A68G_NAN_MP (z) ? A68G_TRUE : A68G_FALSE);
 155    PUSH_VALUE (p, w, A68G_BOOL);
 156  }
 157  
 158  #if (A68G_LEVEL >= 3)
 159  
 160  
 161  //! @brief Whether value is finite
 162  
 163  void genie_is_finite_double (NODE_T * p)
 164  {
 165    A68G_LONG_REAL z;
 166    POP_OBJECT (p, &z, A68G_LONG_REAL);
 167    BOOL_T w = a68g_finite_double ((VALUE (&z)).f);
 168    PUSH_VALUE (p, w, A68G_BOOL);
 169  }
 170  
 171  
 172  //! @brief Whether value is infinite
 173  
 174  void genie_is_infinite_double (NODE_T * p)
 175  {
 176    A68G_LONG_REAL z;
 177    POP_OBJECT (p, &z, A68G_LONG_REAL);
 178    DOUBLE_T v = (VALUE (&z)).f;
 179    BOOL_T w = (v == a68g_minus_inf_double ()) || (v == a68g_plus_inf_double ());
 180    PUSH_VALUE (p, w, A68G_BOOL);
 181  }
 182  
 183  
 184  //! @brief Whether value is +inf 
 185  
 186  void genie_is_plus_inf_double (NODE_T * p)
 187  {
 188    A68G_LONG_REAL z;
 189    POP_OBJECT (p, &z, A68G_LONG_REAL);
 190    BOOL_T w = (VALUE (&z)).f == a68g_plus_inf_double ();
 191    PUSH_VALUE (p, w, A68G_BOOL);
 192  }
 193  
 194  
 195  //! @brief Whether value is -inf 
 196  
 197  void genie_is_minus_inf_double (NODE_T * p)
 198  {
 199    A68G_LONG_REAL z;
 200    POP_OBJECT (p, &z, A68G_LONG_REAL);
 201    BOOL_T w = (VALUE (&z)).f == a68g_minus_inf_double ();
 202    PUSH_VALUE (p, w, A68G_BOOL);
 203  }
 204  
 205  
 206  //! @brief Whether value is NaN 
 207  
 208  void genie_is_nan_double (NODE_T * p)
 209  {
 210    A68G_LONG_REAL z;
 211    POP_OBJECT (p, &z, A68G_LONG_REAL);
 212    BOOL_T w = a68g_isnan_double ((VALUE (&z)).f);
 213    PUSH_VALUE (p, w, A68G_BOOL);
 214  }
 215  
 216  #endif
     

This website is archived by the National Library of the Netherlands.

© J.M. van der Veer   •   jmvdveer@algol68genie.nl