1 # This file is Copyright 2003, 2006, 2007, 2009, 2010 Dean Hall.
3 # This file is part of the Python-on-a-Chip program.
4 # Python-on-a-Chip is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE Version 2.1.
7 # Python-on-a-Chip is distributed in the hope that it will be useful,
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 # A copy of the GNU LESSER GENERAL PUBLIC LICENSE Version 2.1
11 # is seen in the file COPYING in this directory.
17 # @brief Provides PyMite's builtins module, __bi.
21 # The builtins are loaded by the interpreter.
22 # The user SHOULD NOT import this module directly.
26 # return n > 0 and n or -n
37 /* If wrong number of args, raise TypeError */
38 if (NATIVE_GET_NUM_ARGS() != 1)
40 PM_RAISE(retval, PM_RET_EX_TYPE);
44 /* Raise TypeError if arg is not an int */
45 pn = NATIVE_GET_LOCAL(0);
46 if (OBJ_GET_TYPE(pn) != OBJ_TYPE_INT)
48 PM_RAISE(retval, PM_RET_EX_TYPE);
52 /* Raise ValueError if arg is not int within range(256) */
53 n = ((pPmInt_t)pn)->val;
54 if ((n < 0) || (n > 255))
56 PM_RAISE(retval, PM_RET_EX_VAL);
60 /* Create char string from integer value */
61 retval = string_newFromChar((uint8_t)n, &ps);
70 PmReturn_t retval = PM_RET_OK;
78 /* Use globals if no arg given */
79 if (NATIVE_GET_NUM_ARGS() == 0)
81 /* Get the globals dict */
82 po = (pPmObj_t)NATIVE_GET_PFRAME()->fo_globals;
85 /* Otherwise use the given arg */
86 else if (NATIVE_GET_NUM_ARGS() == 1)
88 po = NATIVE_GET_LOCAL(0);
90 /* If object is a function or module, use its attrs dict */
91 if ((OBJ_GET_TYPE(po) == OBJ_TYPE_FXN)
92 || (OBJ_GET_TYPE(po) == OBJ_TYPE_MOD))
94 po = (pPmObj_t)((pPmFunc_t)po)->f_attrs;
98 else if (OBJ_GET_TYPE(po) == OBJ_TYPE_CLO)
100 po = (pPmObj_t)((pPmClass_t)po)->cl_attrs;
102 else if (OBJ_GET_TYPE(po) == OBJ_TYPE_CLI)
104 po = (pPmObj_t)((pPmInstance_t)po)->cli_attrs;
106 else if (OBJ_GET_TYPE(po) == OBJ_TYPE_MTH)
108 po = (pPmObj_t)((pPmMethod_t)po)->m_attrs;
110 #endif /* HAVE_CLASSES */
118 /* Raise TypeError if wrong number of args */
121 PM_RAISE(retval, PM_RET_EX_TYPE);
131 /* Create new list */
132 retval = list_new(&pl);
133 PM_RETURN_IF_ERROR(retval);
135 /* Copy dict's keys to the list */
136 psl = ((pPmDict_t)po)->d_keys;
137 for (i = 0; i < ((pPmDict_t)po)->length; i++)
139 retval = seglist_getItem(psl, i, &pk);
140 PM_RETURN_IF_ERROR(retval);
141 heap_gcPushTempRoot(pl, &objid);
142 retval = list_append(pl, pk);
143 heap_gcPopTempRoot(objid);
144 PM_RETURN_IF_ERROR(retval);
155 # Evaluates a given code object (created by Co()).
156 # Optionally accepts a globals dict as the second parameter
157 # Optionally accepts a locals dict as the third parameter
165 pPmObj_t pg = C_NULL;
166 pPmObj_t pl = C_NULL;
169 /* If wrong number of args, raise TypeError */
170 if ((NATIVE_GET_NUM_ARGS() == 0) || (NATIVE_GET_NUM_ARGS() > 3))
172 PM_RAISE(retval, PM_RET_EX_TYPE);
176 /* Raise ValueError if first arg is not a Code Object */
177 pco = NATIVE_GET_LOCAL(0);
178 if (OBJ_GET_TYPE(pco) != OBJ_TYPE_COB)
180 PM_RAISE(retval, PM_RET_EX_VAL);
184 /* If 2nd arg exists, raise ValueError if it is not a Dict */
185 if (NATIVE_GET_NUM_ARGS() >= 2)
187 pg = NATIVE_GET_LOCAL(1);
188 if (OBJ_GET_TYPE(pg) != OBJ_TYPE_DIC)
190 PM_RAISE(retval, PM_RET_EX_VAL);
195 /* If no args are given, use the caller's globals for the function's */
198 pg = (pPmObj_t)NATIVE_GET_PFRAME()->fo_globals;
201 /* If 3rd arg exists, raise ValueError if it is not a Dict */
202 if (NATIVE_GET_NUM_ARGS() >= 3)
204 pl = NATIVE_GET_LOCAL(2);
205 if (OBJ_GET_TYPE(pl) != OBJ_TYPE_DIC)
207 PM_RAISE(retval, PM_RET_EX_VAL);
212 /* Create func from code object */
213 retval = func_new(pco, pg, &pfunc);
214 PM_RETURN_IF_ERROR(retval);
216 /* Create frame from module object; globals is set to null */
217 heap_gcPushTempRoot(pfunc, &objid);
218 retval = frame_new(pfunc, &pnewframe);
219 heap_gcPopTempRoot(objid);
220 PM_RETURN_IF_ERROR(retval);
222 /* TODO: Reclaim pnewframe's attrs dict created in frame_new */
224 * By default use calling frame's attrs as local namespace.
225 * This works for ipm because the interactive mode
226 * needs a locals namespace that persists across calls to eval()
228 ((pPmFrame_t)pnewframe)->fo_attrs = NATIVE_GET_PFRAME()->fo_attrs;
230 /* If 2nd arg exists, use it as the global namespace for the new func */
231 if (NATIVE_GET_NUM_ARGS() >= 2)
233 ((pPmFrame_t)pnewframe)->fo_globals = (pPmDict_t)pg;
235 /* If only globals is given, locals defaults to it */
236 ((pPmFrame_t)pnewframe)->fo_attrs = (pPmDict_t)pg;
239 /* If 3rd arg exists, use it as the local namespace for the new func */
240 if (NATIVE_GET_NUM_ARGS() >= 3)
242 ((pPmFrame_t)pnewframe)->fo_attrs = (pPmDict_t)pl;
246 * Set the fo_back frame so flow returns to eval()'s caller when completed.
247 * Set the frame pointer so the new frame is interpreted immediately
248 * after this function returns.
250 ((pPmFrame_t)pnewframe)->fo_back = NATIVE_GET_PFRAME();
251 NATIVE_GET_PFRAME() = (pPmFrame_t)pnewframe;
252 retval = PM_RET_FRAME_SWITCH;
260 return [x
for x
in s
if f(x
)]
265 pPmObj_t pr = C_NULL;
268 /* If wrong number of args, raise TypeError */
269 if (NATIVE_GET_NUM_ARGS() != 0)
271 PM_RAISE(retval, PM_RET_EX_TYPE);
275 /* Return calling frame's globals dict on stack*/
276 pr = (pPmObj_t)NATIVE_GET_PFRAME()->fo_globals;
287 pPmObj_t pr = C_NULL;
289 /* If wrong number of args, raise TypeError */
290 if (NATIVE_GET_NUM_ARGS() != 1)
292 PM_RAISE(retval, PM_RET_EX_TYPE);
296 /* Return object's address as an int on the stack */
297 retval = int_new((intptr_t)NATIVE_GET_LOCAL(0), &pr);
305 # Yields every (i)tem in the (s)equence; requires HAVE_GENERATORS
314 pPmObj_t ps = C_NULL;
315 pPmObj_t pr = C_NULL;
317 /* If wrong number of args, raise TypeError */
318 if (NATIVE_GET_NUM_ARGS() != 1)
320 PM_RAISE(retval, PM_RET_EX_TYPE);
325 ps = NATIVE_GET_LOCAL(0);
327 #ifdef HAVE_BYTEARRAY
328 /* If object is an instance, get the thing it contains */
329 if (OBJ_GET_TYPE(ps) == OBJ_TYPE_CLI)
331 retval = dict_getItem((pPmObj_t)((pPmInstance_t)ps)->cli_attrs,
335 /* If None wasn't in attributes, obj is wrong type for len() */
336 if (retval == PM_RET_EX_KEY) retval = PM_RET_EX_TYPE;
337 PM_RETURN_IF_ERROR(retval);
340 #endif /* HAVE_BYTEARRAY */
342 /* Get the length of the arg based on its type */
343 switch (OBJ_GET_TYPE(ps))
346 retval = int_new(((pPmString_t)ps)->length, &pr);
350 retval = int_new(((pPmTuple_t)ps)->length, &pr);
354 retval = int_new(((pPmList_t)ps)->length, &pr);
358 retval = int_new(((pPmDict_t)ps)->length, &pr);
361 #ifdef HAVE_BYTEARRAY
363 retval = int_new(((pPmBytearray_t)ps)->length, &pr);
365 #endif /* HAVE_BYTEARRAY */
368 /* If not a string or sequence type, raise TypeError */
369 PM_RAISE(retval, PM_RET_EX_TYPE);
380 pPmObj_t pr = C_NULL;
383 /* If wrong number of args, raise TypeError */
384 if (NATIVE_GET_NUM_ARGS() != 0)
386 PM_RAISE(retval, PM_RET_EX_TYPE);
390 /* Return calling frame's local attrs dict on the stack */
391 pr = (pPmObj_t)NATIVE_GET_PFRAME()->fo_attrs;
403 # Call function f once with each argument in sequence s
409 # Return list of results
420 /* If wrong number of args, raise TypeError */
421 if (NATIVE_GET_NUM_ARGS() != 1)
423 PM_RAISE(retval, PM_RET_EX_TYPE);
427 ps = NATIVE_GET_LOCAL(0);
429 /* Raise TypeError if arg is not string of length 1 */
430 if ((OBJ_GET_TYPE(ps) != OBJ_TYPE_STR)
431 || (((pPmString_t)ps)->length != 1))
434 PM_RAISE(retval, PM_RET_EX_TYPE);
438 /* Get integer value of character */
439 n = ((pPmString_t)ps)->val[0];
440 retval = int_new(n, &pn);
454 pPmObj_t pa = C_NULL;
455 pPmObj_t pb = C_NULL;
456 pPmObj_t pc = C_NULL;
457 pPmObj_t pi = C_NULL;
458 pPmObj_t pr = C_NULL;
460 uint8_t objid1, objid2;
462 switch (NATIVE_GET_NUM_ARGS())
466 pb = NATIVE_GET_LOCAL(0);
471 pa = NATIVE_GET_LOCAL(0);
472 pb = NATIVE_GET_LOCAL(1);
477 pa = NATIVE_GET_LOCAL(0);
478 pb = NATIVE_GET_LOCAL(1);
479 pc = NATIVE_GET_LOCAL(2);
481 /* If 3rd arg is 0, ValueError */
482 if (((pPmInt_t)pc)->val == 0)
484 PM_RAISE(retval, PM_RET_EX_VAL);
490 /* If wrong number of args, raise TypeError */
491 PM_RAISE(retval, PM_RET_EX_TYPE);
496 retval = list_new(&pr);
497 PM_RETURN_IF_ERROR(retval);
499 /* Iterate depending on counting direction */
500 if (((pPmInt_t)pc)->val > 0)
502 for (i = ((pPmInt_t)pa)->val;
503 i < ((pPmInt_t)pb)->val;
504 i += ((pPmInt_t)pc)->val)
506 heap_gcPushTempRoot(pr, &objid1);
507 retval = int_new(i, &pi);
508 if (retval != PM_RET_OK)
510 heap_gcPopTempRoot(objid1);
514 heap_gcPushTempRoot(pi, &objid2);
515 retval = list_append(pr, pi);
516 heap_gcPopTempRoot(objid1);
517 PM_RETURN_IF_ERROR(retval);
522 for (i = ((pPmInt_t)pa)->val;
523 i > ((pPmInt_t)pb)->val;
524 i += ((pPmInt_t)pc)->val)
526 heap_gcPushTempRoot(pr, &objid1);
527 retval = int_new(i, &pi);
528 if (retval != PM_RET_OK)
530 heap_gcPopTempRoot(objid1);
534 heap_gcPushTempRoot(pi, &objid2);
535 retval = list_append(pr, pi);
536 heap_gcPopTempRoot(objid1);
537 PM_RETURN_IF_ERROR(retval);
559 uint8_t usefloat = C_FALSE;
560 #endif /* HAVE_FLOAT */
562 /* If wrong number of args, raise TypeError */
563 if (NATIVE_GET_NUM_ARGS() != 1)
565 PM_RAISE(retval, PM_RET_EX_TYPE);
569 /* Get the length of the sequence */
570 ps = NATIVE_GET_LOCAL(0);
571 if (OBJ_GET_TYPE(ps) == OBJ_TYPE_TUP)
573 len = ((pPmTuple_t)ps)->length;
575 else if (OBJ_GET_TYPE(ps) == OBJ_TYPE_LST)
577 len = ((pPmList_t)ps)->length;
580 /* Raise TypeError if arg is not a sequence */
583 PM_RAISE(retval, PM_RET_EX_TYPE);
587 /* Calculate the sum of the sequence */
592 for (i = 0; i < len; i++)
594 retval = seq_getSubscript(ps, i, &po);
596 if (OBJ_GET_TYPE(po) == OBJ_TYPE_INT)
598 /* Add value to sum */
599 n += ((pPmInt_t)po)->val;
601 f += (float)((pPmInt_t)po)->val;
602 #endif /* HAVE_FLOAT */
606 else if (OBJ_GET_TYPE(po) == OBJ_TYPE_FLT)
608 /* Add value to sum */
609 f += ((pPmFloat_t)po)->val;
612 #endif /* HAVE_FLOAT */
614 /* Raise TypeError if item is not an integer */
617 PM_RAISE(retval, PM_RET_EX_TYPE);
625 retval = float_new(f, &pn);
628 #endif /* HAVE_FLOAT */
630 retval = int_new(n, &pn);
641 pPmObj_t po = C_NULL;
642 pPmObj_t pr = C_NULL;
644 /* If wrong number of args, raise TypeError */
645 if (NATIVE_GET_NUM_ARGS() != 1)
647 PM_RAISE(retval, PM_RET_EX_TYPE);
652 po = NATIVE_GET_LOCAL(0);
654 /* Create int from type enum */
655 retval = int_new(OBJ_GET_TYPE(po), &pr);
662 # At this time, xrange() works in a for loop, but not in a generator expression
663 # Yes: for i in xrange(42): pass
664 # No: [x for x in xrange(42)]
673 # Creates a code object from the given image string
681 /* If wrong number of args, raise TypeError */
682 if (NATIVE_GET_NUM_ARGS() != 1)
684 PM_RAISE(retval, PM_RET_EX_TYPE);
688 /* Raise ValueError if arg is not a string */
689 pimg = NATIVE_GET_LOCAL(0);
690 if (OBJ_GET_TYPE(pimg) != OBJ_TYPE_CIO)
692 PM_RAISE(retval, PM_RET_EX_VAL);
696 /* Create a code object from the image */
697 retval = obj_loadFromImgObj(pimg, &pco);
698 PM_RETURN_IF_ERROR(retval);
700 /* Return the code object */
707 # This must be declared before any classes because LOAD_NAME(__name__) is
708 # part of every class-declaration, so __name__ must exist.
709 # This is a temporary workaround until __name__ is properly handled.
723 class Exception(object):
726 class AssertionError(Exception):
728 AssertionError.code
= 0xE4
732 # Generator class - used by the vm for generator-iterators,
733 # generator-expressions and generator-coroutines
735 # #207: Add support for the yield keyword
737 # WARNING: unsupported methods: throw, close, __del__
739 class Generator(object):
741 def __init__(self
, fa
):
751 /* Raise TypeError if wrong number of args */
752 if (NATIVE_GET_NUM_ARGS() != 2)
754 PM_RAISE(retval, PM_RET_EX_TYPE);
758 /* Raise ValueError if first args are not: instance, tuple */
759 pself = NATIVE_GET_LOCAL(0);
760 pfa = NATIVE_GET_LOCAL(1);
761 if (OBJ_GET_TYPE(pself) != OBJ_TYPE_CLI)
763 PM_RAISE(retval, PM_RET_EX_VAL);
766 if (OBJ_GET_TYPE(pfa) != OBJ_TYPE_TUP)
768 PM_RAISE(retval, PM_RET_EX_VAL);
772 /* Create a new frame for the function */
773 pfunc = ((pPmTuple_t)pfa)->val[0];
774 retval = frame_new(pfunc, &pframe);
775 PM_RETURN_IF_ERROR(retval);
777 /* Copy args into frame's locals */
778 for (i = 0; i < ((pPmTuple_t)pfa)->length - 1; i++)
780 /* The pfa tuple is (func, [arg0, ... argN]) */
781 ((pPmFrame_t)pframe)->fo_locals[i] = ((pPmTuple_t)pfa)->val[i + 1];
784 /* Store frame in None attr of instance */
785 heap_gcPushTempRoot(pframe, &objid);
786 retval = dict_setItem((pPmObj_t)((pPmInstance_t)pself)->cli_attrs,
788 heap_gcPopTempRoot(objid);
790 NATIVE_SET_TOS(PM_NONE);
797 return self
.send(None)
807 /* Raise TypeError if wrong number of args */
808 if (NATIVE_GET_NUM_ARGS() != 2)
810 PM_RAISE(retval, PM_RET_EX_TYPE);
814 /* Raise ValueError if first arg is not an instance */
815 pself = NATIVE_GET_LOCAL(0);
816 parg = NATIVE_GET_LOCAL(1);
817 if (OBJ_GET_TYPE(pself) != OBJ_TYPE_CLI)
819 PM_RAISE(retval, PM_RET_EX_VAL);
823 /* Get the generator's frame */
824 retval = dict_getItem((pPmObj_t)((pPmInstance_t)pself)->cli_attrs,
825 PM_NONE, &pgenframe);
826 PM_RETURN_IF_ERROR(retval);
828 /* Push argument onto generator's frame's stack */
829 *(((pPmFrame_t)pgenframe)->fo_sp) = parg;
830 ((pPmFrame_t)pgenframe)->fo_sp++;
832 /* Set generator's frame's fo_back so yielded value goes to caller */
833 ((pPmFrame_t)pgenframe)->fo_back = NATIVE_GET_PFRAME();
835 /* Set active frame to run generator */
836 NATIVE_GET_PFRAME() = (pPmFrame_t)pgenframe;
838 return PM_RET_FRAME_SWITCH;
843 # WARNING: Untested. Awaiting implementation of try/except/finally
849 # pPmObj_t pgenframe;
851 # /* Raise TypeError if wrong number of args */
852 # if (NATIVE_GET_NUM_ARGS() != 1)
854 # PM_RAISE(retval, PM_RET_EX_TYPE);
858 # /* Raise ValueError if first arg is not an instance */
859 # pself = NATIVE_GET_LOCAL(0);
860 # if (OBJ_GET_TYPE(pself) != OBJ_TYPE_CLI)
862 # PM_RAISE(retval, PM_RET_EX_VAL);
866 # /* Get the generator's frame */
867 # retval = dict_getItem((pPmObj_t)((pPmInstance_t)pself)->cli_attrs,
868 # PM_NONE, &pgenframe);
869 # PM_RETURN_IF_ERROR(retval);
871 # /* If there was no frame, assume generator already closed, do nothing */
872 # if (OBJ_GET_TYPE(pgenframe) != OBJ_TYPE_FRM)
877 # /* Unbind the frame from the generator instance */
878 # retval = dict_setItem((pPmObj_t)((pPmInstance_t)pself)->cli_attrs,
881 # /* Push argument onto generator's frame's stack */
882 # *(((pPmFrame_t)pgenframe)->fo_sp) = PM_NONE;
883 # ((pPmFrame_t)pgenframe)->fo_sp++;
885 # /* Set generator's frame's fo_back so yielded value goes to caller */
886 # ((pPmFrame_t)pgenframe)->fo_back = NATIVE_GET_PFRAME();
888 # /* Set active frame to run generator */
889 # NATIVE_GET_PFRAME() = (pPmFrame_t)pgenframe;
891 # /* Raise a GeneratorExit where the generator function was paused */
892 # PM_RAISE(retval, PM_RET_EX_GEN);
899 # Returns True if called within a module being run as the main; False otherwise
904 NATIVE_SET_TOS((NATIVE_GET_PFRAME()->fo_isImport) ? PM_FALSE : PM_TRUE);
911 #ifdef HAVE_BYTEARRAY
912 #class bytearray(object):
913 # def __init__(self, o):
921 # /* If only the self arg, create zero-length bytearray */
922 # if (NATIVE_GET_NUM_ARGS() == 1)
927 # /* If two args, get the second arg */
928 # else if (NATIVE_GET_NUM_ARGS() == 2)
930 # po = NATIVE_GET_LOCAL(1);
933 # /* Raise TypeError if wrong number of args */
936 # PM_RAISE(retval, PM_RET_EX_TYPE);
939 # pself = NATIVE_GET_LOCAL(0);
941 # /* Create new bytearray object */
942 # retval = bytearray_new(po, &pba);
943 # PM_RETURN_IF_ERROR(retval);
945 # /* Store bytearray in None attr of instance */
946 # heap_gcPushTempRoot(pba, &objid);
947 # retval = dict_setItem((pPmObj_t)((pPmInstance_t)pself)->cli_attrs,
949 # heap_gcPopTempRoot(objid);
951 # NATIVE_SET_TOS(PM_NONE);
955 #endif /* HAVE_BYTEARRAY */