Embed:
(wiki syntax)
Show/hide line numbers
int.c
Go to the documentation of this file.
00001 /* 00002 # This file is Copyright 2003, 2006, 2007, 2009 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 00020 /** 00021 * \file 00022 * \brief Integer Object Type 00023 * 00024 * Integer object type operations. 00025 */ 00026 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 Tue Jul 12 2022 17:07:01 by
1.7.2