Commits

Anonymous committed 1412a61

#10: mainlining directly

Comments (0)

Files changed (9)

 
             case BINARY_SUBSCR:
                 /* Implements TOS = TOS1[TOS]. */
-                /* get subscr */
+
+                /* get index */
                 pobj1 = PM_POP();
                 /* get sequence */
                 pobj2 = PM_POP();
 
-                /* XXX issue #10: create seq_getSubscript(); */
-                /* XXX index out of range exception? */
-
-                /* if it's a string */
-                if (OBJ_GET_TYPE(*pobj2) == OBJ_TYPE_STR)
+                if (OBJ_GET_TYPE(*pobj2) == OBJ_TYPE_DIC)
                 {
-                    /* TypeError; sequence index must be int */
+                    retval = dict_getItem(pobj2, pobj1, &pobj3);
+                }
+                else
+                {
+                    /* Raise a TypeError if index is not an Integer */
                     if (OBJ_GET_TYPE(*pobj1) != OBJ_TYPE_INT)
                     {
                         PM_RAISE(retval, PM_RET_EX_TYPE);
                         break;
                     }
-
-                    /* Get the character from the string */
-                    t8 = (uint8_t)((pPmString_t)pobj2)->
-                                   val[((pPmInt_t)pobj1)->val];
-
-                    /* Create a new string from the character */
-                    retval = string_newFromChar(t8, &pobj3);
-                    PM_BREAK_IF_ERROR(retval);
+                    t16 = ((pPmInt_t)pobj1)->val;
+                    retval = seq_getSubscript(pobj2, t16, &pobj3);
                 }
-
-                /* if it's a tuple */
-                else if (OBJ_GET_TYPE(*pobj2) == OBJ_TYPE_TUP)
-                {
-                    /* TypeError; sequence index must be int */
-                    if (OBJ_GET_TYPE(*pobj1) != OBJ_TYPE_INT)
-                    {
-                        PM_RAISE(retval, PM_RET_EX_TYPE);
-                        break;
-                    }
-                    /* get the tuple item */
-                    /* XXX index out of range exception? */
-                    pobj3 = ((pPmTuple_t)pobj2)->val[
-                                ((pPmInt_t)pobj1)->val];
-                }
-
-                /* if it's a list */
-                else if (OBJ_GET_TYPE(*pobj2) == OBJ_TYPE_LST)
-                {
-                    /* TypeError; sequence index must be int */
-                    if (OBJ_GET_TYPE(*pobj1) != OBJ_TYPE_INT)
-                    {
-                        PM_RAISE(retval, PM_RET_EX_TYPE);
-                        break;
-                    }
-                    /* get the list item */
-                    retval = list_getItem(pobj2,
-                                          (int16_t)((pPmInt_t)pobj1)->val,
-                                          &pobj3);
-                    PM_BREAK_IF_ERROR(retval);
-                }
-
-                /* if it's a dict */
-                else if (OBJ_GET_TYPE(*pobj2) == OBJ_TYPE_DIC)
-                {
-                    /* get the dict item */
-                    retval = dict_getItem(pobj2, pobj1, &pobj3);
-                    PM_BREAK_IF_ERROR(retval);
-                }
-
-                /* TypeError; unsubscriptable object */
-                else
-                {
-                    PM_RAISE(retval, PM_RET_EX_TYPE);
-                    break;
-                }
-
-                /* push item and continue */
+                PM_BREAK_IF_ERROR(retval);
                 PM_PUSH(pobj3);
                 continue;
 
                     {
                         pobj2 = (pPmObj_t)pb1;
                         pb1 = pb1->next;
-                        PM_BREAK_IF_ERROR(heap_freeChunk(pobj2));
+                        retval = heap_freeChunk(pobj2);
+                        PM_BREAK_IF_ERROR(retval);
                     }
+                    /* Test again outside while loop */
+                    PM_BREAK_IF_ERROR(retval);
+
                     /* restore SP */
                     SP = pb1->b_sp;
                     /* goto handler */
                     IP = pb1->b_handler;
                     /* pop and delete this block */
                     FP->fo_blockstack = pb1->next;
-                    PM_BREAK_IF_ERROR(heap_freeChunk((pPmObj_t)pb1));
+                    retval = heap_freeChunk((pPmObj_t)pb1);
+                    PM_BREAK_IF_ERROR(retval);
                 }
                 continue;
 
                 t16 = GET_ARG();
                 /* get ptr to sequence */
                 pobj1 = PM_POP();
-                /* push objs onto stack based on type */
-                if (OBJ_GET_TYPE(*pobj1) == OBJ_TYPE_TUP)
+
+                /* Push sequence's objs onto stack */
+                if ((OBJ_GET_TYPE(*pobj1) == OBJ_TYPE_TUP)
+                    || (OBJ_GET_TYPE(*pobj1) == OBJ_TYPE_LST))
                 {
                     for (; --t16 >= 0; )
                     {
-                        /* XXX should copy simple objs ? */
-                        PM_PUSH(((pPmTuple_t)pobj1)->val[t16]);
-                    }
-                }
-                else if (OBJ_GET_TYPE(*pobj1) == OBJ_TYPE_LST)
-                {
-                    for (; --t16 >= 0; )
-                    {
-                        /* XXX should copy simple objs */
-                        retval = list_getItem(pobj1,
-                                              t16,
-                                              &pobj2);
+                        retval = seq_getSubscript(pobj1, t16, &pobj2);
                         PM_BREAK_IF_ERROR(retval);
                         PM_PUSH(pobj2);
                     }
+                    /* Test again outside the for loop */
+                    PM_BREAK_IF_ERROR(retval);
                 }
                 continue;
 
                     /* get obj */
                     pobj2 = PM_POP();
                     /* insert obj into list */
-                    retval = list_insert(pobj1, pobj2, 0);
+                    retval = list_insert(pobj1, 0, pobj2);
                     PM_BREAK_IF_ERROR(retval);
                 }
+                /* Test again outside for loop */
+                PM_BREAK_IF_ERROR(retval);
+
                 /* push list onto stack */
                 PM_PUSH(pobj1);
                 continue;
 
             case BUILD_MAP:
+                /* Argument is ignored */
+                t16 = GET_ARG();
                 retval = dict_new(&pobj1);
                 PM_BREAK_IF_ERROR(retval);
                 PM_PUSH(pobj1);
 PmReturn_t
 list_getItem(pPmObj_t plist, int16_t index, pPmObj_t *r_pobj)
 {
-    PmReturn_t retval = PM_RET_STUB;
+    PmReturn_t retval;
     int16_t segnum = 0;
     int16_t segindx = 0;
 
 
 
 PmReturn_t
-list_insert(pPmObj_t plist, pPmObj_t pobj, int8_t index)
+list_insert(pPmObj_t plist, int8_t index, pPmObj_t pobj)
 {
-    PmReturn_t retval = PM_RET_STUB;
+    PmReturn_t retval;
+    int16_t len;
+    int8_t segnum;
+    int8_t segindx;
+
+    C_ASSERT(plist != C_NULL);
+    C_ASSERT(pobj != C_NULL);
+
+    /* Raise a TypeError if plist is not a List */
+    if (OBJ_GET_TYPE(*plist) != OBJ_TYPE_LST)
+    {
+        retval = PM_RET_EX_TYPE;
+        PM_RETURN_IF_ERROR(retval);
+    }
+
+    /* Adjust an out-of-bounds index value */
+    len = ((pPmList_t)plist)->length;
+    if (index < 0)
+    {
+        index += len;
+    }
+    if (index < 0)
+    {
+        index = 0;
+    }
+    if (index > len)
+    {
+        index = len;
+    }
+
+    /* Insert the item in the container */
+    segnum = index / SEGLIST_OBJS_PER_SEG;
+    segindx = index % SEGLIST_OBJS_PER_SEG;
+    retval = seglist_insertItem(((pPmList_t)plist)->val, pobj, segnum, segindx);
+    PM_RETURN_IF_ERROR(retval);
+
+    /* Increment the length of this list */
+    ((pPmList_t)plist)->length++;
     return retval;
 }
 
  * @return  Return status
  */
 PmReturn_t list_insert(pPmObj_t plist,
-                       pPmObj_t pobj,
-                       int8_t index);
+                       int8_t index,
+                       pPmObj_t pobj);
 
 /* XXX TODO - redo these using pobj / return status */
 #if 0
 }
 
 
+/* Returns the object sequence[index] */
+PmReturn_t
+seq_getSubscript(pPmObj_t pobj, int16_t index, pPmObj_t *r_pobj)
+{
+    PmReturn_t retval;
+    uint8_t c;
+
+    switch (OBJ_GET_TYPE(*pobj))
+    {
+        case OBJ_TYPE_STR:
+            /* Adjust for negative index */
+            if (index < 0)
+            {
+                index += ((pPmString_t)pobj)->length;
+            }
+
+            /* Raise IndexError if index is out of bounds */
+            if ((index < 0) || (index > ((pPmString_t)pobj)->length))
+            {
+                PM_RAISE(retval, PM_RET_EX_INDX);
+                break;
+            }
+
+            /* Get the character from the string */
+            c = ((pPmString_t)pobj)->val[index];
+
+            /* Create a new string from the character */
+            retval = string_newFromChar(c, r_pobj);
+            break;
+
+        case OBJ_TYPE_TUP:
+            /* Get the tuple item */
+            retval = tuple_getItem(pobj, index, r_pobj);
+            break;
+
+        case OBJ_TYPE_LST:
+            /* Get the list item */
+            retval = list_getItem(pobj, index, r_pobj);
+            break;
+
+        default:
+            /* Raise TypeError, unsubscriptable object */
+            PM_RAISE(retval, PM_RET_EX_TYPE);
+            break;
+    }
+
+    return retval;
+}
+
+
 /***************************************************************
  * Test
  **************************************************************/
  */
 int8_t obj_compare(pPmObj_t pobj1, pPmObj_t pobj2);
 
+/**
+ * Returns the object from sequence[index]
+ *
+ * @param   pobj Ptr to sequence object to get object from
+ * @param   index Int index into the sequence
+ * @param   r_pobj Return arg, object from sequence
+ * @return  Return status
+ */
+PmReturn_t seq_getSubscript(pPmObj_t pobj, int16_t index, pPmObj_t *r_pobj);
+
 #endif /* __OBJ_H__ */
 #define PM_RAISE(retexn, exn) \
         do \
         { \
+            C_ASSERT(exn >= PM_RET_EX); \
+            C_ASSERT(exn <= PM_RET_EX_WARN); \
             retexn = (exn); \
             gVmGlobal.errFileId = __FILE_ID__; \
             gVmGlobal.errLineNum = (uint16_t)__LINE__; \
  *
  * @param   pseglist Ptr to seglist in which object is placed.
  * @param   pobj Ptr to object which is inserted.
- * @param   segnum Segment number
- * @param   segindx Index within segment
+ * @param   index Index within seglist
  * @return  Return status; PM_RET_OK if the item was inserted.
  *              Any error condition comes from heap_getChunk.
  */
                    pPmObj_t pobj,
                    int8_t segnum,
                    int8_t segindx);
-
 /**
  * Put the item in the designated slot and segment.
  * This is intended to be used after seglist_findEqual()
 }
 
 
+PmReturn_t
+tuple_getItem(pPmObj_t ptup, int16_t index, pPmObj_t *r_pobj)
+{
+    PmReturn_t retval = PM_RET_OK;
+
+    /* Adjust for negative index */
+    if (index < 0)
+    {
+        index += ((pPmTuple_t)ptup)->length;
+    }
+
+    /* Raise IndexError if index is out of bounds */
+    if ((index < 0) || (index > ((pPmTuple_t)ptup)->length))
+    {
+        PM_RAISE(retval, PM_RET_EX_INDX);
+    }
+
+    /* Get the tuple item */
+    *r_pobj = ((pPmTuple_t)ptup)->val[index];
+
+    return retval;
+}
+
+
 /***************************************************************
  * Test
  **************************************************************/
 	 * length of tuple
      * I don't expect a tuple to ever exceed 255 elements,
      * but if I set this type to S8, a 0-element tuple
-	 * is to small to be allocated.
+	 * is too small to be allocated.
 	 */
     int16_t length;
     /** array of ptrs to objs */
  */
 PmReturn_t tuple_copy(pPmObj_t ptup, pPmObj_t *r_ptuple);
 
+/**
+ * Get the object in the tuple at the index.
+ *
+ * @param   pobj Ptr to tuple obj
+ * @param   index Index into tuple
+ * @param   r_pobj Return; ptr to return obj
+ * @return  Return status
+ */
+PmReturn_t tuple_getItem(pPmObj_t ptup, int16_t index, pPmObj_t *r_pobj);
+
 #endif /* __TUPLE_H__ */
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.