__bi.py

Go to the documentation of this file.
00001 # This file is Copyright 2003, 2006, 2007, 2009, 2010 Dean Hall.
00002 #
00003 # This file is part of the Python-on-a-Chip program.
00004 # Python-on-a-Chip is free software: you can redistribute it and/or modify
00005 # it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE Version 2.1.
00006 #
00007 # Python-on-a-Chip is distributed in the hope that it will be useful,
00008 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00009 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00010 # A copy of the GNU LESSER GENERAL PUBLIC LICENSE Version 2.1
00011 # is seen in the file COPYING in this directory.
00012 
00013 ## @file
00014 #  @copybrief __bi
00015 
00016 ## @package __bi
00017 #  @brief Provides PyMite's builtins module, __bi.
00018 #
00019 #  <b>USAGE</b>
00020 #
00021 #  The builtins are loaded by the interpreter.
00022 #  The user SHOULD NOT import this module directly.
00023 
00024 
00025 def abs(n):
00026 #    return n > 0 and n or -n
00027     return (n, -n)[n < 0]
00028 
00029 
00030 def chr(n):
00031     """__NATIVE__
00032     pPmObj_t ps;
00033     pPmObj_t pn;
00034     int32_t n;
00035     PmReturn_t retval;
00036 
00037     /* If wrong number of args, raise TypeError */
00038     if (NATIVE_GET_NUM_ARGS() != 1)
00039     {
00040         PM_RAISE(retval, PM_RET_EX_TYPE);
00041         return retval;
00042     }
00043 
00044     /* Raise TypeError if arg is not an int */
00045     pn = NATIVE_GET_LOCAL(0);
00046     if (OBJ_GET_TYPE(pn) != OBJ_TYPE_INT)
00047     {
00048         PM_RAISE(retval, PM_RET_EX_TYPE);
00049         return retval;
00050     }
00051 
00052     /* Raise ValueError if arg is not int within range(256) */
00053     n = ((pPmInt_t)pn)->val;
00054     if ((n < 0) || (n > 255))
00055     {
00056         PM_RAISE(retval, PM_RET_EX_VAL);
00057         return retval;
00058     }
00059 
00060     /* Create char string from  integer value */
00061     retval = string_newFromChar((uint8_t)n, &ps);
00062     NATIVE_SET_TOS(ps);
00063     return retval;
00064     """
00065     pass
00066 
00067 
00068 def dir(o):
00069     """__NATIVE__
00070     PmReturn_t retval = PM_RET_OK;
00071     pPmObj_t po;
00072     pPmObj_t pk;
00073     pPmObj_t pl;
00074     pSeglist_t psl;
00075     int16_t i;
00076     uint8_t objid;
00077 
00078     /* Use globals if no arg given */
00079     if (NATIVE_GET_NUM_ARGS() == 0)
00080     {
00081         /* Get the globals dict */
00082         po = (pPmObj_t)NATIVE_GET_PFRAME()->fo_globals;
00083     }
00084 
00085     /* Otherwise use the given arg */
00086     else if (NATIVE_GET_NUM_ARGS() == 1)
00087     {
00088         po = NATIVE_GET_LOCAL(0);
00089 
00090         /* If object is a function or module, use its attrs dict */
00091         if ((OBJ_GET_TYPE(po) == OBJ_TYPE_FXN)
00092             || (OBJ_GET_TYPE(po) == OBJ_TYPE_MOD))
00093         {
00094             po = (pPmObj_t)((pPmFunc_t)po)->f_attrs;
00095         }
00096 
00097 #ifdef HAVE_CLASSES
00098         else if (OBJ_GET_TYPE(po) == OBJ_TYPE_CLO)
00099         {
00100             po = (pPmObj_t)((pPmClass_t)po)->cl_attrs;
00101         }
00102         else if (OBJ_GET_TYPE(po) == OBJ_TYPE_CLI)
00103         {
00104             po = (pPmObj_t)((pPmInstance_t)po)->cli_attrs;
00105         }
00106         else if (OBJ_GET_TYPE(po) == OBJ_TYPE_MTH)
00107         {
00108             po = (pPmObj_t)((pPmMethod_t)po)->m_attrs;
00109         }
00110 #endif /* HAVE_CLASSES */
00111 
00112         else
00113         {
00114             po = C_NULL;
00115         }
00116     }
00117 
00118     /* Raise TypeError if wrong number of args */
00119     else
00120     {
00121         PM_RAISE(retval, PM_RET_EX_TYPE);
00122         return retval;
00123     }
00124 
00125     if (po == C_NULL)
00126     {
00127         pl = PM_NONE;
00128     }
00129     else
00130     {
00131         /* Create new list */
00132         retval = list_new(&pl);
00133         PM_RETURN_IF_ERROR(retval);
00134 
00135         /* Copy dict's keys to the list */
00136         psl = ((pPmDict_t)po)->d_keys;
00137         for (i = 0; i < ((pPmDict_t)po)->length; i++)
00138         {
00139             retval = seglist_getItem(psl, i, &pk);
00140             PM_RETURN_IF_ERROR(retval);
00141             heap_gcPushTempRoot(pl, &objid);
00142             retval = list_append(pl, pk);
00143             heap_gcPopTempRoot(objid);
00144             PM_RETURN_IF_ERROR(retval);
00145         }
00146     }
00147 
00148     NATIVE_SET_TOS(pl);
00149     return retval;
00150     """
00151     pass
00152 
00153 
00154 #
00155 # Evaluates a given code object (created by Co()).
00156 # Optionally accepts a globals dict as the second parameter
00157 # Optionally accepts a locals dict as the third parameter
00158 #
00159 def eval(co, g, l):
00160     """__NATIVE__
00161     PmReturn_t retval;
00162     pPmObj_t pco;
00163     pPmObj_t pfunc;
00164     pPmObj_t pnewframe;
00165     pPmObj_t pg = C_NULL;
00166     pPmObj_t pl = C_NULL;
00167     uint8_t objid;
00168 
00169     /* If wrong number of args, raise TypeError */
00170     if ((NATIVE_GET_NUM_ARGS() == 0) || (NATIVE_GET_NUM_ARGS() > 3))
00171     {
00172         PM_RAISE(retval, PM_RET_EX_TYPE);
00173         return retval;
00174     }
00175 
00176     /* Raise ValueError if first arg is not a Code Object */
00177     pco = NATIVE_GET_LOCAL(0);
00178     if (OBJ_GET_TYPE(pco) != OBJ_TYPE_COB)
00179     {
00180         PM_RAISE(retval, PM_RET_EX_VAL);
00181         return retval;
00182     }
00183 
00184     /* If 2nd arg exists, raise ValueError if it is not a Dict */
00185     if (NATIVE_GET_NUM_ARGS() >= 2)
00186     {
00187         pg = NATIVE_GET_LOCAL(1);
00188         if (OBJ_GET_TYPE(pg) != OBJ_TYPE_DIC)
00189         {
00190             PM_RAISE(retval, PM_RET_EX_VAL);
00191             return retval;
00192         }
00193     }
00194 
00195     /* If no args are given, use the caller's globals for the function's */
00196     else
00197     {
00198         pg = (pPmObj_t)NATIVE_GET_PFRAME()->fo_globals;
00199     }
00200 
00201     /* If 3rd arg exists, raise ValueError if it is not a Dict */
00202     if (NATIVE_GET_NUM_ARGS() >= 3)
00203     {
00204         pl = NATIVE_GET_LOCAL(2);
00205         if (OBJ_GET_TYPE(pl) != OBJ_TYPE_DIC)
00206         {
00207             PM_RAISE(retval, PM_RET_EX_VAL);
00208             return retval;
00209         }
00210     }
00211 
00212     /* Create func from code object */
00213     retval = func_new(pco, pg, &pfunc);
00214     PM_RETURN_IF_ERROR(retval);
00215 
00216     /* Create frame from module object; globals is set to null */
00217     heap_gcPushTempRoot(pfunc, &objid);
00218     retval = frame_new(pfunc, &pnewframe);
00219     heap_gcPopTempRoot(objid);
00220     PM_RETURN_IF_ERROR(retval);
00221 
00222     /* TODO: Reclaim pnewframe's attrs dict created in frame_new */
00223     /*
00224      * By default use calling frame's attrs as local namespace.
00225      * This works for ipm because the interactive mode
00226      * needs a locals namespace that persists across calls to eval()
00227      */
00228     ((pPmFrame_t)pnewframe)->fo_attrs = NATIVE_GET_PFRAME()->fo_attrs;
00229 
00230     /* If 2nd arg exists, use it as the global namespace for the new func */
00231     if (NATIVE_GET_NUM_ARGS() >= 2)
00232     {
00233         ((pPmFrame_t)pnewframe)->fo_globals = (pPmDict_t)pg;
00234 
00235         /* If only globals is given, locals defaults to it */
00236         ((pPmFrame_t)pnewframe)->fo_attrs = (pPmDict_t)pg;
00237     }
00238 
00239     /* If 3rd arg exists, use it as the local namespace for the new func */
00240     if (NATIVE_GET_NUM_ARGS() >= 3)
00241     {
00242         ((pPmFrame_t)pnewframe)->fo_attrs = (pPmDict_t)pl;
00243     }
00244 
00245     /*
00246      * Set the fo_back frame so flow returns to eval()'s caller when completed.
00247      * Set the frame pointer so the new frame is interpreted immediately
00248      * after this function returns.
00249      */
00250     ((pPmFrame_t)pnewframe)->fo_back = NATIVE_GET_PFRAME();
00251     NATIVE_GET_PFRAME() = (pPmFrame_t)pnewframe;
00252     retval = PM_RET_FRAME_SWITCH;
00253 
00254     return retval;
00255     """
00256     pass
00257 
00258 
00259 def filter(f, s):
00260     return [x for x in s if f(x)]
00261 
00262 
00263 def globals():
00264     """__NATIVE__
00265     pPmObj_t pr = C_NULL;
00266     PmReturn_t retval;
00267 
00268     /* If wrong number of args, raise TypeError */
00269     if (NATIVE_GET_NUM_ARGS() != 0)
00270     {
00271         PM_RAISE(retval, PM_RET_EX_TYPE);
00272         return retval;
00273     }
00274 
00275     /* Return calling frame's globals dict  on stack*/
00276     pr = (pPmObj_t)NATIVE_GET_PFRAME()->fo_globals;
00277     NATIVE_SET_TOS(pr);
00278 
00279     return PM_RET_OK;
00280     """
00281     pass
00282 
00283 
00284 def id(o):
00285     """__NATIVE__
00286     PmReturn_t retval;
00287     pPmObj_t pr = C_NULL;
00288 
00289     /* If wrong number of args, raise TypeError */
00290     if (NATIVE_GET_NUM_ARGS() != 1)
00291     {
00292         PM_RAISE(retval, PM_RET_EX_TYPE);
00293         return retval;
00294     }
00295 
00296     /* Return object's address as an int on the stack */
00297     retval = int_new((intptr_t)NATIVE_GET_LOCAL(0), &pr);
00298     NATIVE_SET_TOS(pr);
00299 
00300     return retval;
00301     """
00302     pass
00303 
00304 
00305 # Yields every (i)tem in the (s)equence; requires HAVE_GENERATORS
00306 #def iter(s):
00307 #    for i in s:
00308 #        yield i
00309 
00310 
00311 def len(s):
00312     """__NATIVE__
00313     PmReturn_t retval;
00314     pPmObj_t ps = C_NULL;
00315     pPmObj_t pr = C_NULL;
00316 
00317     /* If wrong number of args, raise TypeError */
00318     if (NATIVE_GET_NUM_ARGS() != 1)
00319     {
00320         PM_RAISE(retval, PM_RET_EX_TYPE);
00321         return retval;
00322     }
00323 
00324     /* Get first arg */
00325     ps = NATIVE_GET_LOCAL(0);
00326 
00327 #ifdef HAVE_BYTEARRAY
00328     /* If object is an instance, get the thing it contains */
00329     if (OBJ_GET_TYPE(ps) == OBJ_TYPE_CLI)
00330     {
00331         retval = dict_getItem((pPmObj_t)((pPmInstance_t)ps)->cli_attrs,
00332                               PM_NONE,
00333                               &pr);
00334 
00335         /* If None wasn't in attributes, obj is wrong type for len() */
00336         if (retval == PM_RET_EX_KEY) retval = PM_RET_EX_TYPE;
00337         PM_RETURN_IF_ERROR(retval);
00338         ps = pr;
00339     }
00340 #endif /* HAVE_BYTEARRAY */
00341 
00342     /* Get the length of the arg based on its type */
00343     switch (OBJ_GET_TYPE(ps))
00344     {
00345         case OBJ_TYPE_STR:
00346             retval = int_new(((pPmString_t)ps)->length, &pr);
00347             break;
00348 
00349         case OBJ_TYPE_TUP:
00350             retval = int_new(((pPmTuple_t)ps)->length, &pr);
00351             break;
00352 
00353         case OBJ_TYPE_LST:
00354             retval = int_new(((pPmList_t)ps)->length, &pr);
00355             break;
00356 
00357         case OBJ_TYPE_DIC:
00358             retval = int_new(((pPmDict_t)ps)->length, &pr);
00359             break;
00360 
00361 #ifdef HAVE_BYTEARRAY
00362         case OBJ_TYPE_BYA:
00363             retval = int_new(((pPmBytearray_t)ps)->length, &pr);
00364             break;
00365 #endif /* HAVE_BYTEARRAY */
00366 
00367         default:
00368             /* If not a string or sequence type, raise TypeError */
00369             PM_RAISE(retval, PM_RET_EX_TYPE);
00370     }
00371 
00372     NATIVE_SET_TOS(pr);
00373     return retval;
00374     """
00375     pass
00376 
00377 
00378 def locals():
00379     """__NATIVE__
00380     pPmObj_t pr = C_NULL;
00381     PmReturn_t retval;
00382 
00383     /* If wrong number of args, raise TypeError */
00384     if (NATIVE_GET_NUM_ARGS() != 0)
00385     {
00386         PM_RAISE(retval, PM_RET_EX_TYPE);
00387         return retval;
00388     }
00389 
00390     /* Return calling frame's local attrs dict on the stack */
00391     pr = (pPmObj_t)NATIVE_GET_PFRAME()->fo_attrs;
00392     NATIVE_SET_TOS(pr);
00393 
00394     return PM_RET_OK;
00395     """
00396     pass
00397 
00398 
00399 def map(f, s):
00400     # Allocate the array
00401     r = [None,] * len(s)
00402 
00403     # Call function f once with each argument in sequence s
00404     i = 0
00405     for a in s:
00406         r[i] = f(a)
00407         i += 1
00408 
00409     # Return list of results
00410     return r
00411 
00412 
00413 def ord(s):
00414     """__NATIVE__
00415     pPmObj_t ps;
00416     pPmObj_t pn;
00417     int32_t n;
00418     PmReturn_t retval;
00419 
00420     /* If wrong number of args, raise TypeError */
00421     if (NATIVE_GET_NUM_ARGS() != 1)
00422     {
00423         PM_RAISE(retval, PM_RET_EX_TYPE);
00424         return retval;
00425     }
00426 
00427     ps = NATIVE_GET_LOCAL(0);
00428 
00429     /* Raise TypeError if arg is not string of length 1 */
00430     if ((OBJ_GET_TYPE(ps) != OBJ_TYPE_STR)
00431         || (((pPmString_t)ps)->length != 1))
00432 
00433     {
00434         PM_RAISE(retval, PM_RET_EX_TYPE);
00435         return retval;
00436     }
00437 
00438     /* Get integer value of character */
00439     n = ((pPmString_t)ps)->val[0];
00440     retval = int_new(n, &pn);
00441     NATIVE_SET_TOS(pn);
00442     return retval;
00443     """
00444     pass
00445 
00446 
00447 def pow(x, y):
00448     return x ** y
00449 
00450 
00451 def range(a, b, c):
00452     """__NATIVE__
00453     PmReturn_t retval;
00454     pPmObj_t pa = C_NULL;
00455     pPmObj_t pb = C_NULL;
00456     pPmObj_t pc = C_NULL;
00457     pPmObj_t pi = C_NULL;
00458     pPmObj_t pr = C_NULL;
00459     int16_t i = 0;
00460     uint8_t objid1, objid2;
00461 
00462     switch (NATIVE_GET_NUM_ARGS())
00463     {
00464         case 1:
00465             pa = PM_ZERO;
00466             pb = NATIVE_GET_LOCAL(0);
00467             pc = PM_ONE;
00468             break;
00469 
00470         case 2:
00471             pa = NATIVE_GET_LOCAL(0);
00472             pb = NATIVE_GET_LOCAL(1);
00473             pc = PM_ONE;
00474             break;
00475 
00476         case 3:
00477             pa = NATIVE_GET_LOCAL(0);
00478             pb = NATIVE_GET_LOCAL(1);
00479             pc = NATIVE_GET_LOCAL(2);
00480 
00481             /* If 3rd arg is 0, ValueError */
00482             if (((pPmInt_t)pc)->val == 0)
00483             {
00484                 PM_RAISE(retval, PM_RET_EX_VAL);
00485                 return retval;
00486             }
00487             break;
00488 
00489         default:
00490             /* If wrong number of args, raise TypeError */
00491             PM_RAISE(retval, PM_RET_EX_TYPE);
00492             return retval;
00493     }
00494 
00495     /* Allocate list */
00496     retval = list_new(&pr);
00497     PM_RETURN_IF_ERROR(retval);
00498 
00499     /* Iterate depending on counting direction */
00500     if (((pPmInt_t)pc)->val > 0)
00501     {
00502         for (i = ((pPmInt_t)pa)->val;
00503              i < ((pPmInt_t)pb)->val;
00504              i += ((pPmInt_t)pc)->val)
00505         {
00506             heap_gcPushTempRoot(pr, &objid1);
00507             retval = int_new(i, &pi);
00508             if (retval != PM_RET_OK)
00509             {
00510                 heap_gcPopTempRoot(objid1);
00511                 return retval;
00512             }
00513 
00514             heap_gcPushTempRoot(pi, &objid2);
00515             retval = list_append(pr, pi);
00516             heap_gcPopTempRoot(objid1);
00517             PM_RETURN_IF_ERROR(retval);
00518         }
00519     }
00520     else
00521     {
00522         for (i = ((pPmInt_t)pa)->val;
00523              i > ((pPmInt_t)pb)->val;
00524              i += ((pPmInt_t)pc)->val)
00525         {
00526             heap_gcPushTempRoot(pr, &objid1);
00527             retval = int_new(i, &pi);
00528             if (retval != PM_RET_OK)
00529             {
00530                 heap_gcPopTempRoot(objid1);
00531                 return retval;
00532             }
00533 
00534             heap_gcPushTempRoot(pi, &objid2);
00535             retval = list_append(pr, pi);
00536             heap_gcPopTempRoot(objid1);
00537             PM_RETURN_IF_ERROR(retval);
00538         }
00539     }
00540 
00541     /* Return list */
00542     NATIVE_SET_TOS(pr);
00543     return retval;
00544     """
00545     pass
00546 
00547 
00548 def sum(s):
00549     """__NATIVE__
00550     pPmObj_t ps;
00551     pPmObj_t pn;
00552     pPmObj_t po;
00553     int32_t n;
00554     uint16_t len;
00555     uint16_t i;
00556     PmReturn_t retval;
00557 #ifdef HAVE_FLOAT
00558     float f;
00559     uint8_t usefloat = C_FALSE;
00560 #endif /* HAVE_FLOAT */
00561 
00562     /* If wrong number of args, raise TypeError */
00563     if (NATIVE_GET_NUM_ARGS() != 1)
00564     {
00565         PM_RAISE(retval, PM_RET_EX_TYPE);
00566         return retval;
00567     }
00568 
00569     /* Get the length of the sequence */
00570     ps = NATIVE_GET_LOCAL(0);
00571     if (OBJ_GET_TYPE(ps) == OBJ_TYPE_TUP)
00572     {
00573         len = ((pPmTuple_t)ps)->length;
00574     }
00575     else if (OBJ_GET_TYPE(ps) == OBJ_TYPE_LST)
00576     {
00577         len = ((pPmList_t)ps)->length;
00578     }
00579 
00580     /* Raise TypeError if arg is not a sequence */
00581     else
00582     {
00583         PM_RAISE(retval, PM_RET_EX_TYPE);
00584         return retval;
00585     }
00586 
00587     /* Calculate the sum of the sequence */
00588     n = 0;
00589 #ifdef HAVE_FLOAT
00590     f = 0.0;
00591 #endif
00592     for (i = 0; i < len; i++)
00593     {
00594         retval = seq_getSubscript(ps, i, &po);
00595 
00596         if (OBJ_GET_TYPE(po) == OBJ_TYPE_INT)
00597         {
00598             /* Add value to sum */
00599             n += ((pPmInt_t)po)->val;
00600 #ifdef HAVE_FLOAT
00601             f += (float)((pPmInt_t)po)->val;
00602 #endif /* HAVE_FLOAT */
00603         }
00604 
00605 #ifdef HAVE_FLOAT
00606         else if (OBJ_GET_TYPE(po) == OBJ_TYPE_FLT)
00607         {
00608             /* Add value to sum */
00609             f += ((pPmFloat_t)po)->val;
00610             usefloat = C_TRUE;
00611         }
00612 #endif /* HAVE_FLOAT */
00613 
00614         /* Raise TypeError if item is not an integer */
00615         else
00616         {
00617             PM_RAISE(retval, PM_RET_EX_TYPE);
00618             return retval;
00619         }
00620     }
00621 
00622 #ifdef HAVE_FLOAT
00623     if (usefloat)
00624     {
00625         retval = float_new(f, &pn);
00626     }
00627     else
00628 #endif /* HAVE_FLOAT */
00629     {
00630         retval = int_new(n, &pn);
00631     }
00632     NATIVE_SET_TOS(pn);
00633     return retval;
00634     """
00635     pass
00636 
00637 
00638 def type(o):
00639     """__NATIVE__
00640     PmReturn_t retval;
00641     pPmObj_t po = C_NULL;
00642     pPmObj_t pr = C_NULL;
00643 
00644     /* If wrong number of args, raise TypeError */
00645     if (NATIVE_GET_NUM_ARGS() != 1)
00646     {
00647         PM_RAISE(retval, PM_RET_EX_TYPE);
00648         return retval;
00649     }
00650 
00651     /* Get arg */
00652     po = NATIVE_GET_LOCAL(0);
00653 
00654     /* Create int from type enum */
00655     retval = int_new(OBJ_GET_TYPE(po), &pr);
00656     NATIVE_SET_TOS(pr);
00657     return retval;
00658     """
00659     pass
00660 
00661 
00662 # At this time, xrange() works in a for loop, but not in a generator expression
00663 # Yes: for i in xrange(42): pass
00664 # No:  [x for x in xrange(42)]
00665 #def xrange(n):
00666 #    i = 0
00667 #    while i < n:
00668 #        yield i
00669 #        i += 1
00670 
00671 
00672 #
00673 # Creates a code object from the given image string
00674 #
00675 def Co(i):
00676     """__NATIVE__
00677     PmReturn_t retval;
00678     pPmObj_t pimg;
00679     pPmObj_t pco;
00680 
00681     /* If wrong number of args, raise TypeError */
00682     if (NATIVE_GET_NUM_ARGS() != 1)
00683     {
00684         PM_RAISE(retval, PM_RET_EX_TYPE);
00685         return retval;
00686     }
00687 
00688     /* Raise ValueError if arg is not a string */
00689     pimg = NATIVE_GET_LOCAL(0);
00690     if (OBJ_GET_TYPE(pimg) != OBJ_TYPE_CIO)
00691     {
00692         PM_RAISE(retval, PM_RET_EX_VAL);
00693         return retval;
00694     }
00695 
00696     /* Create a code object from the image */
00697     retval = obj_loadFromImgObj(pimg, &pco);
00698     PM_RETURN_IF_ERROR(retval);
00699 
00700     /* Return the code object */
00701     NATIVE_SET_TOS(pco);
00702     return retval;
00703     """
00704     pass
00705 
00706 
00707 # This must be declared before any classes because LOAD_NAME(__name__) is
00708 # part of every class-declaration, so __name__ must exist.
00709 # This is a temporary workaround until __name__ is properly handled.
00710 __name__ = "TBD"
00711 
00712 
00713 #
00714 # Root object
00715 #
00716 class object():
00717     pass
00718 
00719 
00720 #
00721 # Exception classes
00722 #
00723 class Exception(object):
00724     pass
00725 
00726 class AssertionError(Exception):
00727     pass
00728 AssertionError.code = 0xE4
00729 
00730 
00731 #
00732 # Generator class - used by the vm for generator-iterators,
00733 # generator-expressions and generator-coroutines
00734 #
00735 # #207: Add support for the yield keyword
00736 #
00737 # WARNING: unsupported methods: throw, close, __del__
00738 #
00739 class Generator(object):
00740 
00741     def __init__(self, fa):
00742         """__NATIVE__
00743         PmReturn_t retval;
00744         pPmObj_t pself;
00745         pPmObj_t pfa;
00746         pPmObj_t pfunc;
00747         pPmObj_t pframe;
00748         uint8_t i;
00749         uint8_t objid;
00750 
00751         /* Raise TypeError if wrong number of args */
00752         if (NATIVE_GET_NUM_ARGS() != 2)
00753         {
00754             PM_RAISE(retval, PM_RET_EX_TYPE);
00755             return retval;
00756         }
00757 
00758         /* Raise ValueError if first args are not: instance, tuple */
00759         pself = NATIVE_GET_LOCAL(0);
00760         pfa = NATIVE_GET_LOCAL(1);
00761         if (OBJ_GET_TYPE(pself) != OBJ_TYPE_CLI)
00762         {
00763             PM_RAISE(retval, PM_RET_EX_VAL);
00764             return retval;
00765         }
00766         if (OBJ_GET_TYPE(pfa) != OBJ_TYPE_TUP)
00767         {
00768             PM_RAISE(retval, PM_RET_EX_VAL);
00769             return retval;
00770         }
00771 
00772         /* Create a new frame for the function */
00773         pfunc = ((pPmTuple_t)pfa)->val[0];
00774         retval = frame_new(pfunc, &pframe);
00775         PM_RETURN_IF_ERROR(retval);
00776 
00777         /* Copy args into frame's locals */
00778         for (i = 0; i < ((pPmTuple_t)pfa)->length - 1; i++)
00779         {
00780             /* The pfa tuple is (func, [arg0, ... argN]) */
00781             ((pPmFrame_t)pframe)->fo_locals[i] = ((pPmTuple_t)pfa)->val[i + 1];
00782         }
00783 
00784         /* Store frame in None attr of instance */
00785         heap_gcPushTempRoot(pframe, &objid);
00786         retval = dict_setItem((pPmObj_t)((pPmInstance_t)pself)->cli_attrs,
00787                               PM_NONE, pframe);
00788         heap_gcPopTempRoot(objid);
00789 
00790         NATIVE_SET_TOS(PM_NONE);
00791         return retval;
00792         """
00793         pass
00794 
00795 
00796     def next(self,):
00797         return self.send(None)
00798 
00799 
00800     def send(self, arg):
00801         """__NATIVE__
00802         PmReturn_t retval;
00803         pPmObj_t pself;
00804         pPmObj_t parg;
00805         pPmObj_t pgenframe;
00806 
00807         /* Raise TypeError if wrong number of args */
00808         if (NATIVE_GET_NUM_ARGS() != 2)
00809         {
00810             PM_RAISE(retval, PM_RET_EX_TYPE);
00811             return retval;
00812         }
00813 
00814         /* Raise ValueError if first arg is not an instance */
00815         pself = NATIVE_GET_LOCAL(0);
00816         parg = NATIVE_GET_LOCAL(1);
00817         if (OBJ_GET_TYPE(pself) != OBJ_TYPE_CLI)
00818         {
00819             PM_RAISE(retval, PM_RET_EX_VAL);
00820             return retval;
00821         }
00822 
00823         /* Get the generator's frame */
00824         retval = dict_getItem((pPmObj_t)((pPmInstance_t)pself)->cli_attrs,
00825                               PM_NONE, &pgenframe);
00826         PM_RETURN_IF_ERROR(retval);
00827 
00828         /* Push argument onto generator's frame's stack */
00829         *(((pPmFrame_t)pgenframe)->fo_sp) = parg;
00830         ((pPmFrame_t)pgenframe)->fo_sp++;
00831 
00832         /* Set generator's frame's fo_back so yielded value goes to caller */
00833         ((pPmFrame_t)pgenframe)->fo_back = NATIVE_GET_PFRAME();
00834 
00835         /* Set active frame to run generator */
00836         NATIVE_GET_PFRAME() = (pPmFrame_t)pgenframe;
00837 
00838         return PM_RET_FRAME_SWITCH;
00839         """
00840         pass
00841 
00842 
00843 # WARNING: Untested.  Awaiting implementation of try/except/finally
00844 #
00845 #    def close(self,):
00846 #        """__NATIVE__
00847 #        PmReturn_t retval;
00848 #        pPmObj_t pself;
00849 #        pPmObj_t pgenframe;
00850 #
00851 #        /* Raise TypeError if wrong number of args */
00852 #        if (NATIVE_GET_NUM_ARGS() != 1)
00853 #        {
00854 #            PM_RAISE(retval, PM_RET_EX_TYPE);
00855 #            return retval;
00856 #        }
00857 #
00858 #        /* Raise ValueError if first arg is not an instance */
00859 #        pself = NATIVE_GET_LOCAL(0);
00860 #        if (OBJ_GET_TYPE(pself) != OBJ_TYPE_CLI)
00861 #        {
00862 #            PM_RAISE(retval, PM_RET_EX_VAL);
00863 #            return retval;
00864 #        }
00865 #
00866 #        /* Get the generator's frame */
00867 #        retval = dict_getItem((pPmObj_t)((pPmInstance_t)pself)->cli_attrs,
00868 #                              PM_NONE, &pgenframe);
00869 #        PM_RETURN_IF_ERROR(retval);
00870 #
00871 #        /* If there was no frame, assume generator already closed, do nothing */
00872 #        if (OBJ_GET_TYPE(pgenframe) != OBJ_TYPE_FRM)
00873 #        {
00874 #            return PM_RET_OK;
00875 #        }
00876 #
00877 #        /* Unbind the frame from the generator instance */
00878 #        retval = dict_setItem((pPmObj_t)((pPmInstance_t)pself)->cli_attrs,
00879 #                              PM_NONE, PM_NONE);
00880 #
00881 #        /* Push argument onto generator's frame's stack */
00882 #        *(((pPmFrame_t)pgenframe)->fo_sp) = PM_NONE;
00883 #        ((pPmFrame_t)pgenframe)->fo_sp++;
00884 #
00885 #        /* Set generator's frame's fo_back so yielded value goes to caller */
00886 #        ((pPmFrame_t)pgenframe)->fo_back = NATIVE_GET_PFRAME();
00887 #
00888 #        /* Set active frame to run generator */
00889 #        NATIVE_GET_PFRAME() = (pPmFrame_t)pgenframe;
00890 #
00891 #        /* Raise a GeneratorExit where the generator function was paused */
00892 #        PM_RAISE(retval, PM_RET_EX_GEN);
00893 #        return retval;
00894 #        """
00895 #        pass
00896 
00897 
00898 #
00899 # Returns True if called within a module being run as the main; False otherwise
00900 #
00901 def ismain():
00902     """__NATIVE__
00903 
00904     NATIVE_SET_TOS((NATIVE_GET_PFRAME()->fo_isImport) ? PM_FALSE : PM_TRUE);
00905 
00906     return PM_RET_OK;
00907     """
00908     pass
00909 
00910 
00911 #ifdef HAVE_BYTEARRAY
00912 #class bytearray(object):
00913 #    def __init__(self, o):
00914 #        """__NATIVE__
00915 #        PmReturn_t retval;
00916 #        pPmObj_t pself;
00917 #        pPmObj_t po;
00918 #        pPmObj_t pba;
00919 #        uint8_t objid;
00920 #
00921 #        /* If only the self arg, create zero-length bytearray */
00922 #        if (NATIVE_GET_NUM_ARGS() == 1)
00923 #        {
00924 #            po = PM_ZERO;
00925 #        }
00926 #
00927 #        /* If two args, get the second arg */
00928 #        else if (NATIVE_GET_NUM_ARGS() == 2)
00929 #        {
00930 #            po = NATIVE_GET_LOCAL(1);
00931 #        }
00932 #
00933 #        /* Raise TypeError if wrong number of args */
00934 #        else
00935 #        {
00936 #            PM_RAISE(retval, PM_RET_EX_TYPE);
00937 #            return retval;
00938 #        }
00939 #        pself = NATIVE_GET_LOCAL(0);
00940 #
00941 #        /* Create new bytearray object */
00942 #        retval = bytearray_new(po, &pba);
00943 #        PM_RETURN_IF_ERROR(retval);
00944 #
00945 #        /* Store bytearray in None attr of instance */
00946 #        heap_gcPushTempRoot(pba, &objid);
00947 #        retval = dict_setItem((pPmObj_t)((pPmInstance_t)pself)->cli_attrs,
00948 #                              PM_NONE, pba);
00949 #        heap_gcPopTempRoot(objid);
00950 #
00951 #        NATIVE_SET_TOS(PM_NONE);
00952 #        return retval;
00953 #        """
00954 #        pass
00955 #endif /* HAVE_BYTEARRAY */
00956 
00957 #:mode=c:

Generated on Mon Oct 18 07:40:46 2010 for Python-on-a-chip by  doxygen 1.5.9