python-on-a-chip online compiler

Dependencies:   mbed TSI

/media/uploads/va009039/p14p-f446re.png

more info: python-on-a-chip

Committer:
va009039
Date:
Thu Apr 14 22:32:57 2016 +0000
Revision:
15:94ca5c8003e5
Parent:
0:65f1469d6bfb
update Nucleo-F401RE.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 0:65f1469d6bfb 1 /*
va009039 0:65f1469d6bfb 2 # This file is Copyright 2009 Dean Hall.
va009039 0:65f1469d6bfb 3 # This file is part of the PyMite VM.
va009039 0:65f1469d6bfb 4 # This file is licensed under the MIT License.
va009039 0:65f1469d6bfb 5 # See the LICENSE file for details.
va009039 0:65f1469d6bfb 6 */
va009039 0:65f1469d6bfb 7
va009039 0:65f1469d6bfb 8
va009039 0:65f1469d6bfb 9 #undef __FILE_ID__
va009039 0:65f1469d6bfb 10 #define __FILE_ID__ 0x18
va009039 0:65f1469d6bfb 11
va009039 0:65f1469d6bfb 12
va009039 0:65f1469d6bfb 13 /**
va009039 0:65f1469d6bfb 14 * \file
va009039 0:65f1469d6bfb 15 * \brief Class Object Type
va009039 0:65f1469d6bfb 16 *
va009039 0:65f1469d6bfb 17 * Class object type operations.
va009039 0:65f1469d6bfb 18 */
va009039 0:65f1469d6bfb 19
va009039 0:65f1469d6bfb 20
va009039 0:65f1469d6bfb 21 #include "pm.h"
va009039 0:65f1469d6bfb 22
va009039 0:65f1469d6bfb 23
va009039 0:65f1469d6bfb 24 #ifdef HAVE_AUTOBOX
va009039 0:65f1469d6bfb 25 static uint8_t const *liststr = (uint8_t const *)"list";
va009039 0:65f1469d6bfb 26 static uint8_t const *dictstr = (uint8_t const *)"dict";
va009039 0:65f1469d6bfb 27 static uint8_t const *stringstr = (uint8_t const *)"string";
va009039 0:65f1469d6bfb 28 static uint8_t const *autoboxstr = (uint8_t const *)"_Autobox";
va009039 0:65f1469d6bfb 29 static uint8_t const *objstr = (uint8_t const *)"obj";
va009039 0:65f1469d6bfb 30 #endif
va009039 0:65f1469d6bfb 31
va009039 0:65f1469d6bfb 32
va009039 0:65f1469d6bfb 33 PmReturn_t
va009039 0:65f1469d6bfb 34 class_new(pPmObj_t pattrs, pPmObj_t pbases, pPmObj_t pname, pPmObj_t *r_pclass)
va009039 0:65f1469d6bfb 35 {
va009039 0:65f1469d6bfb 36 PmReturn_t retval = PM_RET_OK;
va009039 0:65f1469d6bfb 37 uint8_t *pchunk;
va009039 0:65f1469d6bfb 38 pPmObj_t pobj;
va009039 0:65f1469d6bfb 39
va009039 0:65f1469d6bfb 40 /* Ensure types */
va009039 0:65f1469d6bfb 41 if ((OBJ_GET_TYPE(pattrs) != OBJ_TYPE_DIC)
va009039 0:65f1469d6bfb 42 || (OBJ_GET_TYPE(pbases) != OBJ_TYPE_TUP)
va009039 0:65f1469d6bfb 43 || (OBJ_GET_TYPE(pname) != OBJ_TYPE_STR))
va009039 0:65f1469d6bfb 44 {
va009039 0:65f1469d6bfb 45 PM_RAISE(retval, PM_RET_EX_TYPE);
va009039 0:65f1469d6bfb 46 return retval;
va009039 0:65f1469d6bfb 47 }
va009039 0:65f1469d6bfb 48
va009039 0:65f1469d6bfb 49 /* Allocate a class obj */
va009039 0:65f1469d6bfb 50 retval = heap_getChunk(sizeof(PmClass_t), &pchunk);
va009039 0:65f1469d6bfb 51 PM_RETURN_IF_ERROR(retval);
va009039 0:65f1469d6bfb 52 pobj = (pPmObj_t)pchunk;
va009039 0:65f1469d6bfb 53 OBJ_SET_TYPE(pobj, OBJ_TYPE_CLO);
va009039 0:65f1469d6bfb 54
va009039 0:65f1469d6bfb 55 /* Class has no access to its CO */
va009039 0:65f1469d6bfb 56 ((pPmClass_t)pobj)->cl_attrs = (pPmDict_t)pattrs;
va009039 0:65f1469d6bfb 57 ((pPmClass_t)pobj)->cl_bases = (pPmTuple_t)pbases;
va009039 0:65f1469d6bfb 58
va009039 0:65f1469d6bfb 59 *r_pclass = pobj;
va009039 0:65f1469d6bfb 60
va009039 0:65f1469d6bfb 61 return retval;
va009039 0:65f1469d6bfb 62 }
va009039 0:65f1469d6bfb 63
va009039 0:65f1469d6bfb 64
va009039 0:65f1469d6bfb 65 /* Returns an instance of the class by reference */
va009039 0:65f1469d6bfb 66 PmReturn_t
va009039 0:65f1469d6bfb 67 class_instantiate(pPmObj_t pclass, pPmObj_t *r_pobj)
va009039 0:65f1469d6bfb 68 {
va009039 0:65f1469d6bfb 69 PmReturn_t retval = PM_RET_OK;
va009039 0:65f1469d6bfb 70 uint8_t *pchunk;
va009039 0:65f1469d6bfb 71 pPmObj_t pobj;
va009039 0:65f1469d6bfb 72 pPmObj_t pattrs;
va009039 0:65f1469d6bfb 73 uint8_t objid;
va009039 0:65f1469d6bfb 74
va009039 0:65f1469d6bfb 75 /* Allocate a class instance */
va009039 0:65f1469d6bfb 76 retval = heap_getChunk(sizeof(PmInstance_t), &pchunk);
va009039 0:65f1469d6bfb 77 PM_RETURN_IF_ERROR(retval);
va009039 0:65f1469d6bfb 78 pobj = (pPmObj_t)pchunk;
va009039 0:65f1469d6bfb 79 OBJ_SET_TYPE(pobj, OBJ_TYPE_CLI);
va009039 0:65f1469d6bfb 80
va009039 0:65f1469d6bfb 81 /* Set the instance's fields */
va009039 0:65f1469d6bfb 82 ((pPmInstance_t)pobj)->cli_class = (pPmClass_t)pclass;
va009039 0:65f1469d6bfb 83 ((pPmInstance_t)pobj)->cli_attrs = C_NULL;
va009039 0:65f1469d6bfb 84
va009039 0:65f1469d6bfb 85 /* Create the attributes dict */
va009039 0:65f1469d6bfb 86 heap_gcPushTempRoot(pobj, &objid);
va009039 0:65f1469d6bfb 87 retval = dict_new(&pattrs);
va009039 0:65f1469d6bfb 88 heap_gcPopTempRoot(objid);
va009039 0:65f1469d6bfb 89 ((pPmInstance_t)pobj)->cli_attrs = (pPmDict_t)pattrs;
va009039 0:65f1469d6bfb 90
va009039 0:65f1469d6bfb 91 /* TODO: Store pclass in __class__ attr */
va009039 0:65f1469d6bfb 92
va009039 0:65f1469d6bfb 93 *r_pobj = pobj;
va009039 0:65f1469d6bfb 94 return retval;
va009039 0:65f1469d6bfb 95 }
va009039 0:65f1469d6bfb 96
va009039 0:65f1469d6bfb 97
va009039 0:65f1469d6bfb 98 #ifdef HAVE_AUTOBOX
va009039 0:65f1469d6bfb 99 PmReturn_t
va009039 0:65f1469d6bfb 100 class_autobox(pPmObj_t *pobj)
va009039 0:65f1469d6bfb 101 {
va009039 0:65f1469d6bfb 102 PmReturn_t retval = PM_RET_OK;
va009039 0:65f1469d6bfb 103 pPmObj_t pmodule, pstr, pclass, pwrapped, pmodcache;
va009039 0:65f1469d6bfb 104
va009039 0:65f1469d6bfb 105 uint8_t const *pliststr = liststr;
va009039 0:65f1469d6bfb 106 uint8_t const *pdictstr = dictstr;
va009039 0:65f1469d6bfb 107 uint8_t const *pstringstr = stringstr;
va009039 0:65f1469d6bfb 108
va009039 0:65f1469d6bfb 109 uint8_t const *pAutoboxstr = autoboxstr;
va009039 0:65f1469d6bfb 110 uint8_t const *pobjstr = objstr;
va009039 0:65f1469d6bfb 111
va009039 0:65f1469d6bfb 112 /* Load the appropriate module name,
va009039 0:65f1469d6bfb 113 * or do nothing if we have a non-boxable type
va009039 0:65f1469d6bfb 114 */
va009039 0:65f1469d6bfb 115 if (OBJ_GET_TYPE(*pobj) == OBJ_TYPE_LST) {
va009039 0:65f1469d6bfb 116 retval = string_new(&pliststr, &pstr);
va009039 0:65f1469d6bfb 117 PM_RETURN_IF_ERROR(retval);
va009039 0:65f1469d6bfb 118 } else if (OBJ_GET_TYPE(*pobj) == OBJ_TYPE_DIC) {
va009039 0:65f1469d6bfb 119 retval = string_new(&pdictstr, &pstr);
va009039 0:65f1469d6bfb 120 PM_RETURN_IF_ERROR(retval);
va009039 0:65f1469d6bfb 121 } else if (OBJ_GET_TYPE(*pobj) == OBJ_TYPE_STR) {
va009039 0:65f1469d6bfb 122 retval = string_new(&pstringstr, &pstr);
va009039 0:65f1469d6bfb 123 PM_RETURN_IF_ERROR(retval);
va009039 0:65f1469d6bfb 124 } else {
va009039 0:65f1469d6bfb 125 return retval;
va009039 0:65f1469d6bfb 126 }
va009039 0:65f1469d6bfb 127
va009039 0:65f1469d6bfb 128 /** first, try to get the module from the cache */
va009039 0:65f1469d6bfb 129 retval = dict_getItem(PM_PBUILTINS, PM_MD_STR, &pmodcache);
va009039 0:65f1469d6bfb 130 PM_RETURN_IF_ERROR(retval);
va009039 0:65f1469d6bfb 131
va009039 0:65f1469d6bfb 132 retval = dict_getItem(pmodcache, pstr, &pmodule);
va009039 0:65f1469d6bfb 133 PM_RETURN_IF_ERROR(retval);
va009039 0:65f1469d6bfb 134
va009039 0:65f1469d6bfb 135 if (!((retval == PM_RET_OK) && (OBJ_GET_TYPE(pmodule) == OBJ_TYPE_MOD)))
va009039 0:65f1469d6bfb 136 {
va009039 0:65f1469d6bfb 137 PM_RAISE(retval, PM_RET_EX_SYS);
va009039 0:65f1469d6bfb 138 return retval;
va009039 0:65f1469d6bfb 139 }
va009039 0:65f1469d6bfb 140
va009039 0:65f1469d6bfb 141 /* grab the class from within the loaded module */
va009039 0:65f1469d6bfb 142 retval = string_new(&pAutoboxstr, &pstr);
va009039 0:65f1469d6bfb 143 PM_RETURN_IF_ERROR(retval);
va009039 0:65f1469d6bfb 144 retval = dict_getItem((pPmObj_t) ((pPmFunc_t)pmodule)->f_attrs, pstr, &pclass);
va009039 0:65f1469d6bfb 145 PM_RETURN_IF_ERROR(retval);
va009039 0:65f1469d6bfb 146
va009039 0:65f1469d6bfb 147 /* instantiate instance of (type)._Autobox */
va009039 0:65f1469d6bfb 148 retval = class_instantiate(pclass, &pwrapped);
va009039 0:65f1469d6bfb 149 PM_RETURN_IF_ERROR(retval);
va009039 0:65f1469d6bfb 150
va009039 0:65f1469d6bfb 151 /* store object as _Autobox().obj */
va009039 0:65f1469d6bfb 152 retval = string_new(&pobjstr, &pstr);
va009039 0:65f1469d6bfb 153 PM_RETURN_IF_ERROR(retval);
va009039 0:65f1469d6bfb 154 retval = dict_setItem((pPmObj_t)((pPmInstance_t)pwrapped)->cli_attrs,
va009039 0:65f1469d6bfb 155 pstr, *pobj);
va009039 0:65f1469d6bfb 156 PM_RETURN_IF_ERROR(retval);
va009039 0:65f1469d6bfb 157
va009039 0:65f1469d6bfb 158 /** replace old object with new instance in place */
va009039 0:65f1469d6bfb 159 *pobj = pwrapped;
va009039 0:65f1469d6bfb 160
va009039 0:65f1469d6bfb 161 return retval;
va009039 0:65f1469d6bfb 162 }
va009039 0:65f1469d6bfb 163 #endif
va009039 0:65f1469d6bfb 164
va009039 0:65f1469d6bfb 165
va009039 0:65f1469d6bfb 166 PmReturn_t
va009039 0:65f1469d6bfb 167 class_method(pPmObj_t pinstance, pPmObj_t pfunc, pPmObj_t *r_pmeth)
va009039 0:65f1469d6bfb 168 {
va009039 0:65f1469d6bfb 169 PmReturn_t retval = PM_RET_OK;
va009039 0:65f1469d6bfb 170 uint8_t *pchunk;
va009039 0:65f1469d6bfb 171 pPmMethod_t pmeth;
va009039 0:65f1469d6bfb 172 pPmObj_t pattrs;
va009039 0:65f1469d6bfb 173 uint8_t objid;
va009039 0:65f1469d6bfb 174
va009039 0:65f1469d6bfb 175 /* Allocate a method */
va009039 0:65f1469d6bfb 176 retval = heap_getChunk(sizeof(PmMethod_t), &pchunk);
va009039 0:65f1469d6bfb 177 PM_RETURN_IF_ERROR(retval);
va009039 0:65f1469d6bfb 178 OBJ_SET_TYPE(pchunk, OBJ_TYPE_MTH);
va009039 0:65f1469d6bfb 179
va009039 0:65f1469d6bfb 180 /* Set method fields */
va009039 0:65f1469d6bfb 181 pmeth = (pPmMethod_t)pchunk;
va009039 0:65f1469d6bfb 182 pmeth->m_instance = (pPmInstance_t)pinstance;
va009039 0:65f1469d6bfb 183 pmeth->m_func = (pPmFunc_t)pfunc;
va009039 0:65f1469d6bfb 184 pmeth->m_attrs = C_NULL;
va009039 0:65f1469d6bfb 185
va009039 0:65f1469d6bfb 186 /* Create the attributes dict */
va009039 0:65f1469d6bfb 187 heap_gcPushTempRoot((pPmObj_t)pmeth, &objid);
va009039 0:65f1469d6bfb 188 retval = dict_new(&pattrs);
va009039 0:65f1469d6bfb 189 heap_gcPopTempRoot(objid);
va009039 0:65f1469d6bfb 190 pmeth->m_attrs = (pPmDict_t)pattrs;
va009039 0:65f1469d6bfb 191
va009039 0:65f1469d6bfb 192 *r_pmeth = (pPmObj_t)pmeth;
va009039 0:65f1469d6bfb 193 return retval;
va009039 0:65f1469d6bfb 194 }
va009039 0:65f1469d6bfb 195
va009039 0:65f1469d6bfb 196
va009039 0:65f1469d6bfb 197 PmReturn_t
va009039 0:65f1469d6bfb 198 class_getAttr(pPmObj_t pobj, pPmObj_t pname, pPmObj_t *r_pobj)
va009039 0:65f1469d6bfb 199 {
va009039 0:65f1469d6bfb 200 PmReturn_t retval;
va009039 0:65f1469d6bfb 201 uint16_t i;
va009039 0:65f1469d6bfb 202 pPmObj_t pparent;
va009039 0:65f1469d6bfb 203
va009039 0:65f1469d6bfb 204 /* If the given obj is an instance, check its attrs */
va009039 0:65f1469d6bfb 205 if (OBJ_GET_TYPE(pobj) == OBJ_TYPE_CLI)
va009039 0:65f1469d6bfb 206 {
va009039 0:65f1469d6bfb 207 retval = dict_getItem((pPmObj_t)((pPmInstance_t)pobj)->cli_attrs, pname,
va009039 0:65f1469d6bfb 208 r_pobj);
va009039 0:65f1469d6bfb 209 if (retval == PM_RET_OK)
va009039 0:65f1469d6bfb 210 {
va009039 0:65f1469d6bfb 211 return retval;
va009039 0:65f1469d6bfb 212 }
va009039 0:65f1469d6bfb 213
va009039 0:65f1469d6bfb 214 /* Otherwise, check the instance's class */
va009039 0:65f1469d6bfb 215 pobj = (pPmObj_t)((pPmInstance_t)pobj)->cli_class;
va009039 0:65f1469d6bfb 216 }
va009039 0:65f1469d6bfb 217
va009039 0:65f1469d6bfb 218 C_ASSERT(OBJ_GET_TYPE(pobj) == OBJ_TYPE_CLO);
va009039 0:65f1469d6bfb 219
va009039 0:65f1469d6bfb 220 retval = dict_getItem((pPmObj_t)((pPmClass_t)pobj)->cl_attrs, pname,
va009039 0:65f1469d6bfb 221 r_pobj);
va009039 0:65f1469d6bfb 222
va009039 0:65f1469d6bfb 223 /* If attr is not found, search parent(s) */
va009039 0:65f1469d6bfb 224 if ((retval == PM_RET_EX_KEY) && (((pPmClass_t)pobj)->cl_bases != C_NULL))
va009039 0:65f1469d6bfb 225 {
va009039 0:65f1469d6bfb 226 for (i = 0; i < ((pPmClass_t)pobj)->cl_bases->length; i++)
va009039 0:65f1469d6bfb 227 {
va009039 0:65f1469d6bfb 228 pparent = ((pPmClass_t)pobj)->cl_bases->val[i];
va009039 0:65f1469d6bfb 229 retval = class_getAttr(pparent, pname, r_pobj);
va009039 0:65f1469d6bfb 230 if (retval == PM_RET_OK)
va009039 0:65f1469d6bfb 231 {
va009039 0:65f1469d6bfb 232 break;
va009039 0:65f1469d6bfb 233 }
va009039 0:65f1469d6bfb 234 }
va009039 0:65f1469d6bfb 235 }
va009039 0:65f1469d6bfb 236
va009039 0:65f1469d6bfb 237 return retval;
va009039 0:65f1469d6bfb 238 }
va009039 0:65f1469d6bfb 239
va009039 0:65f1469d6bfb 240
va009039 0:65f1469d6bfb 241 uint8_t /* boolean */
va009039 0:65f1469d6bfb 242 class_isSubclass(pPmObj_t ptest_class, pPmObj_t pbase_class)
va009039 0:65f1469d6bfb 243 {
va009039 0:65f1469d6bfb 244 uint8_t i;
va009039 0:65f1469d6bfb 245 uint8_t retval;
va009039 0:65f1469d6bfb 246
va009039 0:65f1469d6bfb 247 retval = C_FALSE;
va009039 0:65f1469d6bfb 248
va009039 0:65f1469d6bfb 249 if (ptest_class == pbase_class)
va009039 0:65f1469d6bfb 250 {
va009039 0:65f1469d6bfb 251 return C_TRUE;
va009039 0:65f1469d6bfb 252 }
va009039 0:65f1469d6bfb 253
va009039 0:65f1469d6bfb 254 /* Recursively check if test class has a matching base class */
va009039 0:65f1469d6bfb 255 if (((pPmClass_t)ptest_class)->cl_bases != C_NULL)
va009039 0:65f1469d6bfb 256 {
va009039 0:65f1469d6bfb 257 for (i = 0; i < ((pPmClass_t)ptest_class)->cl_bases->length; i++)
va009039 0:65f1469d6bfb 258 {
va009039 0:65f1469d6bfb 259 retval = class_isSubclass(((pPmClass_t)ptest_class)->cl_bases->val[i],
va009039 0:65f1469d6bfb 260 pbase_class);
va009039 0:65f1469d6bfb 261 if (retval)
va009039 0:65f1469d6bfb 262 {
va009039 0:65f1469d6bfb 263 break;
va009039 0:65f1469d6bfb 264 }
va009039 0:65f1469d6bfb 265 }
va009039 0:65f1469d6bfb 266 }
va009039 0:65f1469d6bfb 267 return retval;
va009039 0:65f1469d6bfb 268 }