python-on-a-chip online compiler

Dependencies:   mbed TSI

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pmstdlib_nat.cpp Source File

pmstdlib_nat.cpp

Go to the documentation of this file.
00001 #undef __FILE_ID__
00002 #define __FILE_ID__ 0x0A
00003 /**
00004  * PyMite std native function file
00005  *
00006  * automatically created by pmImgCreator.py
00007  * on Sat Mar 02 20:27:03 2013
00008  *
00009  * DO NOT EDIT THIS FILE.
00010  * ANY CHANGES WILL BE LOST.
00011  *
00012  * @file    pmstdlib_nat.cpp
00013  */
00014 
00015 #define __IN_LIBNATIVE_C__
00016 #include "pm.h"
00017 
00018 /* From: ../../lib/string.py */
00019 #include <stdlib.h>
00020 #include <string.h>
00021 
00022 PmReturn_t
00023 nat_00___bi_chr(pPmFrame_t *ppframe)
00024 {
00025 
00026     pPmObj_t ps;
00027     pPmObj_t pn;
00028     int32_t n;
00029     PmReturn_t retval;
00030 
00031     /* If wrong number of args, raise TypeError */
00032     if (NATIVE_GET_NUM_ARGS() != 1)
00033     {
00034         PM_RAISE(retval, PM_RET_EX_TYPE);
00035         return retval;
00036     }
00037 
00038     /* Raise TypeError if arg is not an int */
00039     pn = NATIVE_GET_LOCAL(0);
00040     if (OBJ_GET_TYPE(pn) != OBJ_TYPE_INT)
00041     {
00042         PM_RAISE(retval, PM_RET_EX_TYPE);
00043         return retval;
00044     }
00045 
00046     /* Raise ValueError if arg is not int within range(256) */
00047     n = ((pPmInt_t)pn)->val;
00048     if ((n < 0) || (n > 255))
00049     {
00050         PM_RAISE(retval, PM_RET_EX_VAL);
00051         return retval;
00052     }
00053 
00054     /* Create char string from  integer value */
00055     retval = string_newFromChar((uint8_t)n, &ps);
00056     NATIVE_SET_TOS(ps);
00057     return retval;
00058     
00059 }
00060 
00061 PmReturn_t
00062 nat_01___bi_dir(pPmFrame_t *ppframe)
00063 {
00064 
00065     PmReturn_t retval = PM_RET_OK;
00066     pPmObj_t po;
00067     pPmObj_t pk;
00068     pPmObj_t pl;
00069     pSeglist_t psl;
00070     int16_t i;
00071     uint8_t objid;
00072 
00073     /* Use globals if no arg given */
00074     if (NATIVE_GET_NUM_ARGS() == 0)
00075     {
00076         /* Get the globals dict */
00077         po = (pPmObj_t)NATIVE_GET_PFRAME()->fo_globals;
00078     }
00079 
00080     /* Otherwise use the given arg */
00081     else if (NATIVE_GET_NUM_ARGS() == 1)
00082     {
00083         po = NATIVE_GET_LOCAL(0);
00084 
00085         /* If object is a function or module, use its attrs dict */
00086         if ((OBJ_GET_TYPE(po) == OBJ_TYPE_FXN)
00087             || (OBJ_GET_TYPE(po) == OBJ_TYPE_MOD))
00088         {
00089             po = (pPmObj_t)((pPmFunc_t)po)->f_attrs;
00090         }
00091 
00092 #ifdef HAVE_CLASSES
00093         else if (OBJ_GET_TYPE(po) == OBJ_TYPE_CLO)
00094         {
00095             po = (pPmObj_t)((pPmClass_t)po)->cl_attrs;
00096         }
00097         else if (OBJ_GET_TYPE(po) == OBJ_TYPE_CLI)
00098         {
00099             po = (pPmObj_t)((pPmInstance_t)po)->cli_attrs;
00100         }
00101         else if (OBJ_GET_TYPE(po) == OBJ_TYPE_MTH)
00102         {
00103             po = (pPmObj_t)((pPmMethod_t)po)->m_attrs;
00104         }
00105 #endif /* HAVE_CLASSES */
00106 
00107         else
00108         {
00109             po = C_NULL;
00110         }
00111     }
00112 
00113     /* Raise TypeError if wrong number of args */
00114     else
00115     {
00116         PM_RAISE(retval, PM_RET_EX_TYPE);
00117         return retval;
00118     }
00119 
00120     if (po == C_NULL)
00121     {
00122         pl = PM_NONE;
00123     }
00124     else
00125     {
00126         /* Create new list */
00127         retval = list_new(&pl);
00128         PM_RETURN_IF_ERROR(retval);
00129 
00130         /* Copy dict's keys to the list */
00131         psl = ((pPmDict_t)po)->d_keys;
00132         for (i = 0; i < ((pPmDict_t)po)->length; i++)
00133         {
00134             retval = seglist_getItem(psl, i, &pk);
00135             PM_RETURN_IF_ERROR(retval);
00136             heap_gcPushTempRoot(pl, &objid);
00137             retval = list_append(pl, pk);
00138             heap_gcPopTempRoot(objid);
00139             PM_RETURN_IF_ERROR(retval);
00140         }
00141     }
00142 
00143     NATIVE_SET_TOS(pl);
00144     return retval;
00145     
00146 }
00147 
00148 PmReturn_t
00149 nat_02___bi_eval(pPmFrame_t *ppframe)
00150 {
00151 
00152     PmReturn_t retval;
00153     pPmObj_t pco;
00154     pPmObj_t pfunc;
00155     pPmObj_t pnewframe;
00156     pPmObj_t pg = C_NULL;
00157     pPmObj_t pl = C_NULL;
00158     uint8_t objid;
00159 
00160     /* If wrong number of args, raise TypeError */
00161     if ((NATIVE_GET_NUM_ARGS() == 0) || (NATIVE_GET_NUM_ARGS() > 3))
00162     {
00163         PM_RAISE(retval, PM_RET_EX_TYPE);
00164         return retval;
00165     }
00166 
00167     /* Raise ValueError if first arg is not a Code Object */
00168     pco = NATIVE_GET_LOCAL(0);
00169     if (OBJ_GET_TYPE(pco) != OBJ_TYPE_COB)
00170     {
00171         PM_RAISE(retval, PM_RET_EX_VAL);
00172         return retval;
00173     }
00174 
00175     /* If 2nd arg exists, raise ValueError if it is not a Dict */
00176     if (NATIVE_GET_NUM_ARGS() >= 2)
00177     {
00178         pg = NATIVE_GET_LOCAL(1);
00179         if (OBJ_GET_TYPE(pg) != OBJ_TYPE_DIC)
00180         {
00181             PM_RAISE(retval, PM_RET_EX_VAL);
00182             return retval;
00183         }
00184     }
00185 
00186     /* If no args are given, use the caller's globals for the function's */
00187     else
00188     {
00189         pg = (pPmObj_t)NATIVE_GET_PFRAME()->fo_globals;
00190     }
00191 
00192     /* If 3rd arg exists, raise ValueError if it is not a Dict */
00193     if (NATIVE_GET_NUM_ARGS() >= 3)
00194     {
00195         pl = NATIVE_GET_LOCAL(2);
00196         if (OBJ_GET_TYPE(pl) != OBJ_TYPE_DIC)
00197         {
00198             PM_RAISE(retval, PM_RET_EX_VAL);
00199             return retval;
00200         }
00201     }
00202 
00203     /* Create func from code object */
00204     retval = func_new(pco, pg, &pfunc);
00205     PM_RETURN_IF_ERROR(retval);
00206 
00207     /* Create frame from module object; globals is set to null */
00208     heap_gcPushTempRoot(pfunc, &objid);
00209     retval = frame_new(pfunc, &pnewframe);
00210     heap_gcPopTempRoot(objid);
00211     PM_RETURN_IF_ERROR(retval);
00212 
00213     /* TODO: Reclaim pnewframe's attrs dict created in frame_new */
00214     /*
00215      * By default use calling frame's attrs as local namespace.
00216      * This works for ipm because the interactive mode
00217      * needs a locals namespace that persists across calls to eval()
00218      */
00219     ((pPmFrame_t)pnewframe)->fo_attrs = NATIVE_GET_PFRAME()->fo_attrs;
00220 
00221     /* If 2nd arg exists, use it as the global namespace for the new func */
00222     if (NATIVE_GET_NUM_ARGS() >= 2)
00223     {
00224         ((pPmFrame_t)pnewframe)->fo_globals = (pPmDict_t)pg;
00225 
00226         /* If only globals is given, locals defaults to it */
00227         ((pPmFrame_t)pnewframe)->fo_attrs = (pPmDict_t)pg;
00228     }
00229 
00230     /* If 3rd arg exists, use it as the local namespace for the new func */
00231     if (NATIVE_GET_NUM_ARGS() >= 3)
00232     {
00233         ((pPmFrame_t)pnewframe)->fo_attrs = (pPmDict_t)pl;
00234     }
00235 
00236     /*
00237      * Set the fo_back frame so flow returns to eval()'s caller when completed.
00238      * Set the frame pointer so the new frame is interpreted immediately
00239      * after this function returns.
00240      */
00241     ((pPmFrame_t)pnewframe)->fo_back = NATIVE_GET_PFRAME();
00242     NATIVE_GET_PFRAME() = (pPmFrame_t)pnewframe;
00243     retval = PM_RET_FRAME_SWITCH;
00244 
00245     return retval;
00246     
00247 }
00248 
00249 PmReturn_t
00250 nat_03___bi_globals(pPmFrame_t *ppframe)
00251 {
00252 
00253     pPmObj_t pr = C_NULL;
00254     PmReturn_t retval;
00255 
00256     /* If wrong number of args, raise TypeError */
00257     if (NATIVE_GET_NUM_ARGS() != 0)
00258     {
00259         PM_RAISE(retval, PM_RET_EX_TYPE);
00260         return retval;
00261     }
00262 
00263     /* Return calling frame's globals dict  on stack*/
00264     pr = (pPmObj_t)NATIVE_GET_PFRAME()->fo_globals;
00265     NATIVE_SET_TOS(pr);
00266 
00267     return PM_RET_OK;
00268     
00269 }
00270 
00271 PmReturn_t
00272 nat_04___bi_id(pPmFrame_t *ppframe)
00273 {
00274 
00275     PmReturn_t retval;
00276     pPmObj_t pr = C_NULL;
00277 
00278     /* If wrong number of args, raise TypeError */
00279     if (NATIVE_GET_NUM_ARGS() != 1)
00280     {
00281         PM_RAISE(retval, PM_RET_EX_TYPE);
00282         return retval;
00283     }
00284 
00285     /* Return object's address as an int on the stack */
00286     retval = int_new((intptr_t)NATIVE_GET_LOCAL(0), &pr);
00287     NATIVE_SET_TOS(pr);
00288 
00289     return retval;
00290     
00291 }
00292 
00293 PmReturn_t
00294 nat_05___bi_len(pPmFrame_t *ppframe)
00295 {
00296 
00297     PmReturn_t retval;
00298     pPmObj_t ps = C_NULL;
00299     pPmObj_t pr = C_NULL;
00300 
00301     /* If wrong number of args, raise TypeError */
00302     if (NATIVE_GET_NUM_ARGS() != 1)
00303     {
00304         PM_RAISE(retval, PM_RET_EX_TYPE);
00305         return retval;
00306     }
00307 
00308     /* Get first arg */
00309     ps = NATIVE_GET_LOCAL(0);
00310 
00311 #ifdef HAVE_BYTEARRAY
00312     /* If object is an instance, get the thing it contains */
00313     if (OBJ_GET_TYPE(ps) == OBJ_TYPE_CLI)
00314     {
00315         retval = dict_getItem((pPmObj_t)((pPmInstance_t)ps)->cli_attrs,
00316                               PM_NONE,
00317                               &pr);
00318 
00319         /* If None wasn't in attributes, obj is wrong type for len() */
00320         if (retval == PM_RET_EX_KEY) retval = PM_RET_EX_TYPE;
00321         PM_RETURN_IF_ERROR(retval);
00322         ps = pr;
00323     }
00324 #endif /* HAVE_BYTEARRAY */
00325 
00326     /* Get the length of the arg based on its type */
00327     switch (OBJ_GET_TYPE(ps))
00328     {
00329         case OBJ_TYPE_STR:
00330             retval = int_new(((pPmString_t)ps)->length, &pr);
00331             break;
00332 
00333         case OBJ_TYPE_TUP:
00334             retval = int_new(((pPmTuple_t)ps)->length, &pr);
00335             break;
00336 
00337         case OBJ_TYPE_LST:
00338             retval = int_new(((pPmList_t)ps)->length, &pr);
00339             break;
00340 
00341         case OBJ_TYPE_DIC:
00342             retval = int_new(((pPmDict_t)ps)->length, &pr);
00343             break;
00344 
00345 #ifdef HAVE_BYTEARRAY
00346         case OBJ_TYPE_BYA:
00347             retval = int_new(((pPmBytearray_t)ps)->length, &pr);
00348             break;
00349 #endif /* HAVE_BYTEARRAY */
00350 
00351         default:
00352             /* If not a string or sequence type, raise TypeError */
00353             PM_RAISE(retval, PM_RET_EX_TYPE);
00354     }
00355 
00356     NATIVE_SET_TOS(pr);
00357     return retval;
00358     
00359 }
00360 
00361 PmReturn_t
00362 nat_06___bi_locals(pPmFrame_t *ppframe)
00363 {
00364 
00365     pPmObj_t pr = C_NULL;
00366     PmReturn_t retval;
00367 
00368     /* If wrong number of args, raise TypeError */
00369     if (NATIVE_GET_NUM_ARGS() != 0)
00370     {
00371         PM_RAISE(retval, PM_RET_EX_TYPE);
00372         return retval;
00373     }
00374 
00375     /* Return calling frame's local attrs dict on the stack */
00376     pr = (pPmObj_t)NATIVE_GET_PFRAME()->fo_attrs;
00377     NATIVE_SET_TOS(pr);
00378 
00379     return PM_RET_OK;
00380     
00381 }
00382 
00383 PmReturn_t
00384 nat_07___bi_ord(pPmFrame_t *ppframe)
00385 {
00386 
00387     pPmObj_t ps;
00388     pPmObj_t pn;
00389     int32_t n;
00390     PmReturn_t retval;
00391 
00392     /* If wrong number of args, raise TypeError */
00393     if (NATIVE_GET_NUM_ARGS() != 1)
00394     {
00395         PM_RAISE(retval, PM_RET_EX_TYPE);
00396         return retval;
00397     }
00398 
00399     ps = NATIVE_GET_LOCAL(0);
00400 
00401     /* Raise TypeError if arg is not string of length 1 */
00402     if ((OBJ_GET_TYPE(ps) != OBJ_TYPE_STR)
00403         || (((pPmString_t)ps)->length != 1))
00404 
00405     {
00406         PM_RAISE(retval, PM_RET_EX_TYPE);
00407         return retval;
00408     }
00409 
00410     /* Get integer value of character */
00411     n = ((pPmString_t)ps)->val[0];
00412     retval = int_new(n, &pn);
00413     NATIVE_SET_TOS(pn);
00414     return retval;
00415     
00416 }
00417 
00418 PmReturn_t
00419 nat_08___bi_range(pPmFrame_t *ppframe)
00420 {
00421 
00422     PmReturn_t retval;
00423     pPmObj_t pa = C_NULL;
00424     pPmObj_t pb = C_NULL;
00425     pPmObj_t pc = C_NULL;
00426     pPmObj_t pi = C_NULL;
00427     pPmObj_t pr = C_NULL;
00428     int16_t i = 0;
00429     uint8_t objid1, objid2;
00430 
00431     switch (NATIVE_GET_NUM_ARGS())
00432     {
00433         case 1:
00434             pa = PM_ZERO;
00435             pb = NATIVE_GET_LOCAL(0);
00436             pc = PM_ONE;
00437             break;
00438 
00439         case 2:
00440             pa = NATIVE_GET_LOCAL(0);
00441             pb = NATIVE_GET_LOCAL(1);
00442             pc = PM_ONE;
00443             break;
00444 
00445         case 3:
00446             pa = NATIVE_GET_LOCAL(0);
00447             pb = NATIVE_GET_LOCAL(1);
00448             pc = NATIVE_GET_LOCAL(2);
00449 
00450             /* If 3rd arg is 0, ValueError */
00451             if (((pPmInt_t)pc)->val == 0)
00452             {
00453                 PM_RAISE(retval, PM_RET_EX_VAL);
00454                 return retval;
00455             }
00456             break;
00457 
00458         default:
00459             /* If wrong number of args, raise TypeError */
00460             PM_RAISE(retval, PM_RET_EX_TYPE);
00461             return retval;
00462     }
00463 
00464     /* Allocate list */
00465     retval = list_new(&pr);
00466     PM_RETURN_IF_ERROR(retval);
00467 
00468     /* Iterate depending on counting direction */
00469     if (((pPmInt_t)pc)->val > 0)
00470     {
00471         for (i = ((pPmInt_t)pa)->val;
00472              i < ((pPmInt_t)pb)->val;
00473              i += ((pPmInt_t)pc)->val)
00474         {
00475             heap_gcPushTempRoot(pr, &objid1);
00476             retval = int_new(i, &pi);
00477             if (retval != PM_RET_OK)
00478             {
00479                 heap_gcPopTempRoot(objid1);
00480                 return retval;
00481             }
00482 
00483             heap_gcPushTempRoot(pi, &objid2);
00484             retval = list_append(pr, pi);
00485             heap_gcPopTempRoot(objid1);
00486             PM_RETURN_IF_ERROR(retval);
00487         }
00488     }
00489     else
00490     {
00491         for (i = ((pPmInt_t)pa)->val;
00492              i > ((pPmInt_t)pb)->val;
00493              i += ((pPmInt_t)pc)->val)
00494         {
00495             heap_gcPushTempRoot(pr, &objid1);
00496             retval = int_new(i, &pi);
00497             if (retval != PM_RET_OK)
00498             {
00499                 heap_gcPopTempRoot(objid1);
00500                 return retval;
00501             }
00502 
00503             heap_gcPushTempRoot(pi, &objid2);
00504             retval = list_append(pr, pi);
00505             heap_gcPopTempRoot(objid1);
00506             PM_RETURN_IF_ERROR(retval);
00507         }
00508     }
00509 
00510     /* Return list */
00511     NATIVE_SET_TOS(pr);
00512     return retval;
00513     
00514 }
00515 
00516 PmReturn_t
00517 nat_09___bi_sum(pPmFrame_t *ppframe)
00518 {
00519 
00520     pPmObj_t ps;
00521     pPmObj_t pn;
00522     pPmObj_t po;
00523     int32_t n;
00524     uint16_t len;
00525     uint16_t i;
00526     PmReturn_t retval;
00527 #ifdef HAVE_FLOAT
00528     float f;
00529     uint8_t usefloat = C_FALSE;
00530 #endif /* HAVE_FLOAT */
00531 
00532     /* If wrong number of args, raise TypeError */
00533     if (NATIVE_GET_NUM_ARGS() != 1)
00534     {
00535         PM_RAISE(retval, PM_RET_EX_TYPE);
00536         return retval;
00537     }
00538 
00539     ps = NATIVE_GET_LOCAL(0);
00540 
00541 #ifdef HAVE_BYTEARRAY
00542     /* Bytearray is a special case to save RAM converting each byte to an Int */
00543     if (OBJ_GET_TYPE(ps) == OBJ_TYPE_BYA)
00544     {
00545         n = 0;
00546         len = ((pPmBytearray_t)ps)->length;
00547         po = (pPmObj_t)((pPmBytearray_t)ps)->val;
00548         for (i = 0; i < len; i++)
00549         {
00550             n += (uint8_t)((pPmBytes_t)po)->val[i];
00551         }
00552         retval = int_new(n, &pn);
00553         NATIVE_SET_TOS(pn);
00554         return retval;
00555     }
00556 #endif /* HAVE_BYTEARRAY */
00557 
00558     /* Raise TypeError if arg is not a sequence */
00559     if ((OBJ_GET_TYPE(ps) != OBJ_TYPE_TUP)
00560         && (OBJ_GET_TYPE(ps) != OBJ_TYPE_LST)
00561         && (OBJ_GET_TYPE(ps) != OBJ_TYPE_DIC))
00562     {
00563         PM_RAISE(retval, PM_RET_EX_TYPE);
00564         return retval;
00565     }
00566 
00567     /* Get the length of the sequence */
00568     retval = seq_getLength(ps, &len);
00569     PM_RETURN_IF_ERROR(retval);
00570 
00571     /* Calculate the sum of the sequence */
00572     n = 0;
00573 #ifdef HAVE_FLOAT
00574     f = 0.0;
00575 #endif
00576     for (i = 0; i < len; i++)
00577     {
00578         retval = seq_getSubscript(ps, i, &po);
00579 
00580         if (OBJ_GET_TYPE(po) == OBJ_TYPE_INT)
00581         {
00582             /* Add value to sum */
00583             n += ((pPmInt_t)po)->val;
00584 #ifdef HAVE_FLOAT
00585             f += (float)((pPmInt_t)po)->val;
00586 #endif /* HAVE_FLOAT */
00587         }
00588 
00589 #ifdef HAVE_FLOAT
00590         else if (OBJ_GET_TYPE(po) == OBJ_TYPE_FLT)
00591         {
00592             /* Add value to sum */
00593             f += ((pPmFloat_t)po)->val;
00594             usefloat = C_TRUE;
00595         }
00596 #endif /* HAVE_FLOAT */
00597 
00598         /* Raise TypeError if item is not an integer */
00599         else
00600         {
00601             PM_RAISE(retval, PM_RET_EX_TYPE);
00602             return retval;
00603         }
00604     }
00605 
00606 #ifdef HAVE_FLOAT
00607     if (usefloat)
00608     {
00609         retval = float_new(f, &pn);
00610     }
00611     else
00612 #endif /* HAVE_FLOAT */
00613     {
00614         retval = int_new(n, &pn);
00615     }
00616     NATIVE_SET_TOS(pn);
00617     return retval;
00618     
00619 }
00620 
00621 PmReturn_t
00622 nat_10___bi_type(pPmFrame_t *ppframe)
00623 {
00624 
00625     PmReturn_t retval;
00626     pPmObj_t po = C_NULL;
00627     pPmObj_t pr = C_NULL;
00628 
00629     /* If wrong number of args, raise TypeError */
00630     if (NATIVE_GET_NUM_ARGS() != 1)
00631     {
00632         PM_RAISE(retval, PM_RET_EX_TYPE);
00633         return retval;
00634     }
00635 
00636     /* Get arg */
00637     po = NATIVE_GET_LOCAL(0);
00638 
00639     /* Create int from type enum */
00640     retval = int_new(OBJ_GET_TYPE(po), &pr);
00641     NATIVE_SET_TOS(pr);
00642     return retval;
00643     
00644 }
00645 
00646 PmReturn_t
00647 nat_11___bi_Co(pPmFrame_t *ppframe)
00648 {
00649 
00650     PmReturn_t retval;
00651     pPmObj_t pimg;
00652     pPmObj_t pco;
00653 
00654     /* If wrong number of args, raise TypeError */
00655     if (NATIVE_GET_NUM_ARGS() != 1)
00656     {
00657         PM_RAISE(retval, PM_RET_EX_TYPE);
00658         return retval;
00659     }
00660 
00661     /* Raise ValueError if arg is not an Image Obj */
00662     pimg = NATIVE_GET_LOCAL(0);
00663     if (OBJ_GET_TYPE(pimg) != OBJ_TYPE_CIO)
00664     {
00665         PM_RAISE(retval, PM_RET_EX_VAL);
00666         return retval;
00667     }
00668 
00669     /* Create a code object from the image */
00670     retval = obj_loadFromImgObj(pimg, &pco);
00671     PM_RETURN_IF_ERROR(retval);
00672 
00673     /* Return the code object */
00674     NATIVE_SET_TOS(pco);
00675     return retval;
00676     
00677 }
00678 
00679 PmReturn_t
00680 nat_12___bi___init__(pPmFrame_t *ppframe)
00681 {
00682 
00683         PmReturn_t retval;
00684         pPmObj_t pself;
00685         pPmObj_t pfa;
00686         pPmObj_t pfunc;
00687         pPmObj_t pframe;
00688         uint8_t i;
00689         uint8_t objid;
00690 
00691         /* Raise TypeError if wrong number of args */
00692         if (NATIVE_GET_NUM_ARGS() != 2)
00693         {
00694             PM_RAISE(retval, PM_RET_EX_TYPE);
00695             return retval;
00696         }
00697 
00698         /* Raise ValueError if first args are not: instance, tuple */
00699         pself = NATIVE_GET_LOCAL(0);
00700         pfa = NATIVE_GET_LOCAL(1);
00701         if (OBJ_GET_TYPE(pself) != OBJ_TYPE_CLI)
00702         {
00703             PM_RAISE(retval, PM_RET_EX_VAL);
00704             return retval;
00705         }
00706         if (OBJ_GET_TYPE(pfa) != OBJ_TYPE_TUP)
00707         {
00708             PM_RAISE(retval, PM_RET_EX_VAL);
00709             return retval;
00710         }
00711 
00712         /* Create a new frame for the function */
00713         pfunc = ((pPmTuple_t)pfa)->val[0];
00714         retval = frame_new(pfunc, &pframe);
00715         PM_RETURN_IF_ERROR(retval);
00716 
00717         /* Copy args into frame's locals */
00718         for (i = 0; i < ((pPmTuple_t)pfa)->length - 1; i++)
00719         {
00720             /* The pfa tuple is (func, [arg0, ... argN]) */
00721             ((pPmFrame_t)pframe)->fo_locals[i] = ((pPmTuple_t)pfa)->val[i + 1];
00722         }
00723 
00724         /* Store frame in None attr of instance */
00725         heap_gcPushTempRoot(pframe, &objid);
00726         retval = dict_setItem((pPmObj_t)((pPmInstance_t)pself)->cli_attrs,
00727                               PM_NONE, pframe);
00728         heap_gcPopTempRoot(objid);
00729 
00730         NATIVE_SET_TOS(PM_NONE);
00731         return retval;
00732         
00733 }
00734 
00735 PmReturn_t
00736 nat_13___bi_send(pPmFrame_t *ppframe)
00737 {
00738 
00739         PmReturn_t retval;
00740         pPmObj_t pself;
00741         pPmObj_t parg;
00742         pPmObj_t pgenframe;
00743 
00744         /* Raise TypeError if wrong number of args */
00745         if (NATIVE_GET_NUM_ARGS() != 2)
00746         {
00747             PM_RAISE(retval, PM_RET_EX_TYPE);
00748             return retval;
00749         }
00750 
00751         /* Raise ValueError if first arg is not an instance */
00752         pself = NATIVE_GET_LOCAL(0);
00753         parg = NATIVE_GET_LOCAL(1);
00754         if (OBJ_GET_TYPE(pself) != OBJ_TYPE_CLI)
00755         {
00756             PM_RAISE(retval, PM_RET_EX_VAL);
00757             return retval;
00758         }
00759 
00760         /* Get the generator's frame */
00761         retval = dict_getItem((pPmObj_t)((pPmInstance_t)pself)->cli_attrs,
00762                               PM_NONE, &pgenframe);
00763         PM_RETURN_IF_ERROR(retval);
00764 
00765         /* Push argument onto generator's frame's stack */
00766         *(((pPmFrame_t)pgenframe)->fo_sp) = parg;
00767         ((pPmFrame_t)pgenframe)->fo_sp++;
00768 
00769         /* Set generator's frame's fo_back so yielded value goes to caller */
00770         ((pPmFrame_t)pgenframe)->fo_back = NATIVE_GET_PFRAME();
00771 
00772         /* Set active frame to run generator */
00773         NATIVE_GET_PFRAME() = (pPmFrame_t)pgenframe;
00774 
00775         return PM_RET_FRAME_SWITCH;
00776         
00777 }
00778 
00779 PmReturn_t
00780 nat_14___bi_ismain(pPmFrame_t *ppframe)
00781 {
00782 
00783 
00784     NATIVE_SET_TOS((NATIVE_GET_PFRAME()->fo_isImport) ? PM_FALSE : PM_TRUE);
00785 
00786     return PM_RET_OK;
00787     
00788 }
00789 
00790 PmReturn_t
00791 nat_15_dict_clear(pPmFrame_t *ppframe)
00792 {
00793 
00794     pPmObj_t pd;
00795     PmReturn_t retval = PM_RET_OK;
00796 
00797     /* Raise TypeError if it's not a dict or wrong number of args, */
00798     pd = NATIVE_GET_LOCAL(0);
00799     if ((OBJ_GET_TYPE(pd) != OBJ_TYPE_DIC) || (NATIVE_GET_NUM_ARGS() != 1))
00800     {
00801         PM_RAISE(retval, PM_RET_EX_TYPE);
00802         return retval;
00803     }
00804 
00805     /* Clear the contents of the dict */
00806     retval = dict_clear(pd);
00807     PM_RETURN_IF_ERROR(retval);
00808 
00809     NATIVE_SET_TOS(PM_NONE);
00810 
00811     return retval;
00812     
00813 }
00814 
00815 PmReturn_t
00816 nat_16_dict_keys(pPmFrame_t *ppframe)
00817 {
00818 
00819     pPmObj_t pd;
00820     pPmObj_t pl;
00821     pPmObj_t pk;
00822     pSeglist_t psl;
00823     uint16_t i;
00824     PmReturn_t retval = PM_RET_OK;
00825     uint8_t objid;
00826 
00827     /* Raise TypeError if it's not a dict or wrong number of args, */
00828     pd = NATIVE_GET_LOCAL(0);
00829     if ((OBJ_GET_TYPE(pd) != OBJ_TYPE_DIC) || (NATIVE_GET_NUM_ARGS() != 1))
00830     {
00831         PM_RAISE(retval, PM_RET_EX_TYPE);
00832         return retval;
00833     }
00834 
00835     /* Create empty list */
00836     retval = list_new(&pl);
00837     PM_RETURN_IF_ERROR(retval);
00838 
00839     /* Iterate through the keys seglist */
00840     psl = ((pPmDict_t)pd)->d_keys;
00841     for (i = 0; i < ((pPmDict_t)pd)->length; i++)
00842     {
00843         /* Get the key and append it to the list */
00844         retval = seglist_getItem(psl, i, &pk);
00845         PM_RETURN_IF_ERROR(retval);
00846         heap_gcPushTempRoot(pl, &objid);
00847         retval = list_append(pl, pk);
00848         heap_gcPopTempRoot(objid);
00849         PM_RETURN_IF_ERROR(retval);
00850     }
00851 
00852     /* Return the list of keys to the caller */
00853     NATIVE_SET_TOS(pl);
00854 
00855     return retval;
00856     
00857 }
00858 
00859 PmReturn_t
00860 nat_17_dict_values(pPmFrame_t *ppframe)
00861 {
00862 
00863     pPmObj_t pd;
00864     pPmObj_t pl;
00865     pPmObj_t pv;
00866     pSeglist_t psl;
00867     uint16_t i;
00868     PmReturn_t retval = PM_RET_OK;
00869     uint8_t objid;
00870 
00871     /* Raise TypeError if it's not a dict or wrong number of args, */
00872     pd = NATIVE_GET_LOCAL(0);
00873     if ((OBJ_GET_TYPE(pd) != OBJ_TYPE_DIC) || (NATIVE_GET_NUM_ARGS() != 1))
00874     {
00875         PM_RAISE(retval, PM_RET_EX_TYPE);
00876         return retval;
00877     }
00878 
00879     /* Create empty list */
00880     retval = list_new(&pl);
00881     PM_RETURN_IF_ERROR(retval);
00882 
00883     /* Iterate through the values seglist */
00884     psl = ((pPmDict_t)pd)->d_vals;
00885     for (i = 0; i < ((pPmDict_t)pd)->length; i++)
00886     {
00887         /* Get the value and append it to the list */
00888         retval = seglist_getItem(psl, i, &pv);
00889         PM_RETURN_IF_ERROR(retval);
00890         heap_gcPushTempRoot(pl, &objid);
00891         retval = list_append(pl, pv);
00892         heap_gcPopTempRoot(objid);
00893         PM_RETURN_IF_ERROR(retval);
00894     }
00895 
00896     /* Return the list of values to the caller */
00897     NATIVE_SET_TOS(pl);
00898 
00899     return retval;
00900     
00901 }
00902 
00903 PmReturn_t
00904 nat_18_dict_update(pPmFrame_t *ppframe)
00905 {
00906 
00907     pPmObj_t pd1;
00908     pPmObj_t pd2;
00909     PmReturn_t retval;
00910 
00911     /* Raise TypeError if wrong number of args, */
00912     if (NATIVE_GET_NUM_ARGS() != 2)
00913     {
00914         PM_RAISE(retval, PM_RET_EX_TYPE);
00915         return retval;
00916     }
00917 
00918     pd1 = NATIVE_GET_LOCAL(0);
00919     pd2 = NATIVE_GET_LOCAL(1);
00920     retval = dict_update(pd1, pd2, C_FALSE);
00921 
00922     NATIVE_SET_TOS(PM_NONE);
00923     return retval;
00924     
00925 }
00926 
00927 PmReturn_t
00928 nat_19_list_append(pPmFrame_t *ppframe)
00929 {
00930 
00931     pPmObj_t pl;
00932     PmReturn_t retval = PM_RET_OK;
00933 
00934     /* Raise TypeError if it's not a list or wrong number of args, */
00935     pl = NATIVE_GET_LOCAL(0);
00936     if ((OBJ_GET_TYPE(pl) != OBJ_TYPE_LST) || (NATIVE_GET_NUM_ARGS() != 2))
00937     {
00938         PM_RAISE(retval, PM_RET_EX_TYPE);
00939         return retval;
00940     }
00941 
00942     /* Append the object to the list */
00943     retval = list_append(pl, NATIVE_GET_LOCAL(1));
00944 
00945     NATIVE_SET_TOS(PM_NONE);
00946 
00947     return retval;
00948     
00949 }
00950 
00951 PmReturn_t
00952 nat_20_list_index(pPmFrame_t *ppframe)
00953 {
00954 
00955     pPmObj_t pl;
00956     pPmObj_t po;
00957     pPmObj_t pi;
00958     PmReturn_t retval = PM_RET_OK;
00959     uint16_t i;
00960 
00961     /* Raise TypeError if it's not a list or wrong number of args, */
00962     pl = NATIVE_GET_LOCAL(0);
00963     if ((OBJ_GET_TYPE(pl) != OBJ_TYPE_LST) || (NATIVE_GET_NUM_ARGS() != 2))
00964     {
00965         PM_RAISE(retval, PM_RET_EX_TYPE);
00966         return retval;
00967     }
00968 
00969     /* Get the index of the object in the list */
00970     po = NATIVE_GET_LOCAL(1);
00971     retval = list_index(pl, po, &i);
00972 
00973     if (retval == PM_RET_EX_VAL)
00974     {
00975         PM_RAISE(retval, PM_RET_EX_VAL);
00976         return retval;
00977     }
00978 
00979     int_new((int32_t)i, &pi);
00980     NATIVE_SET_TOS(pi);
00981 
00982     return retval;
00983     
00984 }
00985 
00986 PmReturn_t
00987 nat_21_list_insert(pPmFrame_t *ppframe)
00988 {
00989 
00990     pPmObj_t pl;
00991     pPmObj_t pi;
00992     pPmObj_t po;
00993     PmReturn_t retval = PM_RET_OK;
00994     uint16_t i;
00995 
00996     /*
00997      * Raise TypeError if wrong number of args, first arg is not a list, or
00998      * second arg is not an int
00999      */
01000     pl = NATIVE_GET_LOCAL(0);
01001     pi = NATIVE_GET_LOCAL(1);
01002     po = NATIVE_GET_LOCAL(2);
01003     if ((NATIVE_GET_NUM_ARGS() != 3)
01004         || (OBJ_GET_TYPE(pl) != OBJ_TYPE_LST)
01005         || (OBJ_GET_TYPE(pi) != OBJ_TYPE_INT) )
01006     {
01007         PM_RAISE(retval, PM_RET_EX_TYPE);
01008         return retval;
01009     }
01010 
01011     /* Insert the object before the given index */
01012     i = (uint16_t)((pPmInt_t)pi)->val;
01013     retval = list_insert(pl, i, po);
01014 
01015     if (retval != PM_RET_OK)
01016     {
01017         PM_RAISE(retval, PM_RET_EX_SYS);
01018     }
01019 
01020     NATIVE_SET_TOS(PM_NONE);
01021 
01022     return retval;
01023     
01024 }
01025 
01026 PmReturn_t
01027 nat_22_list_pop(pPmFrame_t *ppframe)
01028 {
01029 
01030     pPmObj_t pl;
01031     pPmObj_t pi;
01032     pPmObj_t po;
01033     PmReturn_t retval = PM_RET_OK;
01034     int16_t i;
01035 
01036     /*
01037      * Raise TypeError if first arg is not a list o second arg is not an int
01038      * or there are the wrong number of arguments
01039      */
01040     pl = NATIVE_GET_LOCAL(0);
01041     if (OBJ_GET_TYPE(pl) != OBJ_TYPE_LST)
01042     {
01043         PM_RAISE(retval, PM_RET_EX_TYPE);
01044         return retval;
01045     }
01046 
01047     pi = NATIVE_GET_LOCAL(1);
01048     if (NATIVE_GET_NUM_ARGS() == 2)
01049     {
01050         if (OBJ_GET_TYPE(pi) != OBJ_TYPE_INT)
01051         {
01052             PM_RAISE(retval, PM_RET_EX_TYPE);
01053             return retval;
01054         }
01055         i = (uint16_t)((pPmInt_t)pi)->val;
01056     }
01057     else
01058     {
01059         i = -1;
01060     }
01061     if ((NATIVE_GET_NUM_ARGS() < 1) || (NATIVE_GET_NUM_ARGS() > 2))
01062     {
01063         PM_RAISE(retval, PM_RET_EX_TYPE);
01064         return retval;
01065     }
01066 
01067     /* Get the object at the given index */
01068     retval = list_getItem(pl, i, &po);
01069     PM_RETURN_IF_ERROR(retval);
01070 
01071     /* Return the object to the caller */
01072     NATIVE_SET_TOS(po);
01073 
01074     /* Remove the object from the given index */
01075     retval = list_delItem(pl, i);
01076     PM_RETURN_IF_ERROR(retval);
01077 
01078     return retval;
01079     
01080 }
01081 
01082 PmReturn_t
01083 nat_23_list_remove(pPmFrame_t *ppframe)
01084 {
01085 
01086     pPmObj_t pl;
01087     pPmObj_t pv;
01088     PmReturn_t retval = PM_RET_OK;
01089 
01090     /* Raise TypeError if it's not a list or wrong number of args, */
01091     pl = NATIVE_GET_LOCAL(0);
01092     if ((OBJ_GET_TYPE(pl) != OBJ_TYPE_LST) || (NATIVE_GET_NUM_ARGS() != 2))
01093     {
01094         PM_RAISE(retval, PM_RET_EX_TYPE);
01095         return retval;
01096     }
01097 
01098     /* Remove the value from the list */
01099     pv = NATIVE_GET_LOCAL(1);
01100     retval = list_remove(pl, pv);
01101     if (retval != PM_RET_OK)
01102     {
01103         PM_RAISE(retval, retval);
01104     }
01105 
01106     NATIVE_SET_TOS(PM_NONE);
01107 
01108     return retval;
01109     
01110 }
01111 
01112 PmReturn_t
01113 nat_24_string_atoi(pPmFrame_t *ppframe)
01114 {
01115 
01116     pPmObj_t pa;
01117     pPmObj_t pb;
01118     char const *pc;
01119     char *pend;
01120     long i;
01121     int8_t base;
01122     pPmObj_t pi;
01123     PmReturn_t retval = PM_RET_OK;
01124 
01125     /* Raise TypeError if it's not a string or wrong number of args, */
01126     pa = NATIVE_GET_LOCAL(0);
01127     if ((OBJ_GET_TYPE(pa) != OBJ_TYPE_STR) || (NATIVE_GET_NUM_ARGS() < 1)
01128         || (NATIVE_GET_NUM_ARGS() > 2))
01129     {
01130         PM_RAISE(retval, PM_RET_EX_TYPE);
01131         return retval;
01132     }
01133 
01134     /* Get the base, if it exists; otherwise assume 10 */
01135     base = 10;
01136     if (NATIVE_GET_NUM_ARGS() == 2)
01137     {
01138         pb = NATIVE_GET_LOCAL(1);
01139 
01140         /* Raise a TypeError if 2nd arg is not an int */
01141         if (OBJ_GET_TYPE(pb) != OBJ_TYPE_INT)
01142         {
01143             PM_RAISE(retval, PM_RET_EX_TYPE);
01144             return retval;
01145         }
01146 
01147         base = ((pPmInt_t)pb)->val;
01148 
01149         /* Raise ValueError if base is out of range */
01150         if ((base < 0) || (base == 1) || (base > 36))
01151         {
01152             PM_RAISE(retval, PM_RET_EX_VAL);
01153             return retval;
01154         }
01155     }
01156 
01157     /* Perform conversion */
01158     pend = C_NULL;
01159     pc = (char const *)&(((pPmString_t)pa)->val);
01160     i = strtol(pc, &pend, base);
01161 
01162     /* Raise ValueError if there was a conversion error */
01163     if (*pend != C_NULL)
01164     {
01165         PM_RAISE(retval, PM_RET_EX_VAL);
01166         return retval;
01167     }
01168 
01169     /* Create an int object to hold the result of the conversion */
01170     retval = int_new(i, &pi);
01171 
01172     NATIVE_SET_TOS(pi);
01173 
01174     return retval;
01175     
01176 }
01177 
01178 PmReturn_t
01179 nat_25_string_count(pPmFrame_t *ppframe)
01180 {
01181 
01182     pPmObj_t ps1;
01183     pPmObj_t ps2;
01184     uint8_t *pc1;
01185     uint8_t *pc2;
01186     uint8_t *pscan;
01187     uint8_t *pmatch;
01188     uint8_t pc2c0;
01189     uint16_t pc1len;
01190     uint16_t pc2len;
01191     uint16_t n;
01192     uint16_t remaining;
01193     uint16_t cmp;
01194     pPmObj_t pn;
01195     PmReturn_t retval = PM_RET_OK;
01196 
01197     /* Raise TypeError if it's not a string or wrong number of args, */
01198     ps1 = NATIVE_GET_LOCAL(0);
01199     ps2 = NATIVE_GET_LOCAL(1);
01200     if ((OBJ_GET_TYPE(ps1) != OBJ_TYPE_STR) || (NATIVE_GET_NUM_ARGS() != 2)
01201         || (OBJ_GET_TYPE(ps2) != OBJ_TYPE_STR))
01202     {
01203         PM_RAISE(retval, PM_RET_EX_TYPE);
01204         return retval;
01205     }
01206 
01207     pc1 = ((pPmString_t)ps1)->val;
01208     pc2 = ((pPmString_t)ps2)->val;
01209     pc1len = ((pPmString_t)ps1)->length;
01210     pc2len = ((pPmString_t)ps2)->length;
01211     n = 0;
01212 
01213     /* Handle some quick special cases (order of if-clauses is important) */
01214     if (pc2len == 0)
01215     {
01216         n = pc1len + 1;
01217     }
01218     else if (pc1len == 0)
01219     {
01220         n = 0;
01221     }
01222 
01223     /* Count the number of matches */
01224     else
01225     {
01226         n = 0;
01227         remaining = pc1len;
01228         pscan = pc1;
01229         pc2c0 = pc2[0];
01230         while (pscan <= (pc1 + (pc1len - pc2len)))
01231         {
01232             /* Find the next possible start */
01233             pmatch = (uint8_t *)memchr(pscan, pc2c0, remaining);
01234             if (pmatch == C_NULL) break;
01235             remaining -= (pmatch - pscan);
01236             pscan = pmatch;
01237 
01238             /* If it matches, increase the count, else try the next char */
01239             cmp = memcmp(pscan, pc2, pc2len);
01240             if (cmp == 0)
01241             {
01242                 n++;
01243                 pscan += pc2len;
01244                 remaining -= pc2len;
01245             }
01246             else
01247             {
01248                 pscan++;
01249                 remaining--;
01250             }
01251         }
01252     }
01253 
01254     retval = int_new(n, &pn);
01255 
01256     NATIVE_SET_TOS(pn);
01257 
01258     return retval;
01259     
01260 }
01261 
01262 PmReturn_t
01263 nat_26_string_find(pPmFrame_t *ppframe)
01264 {
01265 
01266     pPmObj_t ps1;
01267     pPmObj_t ps2;
01268     uint8_t *pc1;
01269     uint8_t *pc2;
01270     uint8_t *pmatch;
01271     uint16_t pc1len;
01272     uint16_t pc2len;
01273     int32_t n;
01274     pPmObj_t pn;
01275     PmReturn_t retval = PM_RET_OK;
01276 
01277     /* Raise TypeError if it's not a string or wrong number of args, */
01278     ps1 = NATIVE_GET_LOCAL(0);
01279     ps2 = NATIVE_GET_LOCAL(1);
01280     if ((OBJ_GET_TYPE(ps1) != OBJ_TYPE_STR) || (NATIVE_GET_NUM_ARGS() != 2)
01281         || (OBJ_GET_TYPE(ps2) != OBJ_TYPE_STR))
01282     {
01283         PM_RAISE(retval, PM_RET_EX_TYPE);
01284         return retval;
01285     }
01286 
01287     pc1 = ((pPmString_t)ps1)->val;
01288     pc2 = ((pPmString_t)ps2)->val;
01289     pc1len = ((pPmString_t)ps1)->length;
01290     pc2len = ((pPmString_t)ps2)->length;
01291     n = -1;
01292 
01293     /* Handle a quick special case */
01294     if (pc2len == 0)
01295     {
01296         n = 0;
01297     }
01298 
01299     /* Try to find the index of the substring */
01300     else
01301     {
01302         /* Find the next possible start */
01303         pmatch = (uint8_t *)memchr(pc1, pc2[0], pc1len);
01304         if (pmatch != C_NULL)
01305         {
01306             /* If it matches, calculate the index */
01307             if (memcmp(pmatch, pc2, pc2len) == 0)
01308             {
01309                 n = pmatch - pc1;
01310             }
01311         }
01312     }
01313 
01314     retval = int_new(n, &pn);
01315 
01316     NATIVE_SET_TOS(pn);
01317 
01318     return retval;
01319     
01320 }
01321 
01322 PmReturn_t
01323 nat_27_sys_exit(pPmFrame_t *ppframe)
01324 {
01325 
01326     pPmObj_t pval = C_NULL;
01327     PmReturn_t retval;
01328 
01329     /* If no arg given, assume return 0 */
01330     if (NATIVE_GET_NUM_ARGS() == 0)
01331     {
01332         NATIVE_SET_TOS(PM_ZERO);
01333     }
01334 
01335     /* If 1 arg given, put it on stack */
01336     else if (NATIVE_GET_NUM_ARGS() == 1)
01337     {
01338         pval = NATIVE_GET_LOCAL(0);
01339         NATIVE_SET_TOS(pval);
01340     }
01341 
01342     /* If wrong number of args, raise TypeError */
01343     else
01344     {
01345         PM_RAISE(retval, PM_RET_EX_TYPE);
01346         return retval;
01347     }
01348 
01349     /* Raise the SystemExit exception */
01350     PM_RAISE(retval, PM_RET_EX_EXIT);
01351     return retval;
01352     
01353 }
01354 
01355 PmReturn_t
01356 nat_28_sys_gc(pPmFrame_t *ppframe)
01357 {
01358 
01359     PmReturn_t retval = PM_RET_OK;
01360 #ifdef HAVE_GC
01361     /* If wrong number of args, raise TypeError */
01362     if (NATIVE_GET_NUM_ARGS() != 0)
01363     {
01364         PM_RAISE(retval, PM_RET_EX_TYPE);
01365         return retval;
01366     }
01367 
01368     retval = heap_gcRun();
01369 #endif
01370     NATIVE_SET_TOS(PM_NONE);
01371 
01372     return retval;
01373     
01374 }
01375 
01376 PmReturn_t
01377 nat_29_sys_getb(pPmFrame_t *ppframe)
01378 {
01379 
01380     uint8_t b;
01381     pPmObj_t pb;
01382     PmReturn_t retval;
01383 
01384     /* If wrong number of args, raise TypeError */
01385     if (NATIVE_GET_NUM_ARGS() != 0)
01386     {
01387         PM_RAISE(retval, PM_RET_EX_TYPE);
01388         return retval;
01389     }
01390 
01391     retval = plat_getByte(&b);
01392     PM_RETURN_IF_ERROR(retval);
01393 
01394     retval = int_new((int32_t)b, &pb);
01395     NATIVE_SET_TOS(pb);
01396     return retval;
01397     
01398 }
01399 
01400 PmReturn_t
01401 nat_30_sys_heap(pPmFrame_t *ppframe)
01402 {
01403 
01404     PmReturn_t retval;
01405     pPmObj_t pavail;
01406     pPmObj_t psize;
01407     pPmObj_t ptup;
01408     uint8_t objid;
01409 
01410     /* If wrong number of args, raise TypeError */
01411     if (NATIVE_GET_NUM_ARGS() != 0)
01412     {
01413         PM_RAISE(retval, PM_RET_EX_TYPE);
01414         return retval;
01415     }
01416 
01417     /* Allocate a tuple to store the return values */
01418     retval = tuple_new(2, &ptup);
01419     PM_RETURN_IF_ERROR(retval);
01420 
01421     /* Get the maximum heap size */
01422     heap_gcPushTempRoot(ptup, &objid);
01423     retval = int_new(heap_getSize (), &psize);
01424     if (retval != PM_RET_OK)
01425     {
01426         heap_gcPopTempRoot(objid);
01427         return retval;
01428     }
01429 
01430     /* Allocate an int to hold the amount of heap available */
01431     retval = int_new(heap_getAvail () - sizeof(PmInt_t), &pavail);
01432     heap_gcPopTempRoot(objid);
01433     PM_RETURN_IF_ERROR(retval);
01434 
01435     /* Put the two heap values in the tuple */
01436     ((pPmTuple_t)ptup)->val[0] = pavail;
01437     ((pPmTuple_t)ptup)->val[1] = psize;
01438 
01439     /* Return the tuple on the stack */
01440     NATIVE_SET_TOS(ptup);
01441 
01442     return retval;
01443     
01444 }
01445 
01446 PmReturn_t
01447 nat_31_sys_putb(pPmFrame_t *ppframe)
01448 {
01449 
01450     uint8_t b;
01451     pPmObj_t pb;
01452     PmReturn_t retval;
01453 
01454     pb = NATIVE_GET_LOCAL(0);
01455 
01456     /* If wrong number of args, raise TypeError */
01457     if (NATIVE_GET_NUM_ARGS() != 1)
01458     {
01459         PM_RAISE(retval, PM_RET_EX_TYPE);
01460         return retval;
01461     }
01462 
01463     /* If arg is not an int, raise TypeError */
01464     if (OBJ_GET_TYPE(pb) != OBJ_TYPE_INT)
01465     {
01466         PM_RAISE(retval, PM_RET_EX_TYPE);
01467         return retval;
01468     }
01469 
01470     b = ((pPmInt_t)pb)->val & 0xFF;
01471     retval = plat_putByte(b);
01472     NATIVE_SET_TOS(PM_NONE);
01473     return retval;
01474     
01475 }
01476 
01477 PmReturn_t
01478 nat_32_sys_runInThread(pPmFrame_t *ppframe)
01479 {
01480 
01481     PmReturn_t retval;
01482     pPmObj_t pf;
01483 
01484     /* If wrong number of args, raise TypeError */
01485     if (NATIVE_GET_NUM_ARGS() != 1)
01486     {
01487         PM_RAISE(retval, PM_RET_EX_TYPE);
01488         return retval;
01489     }
01490 
01491     /* If arg is not a function, raise TypeError */
01492     pf = NATIVE_GET_LOCAL(0);
01493     if (OBJ_GET_TYPE(pf) != OBJ_TYPE_FXN)
01494     {
01495         PM_RAISE(retval, PM_RET_EX_TYPE);
01496         return retval;
01497     }
01498 
01499     retval = interp_addThread((pPmFunc_t)pf);
01500     NATIVE_SET_TOS(PM_NONE);
01501     return retval;
01502     
01503 }
01504 
01505 PmReturn_t
01506 nat_33_sys_time(pPmFrame_t *ppframe)
01507 {
01508 
01509     uint32_t t;
01510     pPmObj_t pt;
01511     PmReturn_t retval;
01512 
01513     /* If wrong number of args, raise TypeError */
01514     if (NATIVE_GET_NUM_ARGS() != 0)
01515     {
01516         PM_RAISE(retval, PM_RET_EX_TYPE);
01517         return retval;
01518     }
01519 
01520     /* Get the system time (milliseconds since init) */
01521     retval = plat_getMsTicks(&t);
01522     PM_RETURN_IF_ERROR(retval);
01523 
01524     /*
01525      * Raise ValueError if there is an overflow
01526      * (plat_getMsTicks is unsigned; int is signed)
01527      */
01528     if ((int32_t)t < 0)
01529     {
01530         PM_RAISE(retval, PM_RET_EX_VAL);
01531         return retval;
01532     }
01533 
01534     /* Return an int object with the time value */
01535     retval = int_new((int32_t)t, &pt);
01536     NATIVE_SET_TOS(pt);
01537     return retval;
01538     
01539 }
01540 
01541 PmReturn_t
01542 nat_34_ipm__getImg(pPmFrame_t *ppframe)
01543 {
01544 
01545     PmReturn_t retval;
01546     uint8_t imgType;
01547     uint16_t imgSize;
01548     uint8_t *pchunk;
01549     pPmCodeImgObj_t pimg;
01550     uint16_t i;
01551     uint8_t b;
01552 
01553     /* Get the image type */
01554     retval = plat_getByte(&imgType);
01555     PM_RETURN_IF_ERROR(retval);
01556 
01557     /* Quit if a code image type was not received */
01558     if (imgType != OBJ_TYPE_CIM)
01559     {
01560         PM_RAISE(retval, PM_RET_EX_STOP);
01561         return retval;
01562     }
01563 
01564     /* Get the image size (little endien) */
01565     retval = plat_getByte(&b);
01566     PM_RETURN_IF_ERROR(retval);
01567     imgSize = b;
01568     retval = plat_getByte(&b);
01569     PM_RETURN_IF_ERROR(retval);
01570     imgSize |= (b << 8);
01571 
01572     /* Get space for CodeImgObj */
01573     retval = heap_getChunk(sizeof(PmCodeImgObj_t) + imgSize, &pchunk);
01574     PM_RETURN_IF_ERROR(retval);
01575     pimg = (pPmCodeImgObj_t)pchunk;
01576     OBJ_SET_TYPE(pimg, OBJ_TYPE_CIO);
01577 
01578     /* Start the image with the bytes that have already been received */
01579     i = 0;
01580     pimg->val[i++] = imgType;
01581     pimg->val[i++] = imgSize & 0xFF;
01582     pimg->val[i++] = (imgSize >> 8) & 0xFF;
01583 
01584     /* Get the remaining bytes in the image */
01585     for(; i < imgSize; i++)
01586     {
01587         retval = plat_getByte(&b);
01588         PM_RETURN_IF_ERROR(retval);
01589 
01590         pimg->val[i] = b;
01591     }
01592 
01593     /* Return the image as a code image object on the stack */
01594     NATIVE_SET_TOS((pPmObj_t)pimg);
01595     return retval;
01596     
01597 }
01598 
01599 PmReturn_t
01600 nat_35_ipm_x04(pPmFrame_t *ppframe)
01601 {
01602 
01603     NATIVE_SET_TOS(PM_NONE);
01604     return plat_putByte(0x04);
01605     
01606 }
01607 
01608 /* Native function lookup table */
01609 pPmNativeFxn_t const std_nat_fxn_table[] =
01610 {
01611     nat_00___bi_chr,
01612     nat_01___bi_dir,
01613     nat_02___bi_eval,
01614     nat_03___bi_globals,
01615     nat_04___bi_id,
01616     nat_05___bi_len,
01617     nat_06___bi_locals,
01618     nat_07___bi_ord,
01619     nat_08___bi_range,
01620     nat_09___bi_sum,
01621     nat_10___bi_type,
01622     nat_11___bi_Co,
01623     nat_12___bi___init__,
01624     nat_13___bi_send,
01625     nat_14___bi_ismain,
01626     nat_15_dict_clear,
01627     nat_16_dict_keys,
01628     nat_17_dict_values,
01629     nat_18_dict_update,
01630     nat_19_list_append,
01631     nat_20_list_index,
01632     nat_21_list_insert,
01633     nat_22_list_pop,
01634     nat_23_list_remove,
01635     nat_24_string_atoi,
01636     nat_25_string_count,
01637     nat_26_string_find,
01638     nat_27_sys_exit,
01639     nat_28_sys_gc,
01640     nat_29_sys_getb,
01641     nat_30_sys_heap,
01642     nat_31_sys_putb,
01643     nat_32_sys_runInThread,
01644     nat_33_sys_time,
01645     nat_34_ipm__getImg,
01646     nat_35_ipm_x04,
01647 };