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.
17 #define __FILE_ID__ 0x0F
24 * Object type operations.
32 obj_loadFromImg(PmMemSpace_t memspace
,
33 uint8_t const **paddr
, pPmObj_t
*r_pobj
)
35 PmReturn_t retval
= PM_RET_OK
;
39 /* Get the object descriptor */
40 obj
.od
= (PmObjDesc_t
)0x0000;
41 OBJ_SET_TYPE(&obj
, mem_getByte(memspace
, paddr
));
43 switch (OBJ_GET_TYPE(&obj
))
46 /* If it's the None object, return global None */
51 /* Read an integer and create an integer object with the value */
52 retval
= int_new(mem_getInt(memspace
, paddr
), r_pobj
);
57 /* Read a float and create an float object with the value */
58 retval
= float_new(mem_getFloat(memspace
, paddr
), r_pobj
);
60 #endif /* HAVE_FLOAT */
63 retval
= string_loadFromImg(memspace
, paddr
, r_pobj
);
67 retval
= tuple_loadFromImg(memspace
, paddr
, r_pobj
);
71 /* If it's a native code img, load into a code obj */
72 retval
= no_loadFromImg(memspace
, paddr
, r_pobj
);
76 /* If it's a code img, load into a code obj */
77 retval
= co_loadFromImg(memspace
, paddr
, r_pobj
);
81 /* All other types should not be in an img obj */
82 PM_RAISE(retval
, PM_RET_EX_SYS
);
90 obj_loadFromImgObj(pPmObj_t pimg
, pPmObj_t
*r_pobj
)
92 uint8_t const *imgaddr
;
95 C_ASSERT(OBJ_GET_TYPE(pimg
) == OBJ_TYPE_CIO
);
96 imgaddr
= (uint8_t const *)&(((pPmCodeImgObj_t
)pimg
)->val
);
98 retval
= obj_loadFromImg(MEMSPACE_RAM
, &imgaddr
, r_pobj
);
99 C_ASSERT(OBJ_GET_TYPE(*r_pobj
) == OBJ_TYPE_COB
);
101 /* All COs must reference the top of the code img obj
102 * so the image is marked and prevented from being reclaimed */
103 co_rSetCodeImgAddr((pPmCo_t
)*r_pobj
, (uint8_t const *)pimg
);
109 /* Returns true if the obj is false */
111 obj_isFalse(pPmObj_t pobj
)
113 C_ASSERT(pobj
!= C_NULL
);
115 switch (OBJ_GET_TYPE(pobj
))
118 /* None evaluates to false, so return true */
122 /* Only the integer zero is false */
123 return ((pPmInt_t
)pobj
)->val
== 0;
127 /* The floats 0.0 and -0.0 are false */
128 return (((pPmFloat_t
) pobj
)->val
== 0.0)
129 || (((pPmFloat_t
) pobj
)->val
== -0.0);
130 #endif /* HAVE_FLOAT */
133 /* An empty string is false */
134 return ((pPmString_t
)pobj
)->length
== 0;
137 /* An empty tuple is false */
138 return ((pPmTuple_t
)pobj
)->length
== 0;
141 /* An empty list is false */
142 return ((pPmList_t
)pobj
)->length
== 0;
145 /* An empty dict is false */
146 return ((pPmDict_t
)pobj
)->length
== 0;
149 /* C int zero means false */
150 return ((pPmBoolean_t
) pobj
)->val
== 0;
154 * The following types are always not false:
155 * CodeObj, Function, Module, Class, ClassInstance.
162 /* Returns true if the item is in the container object */
164 obj_isIn(pPmObj_t pobj
, pPmObj_t pitem
)
166 PmReturn_t retval
= PM_RET_NO
;
171 switch (OBJ_GET_TYPE(pobj
))
174 /* Iterate over tuple to find item */
175 for (i
= 0; i
< ((pPmTuple_t
)pobj
)->length
; i
++)
177 PM_RETURN_IF_ERROR(tuple_getItem(pobj
, i
, &ptestItem
));
179 if (obj_compare(pitem
, ptestItem
) == C_SAME
)
188 /* Raise a TypeError if item is not a string */
189 if ((OBJ_GET_TYPE(pitem
) != OBJ_TYPE_STR
))
191 retval
= PM_RET_EX_TYPE
;
195 /* Empty string is alway present */
196 if (((pPmString_t
)pitem
)->length
== 0)
202 /* Raise a ValueError if the string is more than 1 char */
203 else if (((pPmString_t
)pitem
)->length
!= 1)
205 retval
= PM_RET_EX_VAL
;
209 /* Iterate over string to find char */
210 c
= ((pPmString_t
)pitem
)->val
[0];
211 for (i
= 0; i
< ((pPmString_t
)pobj
)->length
; i
++)
213 if (c
== ((pPmString_t
)pobj
)->val
[i
])
222 /* Iterate over list to find item */
223 for (i
= 0; i
< ((pPmList_t
)pobj
)->length
; i
++)
225 PM_RETURN_IF_ERROR(list_getItem(pobj
, i
, &ptestItem
));
227 if (obj_compare(pitem
, ptestItem
) == C_SAME
)
236 /* Check if the item is one of the keys of the dict */
237 retval
= dict_getItem(pobj
, pitem
, &ptestItem
);
238 if (retval
== PM_RET_EX_KEY
)
245 retval
= PM_RET_EX_TYPE
;
254 obj_compare(pPmObj_t pobj1
, pPmObj_t pobj2
)
256 #ifdef HAVE_BYTEARRAY
259 #endif /* HAVE_BYTEARRAY */
261 C_ASSERT(pobj1
!= C_NULL
);
262 C_ASSERT(pobj2
!= C_NULL
);
264 /* Check if pointers are same */
270 /* If types are different, objs must differ */
271 if (OBJ_GET_TYPE(pobj1
) != OBJ_GET_TYPE(pobj2
))
276 #ifdef HAVE_BYTEARRAY
277 /* If object is an instance, get the thing it contains */
278 if (OBJ_GET_TYPE(pobj1
) == OBJ_TYPE_CLI
)
280 retval
= dict_getItem((pPmObj_t
)((pPmInstance_t
)pobj1
)->cli_attrs
,
283 PM_RETURN_IF_ERROR(retval
);
286 if (OBJ_GET_TYPE(pobj2
) == OBJ_TYPE_CLI
)
288 retval
= dict_getItem((pPmObj_t
)((pPmInstance_t
)pobj2
)->cli_attrs
,
291 PM_RETURN_IF_ERROR(retval
);
295 /* If types are different, objs must differ */
296 if (OBJ_GET_TYPE(pobj1
) != OBJ_GET_TYPE(pobj2
))
300 #endif /* HAVE_BYTEARRAY */
302 /* Otherwise handle types individually */
303 switch (OBJ_GET_TYPE(pobj1
))
309 return ((pPmInt_t
)pobj1
)->val
==
310 ((pPmInt_t
)pobj2
)->val
? C_SAME
: C_DIFFER
;
317 float_compare(pobj1
, pobj2
, &r_pobj
, COMP_EQ
);
318 return (r_pobj
== PM_TRUE
) ? C_SAME
: C_DIFFER
;
320 #endif /* HAVE_FLOAT */
323 return string_compare((pPmString_t
)pobj1
, (pPmString_t
)pobj2
);
327 #ifdef HAVE_BYTEARRAY
329 #endif /* HAVE_BYTEARRAY */
330 return seq_compare(pobj1
, pobj2
);
333 /* #17: PyMite does not support Dict comparisons (yet) */
338 /* All other types would need same pointer to be true */
345 obj_print(pPmObj_t pobj
, uint8_t is_expr_repr
, uint8_t is_nested
)
347 PmReturn_t retval
= PM_RET_OK
;
349 C_ASSERT(pobj
!= C_NULL
);
351 /* Something gets printed unless it's None in an unnested expression */
352 if (!((OBJ_GET_TYPE(pobj
) == OBJ_TYPE_NON
) && is_expr_repr
&& !is_nested
))
354 gVmGlobal
.somethingPrinted
= C_TRUE
;
357 switch (OBJ_GET_TYPE(pobj
))
360 if (!is_expr_repr
|| is_nested
)
365 retval
= plat_putByte('e');
369 retval
= int_print(pobj
);
373 retval
= float_print(pobj
);
375 #endif /* HAVE_FLOAT */
377 retval
= string_print(pobj
, (is_expr_repr
|| is_nested
));
380 retval
= tuple_print(pobj
);
383 retval
= list_print(pobj
);
386 retval
= dict_print(pobj
);
389 if (((pPmBoolean_t
) pobj
)->val
== C_TRUE
)
402 retval
= plat_putByte('e');
406 #ifdef HAVE_BYTEARRAY
410 retval
= dict_getItem((pPmObj_t
)((pPmInstance_t
)pobj
)->cli_attrs
,
413 if ((retval
== PM_RET_OK
)
414 && (OBJ_GET_TYPE(pobj2
) == OBJ_TYPE_BYA
))
416 retval
= bytearray_print(pobj2
);
420 #endif /* HAVE_BYTEARRAY */
445 int_printHexByte(OBJ_GET_TYPE(pobj
));
451 _int_printHex((intptr_t)pobj
);
452 retval
= plat_putByte('>');
456 /* Otherwise raise a TypeError */
457 PM_RAISE(retval
, PM_RET_EX_TYPE
);
462 #endif /* HAVE_PRINT */
467 obj_repr(pPmObj_t pobj
, pPmObj_t
*r_pstr
)
470 uint8_t bytesWritten
= 0;
471 PmReturn_t retval
= PM_RET_OK
;
472 uint8_t const *pcstr
= (uint8_t *)tBuffer
;;
474 C_ASSERT(pobj
!= C_NULL
);
476 switch (OBJ_GET_TYPE(pobj
))
479 bytesWritten
= snprintf((char *)&tBuffer
, sizeof(tBuffer
), "%li",
480 (long)((pPmInt_t
)pobj
)->val
);
481 retval
= string_new(&pcstr
, r_pstr
);
486 bytesWritten
= snprintf((char *)&tBuffer
, sizeof(tBuffer
), "%f",
487 ((pPmFloat_t
)pobj
)->val
);
488 retval
= string_new(&pcstr
, r_pstr
);
490 #endif /* HAVE_FLOAT */
493 /* Otherwise raise a TypeError */
494 PM_RAISE(retval
, PM_RET_EX_TYPE
);
499 C_ASSERT(bytesWritten
< sizeof(tBuffer
));
503 #endif /* HAVE_BACKTICK */