Davi Souza
/
pymite
python
Fork of pymite by
platform/mbed/pmstdlib_nat.cpp
- Committer:
- kausdev
- Date:
- 2014-08-28
- Revision:
- 12:d27ad05214e3
- Parent:
- 0:65f1469d6bfb
File content as of revision 12:d27ad05214e3:
#undef __FILE_ID__ #define __FILE_ID__ 0x0A /** * PyMite std native function file * * automatically created by pmImgCreator.py * on Sat Mar 02 20:27:03 2013 * * DO NOT EDIT THIS FILE. * ANY CHANGES WILL BE LOST. * * @file pmstdlib_nat.cpp */ #define __IN_LIBNATIVE_C__ #include "pm.h" /* From: ../../lib/string.py */ #include <stdlib.h> #include <string.h> PmReturn_t nat_00___bi_chr(pPmFrame_t *ppframe) { pPmObj_t ps; pPmObj_t pn; int32_t n; PmReturn_t retval; /* If wrong number of args, raise TypeError */ if (NATIVE_GET_NUM_ARGS() != 1) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* Raise TypeError if arg is not an int */ pn = NATIVE_GET_LOCAL(0); if (OBJ_GET_TYPE(pn) != OBJ_TYPE_INT) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* Raise ValueError if arg is not int within range(256) */ n = ((pPmInt_t)pn)->val; if ((n < 0) || (n > 255)) { PM_RAISE(retval, PM_RET_EX_VAL); return retval; } /* Create char string from integer value */ retval = string_newFromChar((uint8_t)n, &ps); NATIVE_SET_TOS(ps); return retval; } PmReturn_t nat_01___bi_dir(pPmFrame_t *ppframe) { PmReturn_t retval = PM_RET_OK; pPmObj_t po; pPmObj_t pk; pPmObj_t pl; pSeglist_t psl; int16_t i; uint8_t objid; /* Use globals if no arg given */ if (NATIVE_GET_NUM_ARGS() == 0) { /* Get the globals dict */ po = (pPmObj_t)NATIVE_GET_PFRAME()->fo_globals; } /* Otherwise use the given arg */ else if (NATIVE_GET_NUM_ARGS() == 1) { po = NATIVE_GET_LOCAL(0); /* If object is a function or module, use its attrs dict */ if ((OBJ_GET_TYPE(po) == OBJ_TYPE_FXN) || (OBJ_GET_TYPE(po) == OBJ_TYPE_MOD)) { po = (pPmObj_t)((pPmFunc_t)po)->f_attrs; } #ifdef HAVE_CLASSES else if (OBJ_GET_TYPE(po) == OBJ_TYPE_CLO) { po = (pPmObj_t)((pPmClass_t)po)->cl_attrs; } else if (OBJ_GET_TYPE(po) == OBJ_TYPE_CLI) { po = (pPmObj_t)((pPmInstance_t)po)->cli_attrs; } else if (OBJ_GET_TYPE(po) == OBJ_TYPE_MTH) { po = (pPmObj_t)((pPmMethod_t)po)->m_attrs; } #endif /* HAVE_CLASSES */ else { po = C_NULL; } } /* Raise TypeError if wrong number of args */ else { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } if (po == C_NULL) { pl = PM_NONE; } else { /* Create new list */ retval = list_new(&pl); PM_RETURN_IF_ERROR(retval); /* Copy dict's keys to the list */ psl = ((pPmDict_t)po)->d_keys; for (i = 0; i < ((pPmDict_t)po)->length; i++) { retval = seglist_getItem(psl, i, &pk); PM_RETURN_IF_ERROR(retval); heap_gcPushTempRoot(pl, &objid); retval = list_append(pl, pk); heap_gcPopTempRoot(objid); PM_RETURN_IF_ERROR(retval); } } NATIVE_SET_TOS(pl); return retval; } PmReturn_t nat_02___bi_eval(pPmFrame_t *ppframe) { PmReturn_t retval; pPmObj_t pco; pPmObj_t pfunc; pPmObj_t pnewframe; pPmObj_t pg = C_NULL; pPmObj_t pl = C_NULL; uint8_t objid; /* If wrong number of args, raise TypeError */ if ((NATIVE_GET_NUM_ARGS() == 0) || (NATIVE_GET_NUM_ARGS() > 3)) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* Raise ValueError if first arg is not a Code Object */ pco = NATIVE_GET_LOCAL(0); if (OBJ_GET_TYPE(pco) != OBJ_TYPE_COB) { PM_RAISE(retval, PM_RET_EX_VAL); return retval; } /* If 2nd arg exists, raise ValueError if it is not a Dict */ if (NATIVE_GET_NUM_ARGS() >= 2) { pg = NATIVE_GET_LOCAL(1); if (OBJ_GET_TYPE(pg) != OBJ_TYPE_DIC) { PM_RAISE(retval, PM_RET_EX_VAL); return retval; } } /* If no args are given, use the caller's globals for the function's */ else { pg = (pPmObj_t)NATIVE_GET_PFRAME()->fo_globals; } /* If 3rd arg exists, raise ValueError if it is not a Dict */ if (NATIVE_GET_NUM_ARGS() >= 3) { pl = NATIVE_GET_LOCAL(2); if (OBJ_GET_TYPE(pl) != OBJ_TYPE_DIC) { PM_RAISE(retval, PM_RET_EX_VAL); return retval; } } /* Create func from code object */ retval = func_new(pco, pg, &pfunc); PM_RETURN_IF_ERROR(retval); /* Create frame from module object; globals is set to null */ heap_gcPushTempRoot(pfunc, &objid); retval = frame_new(pfunc, &pnewframe); heap_gcPopTempRoot(objid); PM_RETURN_IF_ERROR(retval); /* TODO: Reclaim pnewframe's attrs dict created in frame_new */ /* * By default use calling frame's attrs as local namespace. * This works for ipm because the interactive mode * needs a locals namespace that persists across calls to eval() */ ((pPmFrame_t)pnewframe)->fo_attrs = NATIVE_GET_PFRAME()->fo_attrs; /* If 2nd arg exists, use it as the global namespace for the new func */ if (NATIVE_GET_NUM_ARGS() >= 2) { ((pPmFrame_t)pnewframe)->fo_globals = (pPmDict_t)pg; /* If only globals is given, locals defaults to it */ ((pPmFrame_t)pnewframe)->fo_attrs = (pPmDict_t)pg; } /* If 3rd arg exists, use it as the local namespace for the new func */ if (NATIVE_GET_NUM_ARGS() >= 3) { ((pPmFrame_t)pnewframe)->fo_attrs = (pPmDict_t)pl; } /* * Set the fo_back frame so flow returns to eval()'s caller when completed. * Set the frame pointer so the new frame is interpreted immediately * after this function returns. */ ((pPmFrame_t)pnewframe)->fo_back = NATIVE_GET_PFRAME(); NATIVE_GET_PFRAME() = (pPmFrame_t)pnewframe; retval = PM_RET_FRAME_SWITCH; return retval; } PmReturn_t nat_03___bi_globals(pPmFrame_t *ppframe) { pPmObj_t pr = C_NULL; PmReturn_t retval; /* If wrong number of args, raise TypeError */ if (NATIVE_GET_NUM_ARGS() != 0) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* Return calling frame's globals dict on stack*/ pr = (pPmObj_t)NATIVE_GET_PFRAME()->fo_globals; NATIVE_SET_TOS(pr); return PM_RET_OK; } PmReturn_t nat_04___bi_id(pPmFrame_t *ppframe) { PmReturn_t retval; pPmObj_t pr = C_NULL; /* If wrong number of args, raise TypeError */ if (NATIVE_GET_NUM_ARGS() != 1) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* Return object's address as an int on the stack */ retval = int_new((intptr_t)NATIVE_GET_LOCAL(0), &pr); NATIVE_SET_TOS(pr); return retval; } PmReturn_t nat_05___bi_len(pPmFrame_t *ppframe) { PmReturn_t retval; pPmObj_t ps = C_NULL; pPmObj_t pr = C_NULL; /* If wrong number of args, raise TypeError */ if (NATIVE_GET_NUM_ARGS() != 1) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* Get first arg */ ps = NATIVE_GET_LOCAL(0); #ifdef HAVE_BYTEARRAY /* If object is an instance, get the thing it contains */ if (OBJ_GET_TYPE(ps) == OBJ_TYPE_CLI) { retval = dict_getItem((pPmObj_t)((pPmInstance_t)ps)->cli_attrs, PM_NONE, &pr); /* If None wasn't in attributes, obj is wrong type for len() */ if (retval == PM_RET_EX_KEY) retval = PM_RET_EX_TYPE; PM_RETURN_IF_ERROR(retval); ps = pr; } #endif /* HAVE_BYTEARRAY */ /* Get the length of the arg based on its type */ switch (OBJ_GET_TYPE(ps)) { case OBJ_TYPE_STR: retval = int_new(((pPmString_t)ps)->length, &pr); break; case OBJ_TYPE_TUP: retval = int_new(((pPmTuple_t)ps)->length, &pr); break; case OBJ_TYPE_LST: retval = int_new(((pPmList_t)ps)->length, &pr); break; case OBJ_TYPE_DIC: retval = int_new(((pPmDict_t)ps)->length, &pr); break; #ifdef HAVE_BYTEARRAY case OBJ_TYPE_BYA: retval = int_new(((pPmBytearray_t)ps)->length, &pr); break; #endif /* HAVE_BYTEARRAY */ default: /* If not a string or sequence type, raise TypeError */ PM_RAISE(retval, PM_RET_EX_TYPE); } NATIVE_SET_TOS(pr); return retval; } PmReturn_t nat_06___bi_locals(pPmFrame_t *ppframe) { pPmObj_t pr = C_NULL; PmReturn_t retval; /* If wrong number of args, raise TypeError */ if (NATIVE_GET_NUM_ARGS() != 0) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* Return calling frame's local attrs dict on the stack */ pr = (pPmObj_t)NATIVE_GET_PFRAME()->fo_attrs; NATIVE_SET_TOS(pr); return PM_RET_OK; } PmReturn_t nat_07___bi_ord(pPmFrame_t *ppframe) { pPmObj_t ps; pPmObj_t pn; int32_t n; PmReturn_t retval; /* If wrong number of args, raise TypeError */ if (NATIVE_GET_NUM_ARGS() != 1) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } ps = NATIVE_GET_LOCAL(0); /* Raise TypeError if arg is not string of length 1 */ if ((OBJ_GET_TYPE(ps) != OBJ_TYPE_STR) || (((pPmString_t)ps)->length != 1)) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* Get integer value of character */ n = ((pPmString_t)ps)->val[0]; retval = int_new(n, &pn); NATIVE_SET_TOS(pn); return retval; } PmReturn_t nat_08___bi_range(pPmFrame_t *ppframe) { PmReturn_t retval; pPmObj_t pa = C_NULL; pPmObj_t pb = C_NULL; pPmObj_t pc = C_NULL; pPmObj_t pi = C_NULL; pPmObj_t pr = C_NULL; int16_t i = 0; uint8_t objid1, objid2; switch (NATIVE_GET_NUM_ARGS()) { case 1: pa = PM_ZERO; pb = NATIVE_GET_LOCAL(0); pc = PM_ONE; break; case 2: pa = NATIVE_GET_LOCAL(0); pb = NATIVE_GET_LOCAL(1); pc = PM_ONE; break; case 3: pa = NATIVE_GET_LOCAL(0); pb = NATIVE_GET_LOCAL(1); pc = NATIVE_GET_LOCAL(2); /* If 3rd arg is 0, ValueError */ if (((pPmInt_t)pc)->val == 0) { PM_RAISE(retval, PM_RET_EX_VAL); return retval; } break; default: /* If wrong number of args, raise TypeError */ PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* Allocate list */ retval = list_new(&pr); PM_RETURN_IF_ERROR(retval); /* Iterate depending on counting direction */ if (((pPmInt_t)pc)->val > 0) { for (i = ((pPmInt_t)pa)->val; i < ((pPmInt_t)pb)->val; i += ((pPmInt_t)pc)->val) { heap_gcPushTempRoot(pr, &objid1); retval = int_new(i, &pi); if (retval != PM_RET_OK) { heap_gcPopTempRoot(objid1); return retval; } heap_gcPushTempRoot(pi, &objid2); retval = list_append(pr, pi); heap_gcPopTempRoot(objid1); PM_RETURN_IF_ERROR(retval); } } else { for (i = ((pPmInt_t)pa)->val; i > ((pPmInt_t)pb)->val; i += ((pPmInt_t)pc)->val) { heap_gcPushTempRoot(pr, &objid1); retval = int_new(i, &pi); if (retval != PM_RET_OK) { heap_gcPopTempRoot(objid1); return retval; } heap_gcPushTempRoot(pi, &objid2); retval = list_append(pr, pi); heap_gcPopTempRoot(objid1); PM_RETURN_IF_ERROR(retval); } } /* Return list */ NATIVE_SET_TOS(pr); return retval; } PmReturn_t nat_09___bi_sum(pPmFrame_t *ppframe) { pPmObj_t ps; pPmObj_t pn; pPmObj_t po; int32_t n; uint16_t len; uint16_t i; PmReturn_t retval; #ifdef HAVE_FLOAT float f; uint8_t usefloat = C_FALSE; #endif /* HAVE_FLOAT */ /* If wrong number of args, raise TypeError */ if (NATIVE_GET_NUM_ARGS() != 1) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } ps = NATIVE_GET_LOCAL(0); #ifdef HAVE_BYTEARRAY /* Bytearray is a special case to save RAM converting each byte to an Int */ if (OBJ_GET_TYPE(ps) == OBJ_TYPE_BYA) { n = 0; len = ((pPmBytearray_t)ps)->length; po = (pPmObj_t)((pPmBytearray_t)ps)->val; for (i = 0; i < len; i++) { n += (uint8_t)((pPmBytes_t)po)->val[i]; } retval = int_new(n, &pn); NATIVE_SET_TOS(pn); return retval; } #endif /* HAVE_BYTEARRAY */ /* Raise TypeError if arg is not a sequence */ if ((OBJ_GET_TYPE(ps) != OBJ_TYPE_TUP) && (OBJ_GET_TYPE(ps) != OBJ_TYPE_LST) && (OBJ_GET_TYPE(ps) != OBJ_TYPE_DIC)) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* Get the length of the sequence */ retval = seq_getLength(ps, &len); PM_RETURN_IF_ERROR(retval); /* Calculate the sum of the sequence */ n = 0; #ifdef HAVE_FLOAT f = 0.0; #endif for (i = 0; i < len; i++) { retval = seq_getSubscript(ps, i, &po); if (OBJ_GET_TYPE(po) == OBJ_TYPE_INT) { /* Add value to sum */ n += ((pPmInt_t)po)->val; #ifdef HAVE_FLOAT f += (float)((pPmInt_t)po)->val; #endif /* HAVE_FLOAT */ } #ifdef HAVE_FLOAT else if (OBJ_GET_TYPE(po) == OBJ_TYPE_FLT) { /* Add value to sum */ f += ((pPmFloat_t)po)->val; usefloat = C_TRUE; } #endif /* HAVE_FLOAT */ /* Raise TypeError if item is not an integer */ else { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } } #ifdef HAVE_FLOAT if (usefloat) { retval = float_new(f, &pn); } else #endif /* HAVE_FLOAT */ { retval = int_new(n, &pn); } NATIVE_SET_TOS(pn); return retval; } PmReturn_t nat_10___bi_type(pPmFrame_t *ppframe) { PmReturn_t retval; pPmObj_t po = C_NULL; pPmObj_t pr = C_NULL; /* If wrong number of args, raise TypeError */ if (NATIVE_GET_NUM_ARGS() != 1) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* Get arg */ po = NATIVE_GET_LOCAL(0); /* Create int from type enum */ retval = int_new(OBJ_GET_TYPE(po), &pr); NATIVE_SET_TOS(pr); return retval; } PmReturn_t nat_11___bi_Co(pPmFrame_t *ppframe) { PmReturn_t retval; pPmObj_t pimg; pPmObj_t pco; /* If wrong number of args, raise TypeError */ if (NATIVE_GET_NUM_ARGS() != 1) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* Raise ValueError if arg is not an Image Obj */ pimg = NATIVE_GET_LOCAL(0); if (OBJ_GET_TYPE(pimg) != OBJ_TYPE_CIO) { PM_RAISE(retval, PM_RET_EX_VAL); return retval; } /* Create a code object from the image */ retval = obj_loadFromImgObj(pimg, &pco); PM_RETURN_IF_ERROR(retval); /* Return the code object */ NATIVE_SET_TOS(pco); return retval; } PmReturn_t nat_12___bi___init__(pPmFrame_t *ppframe) { PmReturn_t retval; pPmObj_t pself; pPmObj_t pfa; pPmObj_t pfunc; pPmObj_t pframe; uint8_t i; uint8_t objid; /* Raise TypeError if wrong number of args */ if (NATIVE_GET_NUM_ARGS() != 2) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* Raise ValueError if first args are not: instance, tuple */ pself = NATIVE_GET_LOCAL(0); pfa = NATIVE_GET_LOCAL(1); if (OBJ_GET_TYPE(pself) != OBJ_TYPE_CLI) { PM_RAISE(retval, PM_RET_EX_VAL); return retval; } if (OBJ_GET_TYPE(pfa) != OBJ_TYPE_TUP) { PM_RAISE(retval, PM_RET_EX_VAL); return retval; } /* Create a new frame for the function */ pfunc = ((pPmTuple_t)pfa)->val[0]; retval = frame_new(pfunc, &pframe); PM_RETURN_IF_ERROR(retval); /* Copy args into frame's locals */ for (i = 0; i < ((pPmTuple_t)pfa)->length - 1; i++) { /* The pfa tuple is (func, [arg0, ... argN]) */ ((pPmFrame_t)pframe)->fo_locals[i] = ((pPmTuple_t)pfa)->val[i + 1]; } /* Store frame in None attr of instance */ heap_gcPushTempRoot(pframe, &objid); retval = dict_setItem((pPmObj_t)((pPmInstance_t)pself)->cli_attrs, PM_NONE, pframe); heap_gcPopTempRoot(objid); NATIVE_SET_TOS(PM_NONE); return retval; } PmReturn_t nat_13___bi_send(pPmFrame_t *ppframe) { PmReturn_t retval; pPmObj_t pself; pPmObj_t parg; pPmObj_t pgenframe; /* Raise TypeError if wrong number of args */ if (NATIVE_GET_NUM_ARGS() != 2) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* Raise ValueError if first arg is not an instance */ pself = NATIVE_GET_LOCAL(0); parg = NATIVE_GET_LOCAL(1); if (OBJ_GET_TYPE(pself) != OBJ_TYPE_CLI) { PM_RAISE(retval, PM_RET_EX_VAL); return retval; } /* Get the generator's frame */ retval = dict_getItem((pPmObj_t)((pPmInstance_t)pself)->cli_attrs, PM_NONE, &pgenframe); PM_RETURN_IF_ERROR(retval); /* Push argument onto generator's frame's stack */ *(((pPmFrame_t)pgenframe)->fo_sp) = parg; ((pPmFrame_t)pgenframe)->fo_sp++; /* Set generator's frame's fo_back so yielded value goes to caller */ ((pPmFrame_t)pgenframe)->fo_back = NATIVE_GET_PFRAME(); /* Set active frame to run generator */ NATIVE_GET_PFRAME() = (pPmFrame_t)pgenframe; return PM_RET_FRAME_SWITCH; } PmReturn_t nat_14___bi_ismain(pPmFrame_t *ppframe) { NATIVE_SET_TOS((NATIVE_GET_PFRAME()->fo_isImport) ? PM_FALSE : PM_TRUE); return PM_RET_OK; } PmReturn_t nat_15_dict_clear(pPmFrame_t *ppframe) { pPmObj_t pd; PmReturn_t retval = PM_RET_OK; /* Raise TypeError if it's not a dict or wrong number of args, */ pd = NATIVE_GET_LOCAL(0); if ((OBJ_GET_TYPE(pd) != OBJ_TYPE_DIC) || (NATIVE_GET_NUM_ARGS() != 1)) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* Clear the contents of the dict */ retval = dict_clear(pd); PM_RETURN_IF_ERROR(retval); NATIVE_SET_TOS(PM_NONE); return retval; } PmReturn_t nat_16_dict_keys(pPmFrame_t *ppframe) { pPmObj_t pd; pPmObj_t pl; pPmObj_t pk; pSeglist_t psl; uint16_t i; PmReturn_t retval = PM_RET_OK; uint8_t objid; /* Raise TypeError if it's not a dict or wrong number of args, */ pd = NATIVE_GET_LOCAL(0); if ((OBJ_GET_TYPE(pd) != OBJ_TYPE_DIC) || (NATIVE_GET_NUM_ARGS() != 1)) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* Create empty list */ retval = list_new(&pl); PM_RETURN_IF_ERROR(retval); /* Iterate through the keys seglist */ psl = ((pPmDict_t)pd)->d_keys; for (i = 0; i < ((pPmDict_t)pd)->length; i++) { /* Get the key and append it to the list */ retval = seglist_getItem(psl, i, &pk); PM_RETURN_IF_ERROR(retval); heap_gcPushTempRoot(pl, &objid); retval = list_append(pl, pk); heap_gcPopTempRoot(objid); PM_RETURN_IF_ERROR(retval); } /* Return the list of keys to the caller */ NATIVE_SET_TOS(pl); return retval; } PmReturn_t nat_17_dict_values(pPmFrame_t *ppframe) { pPmObj_t pd; pPmObj_t pl; pPmObj_t pv; pSeglist_t psl; uint16_t i; PmReturn_t retval = PM_RET_OK; uint8_t objid; /* Raise TypeError if it's not a dict or wrong number of args, */ pd = NATIVE_GET_LOCAL(0); if ((OBJ_GET_TYPE(pd) != OBJ_TYPE_DIC) || (NATIVE_GET_NUM_ARGS() != 1)) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* Create empty list */ retval = list_new(&pl); PM_RETURN_IF_ERROR(retval); /* Iterate through the values seglist */ psl = ((pPmDict_t)pd)->d_vals; for (i = 0; i < ((pPmDict_t)pd)->length; i++) { /* Get the value and append it to the list */ retval = seglist_getItem(psl, i, &pv); PM_RETURN_IF_ERROR(retval); heap_gcPushTempRoot(pl, &objid); retval = list_append(pl, pv); heap_gcPopTempRoot(objid); PM_RETURN_IF_ERROR(retval); } /* Return the list of values to the caller */ NATIVE_SET_TOS(pl); return retval; } PmReturn_t nat_18_dict_update(pPmFrame_t *ppframe) { pPmObj_t pd1; pPmObj_t pd2; PmReturn_t retval; /* Raise TypeError if wrong number of args, */ if (NATIVE_GET_NUM_ARGS() != 2) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } pd1 = NATIVE_GET_LOCAL(0); pd2 = NATIVE_GET_LOCAL(1); retval = dict_update(pd1, pd2, C_FALSE); NATIVE_SET_TOS(PM_NONE); return retval; } PmReturn_t nat_19_list_append(pPmFrame_t *ppframe) { pPmObj_t pl; PmReturn_t retval = PM_RET_OK; /* Raise TypeError if it's not a list or wrong number of args, */ pl = NATIVE_GET_LOCAL(0); if ((OBJ_GET_TYPE(pl) != OBJ_TYPE_LST) || (NATIVE_GET_NUM_ARGS() != 2)) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* Append the object to the list */ retval = list_append(pl, NATIVE_GET_LOCAL(1)); NATIVE_SET_TOS(PM_NONE); return retval; } PmReturn_t nat_20_list_index(pPmFrame_t *ppframe) { pPmObj_t pl; pPmObj_t po; pPmObj_t pi; PmReturn_t retval = PM_RET_OK; uint16_t i; /* Raise TypeError if it's not a list or wrong number of args, */ pl = NATIVE_GET_LOCAL(0); if ((OBJ_GET_TYPE(pl) != OBJ_TYPE_LST) || (NATIVE_GET_NUM_ARGS() != 2)) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* Get the index of the object in the list */ po = NATIVE_GET_LOCAL(1); retval = list_index(pl, po, &i); if (retval == PM_RET_EX_VAL) { PM_RAISE(retval, PM_RET_EX_VAL); return retval; } int_new((int32_t)i, &pi); NATIVE_SET_TOS(pi); return retval; } PmReturn_t nat_21_list_insert(pPmFrame_t *ppframe) { pPmObj_t pl; pPmObj_t pi; pPmObj_t po; PmReturn_t retval = PM_RET_OK; uint16_t i; /* * Raise TypeError if wrong number of args, first arg is not a list, or * second arg is not an int */ pl = NATIVE_GET_LOCAL(0); pi = NATIVE_GET_LOCAL(1); po = NATIVE_GET_LOCAL(2); if ((NATIVE_GET_NUM_ARGS() != 3) || (OBJ_GET_TYPE(pl) != OBJ_TYPE_LST) || (OBJ_GET_TYPE(pi) != OBJ_TYPE_INT) ) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* Insert the object before the given index */ i = (uint16_t)((pPmInt_t)pi)->val; retval = list_insert(pl, i, po); if (retval != PM_RET_OK) { PM_RAISE(retval, PM_RET_EX_SYS); } NATIVE_SET_TOS(PM_NONE); return retval; } PmReturn_t nat_22_list_pop(pPmFrame_t *ppframe) { pPmObj_t pl; pPmObj_t pi; pPmObj_t po; PmReturn_t retval = PM_RET_OK; int16_t i; /* * Raise TypeError if first arg is not a list o second arg is not an int * or there are the wrong number of arguments */ pl = NATIVE_GET_LOCAL(0); if (OBJ_GET_TYPE(pl) != OBJ_TYPE_LST) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } pi = NATIVE_GET_LOCAL(1); if (NATIVE_GET_NUM_ARGS() == 2) { if (OBJ_GET_TYPE(pi) != OBJ_TYPE_INT) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } i = (uint16_t)((pPmInt_t)pi)->val; } else { i = -1; } if ((NATIVE_GET_NUM_ARGS() < 1) || (NATIVE_GET_NUM_ARGS() > 2)) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* Get the object at the given index */ retval = list_getItem(pl, i, &po); PM_RETURN_IF_ERROR(retval); /* Return the object to the caller */ NATIVE_SET_TOS(po); /* Remove the object from the given index */ retval = list_delItem(pl, i); PM_RETURN_IF_ERROR(retval); return retval; } PmReturn_t nat_23_list_remove(pPmFrame_t *ppframe) { pPmObj_t pl; pPmObj_t pv; PmReturn_t retval = PM_RET_OK; /* Raise TypeError if it's not a list or wrong number of args, */ pl = NATIVE_GET_LOCAL(0); if ((OBJ_GET_TYPE(pl) != OBJ_TYPE_LST) || (NATIVE_GET_NUM_ARGS() != 2)) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* Remove the value from the list */ pv = NATIVE_GET_LOCAL(1); retval = list_remove(pl, pv); if (retval != PM_RET_OK) { PM_RAISE(retval, retval); } NATIVE_SET_TOS(PM_NONE); return retval; } PmReturn_t nat_24_string_atoi(pPmFrame_t *ppframe) { pPmObj_t pa; pPmObj_t pb; char const *pc; char *pend; long i; int8_t base; pPmObj_t pi; PmReturn_t retval = PM_RET_OK; /* Raise TypeError if it's not a string or wrong number of args, */ pa = NATIVE_GET_LOCAL(0); if ((OBJ_GET_TYPE(pa) != OBJ_TYPE_STR) || (NATIVE_GET_NUM_ARGS() < 1) || (NATIVE_GET_NUM_ARGS() > 2)) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* Get the base, if it exists; otherwise assume 10 */ base = 10; if (NATIVE_GET_NUM_ARGS() == 2) { pb = NATIVE_GET_LOCAL(1); /* Raise a TypeError if 2nd arg is not an int */ if (OBJ_GET_TYPE(pb) != OBJ_TYPE_INT) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } base = ((pPmInt_t)pb)->val; /* Raise ValueError if base is out of range */ if ((base < 0) || (base == 1) || (base > 36)) { PM_RAISE(retval, PM_RET_EX_VAL); return retval; } } /* Perform conversion */ pend = C_NULL; pc = (char const *)&(((pPmString_t)pa)->val); i = strtol(pc, &pend, base); /* Raise ValueError if there was a conversion error */ if (*pend != C_NULL) { PM_RAISE(retval, PM_RET_EX_VAL); return retval; } /* Create an int object to hold the result of the conversion */ retval = int_new(i, &pi); NATIVE_SET_TOS(pi); return retval; } PmReturn_t nat_25_string_count(pPmFrame_t *ppframe) { pPmObj_t ps1; pPmObj_t ps2; uint8_t *pc1; uint8_t *pc2; uint8_t *pscan; uint8_t *pmatch; uint8_t pc2c0; uint16_t pc1len; uint16_t pc2len; uint16_t n; uint16_t remaining; uint16_t cmp; pPmObj_t pn; PmReturn_t retval = PM_RET_OK; /* Raise TypeError if it's not a string or wrong number of args, */ ps1 = NATIVE_GET_LOCAL(0); ps2 = NATIVE_GET_LOCAL(1); if ((OBJ_GET_TYPE(ps1) != OBJ_TYPE_STR) || (NATIVE_GET_NUM_ARGS() != 2) || (OBJ_GET_TYPE(ps2) != OBJ_TYPE_STR)) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } pc1 = ((pPmString_t)ps1)->val; pc2 = ((pPmString_t)ps2)->val; pc1len = ((pPmString_t)ps1)->length; pc2len = ((pPmString_t)ps2)->length; n = 0; /* Handle some quick special cases (order of if-clauses is important) */ if (pc2len == 0) { n = pc1len + 1; } else if (pc1len == 0) { n = 0; } /* Count the number of matches */ else { n = 0; remaining = pc1len; pscan = pc1; pc2c0 = pc2[0]; while (pscan <= (pc1 + (pc1len - pc2len))) { /* Find the next possible start */ pmatch = (uint8_t *)memchr(pscan, pc2c0, remaining); if (pmatch == C_NULL) break; remaining -= (pmatch - pscan); pscan = pmatch; /* If it matches, increase the count, else try the next char */ cmp = memcmp(pscan, pc2, pc2len); if (cmp == 0) { n++; pscan += pc2len; remaining -= pc2len; } else { pscan++; remaining--; } } } retval = int_new(n, &pn); NATIVE_SET_TOS(pn); return retval; } PmReturn_t nat_26_string_find(pPmFrame_t *ppframe) { pPmObj_t ps1; pPmObj_t ps2; uint8_t *pc1; uint8_t *pc2; uint8_t *pmatch; uint16_t pc1len; uint16_t pc2len; int32_t n; pPmObj_t pn; PmReturn_t retval = PM_RET_OK; /* Raise TypeError if it's not a string or wrong number of args, */ ps1 = NATIVE_GET_LOCAL(0); ps2 = NATIVE_GET_LOCAL(1); if ((OBJ_GET_TYPE(ps1) != OBJ_TYPE_STR) || (NATIVE_GET_NUM_ARGS() != 2) || (OBJ_GET_TYPE(ps2) != OBJ_TYPE_STR)) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } pc1 = ((pPmString_t)ps1)->val; pc2 = ((pPmString_t)ps2)->val; pc1len = ((pPmString_t)ps1)->length; pc2len = ((pPmString_t)ps2)->length; n = -1; /* Handle a quick special case */ if (pc2len == 0) { n = 0; } /* Try to find the index of the substring */ else { /* Find the next possible start */ pmatch = (uint8_t *)memchr(pc1, pc2[0], pc1len); if (pmatch != C_NULL) { /* If it matches, calculate the index */ if (memcmp(pmatch, pc2, pc2len) == 0) { n = pmatch - pc1; } } } retval = int_new(n, &pn); NATIVE_SET_TOS(pn); return retval; } PmReturn_t nat_27_sys_exit(pPmFrame_t *ppframe) { pPmObj_t pval = C_NULL; PmReturn_t retval; /* If no arg given, assume return 0 */ if (NATIVE_GET_NUM_ARGS() == 0) { NATIVE_SET_TOS(PM_ZERO); } /* If 1 arg given, put it on stack */ else if (NATIVE_GET_NUM_ARGS() == 1) { pval = NATIVE_GET_LOCAL(0); NATIVE_SET_TOS(pval); } /* If wrong number of args, raise TypeError */ else { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* Raise the SystemExit exception */ PM_RAISE(retval, PM_RET_EX_EXIT); return retval; } PmReturn_t nat_28_sys_gc(pPmFrame_t *ppframe) { PmReturn_t retval = PM_RET_OK; #ifdef HAVE_GC /* If wrong number of args, raise TypeError */ if (NATIVE_GET_NUM_ARGS() != 0) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } retval = heap_gcRun(); #endif NATIVE_SET_TOS(PM_NONE); return retval; } PmReturn_t nat_29_sys_getb(pPmFrame_t *ppframe) { uint8_t b; pPmObj_t pb; PmReturn_t retval; /* If wrong number of args, raise TypeError */ if (NATIVE_GET_NUM_ARGS() != 0) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } retval = plat_getByte(&b); PM_RETURN_IF_ERROR(retval); retval = int_new((int32_t)b, &pb); NATIVE_SET_TOS(pb); return retval; } PmReturn_t nat_30_sys_heap(pPmFrame_t *ppframe) { PmReturn_t retval; pPmObj_t pavail; pPmObj_t psize; pPmObj_t ptup; uint8_t objid; /* If wrong number of args, raise TypeError */ if (NATIVE_GET_NUM_ARGS() != 0) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* Allocate a tuple to store the return values */ retval = tuple_new(2, &ptup); PM_RETURN_IF_ERROR(retval); /* Get the maximum heap size */ heap_gcPushTempRoot(ptup, &objid); retval = int_new(heap_getSize(), &psize); if (retval != PM_RET_OK) { heap_gcPopTempRoot(objid); return retval; } /* Allocate an int to hold the amount of heap available */ retval = int_new(heap_getAvail() - sizeof(PmInt_t), &pavail); heap_gcPopTempRoot(objid); PM_RETURN_IF_ERROR(retval); /* Put the two heap values in the tuple */ ((pPmTuple_t)ptup)->val[0] = pavail; ((pPmTuple_t)ptup)->val[1] = psize; /* Return the tuple on the stack */ NATIVE_SET_TOS(ptup); return retval; } PmReturn_t nat_31_sys_putb(pPmFrame_t *ppframe) { uint8_t b; pPmObj_t pb; PmReturn_t retval; pb = NATIVE_GET_LOCAL(0); /* If wrong number of args, raise TypeError */ if (NATIVE_GET_NUM_ARGS() != 1) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* If arg is not an int, raise TypeError */ if (OBJ_GET_TYPE(pb) != OBJ_TYPE_INT) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } b = ((pPmInt_t)pb)->val & 0xFF; retval = plat_putByte(b); NATIVE_SET_TOS(PM_NONE); return retval; } PmReturn_t nat_32_sys_runInThread(pPmFrame_t *ppframe) { PmReturn_t retval; pPmObj_t pf; /* If wrong number of args, raise TypeError */ if (NATIVE_GET_NUM_ARGS() != 1) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* If arg is not a function, raise TypeError */ pf = NATIVE_GET_LOCAL(0); if (OBJ_GET_TYPE(pf) != OBJ_TYPE_FXN) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } retval = interp_addThread((pPmFunc_t)pf); NATIVE_SET_TOS(PM_NONE); return retval; } PmReturn_t nat_33_sys_time(pPmFrame_t *ppframe) { uint32_t t; pPmObj_t pt; PmReturn_t retval; /* If wrong number of args, raise TypeError */ if (NATIVE_GET_NUM_ARGS() != 0) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* Get the system time (milliseconds since init) */ retval = plat_getMsTicks(&t); PM_RETURN_IF_ERROR(retval); /* * Raise ValueError if there is an overflow * (plat_getMsTicks is unsigned; int is signed) */ if ((int32_t)t < 0) { PM_RAISE(retval, PM_RET_EX_VAL); return retval; } /* Return an int object with the time value */ retval = int_new((int32_t)t, &pt); NATIVE_SET_TOS(pt); return retval; } PmReturn_t nat_34_ipm__getImg(pPmFrame_t *ppframe) { PmReturn_t retval; uint8_t imgType; uint16_t imgSize; uint8_t *pchunk; pPmCodeImgObj_t pimg; uint16_t i; uint8_t b; /* Get the image type */ retval = plat_getByte(&imgType); PM_RETURN_IF_ERROR(retval); /* Quit if a code image type was not received */ if (imgType != OBJ_TYPE_CIM) { PM_RAISE(retval, PM_RET_EX_STOP); return retval; } /* Get the image size (little endien) */ retval = plat_getByte(&b); PM_RETURN_IF_ERROR(retval); imgSize = b; retval = plat_getByte(&b); PM_RETURN_IF_ERROR(retval); imgSize |= (b << 8); /* Get space for CodeImgObj */ retval = heap_getChunk(sizeof(PmCodeImgObj_t) + imgSize, &pchunk); PM_RETURN_IF_ERROR(retval); pimg = (pPmCodeImgObj_t)pchunk; OBJ_SET_TYPE(pimg, OBJ_TYPE_CIO); /* Start the image with the bytes that have already been received */ i = 0; pimg->val[i++] = imgType; pimg->val[i++] = imgSize & 0xFF; pimg->val[i++] = (imgSize >> 8) & 0xFF; /* Get the remaining bytes in the image */ for(; i < imgSize; i++) { retval = plat_getByte(&b); PM_RETURN_IF_ERROR(retval); pimg->val[i] = b; } /* Return the image as a code image object on the stack */ NATIVE_SET_TOS((pPmObj_t)pimg); return retval; } PmReturn_t nat_35_ipm_x04(pPmFrame_t *ppframe) { NATIVE_SET_TOS(PM_NONE); return plat_putByte(0x04); } /* Native function lookup table */ pPmNativeFxn_t const std_nat_fxn_table[] = { nat_00___bi_chr, nat_01___bi_dir, nat_02___bi_eval, nat_03___bi_globals, nat_04___bi_id, nat_05___bi_len, nat_06___bi_locals, nat_07___bi_ord, nat_08___bi_range, nat_09___bi_sum, nat_10___bi_type, nat_11___bi_Co, nat_12___bi___init__, nat_13___bi_send, nat_14___bi_ismain, nat_15_dict_clear, nat_16_dict_keys, nat_17_dict_values, nat_18_dict_update, nat_19_list_append, nat_20_list_index, nat_21_list_insert, nat_22_list_pop, nat_23_list_remove, nat_24_string_atoi, nat_25_string_count, nat_26_string_find, nat_27_sys_exit, nat_28_sys_gc, nat_29_sys_getb, nat_30_sys_heap, nat_31_sys_putb, nat_32_sys_runInThread, nat_33_sys_time, nat_34_ipm__getImg, nat_35_ipm_x04, };