Norimasa Okamoto
/
pymite
python-on-a-chip online compiler
- http://pymbed.appspot.com/
- https://code.google.com/p/python-on-a-chip/
- http://www.youtube.com/watch?v=Oyqc2bFRW9I
- https://bitbucket.org/va009039/pymbed/
more info: python-on-a-chip
vm/class.c@15:94ca5c8003e5, 2016-04-14 (annotated)
- 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?
User | Revision | Line number | New 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 | } |