PmReturn_t class_new(pPmObj_t pattrs, pPmObj_t pbases, pPmObj_t pname, pPmObj_t *r_pclass) { PmReturn_t retval = PM_RET_OK; uint8_t *pchunk; pPmObj_t pobj; /* Ensure types */ if ((OBJ_GET_TYPE(pattrs) != OBJ_TYPE_DIC) || (OBJ_GET_TYPE(pbases) != OBJ_TYPE_TUP) || (OBJ_GET_TYPE(pname) != OBJ_TYPE_STR)) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* Allocate a class obj */ retval = heap_getChunk(sizeof(PmClass_t), &pchunk); PM_RETURN_IF_ERROR(retval); pobj = (pPmObj_t)pchunk; OBJ_SET_TYPE(pobj, OBJ_TYPE_CLO); /* Class has no access to its CO */ ((pPmClass_t)pobj)->cl_attrs = (pPmDict_t)pattrs; ((pPmClass_t)pobj)->cl_bases = (pPmTuple_t)pbases; *r_pclass = pobj; return retval; }
PmReturn_t seqiter_new(pPmObj_t pobj, pPmObj_t *r_pobj) { PmReturn_t retval; uint8_t *pchunk; pPmSeqIter_t psi; C_ASSERT(pobj != C_NULL); C_ASSERT(*r_pobj != C_NULL); /* Raise a TypeError if pobj is not a sequence */ if ((OBJ_GET_TYPE(pobj) != OBJ_TYPE_STR) && (OBJ_GET_TYPE(pobj) != OBJ_TYPE_TUP) && (OBJ_GET_TYPE(pobj) != OBJ_TYPE_LST)) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* Alloc a chunk for the sequence iterator obj */ retval = heap_getChunk(sizeof(PmSeqIter_t), &pchunk); PM_RETURN_IF_ERROR(retval); /* Set the sequence iterator's fields */ psi = (pPmSeqIter_t)pchunk; OBJ_SET_TYPE(psi, OBJ_TYPE_SQI); psi->si_sequence = pobj; psi->si_index = 0; *r_pobj = (pPmObj_t)psi; return retval; }
/* * Compares two sequence objects * Assumes both objects are of same type (guaranteed by obj_compare) */ int8_t seq_compare(pPmObj_t pobj1, pPmObj_t pobj2) { int16_t l1; int16_t l2; pPmObj_t pa; pPmObj_t pb; PmReturn_t retval; int8_t retcompare; /* Get the lengths of supported types or return differ */ if (OBJ_GET_TYPE(pobj1) == OBJ_TYPE_TUP) { l1 = ((pPmTuple_t)pobj1)->length; l2 = ((pPmTuple_t)pobj2)->length; } else if (OBJ_GET_TYPE(pobj1) == OBJ_TYPE_LST) { l1 = ((pPmList_t)pobj2)->length; l2 = ((pPmList_t)pobj2)->length; } else { return C_DIFFER; } /* Return if the lengths differ */ if (l1 != l2) { return C_DIFFER; } /* Compare all items in the sequences */ while (--l1 >= 0) { retval = seq_getSubscript(pobj1, l1, &pa); if (retval != PM_RET_OK) { return C_DIFFER; } retval = seq_getSubscript(pobj2, l1, &pb); if (retval != PM_RET_OK) { return C_DIFFER; } retcompare = obj_compare(pa, pb); if (retcompare != C_SAME) { return retcompare; } } return C_SAME; }
/*----------------------------------------------------------------------------*/ PmReturn_t tres_pm_get_state(pPmFrame_t *ppframe) { PmReturn_t retv = PM_RET_OK; pPmObj_t pobj; pPmObj_t pobj_new; pPmInstance_t pcli; pPmDict_t pdict; int16_t index; float fval; int32_t ival; if(NATIVE_GET_NUM_ARGS() != 1) { PM_RAISE(retv, PM_RET_EX_TYPE); return retv; } pobj = NATIVE_GET_LOCAL(0); if(OBJ_GET_TYPE(pobj) != OBJ_TYPE_CLI) { PM_RAISE(retv, PM_RET_EX_TYPE); return retv; } pcli = (pPmInstance_t)pobj; pdict = pcli->cli_attrs; if(*tres_pm_io.state_len > 0) { // restore each attribute of the object for(index = pdict->length - 1; index >= 0; index--) { seglist_getItem(pdict->d_keys, index, &pobj); retv = seglist_getItem(pdict->d_vals, index, &pobj); PM_RETURN_IF_ERROR(retv); switch (OBJ_GET_TYPE(pobj)) { case OBJ_TYPE_INT: //pop int pop_int(&ival); retv = int_new(ival, &pobj_new); break; case OBJ_TYPE_FLT: //pop float pop_float(&fval); retv = float_new(fval, &pobj_new); break; default: /* Raise TypeError */ PM_RAISE(retv, PM_RET_EX_TYPE); } if (retv == PM_RET_OK) { seglist_setItem(pdict->d_vals, pobj_new, index); } } } NATIVE_SET_TOS((pPmObj_t)pcli); return retv; }
PmReturn_t obj_repr(pPmObj_t pobj, pPmObj_t *r_pstr) { uint8_t tBuffer[32]; PmReturn_t retval = PM_RET_OK; uint8_t const *pcstr = (uint8_t *)tBuffer;; C_ASSERT(pobj != C_NULL); switch (OBJ_GET_TYPE(pobj)) { case OBJ_TYPE_INT: retval = sli_ltoa10(((pPmInt_t)pobj)->val, tBuffer, sizeof(tBuffer)); PM_RETURN_IF_ERROR(retval); retval = string_new(&pcstr, r_pstr); break; #ifdef HAVE_FLOAT case OBJ_TYPE_FLT: /* #212: Use homebrew float formatter */ retval = sli_ftoa(((pPmFloat_t)pobj)->val, tBuffer, sizeof(tBuffer)); sli_strlen((char *)tBuffer); retval = string_new(&pcstr, r_pstr); break; #endif /* HAVE_FLOAT */ default: /* Otherwise raise a TypeError */ PM_RAISE(retval, PM_RET_EX_TYPE); break; } return retval; }
PmReturn_t mod_new(pPmObj_t pco, pPmObj_t *pmod) { PmReturn_t retval; uint8_t *pchunk; pPmObj_t pobj; /* If it's not a code obj, raise TypeError */ if (OBJ_GET_TYPE(pco) != OBJ_TYPE_COB) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* Alloc and init func obj */ retval = heap_getChunk(sizeof(PmFunc_t), &pchunk); PM_RETURN_IF_ERROR(retval); *pmod = (pPmObj_t)pchunk; OBJ_SET_TYPE(*pmod, OBJ_TYPE_MOD); ((pPmFunc_t)*pmod)->f_co = (pPmCo_t)pco; /* Alloc and init attrs dict */ retval = dict_new(&pobj); ((pPmFunc_t)*pmod)->f_attrs = (pPmDict_t)pobj; /* A module's globals is the same as its attrs */ ((pPmFunc_t)*pmod)->f_globals = (pPmDict_t)pobj; return retval; }
PmReturn_t float_print(pPmObj_t pf) { uint8_t tBuffer[32]; uint8_t bytesWritten; uint8_t i; PmReturn_t retval = PM_RET_OK; C_ASSERT(pf != C_NULL); /* Raise TypeError if obj is not an float */ if (OBJ_GET_TYPE(pf) != OBJ_TYPE_FLT) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* #196: Changed to use snprintf */ bytesWritten = snprintf((char *)&tBuffer, 32, "%f", ((pPmFloat_t) pf)->val); /* Sanity check */ C_ASSERT(bytesWritten != 0); C_ASSERT(bytesWritten < sizeof(tBuffer)); for (i = (uint8_t)0; i < bytesWritten; i++) { retval = plat_putByte(tBuffer[i]); PM_RETURN_IF_ERROR(retval); } return PM_RET_OK; }
PmReturn_t thread_new(pPmObj_t pframe, pPmObj_t *r_pobj) { PmReturn_t retval = PM_RET_OK; pPmThread_t pthread = C_NULL; C_ASSERT(pframe != C_NULL); /* If it's not a frame, raise TypeError */ if (OBJ_GET_TYPE(pframe) != OBJ_TYPE_FRM) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* Allocate a thread */ retval = heap_getChunk(sizeof(PmThread_t), (uint8_t **)r_pobj); PM_RETURN_IF_ERROR(retval); /* Set type, frame and initialize status */ pthread = (pPmThread_t)*r_pobj; OBJ_SET_TYPE(pthread, OBJ_TYPE_THR); pthread->pframe = (pPmFrame_t)pframe; pthread->interpctrl = INTERP_CTRL_CONT; return retval; }
PmReturn_t seqiter_getNext(pPmObj_t pobj, pPmObj_t *r_pitem) { PmReturn_t retval; int16_t length; C_ASSERT(pobj != C_NULL); C_ASSERT(*r_pitem != C_NULL); C_ASSERT(OBJ_GET_TYPE(pobj) == OBJ_TYPE_SQI); /* * Raise TypeError if sequence iterator's object is not a sequence * otherwise, the get sequence's length */ retval = seq_getLength(((pPmSeqIter_t)pobj)->si_sequence, &length); PM_RETURN_IF_ERROR(retval); /* Raise StopIteration if at the end of the sequence */ if (((pPmSeqIter_t)pobj)->si_index == length) { /* Make null the pointer to the sequence */ ((pPmSeqIter_t)pobj)->si_sequence = C_NULL; PM_RAISE(retval, PM_RET_EX_STOP); return retval; } /* Get the item at the current index */ retval = seq_getSubscript(((pPmSeqIter_t)pobj)->si_sequence, ((pPmSeqIter_t)pobj)->si_index, r_pitem); /* Increment the index */ ((pPmSeqIter_t)pobj)->si_index++; return retval; }
PmReturn_t dict_clear(pPmObj_t pdict) { PmReturn_t retval = PM_RET_OK; C_ASSERT(pdict != C_NULL); /* Raise TypeError if arg is not a dict */ if (OBJ_GET_TYPE(pdict) != OBJ_TYPE_DIC) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* clear length */ ((pPmDict_t)pdict)->length = 0; /* Free the keys and values seglists if needed */ if (((pPmDict_t)pdict)->d_keys != C_NULL) { PM_RETURN_IF_ERROR(seglist_clear(((pPmDict_t)pdict)->d_keys)); PM_RETURN_IF_ERROR(heap_freeChunk((pPmObj_t) ((pPmDict_t)pdict)->d_keys)); ((pPmDict_t)pdict)->d_keys = C_NULL; } if (((pPmDict_t)pdict)->d_vals != C_NULL) { PM_RETURN_IF_ERROR(seglist_clear(((pPmDict_t)pdict)->d_vals)); retval = heap_freeChunk((pPmObj_t)((pPmDict_t)pdict)->d_vals); ((pPmDict_t)pdict)->d_vals = C_NULL; } return retval; }
/* Returns the length of the sequence */ PmReturn_t seq_getLength(pPmObj_t pobj, int16_t *r_index) { PmReturn_t retval = PM_RET_OK; switch (OBJ_GET_TYPE(pobj)) { case OBJ_TYPE_STR: *r_index = ((pPmString_t)pobj)->length; break; case OBJ_TYPE_TUP: *r_index = ((pPmTuple_t)pobj)->length; break; case OBJ_TYPE_LST: *r_index = ((pPmList_t)pobj)->length; break; default: /* Raise TypeError, non-sequence object */ PM_RAISE(retval, PM_RET_EX_TYPE); break; } return retval; }
PmReturn_t dict_update(pPmObj_t pdestdict, pPmObj_t psourcedict, uint8_t omit_underscored) { PmReturn_t retval = PM_RET_OK; int16_t i; pPmObj_t pkey; pPmObj_t pval; C_ASSERT(pdestdict != C_NULL); C_ASSERT(psourcedict != C_NULL); /* If it's not a dict, raise TypeError */ if (OBJ_GET_TYPE(pdestdict) != OBJ_TYPE_DIC) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* If it's not a dict, raise TypeError */ if (OBJ_GET_TYPE(psourcedict) != OBJ_TYPE_DIC) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* Iterate over the add-on dict */ for (i = 0; i < ((pPmDict_t)psourcedict)->length; i++) { /* Get the key,val from the add-on dict */ retval = seglist_getItem(((pPmDict_t)psourcedict)->d_keys, i, &pkey); PM_RETURN_IF_ERROR(retval); retval = seglist_getItem(((pPmDict_t)psourcedict)->d_vals, i, &pval); PM_RETURN_IF_ERROR(retval); if (!(omit_underscored && (OBJ_GET_TYPE(pkey) == OBJ_TYPE_STR) && ((pPmString_t)pkey)->val[0] == '_')) { /* Set the key,val to the destination dict */ retval = dict_setItem(pdestdict, pkey, pval); PM_RETURN_IF_ERROR(retval); } } return retval; }
PmReturn_t obj_loadFromImgObj(pPmObj_t pimg, pPmObj_t *r_pobj) { uint8_t const *imgaddr; PmReturn_t retval; C_ASSERT(OBJ_GET_TYPE(pimg) == OBJ_TYPE_CIO); imgaddr = (uint8_t const *)&(((pPmCodeImgObj_t)pimg)->val); retval = obj_loadFromImg(MEMSPACE_RAM, &imgaddr, r_pobj); C_ASSERT(OBJ_GET_TYPE(*r_pobj) == OBJ_TYPE_COB); /* All COs must reference the top of the code img obj * so the image is marked and prevented from being reclaimed */ co_rSetCodeImgAddr((pPmCo_t)*r_pobj, (uint8_t const *)pimg); return retval; }
PmReturn_t obj_loadFromImg(PmMemSpace_t memspace, uint8_t const **paddr, pPmObj_t *r_pobj) { PmReturn_t retval = PM_RET_OK; PmObj_t obj; /* Get the object descriptor */ obj.od = (PmObjDesc_t)0x0000; OBJ_SET_TYPE(&obj, mem_getByte(memspace, paddr)); switch (OBJ_GET_TYPE(&obj)) { case OBJ_TYPE_NON: /* If it's the None object, return global None */ *r_pobj = PM_NONE; break; case OBJ_TYPE_INT: /* Read an integer and create an integer object with the value */ retval = int_new(mem_getInt(memspace, paddr), r_pobj); break; #ifdef HAVE_FLOAT case OBJ_TYPE_FLT: /* Read a float and create an float object with the value */ retval = float_new(mem_getFloat(memspace, paddr), r_pobj); break; #endif /* HAVE_FLOAT */ case OBJ_TYPE_STR: retval = string_loadFromImg(memspace, paddr, r_pobj); break; case OBJ_TYPE_TUP: retval = tuple_loadFromImg(memspace, paddr, r_pobj); break; case OBJ_TYPE_NIM: /* If it's a native code img, load into a code obj */ retval = no_loadFromImg(memspace, paddr, r_pobj); break; case OBJ_TYPE_CIM: /* If it's a code img, load into a code obj */ retval = co_loadFromImg(memspace, paddr, r_pobj); break; default: /* All other types should not be in an img obj */ PM_RAISE(retval, PM_RET_EX_SYS); break; } return retval; }
PmReturn_t class_getAttr(pPmObj_t pobj, pPmObj_t pname, pPmObj_t *r_pobj) { PmReturn_t retval; uint16_t i; pPmObj_t pparent; /* If the given obj is an instance, check its attrs */ if (OBJ_GET_TYPE(pobj) == OBJ_TYPE_CLI) { retval = dict_getItem((pPmObj_t)((pPmInstance_t)pobj)->cli_attrs, pname, r_pobj); if (retval == PM_RET_OK) { return retval; } /* Otherwise, check the instance's class */ pobj = (pPmObj_t)((pPmInstance_t)pobj)->cli_class; } C_ASSERT(OBJ_GET_TYPE(pobj) == OBJ_TYPE_CLO); retval = dict_getItem((pPmObj_t)((pPmClass_t)pobj)->cl_attrs, pname, r_pobj); /* If attr is not found, search parent(s) */ if ((retval == PM_RET_EX_KEY) && (((pPmClass_t)pobj)->cl_bases != C_NULL)) { for (i = 0; i < ((pPmClass_t)pobj)->cl_bases->length; i++) { pparent = ((pPmClass_t)pobj)->cl_bases->val[i]; retval = class_getAttr(pparent, pname, r_pobj); if (retval == PM_RET_OK) { break; } } } return retval; }
/*----------------------------------------------------------------------------*/ PmReturn_t tres_pm_save_state(pPmFrame_t *ppframe) { PmReturn_t retv = PM_RET_OK; pPmObj_t pobj; pPmInstance_t pcli; pPmDict_t pdict; uint16_t index; if(NATIVE_GET_NUM_ARGS() != 1) { PM_RAISE(retv, PM_RET_EX_TYPE); return retv; } pobj = NATIVE_GET_LOCAL(0); if(OBJ_GET_TYPE(pobj) != OBJ_TYPE_CLI) { PM_RAISE(retv, PM_RET_EX_TYPE); return retv; } pcli = (pPmInstance_t)pobj; pdict = pcli->cli_attrs; // store each attribute of the object for(index = 0; index < pdict->length; index++) { seglist_getItem(pdict->d_keys, index, &pobj); retv = seglist_getItem(pdict->d_vals, index, &pobj); PM_RETURN_IF_ERROR(retv); switch (OBJ_GET_TYPE(pobj)) { case OBJ_TYPE_INT: push_int(((pPmInt_t) pobj)->val); break; case OBJ_TYPE_FLT: push_float(((pPmFloat_t) pobj)->val); break; } } NATIVE_SET_TOS(PM_NONE); return retv; }
/* Returns true if the obj is false */ int8_t obj_isFalse(pPmObj_t pobj) { C_ASSERT(pobj != C_NULL); switch (OBJ_GET_TYPE(pobj)) { case OBJ_TYPE_NON: /* None evaluates to false, so return true */ return C_TRUE; case OBJ_TYPE_INT: /* Only the integer zero is false */ return ((pPmInt_t)pobj)->val == 0; #ifdef HAVE_FLOAT case OBJ_TYPE_FLT: /* The floats 0.0 and -0.0 are false */ return (((pPmFloat_t) pobj)->val == 0.0) || (((pPmFloat_t) pobj)->val == -0.0); #endif /* HAVE_FLOAT */ case OBJ_TYPE_STR: /* An empty string is false */ return ((pPmString_t)pobj)->length == 0; case OBJ_TYPE_TUP: /* An empty tuple is false */ return ((pPmTuple_t)pobj)->length == 0; case OBJ_TYPE_LST: /* An empty list is false */ return ((pPmList_t)pobj)->length == 0; case OBJ_TYPE_DIC: /* An empty dict is false */ return ((pPmDict_t)pobj)->length == 0; case OBJ_TYPE_BOOL: /* C int zero means false */ return ((pPmBoolean_t) pobj)->val == 0; default: /* * The following types are always not false: * CodeObj, Function, Module, Class, ClassInstance. */ return C_FALSE; } }
/** * Test dict_new(): * retval is OK * obj pointer is not C_NULL * obj type must be DICT * obj const bit must be clear * dict length must be 0 */ void ut_dict_new_000(CuTest* tc) { uint8_t heap[HEAP_SIZE]; pPmObj_t pobj = C_NULL; PmReturn_t retval; retval = pm_init(heap, HEAP_SIZE, MEMSPACE_RAM, C_NULL); retval = dict_new(&pobj); CuAssertTrue(tc, retval == PM_RET_OK); CuAssertPtrNotNull(tc, pobj); CuAssertTrue(tc, OBJ_GET_TYPE(pobj) == OBJ_TYPE_DIC); CuAssertTrue(tc, ((pPmDict_t)pobj)->length == 0); }
/* Returns the object sequence[index] */ PmReturn_t seq_getSubscript(pPmObj_t pobj, int16_t index, pPmObj_t *r_pobj) { PmReturn_t retval; uint8_t c; switch (OBJ_GET_TYPE(pobj)) { case OBJ_TYPE_STR: /* Adjust for negative index */ if (index < 0) { index += ((pPmString_t)pobj)->length; } /* Raise IndexError if index is out of bounds */ if ((index < 0) || (index > ((pPmString_t)pobj)->length)) { PM_RAISE(retval, PM_RET_EX_INDX); break; } /* Get the character from the string */ c = ((pPmString_t)pobj)->val[index]; /* Create a new string from the character */ retval = string_newFromChar(c, r_pobj); break; case OBJ_TYPE_TUP: /* Get the tuple item */ retval = tuple_getItem(pobj, index, r_pobj); break; case OBJ_TYPE_LST: /* Get the list item */ retval = list_getItem(pobj, index, r_pobj); break; default: /* Raise TypeError, unsubscriptable object */ PM_RAISE(retval, PM_RET_EX_TYPE); break; } return retval; }
PmReturn_t dict_getItem(pPmObj_t pdict, pPmObj_t pkey, pPmObj_t *r_pobj) { PmReturn_t retval = PM_RET_OK; int16_t indx = 0; /* C_ASSERT(pdict != C_NULL);*/ /* if it's not a dict, raise TypeError */ if (OBJ_GET_TYPE(pdict) != OBJ_TYPE_DIC) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* if dict is empty, raise KeyError */ if (((pPmDict_t)pdict)->length <= 0) { PM_RAISE(retval, PM_RET_EX_KEY); return retval; } /* #147: Change boolean keys to integers */ if (pkey == PM_TRUE) { pkey = PM_ONE; } else if (pkey == PM_FALSE) { pkey = PM_ZERO; } /* check for matching key */ retval = seglist_findEqual(((pPmDict_t)pdict)->d_keys, pkey, &indx); /* if key not found, raise KeyError */ if (retval == PM_RET_NO) { PM_RAISE(retval, PM_RET_EX_KEY); } /* return any other error */ PM_RETURN_IF_ERROR(retval); /* key was found, get obj from vals */ retval = seglist_getItem(((pPmDict_t)pdict)->d_vals, indx, r_pobj); return retval; }
PmReturn_t dict_print(pPmObj_t pdict) { PmReturn_t retval = PM_RET_OK; int16_t index; pSeglist_t keys, vals; pPmObj_t pobj1; C_ASSERT(pdict != C_NULL); /* if it's not a dict, raise TypeError */ if (OBJ_GET_TYPE(pdict) != OBJ_TYPE_DIC) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } plat_putByte('{'); keys = ((pPmDict_t)pdict)->d_keys; vals = ((pPmDict_t)pdict)->d_vals; /* if dict is empty, raise KeyError */ for (index = 0; index < ((pPmDict_t)pdict)->length; index++) { if (index != 0) { plat_putByte(','); plat_putByte(' '); } retval = seglist_getItem(keys, index, &pobj1); PM_RETURN_IF_ERROR(retval); retval = obj_print(pobj1, C_FALSE, C_TRUE); PM_RETURN_IF_ERROR(retval); plat_putByte(':'); retval = seglist_getItem(vals, index, &pobj1); PM_RETURN_IF_ERROR(retval); retval = obj_print(pobj1, C_FALSE, C_TRUE); PM_RETURN_IF_ERROR(retval); } return plat_putByte('}'); }
/*----------------------------------------------------------------------------*/ PmReturn_t tres_pm_state_pop(pPmFrame_t *ppframe) { PmReturn_t retv = PM_RET_OK; pPmObj_t r_pflt; pPmObj_t pa; float fval; int32_t ival; int pop_retv; /* Raise TypeError if wrong number of args */ pa = NATIVE_GET_LOCAL(0); if(NATIVE_GET_NUM_ARGS() != 1) { PM_RAISE(retv, PM_RET_EX_TYPE); return retv; } switch (OBJ_GET_TYPE(pa)) { //case OBJ_TYPE_STR: // ptr = (char const *)&(((pPmString_t)pa)->val); // // TODO: unimplemented // break; case OBJ_TYPE_INT: pop_retv = pop_int(&ival); if(pop_retv != TRES_ERR_NONE) { ival = ((pPmInt_t) pa)->val; } retv = int_new(ival, &r_pflt); break; case OBJ_TYPE_FLT: pop_retv = pop_float(&fval); if(pop_retv != TRES_ERR_NONE) { fval = ((pPmFloat_t) pa)->val; } retv = float_new(fval, &r_pflt); break; default: /* Raise TypeError */ PM_RAISE(retv, PM_RET_EX_TYPE); } NATIVE_SET_TOS(r_pflt); return retv; }
PmReturn_t mod_import(pPmObj_t pstr, pPmObj_t *pmod) { pPmImgInfo_t pii = C_NULL; uint8_t const *imgaddr = C_NULL; pPmCo_t pco = C_NULL; PmReturn_t retval = PM_RET_OK; pPmObj_t pobj; /* If it's not a string obj, raise SyntaxError */ if (OBJ_GET_TYPE(pstr) != OBJ_TYPE_STR) { PM_RAISE(retval, PM_RET_EX_SYNTAX); return retval; } /* Iterate through the global img list */ pii = gVmGlobal.pimglist; /* Scan until end of list or string matches */ while ((pii != C_NULL) && (string_compare((pPmString_t)pstr, pii->ii_name) == C_DIFFER)) { pii = pii->next; } /* If img was not found, raise ImportError */ if (pii == C_NULL) { PM_RAISE(retval, PM_RET_EX_IMPRT); return retval; } /* Make copy of addr so image list pointer isn't modified */ imgaddr = pii->ii_addr; /* Load img into code obj */ retval = obj_loadFromImg(pii->ii_memspace, &imgaddr, &pobj); PM_RETURN_IF_ERROR(retval); pco = (pPmCo_t)pobj; return mod_new((pPmObj_t)pco, pmod); }
/*----------------------------------------------------------------------------*/ PmReturn_t tres_pm_set_output(pPmFrame_t *ppframe) { const char *ptr; int32_t ival; float fval; PmReturn_t retv = PM_RET_OK; pPmObj_t pa; /* Raise TypeError if wrong number of args */ if(NATIVE_GET_NUM_ARGS() != 1) { PM_RAISE(retv, PM_RET_EX_TYPE); return retv; } pa = NATIVE_GET_LOCAL(0); switch (OBJ_GET_TYPE(pa)) { case OBJ_TYPE_STR: ptr = (char const *)&(((pPmString_t) pa)->val); snprintf(tres_pm_io.out, REST_MAX_CHUNK_SIZE, "%s", ptr); break; case OBJ_TYPE_INT: ival = ((pPmInt_t) pa)->val; snprintf(tres_pm_io.out, REST_MAX_CHUNK_SIZE, "%" PRId32, ival); break; case OBJ_TYPE_FLT: fval = ((pPmFloat_t) pa)->val; // we cannot use snprintf: float are not supported //snprintf(tres_pm_io.out, REST_MAX_CHUNK_SIZE, "%f", fval); //therefore we use pymite sli_ftoa, which, however requires a buffer => 15 if(REST_MAX_CHUNK_SIZE >= 15) { sli_ftoa(fval, (uint8_t *)tres_pm_io.out, REST_MAX_CHUNK_SIZE); } break; default: /* Raise TypeError */ PM_RAISE(retv, PM_RET_EX_TYPE); } tres_pm_io.output_set = 1; NATIVE_SET_TOS(PM_NONE); return retv; }
PmReturn_t obj_repr(pPmObj_t pobj, pPmObj_t *r_pstr) { uint8_t tBuffer[32]; uint8_t bytesWritten = 0; PmReturn_t retval = PM_RET_OK; uint8_t const *pcstr = (uint8_t *)tBuffer;; C_ASSERT(pobj != C_NULL); switch (OBJ_GET_TYPE(pobj)) { case OBJ_TYPE_INT: bytesWritten = snprintf((char *)&tBuffer, sizeof(tBuffer), "%li", (long)((pPmInt_t)pobj)->val); retval = string_new(&pcstr, r_pstr); break; #ifdef HAVE_FLOAT case OBJ_TYPE_FLT: bytesWritten = snprintf((char *)&tBuffer, sizeof(tBuffer), "%f", ((pPmFloat_t)pobj)->val); retval = string_new(&pcstr, r_pstr); break; #endif /* HAVE_FLOAT */ default: /* Otherwise raise a TypeError */ PM_RAISE(retval, PM_RET_EX_TYPE); break; } /* Sanity check */ C_ASSERT(bytesWritten < sizeof(tBuffer)); return retval; }
/*----------------------------------------------------------------------------*/ PmReturn_t tres_pm_state_push(pPmFrame_t *ppframe) { //const char *ptr; int32_t ival; float fval; PmReturn_t retv = PM_RET_OK; pPmObj_t pa; /* Raise TypeError if wrong number of args */ pa = NATIVE_GET_LOCAL(0); if(NATIVE_GET_NUM_ARGS() != 1) { PM_RAISE(retv, PM_RET_EX_TYPE); return retv; } switch (OBJ_GET_TYPE(pa)) { //case OBJ_TYPE_STR: // ptr = (char const *)&(((pPmString_t)pa)->val); // // TODO: unimplemented // break; case OBJ_TYPE_INT: ival = ((pPmInt_t) pa)->val; push_int(ival); break; case OBJ_TYPE_FLT: fval = ((pPmFloat_t) pa)->val; push_float(fval); break; default: /* Raise TypeError */ PM_RAISE(retv, PM_RET_EX_TYPE); } NATIVE_SET_TOS(PM_NONE); return retv; }
/* * Sets a value in the dict using the given key. * * Scans dict for the key. If key val found, replace old * with new val. If no key found, add key/val pair to dict. */ PmReturn_t dict_setItem(pPmObj_t pdict, pPmObj_t pkey, pPmObj_t pval) { PmReturn_t retval = PM_RET_OK; int16_t indx; C_ASSERT(pdict != C_NULL); C_ASSERT(pkey != C_NULL); C_ASSERT(pval != C_NULL); /* If it's not a dict, raise TypeError */ if (OBJ_GET_TYPE(pdict) != OBJ_TYPE_DIC) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* #112: Force Dict keys to be of hashable type */ /* If key is not hashable, raise TypeError */ if (OBJ_GET_TYPE(pkey) > OBJ_TYPE_HASHABLE_MAX) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* #147: Change boolean keys to integers */ if (pkey == PM_TRUE) { pkey = PM_ONE; } else if (pkey == PM_FALSE) { pkey = PM_ZERO; } /* * #115: If this is the first key/value pair to be added to the Dict, * allocate the key and value seglists that hold those items */ if (((pPmDict_t)pdict)->length == 0) { retval = seglist_new(&((pPmDict_t)pdict)->d_keys); PM_RETURN_IF_ERROR(retval); retval = seglist_new(&((pPmDict_t)pdict)->d_vals); PM_RETURN_IF_ERROR(retval); } else { /* Check for matching key */ indx = 0; retval = seglist_findEqual(((pPmDict_t)pdict)->d_keys, pkey, &indx); /* If found a matching key, replace val obj */ if (retval == PM_RET_OK) { retval = seglist_setItem(((pPmDict_t)pdict)->d_vals, pval, indx); return retval; } } /* Otherwise, insert the key,val pair */ retval = seglist_insertItem(((pPmDict_t)pdict)->d_keys, pkey, 0); PM_RETURN_IF_ERROR(retval); retval = seglist_insertItem(((pPmDict_t)pdict)->d_vals, pval, 0); ((pPmDict_t)pdict)->length++; return retval; }
PmReturn_t obj_print(pPmObj_t pobj, uint8_t is_expr_repr, uint8_t is_nested) { PmReturn_t retval = PM_RET_OK; C_ASSERT(pobj != C_NULL); /* Something gets printed unless it's None in an unnested expression */ if (!((OBJ_GET_TYPE(pobj) == OBJ_TYPE_NON) && is_expr_repr && !is_nested)) { gVmGlobal.somethingPrinted = C_TRUE; } switch (OBJ_GET_TYPE(pobj)) { case OBJ_TYPE_NON: if (!is_expr_repr || is_nested) { plat_putByte('N'); plat_putByte('o'); plat_putByte('n'); retval = plat_putByte('e'); } break; case OBJ_TYPE_INT: retval = int_print(pobj); break; #ifdef HAVE_FLOAT case OBJ_TYPE_FLT: retval = float_print(pobj); break; #endif /* HAVE_FLOAT */ case OBJ_TYPE_STR: retval = string_print(pobj, (is_expr_repr || is_nested)); break; case OBJ_TYPE_TUP: retval = tuple_print(pobj); break; case OBJ_TYPE_LST: retval = list_print(pobj); break; case OBJ_TYPE_DIC: retval = dict_print(pobj); break; case OBJ_TYPE_BOOL: if (((pPmBoolean_t) pobj)->val == C_TRUE) { plat_putByte('T'); plat_putByte('r'); plat_putByte('u'); } else { plat_putByte('F'); plat_putByte('a'); plat_putByte('l'); plat_putByte('s'); } retval = plat_putByte('e'); break; case OBJ_TYPE_CLI: #ifdef HAVE_BYTEARRAY { pPmObj_t pobj2; retval = dict_getItem((pPmObj_t)((pPmInstance_t)pobj)->cli_attrs, PM_NONE, (pPmObj_t *)&pobj2); if ((retval == PM_RET_OK) && (OBJ_GET_TYPE(pobj2) == OBJ_TYPE_BYA)) { retval = bytearray_print(pobj2); break; } } #endif /* HAVE_BYTEARRAY */ case OBJ_TYPE_COB: case OBJ_TYPE_MOD: case OBJ_TYPE_CLO: case OBJ_TYPE_FXN: case OBJ_TYPE_CIM: case OBJ_TYPE_NIM: case OBJ_TYPE_NOB: case OBJ_TYPE_THR: case OBJ_TYPE_CIO: case OBJ_TYPE_MTH: case OBJ_TYPE_SQI: plat_putByte('<'); plat_putByte('o'); plat_putByte('b'); plat_putByte('j'); plat_putByte(' '); plat_putByte('t'); plat_putByte('y'); plat_putByte('p'); plat_putByte('e'); plat_putByte(' '); plat_putByte('0'); plat_putByte('x'); int_printHexByte(OBJ_GET_TYPE(pobj)); plat_putByte(' '); plat_putByte('@'); plat_putByte(' '); plat_putByte('0'); plat_putByte('x'); _int_printHex((intptr_t)pobj); retval = plat_putByte('>'); break; default: /* Otherwise raise a TypeError */ PM_RAISE(retval, PM_RET_EX_TYPE); break; } return retval; }
/* Returns true if the item is in the container object */ PmReturn_t obj_isIn(pPmObj_t pobj, pPmObj_t pitem) { PmReturn_t retval = PM_RET_NO; pPmObj_t ptestItem; int16_t i; uint8_t c; switch (OBJ_GET_TYPE(pobj)) { case OBJ_TYPE_TUP: /* Iterate over tuple to find item */ for (i = 0; i < ((pPmTuple_t)pobj)->length; i++) { PM_RETURN_IF_ERROR(tuple_getItem(pobj, i, &ptestItem)); if (obj_compare(pitem, ptestItem) == C_SAME) { retval = PM_RET_OK; break; } } break; case OBJ_TYPE_STR: /* Raise a TypeError if item is not a string */ if ((OBJ_GET_TYPE(pitem) != OBJ_TYPE_STR)) { retval = PM_RET_EX_TYPE; break; } /* Empty string is alway present */ if (((pPmString_t)pitem)->length == 0) { retval = PM_RET_OK; break; } /* Raise a ValueError if the string is more than 1 char */ else if (((pPmString_t)pitem)->length != 1) { retval = PM_RET_EX_VAL; break; } /* Iterate over string to find char */ c = ((pPmString_t)pitem)->val[0]; for (i = 0; i < ((pPmString_t)pobj)->length; i++) { if (c == ((pPmString_t)pobj)->val[i]) { retval = PM_RET_OK; break; } } break; case OBJ_TYPE_LST: /* Iterate over list to find item */ for (i = 0; i < ((pPmList_t)pobj)->length; i++) { PM_RETURN_IF_ERROR(list_getItem(pobj, i, &ptestItem)); if (obj_compare(pitem, ptestItem) == C_SAME) { retval = PM_RET_OK; break; } } break; case OBJ_TYPE_DIC: /* Check if the item is one of the keys of the dict */ retval = dict_getItem(pobj, pitem, &ptestItem); if (retval == PM_RET_EX_KEY) { retval = PM_RET_NO; } break; default: retval = PM_RET_EX_TYPE; break; } return retval; }
int8_t obj_compare(pPmObj_t pobj1, pPmObj_t pobj2) { #ifdef HAVE_BYTEARRAY PmReturn_t retval; pPmObj_t pobj; #endif /* HAVE_BYTEARRAY */ C_ASSERT(pobj1 != C_NULL); C_ASSERT(pobj2 != C_NULL); /* Check if pointers are same */ if (pobj1 == pobj2) { return C_SAME; } /* If types are different, objs must differ */ if (OBJ_GET_TYPE(pobj1) != OBJ_GET_TYPE(pobj2)) { return C_DIFFER; } #ifdef HAVE_BYTEARRAY /* If object is an instance, get the thing it contains */ if (OBJ_GET_TYPE(pobj1) == OBJ_TYPE_CLI) { retval = dict_getItem((pPmObj_t)((pPmInstance_t)pobj1)->cli_attrs, PM_NONE, &pobj); PM_RETURN_IF_ERROR(retval); pobj1 = pobj; } if (OBJ_GET_TYPE(pobj2) == OBJ_TYPE_CLI) { retval = dict_getItem((pPmObj_t)((pPmInstance_t)pobj2)->cli_attrs, PM_NONE, &pobj); PM_RETURN_IF_ERROR(retval); pobj2 = pobj; } /* If types are different, objs must differ */ if (OBJ_GET_TYPE(pobj1) != OBJ_GET_TYPE(pobj2)) { return C_DIFFER; } #endif /* HAVE_BYTEARRAY */ /* Otherwise handle types individually */ switch (OBJ_GET_TYPE(pobj1)) { case OBJ_TYPE_NON: return C_SAME; case OBJ_TYPE_INT: return ((pPmInt_t)pobj1)->val == ((pPmInt_t)pobj2)->val ? C_SAME : C_DIFFER; #ifdef HAVE_FLOAT case OBJ_TYPE_FLT: { pPmObj_t r_pobj; float_compare(pobj1, pobj2, &r_pobj, COMP_EQ); return (r_pobj == PM_TRUE) ? C_SAME : C_DIFFER; } #endif /* HAVE_FLOAT */ case OBJ_TYPE_STR: return string_compare((pPmString_t)pobj1, (pPmString_t)pobj2); case OBJ_TYPE_TUP: case OBJ_TYPE_LST: #ifdef HAVE_BYTEARRAY case OBJ_TYPE_BYA: #endif /* HAVE_BYTEARRAY */ return seq_compare(pobj1, pobj2); case OBJ_TYPE_DIC: return dict_compare(pobj1, pobj2); default: break; } /* All other types would need same pointer to be true */ return C_DIFFER; }