Commits

Dean Hall  committed 9ac608d

#58: Mainlining directly

  • Participants
  • Parent commits 0a29e3e

Comments (0)

Files changed (6)

File src/lib/__bi.py

     pass
 
 
+#
+# This implementation is needed by bytecodes BINARY_POWER and INPLACE_POWER
+#
 def pow(x, y):
     """__NATIVE__
     pPmObj_t px;

File src/tests/system/t058.c

+/*
+ * PyMite - A flyweight Python interpreter for 8-bit microcontrollers and more.
+ * Copyright 2002 Dean Hall
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+/**
+ * System Test 058
+ *
+ * Tests implementation of keyword "in" for Tuple, List and String
+ *
+ * Log
+ * ---
+ *
+ * 2006/11/26   First.
+ */
+
+#include "pm.h"
+
+
+extern unsigned char usrlib_img[];
+
+
+int main(void)
+{
+    PmReturn_t retval;
+
+    retval = pm_init(MEMSPACE_FLASH, usrlib_img);
+    PM_RETURN_IF_ERROR(retval);
+
+    retval = pm_run((uint8_t *)"t058");
+    pm_reportResult(retval);
+    return (int)retval;
+}

File src/tests/system/t058.py

+# PyMite - A flyweight Python interpreter for 8-bit microcontrollers and more.
+# Copyright 2002 Dean Hall
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+#
+
+#
+# System Test 058
+# Tests implementation of keyword "in" for Tuple, List and String
+#
+
+
+t = (2,5,6)
+assert 2 in t
+assert 5 in t
+assert 6 in t
+assert 8 not in t
+assert "c" not in t
+
+l = [2,5,6]
+assert 2 in l
+assert 5 in l
+assert 6 in l
+assert 8 not in l
+assert "c" not in l
+
+s = "256"
+assert "2" in s
+assert "5" in s
+assert "6" in s
+assert "8" not in s
+assert "c" not in s
+
+d = {2:2, 5:"5", 6:None}
+assert 2 in d
+assert 5 in d
+assert 6 in d
+assert 8 not in d
+assert "5" not in d
+assert "c" not in d

File src/vm/interp.c

                 pobj1 = PM_POP();
                 pobj2 = PM_POP();
                 t16 = GET_ARG();
+
+                /* Handle all integer-to-integer comparisons */
                 if ((OBJ_GET_TYPE(*pobj1) == OBJ_TYPE_INT) &&
                     (OBJ_GET_TYPE(*pobj2) == OBJ_TYPE_INT))
                 {
                     PM_BREAK_IF_ERROR(retval);
                     pobj3 = (t8) ? PM_TRUE : PM_FALSE;
                 }
-                else if (t16 == COMP_EQ)
-                {
-                    if (obj_compare(pobj1, pobj2) == C_SAME)
-                    {
-                        pobj3 = PM_TRUE;
-                    }
-                    else
-                    {
-                        pobj3 = PM_FALSE;
-                    }
-                }
-                else if (t16 == COMP_NE)
-                {
-                    if (obj_compare(pobj1, pobj2) == C_DIFFER)
-                    {
-                        pobj3 = PM_TRUE;
-                    }
-                    else
-                    {
-                        pobj3 = PM_FALSE;
-                    }
-                }
 
-                /* Other compare not implemented yet */
+                /* Handle non-integer comparisons */
                 else
                 {
-                    PM_RAISE(retval, PM_RET_EX_SYS);
-                    break;
+                    retval = PM_RET_OK;
+                    switch (t16)
+                    {
+                        /* Handle equality comparisons for non-intger types */
+                        case COMP_EQ:
+                        case COMP_NE:
+                            pobj3 = PM_FALSE;
+                            t8 = obj_compare(pobj1, pobj2);
+                            if (((t8 == C_SAME) && (t16 == COMP_EQ))
+                                || ((t8 == C_DIFFER) && (t16 == COMP_NE)))
+                            {
+                                pobj3 = PM_TRUE;
+                            }
+                            else
+                            {
+                                pobj3 = PM_FALSE;
+                            }
+                            break;
+
+                        /* Handle membership comparisons */
+                        case COMP_IN:
+                        case COMP_NOT_IN:
+                            pobj3 = PM_FALSE;
+                            retval = obj_isIn(pobj1, pobj2);
+                            if (retval == PM_RET_OK)
+                            {
+                                if (t16 == COMP_IN)
+                                {
+                                    pobj3 = PM_TRUE;
+                                }
+                            }
+                            else if (retval == PM_RET_NO)
+                            {
+                                retval = PM_RET_OK;
+                                if (t16 == COMP_NOT_IN)
+                                {
+                                    pobj3 = PM_TRUE;
+                                }
+                            }
+                            break;
+
+                        /* Other comparisons are not implemented */
+                        default:
+                            PM_RAISE(retval, PM_RET_EX_SYS);
+                            break;
+                    }
+                    PM_BREAK_IF_ERROR(retval);
                 }
                 PM_PUSH(pobj3);
                 continue;

File src/vm/obj.c

 }
 
 
-/* return true if the obj is false */
+/* Returns true if the obj is false */
 int8_t
 obj_isFalse(pPmObj_t pobj)
 {
     C_ASSERT(pobj != C_NULL);
 
     /* return true if it's None */
-    if (OBJ_GET_TYPE(*pobj) == OBJ_TYPE_NON)
+    switch (OBJ_GET_TYPE(*pobj))
     {
-        return C_TRUE;
+        /* None evaluates to false */
+        case OBJ_TYPE_NON:
+            return C_FALSE;
+
+        /* Only the integer zero is false */
+        case OBJ_TYPE_INT:
+            return ((pPmInt_t)pobj)->val == 0;
+
+        /* An empty string is false */
+        case OBJ_TYPE_STR:
+            return ((pPmString_t)pobj)->length == 0;
+
+        /* An empty tuple is false */
+        case OBJ_TYPE_TUP:
+            return ((pPmTuple_t)pobj)->length == 0;
+
+        /* An empty list is false */
+        case OBJ_TYPE_LST:
+            return ((pPmList_t)pobj)->length == 0;
+
+        /* An empty dict is false */
+        case OBJ_TYPE_DIC:
+            return ((pPmDict_t)pobj)->length == 0;
+
+        /*
+         * The following types are always not false:
+         * CodeObj, Function, Module, Class, ClassInstance.
+         */
+        default:
+            return C_FALSE;
+    }
+}
+
+
+/* Returns true if the item is in the container object */
+PmReturn_t
+obj_isIn(pPmObj_t pobj, pPmObj_t pitem)
+{
+    PmReturn_t retval = PM_RET_NO;
+    pPmObj_t ptestItem;
+    int16_t i;
+    uint8_t c;
+
+    switch(OBJ_GET_TYPE(*pobj))
+    {
+        case OBJ_TYPE_TUP:
+            /* Iterate over tuple to find item */
+            for (i=0; i<((pPmTuple_t)pobj)->length; i++)
+            {
+                PM_RETURN_IF_ERROR(tuple_getItem(pobj, i, &ptestItem));
+
+                if (obj_compare(pitem, ptestItem) == C_SAME)
+                {
+                    retval = PM_RET_OK;
+                    break;
+                }
+            }
+            break;
+
+        case OBJ_TYPE_STR:
+            /* Raise a TypeError if item is not a string */
+            if ((OBJ_GET_TYPE(*pitem) != OBJ_TYPE_STR))
+            {
+                retval = PM_RET_EX_TYPE;
+                break;
+            }
+
+            /* Empty string is alway present */
+            if (((pPmString_t)pitem)->length == 0)
+            {
+                retval = PM_RET_OK;
+                break;
+            }
+
+            /* Raise a ValueError exception if the string is more than 1 char */
+            else if (((pPmString_t)pitem)->length != 1)
+            {
+                retval = PM_RET_EX_VAL;
+                break;
+            }
+
+            /* Iterate over string to find char */
+            c = ((pPmString_t)pitem)->val[0];
+            for (i=0; i<((pPmString_t)pobj)->length; i++)
+            {
+                if (c == ((pPmString_t)pobj)->val[i])
+                {
+                    retval = PM_RET_OK;
+                    break;
+                }
+            }
+            break;
+
+        case OBJ_TYPE_LST:
+            /* Iterate over list to find item */
+            for (i=0; i<((pPmList_t)pobj)->length; i++)
+            {
+                PM_RETURN_IF_ERROR(list_getItem(pobj, i, &ptestItem));
+
+                if (obj_compare(pitem, ptestItem) == C_SAME)
+                {
+                    retval = PM_RET_OK;
+                    break;
+                }
+            }
+            break;
+
+        case OBJ_TYPE_DIC:
+            /* Check if the item is one of the keys of the dict */
+            retval = dict_getItem(pobj, pitem, &ptestItem);
+            if (retval == PM_RET_EX_KEY)
+            {
+                retval = PM_RET_NO;
+            }
+            break;
+
+        default:
+            retval = PM_RET_EX_TYPE;
+            break;
     }
 
-    /* the integer zero is false */
-    if ((OBJ_GET_TYPE(*pobj) == OBJ_TYPE_INT) &&
-        (((pPmInt_t)pobj)->val == 0))
-    {
-        return C_TRUE;
-    }
-
-    /* the floating point value of 0.0 is false */
-    /*
-    if ((OBJ_GET_TYPE(*pobj) == OBJ_TYPE_FLT) &&
-        (((pPmFloat)pobj)->val == 0.0))
-    {
-        retrun C_TRUE;
-    }
-    */
-
-    /* an empty string is false */
-    if (OBJ_GET_TYPE(*pobj) == OBJ_TYPE_STR)
-    {
-        /* XXX this is for null-term string */
-        return ((pPmString_t)pobj)->val[0] == C_NULL;
-    }
-
-    /* an empty tuple is false */
-    if (OBJ_GET_TYPE(*pobj) == OBJ_TYPE_TUP)
-    {
-        return ((pPmTuple_t)pobj)->length == 0;
-    }
-
-    /* an empty list is false */
-    if (OBJ_GET_TYPE(*pobj) == OBJ_TYPE_LST)
-    {
-        return ((pPmList_t)pobj)->length == 0;
-    }
-
-    /* an empty dict is false */
-    if (OBJ_GET_TYPE(*pobj) == OBJ_TYPE_DIC)
-    {
-        return ((pPmDict_t)pobj)->length == 0;
-    }
-
-    /*
-     * the following types are always not false:
-     * CodeObj, Function, Module, Class, ClassInstance.
-     */
-    return C_FALSE;
+    return retval;
 }
 
 
 int8_t
 obj_compare(pPmObj_t pobj1, pPmObj_t pobj2)
 {
-    /* null pointers are invalid */
-    if ((pobj1 == C_NULL) || (pobj2 == C_NULL))
-    {
-        return C_DIFFER;
-    }
+    C_ASSERT(pobj1 != C_NULL);
+    C_ASSERT(pobj2 != C_NULL);
 
     /* check if pointers are same */
     if (pobj1 == pobj2)

File src/vm/obj.h

 int8_t obj_isFalse(pPmObj_t pobj);
 
 /**
+ * Returns the boolean true if the item is in the object
+ *
+ * @param   pobj Ptr to container object
+ * @param   pitem Ptr to item
+ */
+PmReturn_t obj_isIn(pPmObj_t pobj, pPmObj_t pitem);
+
+/**
  * Compares two objects for equality.
  *
  * @param   pobj1 Ptr to first object.