update credits
[librepilot.git] / flight / libraries / PyMite / vm / int.c
blob51a1dffe5333502655b38374ddc9b81213bbd461
1 /*
2 # This file is Copyright 2003, 2006, 2007, 2009, 2010 Dean Hall.
4 # This file is part of the PyMite VM.
5 # The PyMite VM is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU GENERAL PUBLIC LICENSE Version 2.
8 # The PyMite VM is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 # A copy of the GNU GENERAL PUBLIC LICENSE Version 2
12 # is seen in the file COPYING in this directory.
16 #undef __FILE_ID__
17 #define __FILE_ID__ 0x08
20 /**
21 * \file
22 * \brief Integer Object Type
24 * Integer object type operations.
27 #include <stdint.h>
28 #include <limits.h>
30 #include "pm.h"
33 PmReturn_t
34 int_dup(pPmObj_t pint, pPmObj_t *r_pint)
36 PmReturn_t retval = PM_RET_OK;
38 /* Allocate new int */
39 retval = heap_getChunk(sizeof(PmInt_t), (uint8_t **)r_pint);
40 PM_RETURN_IF_ERROR(retval);
42 /* Copy value */
43 OBJ_SET_TYPE(*r_pint, OBJ_TYPE_INT);
44 ((pPmInt_t)*r_pint)->val = ((pPmInt_t)pint)->val;
45 return retval;
49 PmReturn_t
50 int_new(int32_t n, pPmObj_t *r_pint)
52 PmReturn_t retval = PM_RET_OK;
54 /* If n is 0,1,-1, return static int objects from global struct */
55 if (n == 0)
57 *r_pint = PM_ZERO;
58 return PM_RET_OK;
60 if (n == 1)
62 *r_pint = PM_ONE;
63 return PM_RET_OK;
65 if (n == -1)
67 *r_pint = PM_NEGONE;
68 return PM_RET_OK;
71 /* Else create and return new int obj */
72 retval = heap_getChunk(sizeof(PmInt_t), (uint8_t **)r_pint);
73 PM_RETURN_IF_ERROR(retval);
74 OBJ_SET_TYPE(*r_pint, OBJ_TYPE_INT);
75 ((pPmInt_t)*r_pint)->val = n;
76 return retval;
80 PmReturn_t
81 int_positive(pPmObj_t pobj, pPmObj_t *r_pint)
83 PmReturn_t retval;
85 /* Raise TypeError if obj is not an int */
86 if (OBJ_GET_TYPE(pobj) != OBJ_TYPE_INT)
88 PM_RAISE(retval, PM_RET_EX_TYPE);
89 return retval;
92 /* Create new int obj */
93 return int_new(((pPmInt_t)pobj)->val, r_pint);
97 PmReturn_t
98 int_negative(pPmObj_t pobj, pPmObj_t *r_pint)
100 PmReturn_t retval;
102 /* Raise TypeError if obj is not an int */
103 if (OBJ_GET_TYPE(pobj) != OBJ_TYPE_INT)
105 PM_RAISE(retval, PM_RET_EX_TYPE);
106 return retval;
109 /* Create new int obj */
110 return int_new(-((pPmInt_t)pobj)->val, r_pint);
114 PmReturn_t
115 int_bitInvert(pPmObj_t pobj, pPmObj_t *r_pint)
117 PmReturn_t retval;
119 /* Raise TypeError if obj is not an int */
120 if (OBJ_GET_TYPE(pobj) != OBJ_TYPE_INT)
122 PM_RAISE(retval, PM_RET_EX_TYPE);
123 return retval;
126 /* Create new int obj */
127 return int_new(~((pPmInt_t)pobj)->val, r_pint);
131 #ifdef HAVE_PRINT
132 PmReturn_t
133 int_print(pPmObj_t pint)
135 /* 2^31-1 has 10 decimal digits, plus sign and zero byte */
136 uint8_t tBuffer[10 + 1 + 1];
137 uint8_t bytesWritten;
138 uint8_t k;
139 PmReturn_t retval = PM_RET_OK;
141 C_ASSERT(pint != C_NULL);
143 /* Raise TypeError if obj is not an int */
144 if (OBJ_GET_TYPE(pint) != OBJ_TYPE_INT)
146 PM_RAISE(retval, PM_RET_EX_TYPE);
147 return retval;
150 /* #196: Changed to use snprintf */
151 bytesWritten =
152 snprintf((char *)&tBuffer, 12, "%li", (long int)((pPmInt_t)pint)->val);
155 /* Sanity check */
156 C_ASSERT(bytesWritten != 0);
157 C_ASSERT(bytesWritten < sizeof(tBuffer));
159 for (k = (uint8_t)0; k < bytesWritten; k++)
161 retval = plat_putByte(tBuffer[k]);
162 PM_RETURN_IF_ERROR(retval);
164 return PM_RET_OK;
168 PmReturn_t
169 int_printHexByte(uint8_t b)
171 uint8_t nibble;
172 PmReturn_t retval;
174 nibble = (b >> 4) + '0';
175 if (nibble > '9')
176 nibble += ('a' - '0' - 10);
177 retval = plat_putByte(nibble);
178 PM_RETURN_IF_ERROR(retval);
180 nibble = (b & (uint8_t)0x0F) + '0';
181 if (nibble > '9')
182 nibble += ('a' - '0' - (uint8_t)10);
183 retval = plat_putByte(nibble);
184 return retval;
188 PmReturn_t
189 _int_printHex(intptr_t n)
191 PmReturn_t retval;
192 int8_t i;
194 /* Print the hex value, most significant byte first */
195 for (i = CHAR_BIT * sizeof(intptr_t) - 8; i >= 0; i -= 8)
197 retval = int_printHexByte((n >> i) & 0xFF);
198 PM_BREAK_IF_ERROR(retval);
201 return retval;
205 PmReturn_t
206 int_printHex(pPmObj_t pint)
208 C_ASSERT(OBJ_GET_TYPE(pint) == OBJ_TYPE_INT);
210 /* Print the integer object */
211 return _int_printHex(((pPmInt_t)pint)->val);
213 #endif /* HAVE_PRINT */
216 PmReturn_t
217 int_pow(pPmObj_t px, pPmObj_t py, pPmObj_t *r_pn)
219 int32_t x;
220 int32_t y;
221 int32_t n;
222 PmReturn_t retval;
224 /* Raise TypeError if args aren't ints */
225 if ((OBJ_GET_TYPE(px) != OBJ_TYPE_INT)
226 || (OBJ_GET_TYPE(py) != OBJ_TYPE_INT))
228 PM_RAISE(retval, PM_RET_EX_TYPE);
229 return retval;
232 x = ((pPmInt_t)px)->val;
233 y = ((pPmInt_t)py)->val;
235 /* Raise Value error if exponent is negative */
236 if (y < 0)
238 PM_RAISE(retval, PM_RET_EX_VAL);
239 return retval;
242 /* Calculate x raised to y */
243 n = 1;
244 while (y > 0)
246 n = n * x;
247 y--;
249 retval = int_new(n, r_pn);
251 return retval;