Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
class.c
00001 /* 00002 # This file is Copyright 2009 Dean Hall. 00003 # 00004 # This file is part of the PyMite VM. 00005 # The PyMite VM is free software: you can redistribute it and/or modify 00006 # it under the terms of the GNU GENERAL PUBLIC LICENSE Version 2. 00007 # 00008 # The PyMite VM is distributed in the hope that it will be useful, 00009 # but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00011 # A copy of the GNU GENERAL PUBLIC LICENSE Version 2 00012 # is seen in the file COPYING in this directory. 00013 */ 00014 00015 00016 #undef __FILE_ID__ 00017 #define __FILE_ID__ 0x18 00018 00019 00020 /** 00021 * \file 00022 * \brief Class Object Type 00023 * 00024 * Class object type operations. 00025 */ 00026 00027 00028 #include "pm.h" 00029 00030 00031 PmReturn_t 00032 class_new(pPmObj_t pattrs, pPmObj_t pbases, pPmObj_t pname, pPmObj_t *r_pclass) 00033 { 00034 PmReturn_t retval = PM_RET_OK; 00035 uint8_t *pchunk; 00036 pPmObj_t pobj; 00037 00038 /* Ensure types */ 00039 if ((OBJ_GET_TYPE(pattrs) != OBJ_TYPE_DIC) 00040 || (OBJ_GET_TYPE(pbases) != OBJ_TYPE_TUP) 00041 || (OBJ_GET_TYPE(pname) != OBJ_TYPE_STR)) 00042 { 00043 PM_RAISE(retval, PM_RET_EX_TYPE); 00044 return retval; 00045 } 00046 00047 /* Allocate a class obj */ 00048 retval = heap_getChunk(sizeof(PmClass_t), &pchunk); 00049 PM_RETURN_IF_ERROR(retval); 00050 pobj = (pPmObj_t)pchunk; 00051 OBJ_SET_TYPE(pobj, OBJ_TYPE_CLO); 00052 00053 /* Class has no access to its CO */ 00054 ((pPmClass_t)pobj)->cl_attrs = (pPmDict_t)pattrs; 00055 ((pPmClass_t)pobj)->cl_bases = (pPmTuple_t)pbases; 00056 00057 *r_pclass = pobj; 00058 00059 return retval; 00060 } 00061 00062 00063 /* Returns an instance of the class by reference */ 00064 PmReturn_t 00065 class_instantiate(pPmObj_t pclass, pPmObj_t *r_pobj) 00066 { 00067 PmReturn_t retval = PM_RET_OK; 00068 uint8_t *pchunk; 00069 pPmObj_t pobj; 00070 pPmObj_t pattrs; 00071 00072 /* Allocate a class instance */ 00073 retval = heap_getChunk(sizeof(PmInstance_t), &pchunk); 00074 PM_RETURN_IF_ERROR(retval); 00075 pobj = (pPmObj_t)pchunk; 00076 OBJ_SET_TYPE(pobj, OBJ_TYPE_CLI); 00077 00078 /* Set the instance's class */ 00079 ((pPmInstance_t)pobj)->cli_class = (pPmClass_t)pclass; 00080 00081 /* Create the attributes dict */ 00082 retval = dict_new(&pattrs); 00083 ((pPmInstance_t)pobj)->cli_attrs = (pPmDict_t)pattrs; 00084 00085 /* TODO: Store pclass in __class__ attr */ 00086 00087 *r_pobj = pobj; 00088 return retval; 00089 } 00090 00091 00092 PmReturn_t 00093 class_method(pPmObj_t pinstance, pPmObj_t pfunc, pPmObj_t *r_pmeth) 00094 { 00095 PmReturn_t retval = PM_RET_OK; 00096 uint8_t *pchunk; 00097 pPmMethod_t pmeth; 00098 pPmObj_t pattrs; 00099 00100 /* Allocate a method */ 00101 retval = heap_getChunk(sizeof(PmMethod_t), &pchunk); 00102 PM_RETURN_IF_ERROR(retval); 00103 OBJ_SET_TYPE(pchunk, OBJ_TYPE_MTH); 00104 00105 /* Set method fields */ 00106 pmeth = (pPmMethod_t)pchunk; 00107 pmeth->m_instance = (pPmInstance_t)pinstance; 00108 pmeth->m_func = (pPmFunc_t)pfunc; 00109 00110 /* Create the attributes dict */ 00111 retval = dict_new(&pattrs); 00112 pmeth->m_attrs = (pPmDict_t)pattrs; 00113 00114 *r_pmeth = (pPmObj_t)pmeth; 00115 return retval; 00116 } 00117 00118 00119 PmReturn_t 00120 class_getAttr(pPmObj_t pobj, pPmObj_t pname, pPmObj_t *r_pobj) 00121 { 00122 PmReturn_t retval; 00123 uint16_t i; 00124 pPmObj_t pparent; 00125 00126 /* If the given obj is an instance, check its attrs */ 00127 if (OBJ_GET_TYPE(pobj) == OBJ_TYPE_CLI) 00128 { 00129 retval = dict_getItem((pPmObj_t)((pPmInstance_t)pobj)->cli_attrs, pname, 00130 r_pobj); 00131 if (retval == PM_RET_OK) 00132 { 00133 return retval; 00134 } 00135 00136 /* Otherwise, check the instance's class */ 00137 pobj = (pPmObj_t)((pPmInstance_t)pobj)->cli_class; 00138 } 00139 00140 C_ASSERT(OBJ_GET_TYPE(pobj) == OBJ_TYPE_CLO); 00141 00142 retval = dict_getItem((pPmObj_t)((pPmClass_t)pobj)->cl_attrs, pname, 00143 r_pobj); 00144 00145 /* If attr is not found, search parent(s) */ 00146 if ((retval == PM_RET_EX_KEY) && (((pPmClass_t)pobj)->cl_bases != C_NULL)) 00147 { 00148 for (i = 0; i < ((pPmClass_t)pobj)->cl_bases->length; i++) 00149 { 00150 pparent = ((pPmClass_t)pobj)->cl_bases->val[i]; 00151 retval = class_getAttr(pparent, pname, r_pobj); 00152 if (retval == PM_RET_OK) 00153 { 00154 break; 00155 } 00156 } 00157 } 00158 00159 return retval; 00160 } 00161 00162 00163 uint8_t /* boolean */ 00164 class_isSubclass(pPmObj_t ptest_class, pPmObj_t pbase_class) 00165 { 00166 uint8_t i; 00167 uint8_t retval; 00168 00169 retval = C_FALSE; 00170 00171 if (ptest_class == pbase_class) 00172 { 00173 return C_TRUE; 00174 } 00175 00176 /* Recursively check if test class has a matching base class */ 00177 if (((pPmClass_t)ptest_class)->cl_bases != C_NULL) 00178 { 00179 for (i = 0; i < ((pPmClass_t)ptest_class)->cl_bases->length; i++) 00180 { 00181 retval = class_isSubclass(((pPmClass_t)ptest_class)->cl_bases->val[i], 00182 pbase_class); 00183 if (retval) 00184 { 00185 break; 00186 } 00187 } 00188 } 00189 return retval; 00190 }
Generated on Tue Jul 12 2022 17:07:01 by
