python-on-a-chip online compiler

Dependencies:   mbed TSI

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers int.c Source File

int.c

Go to the documentation of this file.
00001 /*
00002 # This file is Copyright 2002 Dean Hall.
00003 # This file is part of the PyMite VM.
00004 # This file is licensed under the MIT License.
00005 # See the LICENSE file for details.
00006 */
00007 
00008 
00009 #undef __FILE_ID__
00010 #define __FILE_ID__ 0x08
00011 
00012 
00013 /**
00014  * \file
00015  * \brief Integer Object Type
00016  *
00017  * Integer object type operations.
00018  */
00019 
00020 #include <limits.h>
00021 
00022 #include "pm.h"
00023 
00024 
00025 PmReturn_t
00026 int_dup(pPmObj_t pint, pPmObj_t *r_pint)
00027 {
00028     PmReturn_t retval = PM_RET_OK;
00029 
00030     /* Allocate new int */
00031     retval = heap_getChunk(sizeof(PmInt_t), (uint8_t **)r_pint);
00032     PM_RETURN_IF_ERROR(retval);
00033 
00034     /* Copy value */
00035     OBJ_SET_TYPE(*r_pint, OBJ_TYPE_INT);
00036     ((pPmInt_t)*r_pint)->val = ((pPmInt_t)pint)->val;
00037     return retval;
00038 }
00039 
00040 
00041 PmReturn_t
00042 int_new(int32_t n, pPmObj_t *r_pint)
00043 {
00044     PmReturn_t retval = PM_RET_OK;
00045 
00046     /* If n is 0,1,-1, return static int objects from global struct */
00047     if (n == 0)
00048     {
00049         *r_pint = PM_ZERO;
00050         return PM_RET_OK;
00051     }
00052     if (n == 1)
00053     {
00054         *r_pint = PM_ONE;
00055         return PM_RET_OK;
00056     }
00057     if (n == -1)
00058     {
00059         *r_pint = PM_NEGONE;
00060         return PM_RET_OK;
00061     }
00062 
00063     /* Else create and return new int obj */
00064     retval = heap_getChunk(sizeof(PmInt_t), (uint8_t **)r_pint);
00065     PM_RETURN_IF_ERROR(retval);
00066     OBJ_SET_TYPE(*r_pint, OBJ_TYPE_INT);
00067     ((pPmInt_t)*r_pint)->val = n;
00068     return retval;
00069 }
00070 
00071 
00072 PmReturn_t
00073 int_positive(pPmObj_t pobj, pPmObj_t *r_pint)
00074 {
00075     PmReturn_t retval;
00076 
00077     /* Raise TypeError if obj is not an int */
00078     if (OBJ_GET_TYPE(pobj) != OBJ_TYPE_INT)
00079     {
00080         PM_RAISE(retval, PM_RET_EX_TYPE);
00081         return retval;
00082     }
00083 
00084     /* Create new int obj */
00085     return int_new(((pPmInt_t)pobj)->val, r_pint);
00086 }
00087 
00088 
00089 PmReturn_t
00090 int_negative(pPmObj_t pobj, pPmObj_t *r_pint)
00091 {
00092     PmReturn_t retval;
00093 
00094     /* Raise TypeError if obj is not an int */
00095     if (OBJ_GET_TYPE(pobj) != OBJ_TYPE_INT)
00096     {
00097         PM_RAISE(retval, PM_RET_EX_TYPE);
00098         return retval;
00099     }
00100 
00101     /* Create new int obj */
00102     return int_new(-((pPmInt_t)pobj)->val, r_pint);
00103 }
00104 
00105 
00106 PmReturn_t
00107 int_bitInvert(pPmObj_t pobj, pPmObj_t *r_pint)
00108 {
00109     PmReturn_t retval;
00110 
00111     /* Raise TypeError if obj is not an int */
00112     if (OBJ_GET_TYPE(pobj) != OBJ_TYPE_INT)
00113     {
00114         PM_RAISE(retval, PM_RET_EX_TYPE);
00115         return retval;
00116     }
00117 
00118     /* Create new int obj */
00119     return int_new(~((pPmInt_t)pobj)->val, r_pint);
00120 }
00121 
00122 
00123 PmReturn_t
00124 int_print(pPmObj_t pint)
00125 {
00126     PmReturn_t retval = PM_RET_OK;
00127     uint8_t buf[12];
00128 
00129     C_ASSERT(pint != C_NULL);
00130 
00131     /* Raise TypeError if obj is not an int */
00132     if (OBJ_GET_TYPE(pint) != OBJ_TYPE_INT)
00133     {
00134         PM_RAISE(retval, PM_RET_EX_TYPE);
00135         return retval;
00136     }
00137 
00138     retval = sli_ltoa10(((pPmInt_t)pint)->val, buf, sizeof(buf));
00139     PM_RETURN_IF_ERROR(retval);
00140     sli_puts(buf);
00141 
00142     return retval;
00143 }
00144 
00145 
00146 PmReturn_t
00147 int_printHex(pPmObj_t pint)
00148 {
00149     uint8_t buf[9];
00150     PmReturn_t retval = PM_RET_OK;
00151 
00152     C_ASSERT(OBJ_GET_TYPE(pint) == OBJ_TYPE_INT);
00153 
00154     /* Print the integer object */
00155     retval = sli_ltoa16(((pPmInt_t)pint)->val, buf, sizeof(buf), 1);
00156     sli_puts(buf);
00157     return retval;
00158 }
00159 
00160 
00161 PmReturn_t
00162 int_pow(pPmObj_t px, pPmObj_t py, pPmObj_t *r_pn)
00163 {
00164     int32_t x;
00165     int32_t y;
00166     int32_t n;
00167     PmReturn_t retval;
00168 
00169     /* Raise TypeError if args aren't ints */
00170     if ((OBJ_GET_TYPE(px) != OBJ_TYPE_INT)
00171         || (OBJ_GET_TYPE(py) != OBJ_TYPE_INT))
00172     {
00173         PM_RAISE(retval, PM_RET_EX_TYPE);
00174         return retval;
00175     }
00176 
00177     x = ((pPmInt_t)px)->val;
00178     y = ((pPmInt_t)py)->val;
00179 
00180     /* Raise Value error if exponent is negative */
00181     if (y < 0)
00182     {
00183         PM_RAISE(retval, PM_RET_EX_VAL);
00184         return retval;
00185     }
00186 
00187     /* Calculate x raised to y */
00188     n = 1;
00189     while (y > 0)
00190     {
00191         n = n * x;
00192         y--;
00193     }
00194     retval = int_new(n, r_pn);
00195 
00196     return retval;
00197 }
00198 
00199 
00200 PmReturn_t
00201 int_divmod(pPmObj_t px, pPmObj_t py, uint8_t op, pPmObj_t *r_pxopy)
00202 {
00203     int32_t x;
00204     int32_t y;
00205     int32_t xdivy;
00206     int32_t xmody;
00207     int32_t xopy;
00208     PmReturn_t retval = PM_RET_OK;
00209 
00210     /* Raise TypeError if args aren't ints */
00211     if ((OBJ_GET_TYPE(px) != OBJ_TYPE_INT)
00212         || (OBJ_GET_TYPE(py) != OBJ_TYPE_INT))
00213     {
00214         PM_RAISE(retval, PM_RET_EX_TYPE);
00215         return retval;
00216     }
00217 
00218     x = ((pPmInt_t)px)->val;
00219     y = ((pPmInt_t)py)->val;
00220 
00221     /* Raise ZeroDivisionError if denominator is zero */
00222     if (y == 0)
00223     {
00224         PM_RAISE(retval, PM_RET_EX_ZDIV);
00225         return retval;
00226     }
00227 
00228     /* Issue #167: Make overflow silent until exceptions can be caught */
00229     /* (-sys.maxint-1)/-1 is the only overflow case. */
00230     /* TODO:  enable the overflow for Issue #169 */
00231     /*
00232     if ((y == -1) && (op == '/') && (x < 0)
00233         && ((uint32_t)x == (0 - (uint32_t)x)))
00234     {
00235         PM_RAISE(retval, PM_RET_EX_OFLOW);
00236         return retval;
00237     }
00238     */
00239 
00240     /* Shortcut when denominator is one or negative one */
00241     if (y == 1)
00242     {
00243         xdivy = x;
00244         xmody = 0;
00245     }
00246     else if (y == -1)
00247     {
00248         xdivy = -x;
00249         xmody = 0;
00250     }
00251 
00252     else
00253     {
00254         xdivy = x / y;
00255         xmody = x - xdivy * y;
00256 
00257         /*
00258          * If the remainder is non-0 and the signs of x and y differ,
00259          * C89 doesn't define whether xdivy is now the floor or the
00260          * ceiling of the infinitely precise quotient.  We want the floor,
00261          * and we have it iff the remainder's sign matches y's.
00262          */
00263         if ((xmody != 0) && ((y ^ xmody) < 0))
00264         {
00265             xmody += y;
00266             --xdivy;
00267             C_ASSERT(xmody && ((y ^ xmody) >= 0));
00268         }
00269     }
00270     xopy = (op == '/') ? xdivy : xmody;
00271     return int_new(xopy, r_pxopy);
00272 }