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__ 0x13
22 * \brief Tuple Object Type
24 * Tuple object type operations.
31 /* The follwing value should match that in pmImgCreator.py */
32 #define MAX_TUPLE_LEN 253
36 tuple_loadFromImg(PmMemSpace_t memspace
,
37 uint8_t const **paddr
, pPmObj_t
*r_ptuple
)
39 PmReturn_t retval
= PM_RET_OK
;
40 uint8_t i
= (uint8_t)0;
41 uint8_t n
= (uint8_t)0;
44 /* Get num objs in tuple */
45 n
= mem_getByte(memspace
, paddr
);
47 /* Create empty tuple */
48 retval
= tuple_new(n
, r_ptuple
);
49 PM_RETURN_IF_ERROR(retval
);
50 ((pPmTuple_t
)*r_ptuple
)->length
= 0;
52 /* Load the next n objs into tuple */
53 heap_gcPushTempRoot((pPmObj_t
)*r_ptuple
, &objid
);
54 for (i
= (uint8_t)0; i
< n
; i
++)
56 retval
= obj_loadFromImg(memspace
,
58 (pPmObj_t
*)&(((pPmTuple_t
)*r_ptuple
)->
60 if (retval
!= PM_RET_OK
)
62 heap_gcPopTempRoot(objid
);
65 ((pPmTuple_t
)*r_ptuple
)->length
++;
67 heap_gcPopTempRoot(objid
);
73 tuple_new(uint16_t n
, pPmObj_t
*r_ptuple
)
75 PmReturn_t retval
= PM_RET_OK
;
78 /* Raise a SystemError for a Tuple that is too large */
79 if (n
> MAX_TUPLE_LEN
)
81 PM_RAISE(retval
, PM_RET_EX_SYS
);
85 /* Calc size of struct to hold tuple; (n-1) because PmTuple_t has val[1] */
86 size
= sizeof(PmTuple_t
) + ((n
- 1) * sizeof(pPmObj_t
));
88 /* Allocate a tuple */
89 retval
= heap_getChunk(size
, (uint8_t **)r_ptuple
);
90 PM_RETURN_IF_ERROR(retval
);
91 OBJ_SET_TYPE(*r_ptuple
, OBJ_TYPE_TUP
);
93 /* Set the number of objs in the tuple */
94 ((pPmTuple_t
)*r_ptuple
)->length
= n
;
96 /* No need to null the ptrs because they are set by the caller */
102 tuple_replicate(pPmObj_t ptup
, int16_t n
, pPmObj_t
*r_ptuple
)
104 PmReturn_t retval
= PM_RET_OK
;
109 /* Raise TypeError if object is not a Tuple */
110 if (OBJ_GET_TYPE(ptup
) != OBJ_TYPE_TUP
)
112 PM_RAISE(retval
, PM_RET_EX_SYS
);
118 /* Allocate the new tuple */
119 length
= ((pPmTuple_t
)ptup
)->length
;
120 retval
= tuple_new(length
* n
, r_ptuple
);
121 PM_RETURN_IF_ERROR(retval
);
123 /* Copy src tuple the designated number of times */
124 for (i
= 0; i
< n
; i
++)
126 for (j
= 0; j
< length
; j
++)
128 ((pPmTuple_t
)*r_ptuple
)->val
[length
* i
+ j
] =
129 ((pPmTuple_t
)ptup
)->val
[j
];
137 tuple_getItem(pPmObj_t ptup
, int16_t index
, pPmObj_t
*r_pobj
)
139 PmReturn_t retval
= PM_RET_OK
;
141 /* Adjust for negative index */
144 index
+= ((pPmTuple_t
)ptup
)->length
;
147 /* Raise IndexError if index is out of bounds */
148 if ((index
< 0) || (index
> ((pPmTuple_t
)ptup
)->length
))
150 PM_RAISE(retval
, PM_RET_EX_INDX
);
153 /* Get the tuple item */
154 *r_pobj
= ((pPmTuple_t
)ptup
)->val
[index
];
162 tuple_print(pPmObj_t ptup
)
164 PmReturn_t retval
= PM_RET_OK
;
167 C_ASSERT(ptup
!= C_NULL
);
169 /* If it's not a tuple, raise TypeError */
170 if (OBJ_GET_TYPE(ptup
) != OBJ_TYPE_TUP
)
172 PM_RAISE(retval
, PM_RET_EX_TYPE
);
178 for (index
= 0; index
< ((pPmTuple_t
)ptup
)->length
; index
++)
185 retval
= obj_print(((pPmTuple_t
)ptup
)->val
[index
], C_FALSE
, C_TRUE
);
186 PM_RETURN_IF_ERROR(retval
);
189 return plat_putByte(')');
191 #endif /* HAVE_PRINT */