int.c

Go to the documentation of this file.
00001 /*
00002 # This file is Copyright 2003, 2006, 2007, 2009, 2010 Dean Hall.
00003 #
00004 # This file is part of the PyMite VM.
00005 # The PyMite VM is free software: you can redistribute it and/or modify
00006 # it under the terms of the GNU GENERAL PUBLIC LICENSE Version 2.
00007 #
00008 # The PyMite VM is distributed in the hope that it will be useful,
00009 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00011 # A copy of the GNU GENERAL PUBLIC LICENSE Version 2
00012 # is seen in the file COPYING in this directory.
00013 */
00014 
00015 
00016 #undef __FILE_ID__
00017 #define __FILE_ID__ 0x08
00018 
00019 
00027 #include <stdint.h>
00028 #include <limits.h>
00029 
00030 #include "pm.h"
00031 
00032 
00033 PmReturn_t
00034 int_dup(pPmObj_t pint, pPmObj_t *r_pint)
00035 {
00036     PmReturn_t retval = PM_RET_OK;
00037 
00038     /* Allocate new int */
00039     retval = heap_getChunk(sizeof(PmInt_t), (uint8_t **)r_pint);
00040     PM_RETURN_IF_ERROR(retval);
00041 
00042     /* Copy value */
00043     OBJ_SET_TYPE(*r_pint, OBJ_TYPE_INT);
00044     ((pPmInt_t)*r_pint)->val = ((pPmInt_t)pint)->val;
00045     return retval;
00046 }
00047 
00048 
00049 PmReturn_t
00050 int_new(int32_t n, pPmObj_t *r_pint)
00051 {
00052     PmReturn_t retval = PM_RET_OK;
00053 
00054     /* If n is 0,1,-1, return static int objects from global struct */
00055     if (n == 0)
00056     {
00057         *r_pint = PM_ZERO;
00058         return PM_RET_OK;
00059     }
00060     if (n == 1)
00061     {
00062         *r_pint = PM_ONE;
00063         return PM_RET_OK;
00064     }
00065     if (n == -1)
00066     {
00067         *r_pint = PM_NEGONE;
00068         return PM_RET_OK;
00069     }
00070 
00071     /* Else create and return new int obj */
00072     retval = heap_getChunk(sizeof(PmInt_t), (uint8_t **)r_pint);
00073     PM_RETURN_IF_ERROR(retval);
00074     OBJ_SET_TYPE(*r_pint, OBJ_TYPE_INT);
00075     ((pPmInt_t)*r_pint)->val = n;
00076     return retval;
00077 }
00078 
00079 
00080 PmReturn_t
00081 int_positive(pPmObj_t pobj, pPmObj_t *r_pint)
00082 {
00083     PmReturn_t retval;
00084 
00085     /* Raise TypeError if obj is not an int */
00086     if (OBJ_GET_TYPE(pobj) != OBJ_TYPE_INT)
00087     {
00088         PM_RAISE(retval, PM_RET_EX_TYPE);
00089         return retval;
00090     }
00091 
00092     /* Create new int obj */
00093     return int_new(((pPmInt_t)pobj)->val, r_pint);
00094 }
00095 
00096 
00097 PmReturn_t
00098 int_negative(pPmObj_t pobj, pPmObj_t *r_pint)
00099 {
00100     PmReturn_t retval;
00101 
00102     /* Raise TypeError if obj is not an int */
00103     if (OBJ_GET_TYPE(pobj) != OBJ_TYPE_INT)
00104     {
00105         PM_RAISE(retval, PM_RET_EX_TYPE);
00106         return retval;
00107     }
00108 
00109     /* Create new int obj */
00110     return int_new(-((pPmInt_t)pobj)->val, r_pint);
00111 }
00112 
00113 
00114 PmReturn_t
00115 int_bitInvert(pPmObj_t pobj, pPmObj_t *r_pint)
00116 {
00117     PmReturn_t retval;
00118 
00119     /* Raise TypeError if obj is not an int */
00120     if (OBJ_GET_TYPE(pobj) != OBJ_TYPE_INT)
00121     {
00122         PM_RAISE(retval, PM_RET_EX_TYPE);
00123         return retval;
00124     }
00125 
00126     /* Create new int obj */
00127     return int_new(~((pPmInt_t)pobj)->val, r_pint);
00128 }
00129 
00130 
00131 #ifdef HAVE_PRINT
00132 PmReturn_t
00133 int_print(pPmObj_t pint)
00134 {
00135     /* 2^31-1 has 10 decimal digits, plus sign and zero byte */
00136     uint8_t tBuffer[10 + 1 + 1];
00137     uint8_t bytesWritten;
00138     uint8_t k;
00139     PmReturn_t retval = PM_RET_OK;
00140 
00141     C_ASSERT(pint != C_NULL);
00142 
00143     /* Raise TypeError if obj is not an int */
00144     if (OBJ_GET_TYPE(pint) != OBJ_TYPE_INT)
00145     {
00146         PM_RAISE(retval, PM_RET_EX_TYPE);
00147         return retval;
00148     }
00149 
00150     /* #196: Changed to use snprintf */
00151     bytesWritten =
00152         snprintf((char *)&tBuffer, 12, "%li", (long int)((pPmInt_t)pint)->val);
00153 
00154 
00155     /* Sanity check */
00156     C_ASSERT(bytesWritten != 0);
00157     C_ASSERT(bytesWritten < sizeof(tBuffer));
00158 
00159     for (k = (uint8_t)0; k < bytesWritten; k++)
00160     {
00161         retval = plat_putByte(tBuffer[k]);
00162         PM_RETURN_IF_ERROR(retval);
00163     }
00164     return PM_RET_OK;
00165 }
00166 
00167 
00168 PmReturn_t
00169 int_printHexByte(uint8_t b)
00170 {
00171     uint8_t nibble;
00172     PmReturn_t retval;
00173 
00174     nibble = (b >> 4) + '0';
00175     if (nibble > '9')
00176         nibble += ('a' - '0' - 10);
00177     retval = plat_putByte(nibble);
00178     PM_RETURN_IF_ERROR(retval);
00179 
00180     nibble = (b & (uint8_t)0x0F) + '0';
00181     if (nibble > '9')
00182         nibble += ('a' - '0' - (uint8_t)10);
00183     retval = plat_putByte(nibble);
00184     return retval;
00185 }
00186 
00187 
00188 PmReturn_t
00189 _int_printHex(intptr_t n)
00190 {
00191     PmReturn_t retval;
00192     int8_t i;
00193 
00194     /* Print the hex value, most significant byte first */
00195     for (i = CHAR_BIT * sizeof(intptr_t) - 8; i >= 0; i -= 8)
00196     {
00197         retval = int_printHexByte((n >> i) & 0xFF);
00198         PM_BREAK_IF_ERROR(retval);
00199     }
00200 
00201     return retval;
00202 }
00203 
00204 
00205 PmReturn_t
00206 int_printHex(pPmObj_t pint)
00207 {
00208     C_ASSERT(OBJ_GET_TYPE(pint) == OBJ_TYPE_INT);
00209 
00210     /* Print the integer object */
00211     return _int_printHex(((pPmInt_t)pint)->val);
00212 }
00213 #endif /* HAVE_PRINT */
00214 
00215 
00216 PmReturn_t
00217 int_pow(pPmObj_t px, pPmObj_t py, pPmObj_t *r_pn)
00218 {
00219     int32_t x;
00220     int32_t y;
00221     int32_t n;
00222     PmReturn_t retval;
00223 
00224     /* Raise TypeError if args aren't ints */
00225     if ((OBJ_GET_TYPE(px) != OBJ_TYPE_INT)
00226         || (OBJ_GET_TYPE(py) != OBJ_TYPE_INT))
00227     {
00228         PM_RAISE(retval, PM_RET_EX_TYPE);
00229         return retval;
00230     }
00231 
00232     x = ((pPmInt_t)px)->val;
00233     y = ((pPmInt_t)py)->val;
00234 
00235     /* Raise Value error if exponent is negative */
00236     if (y < 0)
00237     {
00238         PM_RAISE(retval, PM_RET_EX_VAL);
00239         return retval;
00240     }
00241 
00242     /* Calculate x raised to y */
00243     n = 1;
00244     while (y > 0)
00245     {
00246         n = n * x;
00247         y--;
00248     }
00249     retval = int_new(n, r_pn);
00250 
00251     return retval;
00252 }

Generated on Mon Oct 18 07:40:47 2010 for Python-on-a-chip by  doxygen 1.5.9