Commits

Anonymous committed a9e9739

#54: Mainlining: Merged in branch issue_0054_dwhall_change_seglist_api 113:114

  • Participants
  • Parent commits 1412a61

Comments (0)

Files changed (22)

File src/lib/__bi.py

 #elif defined(TARGET_DESKTOP) || defined(TARGET_ARM)
     retval = int_new((int32_t)NATIVE_GET_LOCAL(0), &pr);
 #else
-#error Code is not implemented for the desired target
+#error Native function, __bi.id(), is not implemented for the desired target
 #endif
     NATIVE_SET_TOS(pr);
 

File src/tests/system/Makefile

 check : vm $(EXECS)
 
 vm :
-	make -C ../../vm
+	make -C ../../vm DEBUG=true
 
 # Removes files made by default make
 clean :

File src/tests/system/t010.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.
+ */
+
+/**
+ * Regression Test for Issue #10
+ *
+ * Create sequence_getSubscript()
+ *
+ */
+
+#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 *)"t010");
+    pm_reportResult(retval);
+    return (int)retval;
+}

File src/tests/system/t010.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.
+#
+
+#
+# Regression Test for Issue #10
+#
+# Create sequence_getSubscript()
+#
+# The new function is used in BINARY_SUBSCRIPT,
+# so this tests the four supported subscript statements
+#
+
+# Test string subscript
+s = "test"
+assert s[0] == 't'
+assert s[-2] == 's'
+
+# Test tuple subscript
+t = (4, 2)
+assert t[1] == 2
+assert t[-2] == 4
+
+# Test list subscript
+l = [2, 5, 6]
+assert l[2] == 6
+assert l[-1] == 6
+
+# Test dict subscript
+d = {0:0, 1:'t', "2":2}
+assert d[0] == 0
+assert d[1] == 't'
+assert d["2"] == 2
+
+#
+# UNPACK_SEQUENCE also uses seq_getSubscript()
+#
+a,b,c = (1,2,3)
+assert a == 1
+assert b == 2
+assert c == 3
+
+c,b,a = [2,5,6]
+assert c == 2
+assert b == 5
+assert a == 6

File src/tests/system/t050.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.
+ */
+
+/**
+ * Feature Test for Issue #50
+ *
+ * Integrate __LINE__ into PM_RAISE
+ *
+ */
+
+#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 *)"t050");
+    pm_reportResult(retval);
+    return (int)retval;
+}

File src/tests/system/t050.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.
+#
+
+#
+# Feature Test for Issue #50
+#
+# Integrate __LINE__ into PM_RAISE
+#
+# To check that PM_RAISE works, I made a simple code snippet below that
+# will exercise specific functions in int.c
+#
+
+n = 1
+
+n0 = +n
+assert n0 == 1
+
+n1 = ~n
+assert n1 == -2
+
+n2 = -n
+assert n2 == -1

File src/tests/system/t054.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 054
+ * Tests lists and dicts with lengths > 8 to test underlying seglist.
+ *
+ * Log
+ * ---
+ *
+ * 2006/11/23   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 *)"t054");
+    pm_reportResult(retval);
+    return (int)retval;
+}

File src/tests/system/t054.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 054
+# Tests lists and dicts with lengths > 8 to test underlying seglist.
+#
+
+
+l = range(9)
+assert l[0] == 0
+assert l[8] == 8
+assert l[-1] == 8
+
+
+d = {}
+i = 9
+while i >= 0:
+    d[i] = i
+    i -= 1
+assert d[0] == 0
+assert d[9] == 9

File src/tests/unit/Makefile

 SHELL = /bin/sh
 
 TARGET ?= DESKTOP
-CDEFS = -DHEAP_SIZE=0x0D00
-CFLAGS = -I../../vm $(CDEFS)
+HEAP_SIZE ?= 0x1000
+
+CDEFS = -DHEAP_SIZE=$(HEAP_SIZE) -DTARGET_$(TARGET) -D__DEBUG__=1
+CFLAGS = -g -I../../vm $(CDEFS)
 UT_SOURCES = $(wildcard ut*.c)
 ALL_SOURCES = runTests.c CuTest.c $(UT_SOURCES)
 OBJS = $(ALL_SOURCES:.c=.o)
 PRODUCT = runTests.out
 
-ifeq ($(TARGET), DESKTOP)
-	CDEFS += -DTARGET_DESKTOP
-endif
-
 .PHONY: all check
 
 # Default action is to build and run tests
 	$(CC) -c -o $@ $<
 
 vm :
-	make -C ../../vm
+	make -C ../../vm DEBUG=true
 
 # Removes files made by default make
 clean :

File src/tests/unit/runTests.c

 /* Need to declare this array since no PyMite application is linked */
 const unsigned char usr_nat_fxn_table[] = {};
 
+CuSuite *getSuite_testHeap(void);
 CuSuite *getSuite_testDict(void);
 CuSuite *getSuite_testList(void);
+CuSuite *getSuite_testSeglist(void);
 
 
 int main(void)
 {
     CuString *output = CuStringNew();
-    CuSuite* suite = CuSuiteNew();
+    CuSuite *suite = CuSuiteNew();
 
+    CuSuiteAddSuite(suite, getSuite_testHeap());
+    CuSuiteAddSuite(suite, getSuite_testSeglist());
     CuSuiteAddSuite(suite, getSuite_testDict());
     CuSuiteAddSuite(suite, getSuite_testList());
 

File src/tests/unit/ut_heap.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.
+ */
+
+
+/**
+ * Heap Unit Tests
+ *
+ * Tests the Heap implementation.
+ *
+ * Log
+ * ---
+ *
+ * 2006/11/21   First.
+ */
+
+
+#include "CuTest.h"
+#include "pm.h"
+
+
+/**
+ * Tests heap_init():
+ *      retval is OK
+ *      avail size is greater than zero
+ */
+void
+ut_heap_init_000(CuTest *tc)
+{
+    uint16_t avail;
+    PmReturn_t retval;
+
+    retval = heap_init();
+
+    CuAssertTrue(tc, retval == PM_RET_OK);
+
+    retval = heap_getAvail(&avail);
+    CuAssertTrue(tc, avail > 0);
+}
+
+
+/**
+ * Tests heap_getChunk():
+ *      retval is OK
+ *      return arg pointer is non-null
+ *      return chunk is of requested size (rounded up to next multiple of four)
+ */
+void
+ut_heap_getChunk_000(CuTest *tc)
+{
+    uint8_t *pchunk;
+    PmReturn_t retval;
+    pPmObj_t pobj;
+
+    retval = heap_init();
+    retval = heap_getChunk(8, &pchunk);
+    pobj = (pPmObj_t)pchunk;
+
+    CuAssertTrue(tc, retval == PM_RET_OK);
+    CuAssertPtrNotNull(tc, pchunk);
+    CuAssertTrue(tc, OBJ_GET_SIZE(*pobj) == 8);
+}
+
+
+/**
+ * Tests heap_getAvail():
+ *      retval is OK
+ *      avail is reduced by amount obtained in getChunk
+ */
+void
+ut_heap_getAvail_000(CuTest *tc)
+{
+    uint16_t avail1;
+    uint16_t avail2;
+    uint8_t *pchunk;
+    PmReturn_t retval;
+
+    retval = heap_init();
+    retval = heap_getAvail(&avail1);
+    CuAssertTrue(tc, retval == PM_RET_OK);
+
+    retval = heap_getChunk(16, &pchunk);
+    retval = heap_getAvail(&avail2);
+    CuAssertTrue(tc, (avail1 - avail2) == 16);
+}
+
+
+/**
+ * Tests heap_freeChunk():
+ *      retval is OK
+ *      avail is increased by amount obtained in freeChunk
+ */
+void
+ut_heap_freeChunk_000(CuTest *tc)
+{
+    uint16_t avail1;
+    uint16_t avail2;
+    uint8_t *pchunk;
+    PmReturn_t retval;
+
+    retval = heap_init();
+    retval = heap_getChunk(16, &pchunk);
+    retval = heap_getAvail(&avail1);
+    retval = heap_freeChunk((pPmObj_t)pchunk);
+    CuAssertTrue(tc, retval == PM_RET_OK);
+
+    retval = heap_getAvail(&avail2);
+    CuAssertTrue(tc, (avail2 - avail1) == 16);
+}
+
+
+/** Make a suite from all tests in this file */
+CuSuite *getSuite_testHeap(void)
+{
+	CuSuite* suite = CuSuiteNew();
+
+	SUITE_ADD_TEST(suite, ut_heap_init_000);
+	SUITE_ADD_TEST(suite, ut_heap_getChunk_000);
+	SUITE_ADD_TEST(suite, ut_heap_getAvail_000);
+	SUITE_ADD_TEST(suite, ut_heap_freeChunk_000);
+
+    return suite;
+}

File src/tests/unit/ut_seglist.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.
+ */
+
+
+/**
+ * Seglist Unit Tests
+ *
+ * Tests the Seglist implementation.
+ *
+ * Log
+ * ---
+ *
+ * 2006/11/22   First.
+ */
+
+
+#include "CuTest.h"
+#include "pm.h"
+
+
+/**
+ * Tests seglist_new():
+ *      retval is OK
+ *      seglist is non-null
+ */
+void
+ut_seglist_new_000(CuTest *tc)
+{
+    PmReturn_t retval;
+    pSeglist_t pseglist;
+
+    retval = seglist_new(&pseglist);
+
+    CuAssertTrue(tc, retval == PM_RET_OK);
+    CuAssertPtrNotNull(tc, pseglist);
+}
+
+
+/**
+ * Tests seglist_appendItem()
+ *      retval is OK
+ *      length is incremented
+ */
+void
+ut_seglist_appendItem_000(CuTest *tc)
+{
+    PmReturn_t retval;
+    pSeglist_t pseglist;
+
+    retval = seglist_new(&pseglist);
+    retval = seglist_appendItem(pseglist, PM_ZERO);
+
+    CuAssertTrue(tc, retval == PM_RET_OK);
+    CuAssertTrue(tc, pseglist->sl_length == 1);
+}
+
+
+/**
+ * Tests seglist_appendItem() nine times
+ *      retval is OK
+ *      length is 9
+ */
+void
+ut_seglist_appendItem_001(CuTest *tc)
+{
+    PmReturn_t retval;
+    pSeglist_t pseglist;
+    int8_t i;
+
+    retval = seglist_new(&pseglist);
+    for (i=8; i>0; i--)
+    {
+        seglist_appendItem(pseglist, PM_ZERO);
+    }
+    retval = seglist_appendItem(pseglist, PM_ONE);
+
+    CuAssertTrue(tc, retval == PM_RET_OK);
+    CuAssertTrue(tc, pseglist->sl_length == 9);
+}
+
+
+/**
+ * Tests seglist_insertItem()
+ *      retval is OK
+ *      length is incremented
+ */
+void
+ut_seglist_insertItem_000(CuTest *tc)
+{
+    PmReturn_t retval;
+    pSeglist_t pseglist;
+
+    retval = seglist_new(&pseglist);
+    retval = seglist_insertItem(pseglist, PM_ZERO, 0);
+
+    CuAssertTrue(tc, retval == PM_RET_OK);
+    CuAssertTrue(tc, pseglist->sl_length == 1);
+}
+
+
+/**
+ * Tests seglist_insertItem() nine times
+ *      retval is OK
+ *      length is 9
+ */
+void
+ut_seglist_insertItem_001(CuTest *tc)
+{
+    PmReturn_t retval;
+    pSeglist_t pseglist;
+    int8_t i;
+
+    retval = seglist_new(&pseglist);
+    retval = seglist_insertItem(pseglist, PM_ONE, 0);
+    for (i=8; i>0; i--)
+    {
+        seglist_insertItem(pseglist, PM_ZERO, 0);
+    }
+
+    CuAssertTrue(tc, retval == PM_RET_OK);
+    CuAssertTrue(tc, pseglist->sl_length == 9);
+}
+
+
+/**
+ * Tests seglist_insertItem with more than one segment:
+ *      retval is OK
+ *      first and last items are the given objs
+ */
+void
+ut_seglist_insertItem_002(CuTest *tc)
+{
+    PmReturn_t retval;
+    pSeglist_t pseglist;
+    pPmObj_t pobj;
+    int8_t i;
+
+    seglist_new(&pseglist);
+    seglist_insertItem(pseglist, PM_ONE, 0);
+    for (i=8; i>0; i--)
+    {
+        seglist_insertItem(pseglist, PM_ZERO, 0);
+    }
+    retval = seglist_getItem(pseglist, 0, &pobj);
+    CuAssertTrue(tc, retval == PM_RET_OK);
+    CuAssertTrue(tc, pobj == PM_ZERO);
+
+    retval = seglist_getItem(pseglist, 8, &pobj);
+    CuAssertTrue(tc, retval == PM_RET_OK);
+    CuAssertTrue(tc, pobj == PM_ONE);
+}
+
+
+/**
+ * Tests seglist_getItem()
+ *      retval is OK
+ *      obj matches the given obj
+ */
+void
+ut_seglist_getItem_000(CuTest *tc)
+{
+    PmReturn_t retval;
+    pSeglist_t pseglist;
+    pPmObj_t pobj;
+
+    seglist_new(&pseglist);
+    seglist_appendItem(pseglist, PM_ZERO);
+    retval = seglist_getItem(pseglist, 0, &pobj);
+
+    CuAssertTrue(tc, retval == PM_RET_OK);
+    CuAssertTrue(tc, pobj == PM_ZERO);
+}
+
+
+/**
+ * Tests seglist_getItem() nine times
+ *      retval is OK
+ *      first and last items are the given objs
+ */
+void
+ut_seglist_getItem_001(CuTest *tc)
+{
+    PmReturn_t retval;
+    pSeglist_t pseglist;
+    pPmObj_t pobj;
+    int8_t i;
+
+    retval = seglist_new(&pseglist);
+    for (i=8; i>0; i--)
+    {
+        seglist_appendItem(pseglist, PM_ZERO);
+    }
+    seglist_appendItem(pseglist, PM_ONE);
+    retval = seglist_getItem(pseglist, 0, &pobj);
+    CuAssertTrue(tc, retval == PM_RET_OK);
+    CuAssertTrue(tc, pobj == PM_ZERO);
+
+    retval = seglist_getItem(pseglist, 8, &pobj);
+    CuAssertTrue(tc, retval == PM_RET_OK);
+    CuAssertTrue(tc, pobj == PM_ONE);
+}
+
+
+/** Make a suite from all tests in this file */
+CuSuite *getSuite_testSeglist(void)
+{
+	CuSuite* suite = CuSuiteNew();
+
+	SUITE_ADD_TEST(suite, ut_seglist_new_000);
+    SUITE_ADD_TEST(suite, ut_seglist_appendItem_000);
+    SUITE_ADD_TEST(suite, ut_seglist_appendItem_001);
+    SUITE_ADD_TEST(suite, ut_seglist_insertItem_000);
+    SUITE_ADD_TEST(suite, ut_seglist_insertItem_001);
+    SUITE_ADD_TEST(suite, ut_seglist_insertItem_002);
+    SUITE_ADD_TEST(suite, ut_seglist_getItem_000);
+    SUITE_ADD_TEST(suite, ut_seglist_getItem_001);
+
+    return suite;
+}

File src/vm/dict.c

 dict_setItem(pPmObj_t pdict, pPmObj_t pkey, pPmObj_t pval)
 {
     PmReturn_t retval = PM_RET_OK;
-    int8_t segnum = 0;
-    int8_t indx = 0;
+    int16_t indx = 0;
 
     /* if null parms, raise SystemError */
     if ((pdict == C_NULL)
     /* XXX if key's hash hasn't been calculated */
 
     /* check for matching key */
-    retval = seglist_findEqual(((pPmDict_t)pdict)->d_keys,
-                               pkey,
-                               &segnum,
-                               &indx);
+    retval = seglist_findEqual(((pPmDict_t)pdict)->d_keys, pkey, &indx);
 
     /* if found a matching key, replace val obj */
     if (retval == PM_RET_OK)
     {
-        retval = seglist_setItem(((pPmDict_t)pdict)->d_vals,
-                                 pval,
-                                 segnum,
-                                 indx);
-        PM_RETURN_IF_ERROR(retval);
-        /* incr length */
-        ((pPmDict_t)pdict)->length++;
-        return PM_RET_OK;
+        retval = seglist_setItem(((pPmDict_t)pdict)->d_vals, pval, indx);
+        return retval;
     }
 
     /* if no matching key, insert the key,val pair */
     if (retval == PM_RET_NO)
     {
-        retval = seglist_insertItem(((pPmDict_t)pdict)->d_keys,
-                                    pkey,
-                                    0,
-                                    0);
-        /* XXX if error here, dict might be hosed */
+        retval = seglist_insertItem(((pPmDict_t)pdict)->d_keys, pkey, 0);
         PM_RETURN_IF_ERROR(retval);
-        retval = seglist_insertItem(((pPmDict_t)pdict)->d_vals,
-                                    pval,
-                                    0,
-                                    0);
+        retval = seglist_insertItem(((pPmDict_t)pdict)->d_vals, pval, 0);
         PM_RETURN_IF_ERROR(retval);
-        /* incr length */
         ((pPmDict_t)pdict)->length++;
         return PM_RET_OK;
     }
 dict_getItem(pPmObj_t pdict, pPmObj_t pkey, pPmObj_t * r_pobj)
 {
     PmReturn_t retval = PM_RET_OK;
-    int8_t segnum = 0;
-    int8_t indx = 0;
+    int16_t indx = 0;
 
     /* if dict is null, raise SystemError */
     if (pdict == C_NULL)
     }
 
     /* check for matching key */
-    retval = seglist_findEqual(((pPmDict_t)pdict)->d_keys,
-                               pkey,
-                               &segnum,
-                               &indx);
+    retval = seglist_findEqual(((pPmDict_t)pdict)->d_keys, pkey, &indx);
     /* if key not found, raise KeyError */
     if (retval == PM_RET_NO)
     {
     PM_RETURN_IF_ERROR(retval);
 
     /* key was found, get obj from vals */
-    retval = seglist_getItem(((pPmDict_t)pdict)->d_vals,
-                             segnum,
-                             indx,
-                             r_pobj);
+    retval = seglist_getItem(((pPmDict_t)pdict)->d_vals, indx, r_pobj);
     return retval;
 }
 

File src/vm/dict.h

 /**
  * Dict
  *
- * Contains ptr to two seglists; 
- * one for keys, the other for values
+ * Contains ptr to two seglists,
+ * one for keys, the other for values;
+ * and a length, the number of key/value pairs.
  */
 typedef struct PmDict_s
 {

File src/vm/heap.c

 
     return PM_RET_OK;
 }
+
+
+PmReturn_t
+heap_getAvail(uint16_t *r_avail)
+{
+    *r_avail = pmHeap.avail;
+    return PM_RET_OK;
+}

File src/vm/heap.h

  * Macros
  **************************************************************/
 
+#ifdef __DEBUG__
+#define DEBUG_PRINT_HEAP_AVAIL(s) \
+    do { uint16_t n; heap_getAvail(&n); printf(s "heap avail = %d\n", n); } \
+    while (0)
+#else
+#define DEBUG_PRINT_HEAP_AVAIL(s)
+#endif
+
+
 /***************************************************************
  * Types
  **************************************************************/
  */
 PmReturn_t heap_freeChunk(pPmObj_t);
 
+/**
+ * Returns the number of bytes available in the heap
+ *
+ * @param   r_avail Return arg; number of bytes available in the heap
+ * @return  Return code
+ */
+PmReturn_t heap_getAvail(uint16_t *r_avail);
+
 #endif /* __HEAP_H__ */

File src/vm/interp.c

                 break;
 
             case BINARY_MULTIPLY:
-                /* if both objs are ints, simple multiply */
-                if ((OBJ_GET_TYPE(*TOS)  == OBJ_TYPE_INT)
+            case INPLACE_MULTIPLY:
+                /* If both objs are ints, perform the op */
+                if ((OBJ_GET_TYPE(*TOS) == OBJ_TYPE_INT)
                     && (OBJ_GET_TYPE(*TOS1) == OBJ_TYPE_INT))
                 {
                     pobj1 = PM_POP();
-                    retval = int_new(
-                                ((pPmInt_t)PM_POP())->val *
-                                ((pPmInt_t)pobj1)->val,
-                                &pobj2);
+                    pobj2 = PM_POP();
+                    retval = int_new(((pPmInt_t)pobj2)->val *
+                                     ((pPmInt_t)pobj1)->val,
+                                     &pobj3);
                     PM_BREAK_IF_ERROR(retval);
-                    PM_PUSH(pobj2);
+                    PM_PUSH(pobj3);
                     continue;
                 }
 
-                /* if it's a list replication operation */
+                /* If it's a list replication operation */
                 else if ((OBJ_GET_TYPE(*TOS)  == OBJ_TYPE_INT)
                          && (OBJ_GET_TYPE(*TOS1) == OBJ_TYPE_LST))
                 {
 
                     /* list that is copied */
                     pobj2 = PM_POP();
-                    retval = list_replicate(pobj2,
-                                            t16,
-                                            &pobj3);
+                    retval = list_replicate(pobj2, t16, &pobj3);
                     PM_BREAK_IF_ERROR(retval);
                     PM_PUSH(pobj3);
                     continue;
                 }
 
-                /* else it's a TypeError */
-                else
+                /* Otherwise raise a TypeError */
+                PM_RAISE(retval, PM_RET_EX_TYPE);
+                break;
+
+            case BINARY_DIVIDE:
+            case INPLACE_DIVIDE:
+                /* Raise TypeError if args aren't ints */
+                if ((OBJ_GET_TYPE(*TOS) != OBJ_TYPE_INT)
+                    || (OBJ_GET_TYPE(*TOS1) != OBJ_TYPE_INT))
                 {
                     PM_RAISE(retval, PM_RET_EX_TYPE);
                     break;
                 }
 
-            case BINARY_DIVIDE:
-                /* if both objs are ints, simple divide */
-                if ((OBJ_GET_TYPE(*TOS)  == OBJ_TYPE_INT)
-                    && (OBJ_GET_TYPE(*TOS1) == OBJ_TYPE_INT))
+                /* Raise ZeroDivisionError if denominator is zero */
+                if (((pPmInt_t)TOS)->val == 0)
                 {
-                    pobj1 = PM_POP();
-
-                    /* ZeroDivisionError */
-                    if (((pPmInt_t)pobj1)->val == 0)
-                    {
-                        PM_RAISE(retval, PM_RET_EX_ZDIV);
-                        break;
-                    }
-                    /* perform division */
-                    retval = int_new(
-                                ((pPmInt_t)PM_POP())->val /
-                                ((pPmInt_t)pobj1)->val,
-                                &pobj2);
-                    PM_BREAK_IF_ERROR(retval);
-                    PM_PUSH(pobj2);
-                    continue;
+                    PM_RAISE(retval, PM_RET_EX_ZDIV);
+                    break;
                 }
 
-                /* else it's a TypeError */
-                else
+                /* Otherwise perform operation */
+                pobj1 = PM_POP();
+                pobj2 = PM_POP();
+                retval = int_new(((pPmInt_t)pobj2)->val /
+                                 ((pPmInt_t)pobj1)->val,
+                                 &pobj3);
+                PM_BREAK_IF_ERROR(retval);
+                PM_PUSH(pobj3);
+                continue;
+
+            case BINARY_MODULO:
+            case INPLACE_MODULO:
+                /* Raise TypeError if args aren't ints */
+                if ((OBJ_GET_TYPE(*TOS) != OBJ_TYPE_INT)
+                    || (OBJ_GET_TYPE(*TOS1) != OBJ_TYPE_INT))
                 {
                     PM_RAISE(retval, PM_RET_EX_TYPE);
                     break;
                 }
 
-            case BINARY_MODULO:
-                /* if both objs are ints, perform modulo */
-                if ((OBJ_GET_TYPE(*TOS)  == OBJ_TYPE_INT)
-                    && (OBJ_GET_TYPE(*TOS1) == OBJ_TYPE_INT))
+                /* Raise ZeroDivisionError if denominator is zero */
+                if (((pPmInt_t)TOS)->val == 0)
                 {
-                    pobj1 = PM_POP();
-                    /* ZeroDivisionError */
-                    if (((pPmInt_t)pobj1)->val == 0)
-                    {
-                        PM_RAISE(retval, PM_RET_EX_ZDIV);
-                        break;
-                    }
-                    retval = int_new(
-                                ((pPmInt_t)PM_POP())->val %
-                                ((pPmInt_t)pobj1)->val,
-                                &pobj2);
-                    PM_BREAK_IF_ERROR(retval);
-                    PM_PUSH(pobj2);
-                    continue;
-                }
-
-                /* else it's a TypeError */
-                else
-                {
-                    PM_RAISE(retval, PM_RET_EX_TYPE);
+                    PM_RAISE(retval, PM_RET_EX_ZDIV);
                     break;
                 }
 
+                /* Otherwise perform operation */
+                pobj1 = PM_POP();
+                pobj2 = PM_POP();
+                retval = int_new(((pPmInt_t)pobj2)->val %
+                                 ((pPmInt_t)pobj1)->val,
+                                 &pobj3);
+                PM_BREAK_IF_ERROR(retval);
+                PM_PUSH(pobj3);
+                continue;
+
             case BINARY_ADD:
-                /* if both objs are ints, perform the op */
+            case INPLACE_ADD:
+                /* If both objs are ints, perform the op */
                 if ((OBJ_GET_TYPE(*TOS) == OBJ_TYPE_INT)
                     && (OBJ_GET_TYPE(*TOS1) == OBJ_TYPE_INT))
                 {
                     pobj1 = PM_POP();
-                    retval = int_new(
-                                ((pPmInt_t)PM_POP())->val +
-                                ((pPmInt_t)pobj1)->val,
-                                &pobj2);
+                    pobj2 = PM_POP();
+                    retval = int_new(((pPmInt_t)pobj2)->val +
+                                     ((pPmInt_t)pobj1)->val,
+                                     &pobj3);
                     PM_BREAK_IF_ERROR(retval);
-                    PM_PUSH(pobj2);
+                    PM_PUSH(pobj3);
                     continue;
                 }
 
-                /* else it's a TypeError */
-                else
-                {
-                    PM_RAISE(retval, PM_RET_EX_TYPE);
-                    break;
-                }
+                /* Otherwise raise a TypeError */
+                PM_RAISE(retval, PM_RET_EX_TYPE);
+                break;
 
             case BINARY_SUBTRACT:
-                /* if both objs are ints, perform the op */
+            case INPLACE_SUBTRACT:
+                /* If both objs are ints, perform the op */
                 if ((OBJ_GET_TYPE(*TOS) == OBJ_TYPE_INT)
                     && (OBJ_GET_TYPE(*TOS1) == OBJ_TYPE_INT))
                 {
                     pobj1 = PM_POP();
-                    retval = int_new(
-                                ((pPmInt_t)PM_POP())->val -
-                                ((pPmInt_t)pobj1)->val,
-                                &pobj2);
+                    pobj2 = PM_POP();
+                    retval = int_new(((pPmInt_t)pobj2)->val -
+                                     ((pPmInt_t)pobj1)->val,
+                                     &pobj3);
                     PM_BREAK_IF_ERROR(retval);
-                    PM_PUSH(pobj2);
+                    PM_PUSH(pobj3);
                     continue;
                 }
 
-                /* else it's a TypeError */
-                else
-                {
-                    PM_RAISE(retval, PM_RET_EX_TYPE);
-                    break;
-                }
+                /* Otherwise raise a TypeError */
+                PM_RAISE(retval, PM_RET_EX_TYPE);
+                break;
 
             case BINARY_SUBSCR:
                 /* Implements TOS = TOS1[TOS]. */
                 PM_RAISE(retval, PM_RET_EX_SYS);
                 break;
 
-            case INPLACE_ADD:
-                if ((OBJ_GET_TYPE(*TOS)  == OBJ_TYPE_INT)
-                    && (OBJ_GET_TYPE(*TOS1) == OBJ_TYPE_INT))
-                {
-                    /* if int is constant, make new result */
-                    if (OBJ_IS_CONST(*TOS1)) {
-                        pobj1 = PM_POP();
-                        retval = int_new(
-                                    ((pPmInt_t)PM_POP())->val +
-                                    ((pPmInt_t)pobj1)->val,
-                                    &pobj2);
-                        PM_BREAK_IF_ERROR(retval);
-                        PM_PUSH(pobj2);
-                    }
-
-                    /* else result stores in-place */
-                    else
-                    {
-                        ((pPmInt_t)TOS1)->val +=
-                                ((pPmInt_t)TOS)->val;
-                        SP--;
-                    }
-                    continue;
-                }
-
-                /* TypeError; unsupported type */
-                else
-                {
-                    PM_RAISE(retval, PM_RET_EX_TYPE);
-                    break;
-                }
-
-            case INPLACE_SUBTRACT:
-                if ((OBJ_GET_TYPE(*TOS) == OBJ_TYPE_INT)
-                    && (OBJ_GET_TYPE(*TOS1) == OBJ_TYPE_INT))
-                {
-                    /* if target obj is a constant obj */
-                    if (OBJ_IS_CONST(*TOS1)) {
-                        pobj1 = PM_POP();
-                        retval = int_new(
-                                    ((pPmInt_t)PM_POP())->val -
-                                    ((pPmInt_t)pobj1)->val,
-                                    &pobj2);
-                        PM_BREAK_IF_ERROR(retval);
-                        PM_PUSH(pobj2);
-                    }
-
-                    /* otherwise do true in-place operation */
-                    else
-                    {
-                        ((pPmInt_t)TOS1)->val -=
-                                ((pPmInt_t)TOS)->val;
-                        SP--;
-                    }
-                    continue;
-                }
-
-                /* TypeError; unsupported type */
-                else
-                {
-                    PM_RAISE(retval, PM_RET_EX_TYPE);
-                    break;
-                }
-
-            case INPLACE_MULTIPLY:
-                if ((OBJ_GET_TYPE(*TOS) == OBJ_TYPE_INT)
-                    && (OBJ_GET_TYPE(*TOS1) == OBJ_TYPE_INT))
-                {
-                    /* if target obj is a constant obj */
-                    if (OBJ_IS_CONST(*TOS1)) {
-                        pobj1 = PM_POP();
-                        retval = int_new(
-                                    ((pPmInt_t)PM_POP())->val *
-                                    ((pPmInt_t)pobj1)->val,
-                                    &pobj2);
-                        PM_BREAK_IF_ERROR(retval);
-                        PM_PUSH(pobj2);
-                    }
-
-                    /* otherwise do true in-place operation */
-                    else
-                    {
-                        ((pPmInt_t)TOS1)->val *=
-                                ((pPmInt_t)TOS)->val;
-                        SP--;
-                    }
-                    continue;
-                }
-
-                /* TypeError; unsupported type */
-                else
-                {
-                    PM_RAISE(retval, PM_RET_EX_TYPE);
-                    break;
-                }
-
-            case INPLACE_DIVIDE:
-                /* TypeError; unsupported type */
-                if ((OBJ_GET_TYPE(*TOS) != OBJ_TYPE_INT)
-                    || (OBJ_GET_TYPE(*TOS1) != OBJ_TYPE_INT))
-                {
-                    PM_RAISE(retval, PM_RET_EX_TYPE);
-                    break;
-                }
-
-                /* ZeroDivisionError */
-                if (((pPmInt_t)TOS)->val == 0)
-                {
-                    PM_RAISE(retval, PM_RET_EX_ZDIV);
-                    break;
-                }
-
-                /* if target obj is a constant obj */
-                if (OBJ_IS_CONST(*TOS1)) {
-                    pobj1 = PM_POP();
-                    retval = int_new(
-                                ((pPmInt_t)PM_POP())->val /
-                                ((pPmInt_t)pobj1)->val,
-                                &pobj2);
-                    PM_BREAK_IF_ERROR(retval);
-                    PM_PUSH(pobj2);
-                }
-
-                /* otherwise do true in-place operation */
-                else
-                {
-                    ((pPmInt_t)TOS1)->val /=
-                            ((pPmInt_t)TOS)->val;
-                    SP--;
-                }
-                continue;
-
-            case INPLACE_MODULO:
-                /* TypeError; unsupported type */
-                if ((OBJ_GET_TYPE(*TOS) != OBJ_TYPE_INT)
-                    || (OBJ_GET_TYPE(*TOS1) != OBJ_TYPE_INT))
-                {
-                    PM_RAISE(retval, PM_RET_EX_TYPE);
-                    break;
-                }
-
-                /* ZeroDivisionError */
-                if (((pPmInt_t)TOS)->val == 0)
-                {
-                    PM_RAISE(retval, PM_RET_EX_ZDIV);
-                    break;
-                }
-
-                /* if target obj is a constant obj */
-                if (OBJ_IS_CONST(*TOS1)) {
-                    pobj1 = PM_POP();
-                    retval = int_new(
-                                ((pPmInt_t)PM_POP())->val %
-                                ((pPmInt_t)pobj1)->val,
-                                &pobj2);
-                    PM_BREAK_IF_ERROR(retval);
-                    PM_PUSH(pobj2);
-                }
-
-                /* otherwise do true in-place operation */
-                else
-                {
-                    ((pPmInt_t)TOS1)->val %=
-                            ((pPmInt_t)TOS)->val;
-                    SP--;
-                }
-                continue;
-
             case STORE_SUBSCR:
                 /* implements TOS1[TOS] = TOS2 */
                 pobj1 = PM_POP();
                 break;
 
             case BINARY_LSHIFT:
-                /* If either arg is not an int, raise a TypeError */
-                if ((OBJ_GET_TYPE(*TOS) != OBJ_TYPE_INT)
-                    || (OBJ_GET_TYPE(*TOS1) != OBJ_TYPE_INT))
+            case INPLACE_LSHIFT:
+                /* If both objs are ints, perform the op */
+                if ((OBJ_GET_TYPE(*TOS) == OBJ_TYPE_INT)
+                    && (OBJ_GET_TYPE(*TOS1) == OBJ_TYPE_INT))
                 {
-                    PM_RAISE(retval, PM_RET_EX_TYPE);
-                    break;
+                    pobj1 = PM_POP();
+                    pobj2 = PM_POP();
+                    retval = int_new(((pPmInt_t)pobj2)->val <<
+                                     ((pPmInt_t)pobj1)->val,
+                                     &pobj3);
+                    PM_BREAK_IF_ERROR(retval);
+                    PM_PUSH(pobj3);
+                    continue;
                 }
 
-                pobj1 = PM_POP();
-                retval = int_new(
-                            ((pPmInt_t)PM_POP())->val <<
-                            ((pPmInt_t)pobj1)->val,
-                            &pobj2);
-                PM_BREAK_IF_ERROR(retval);
-                PM_PUSH(pobj2);
-                continue;
+                /* Otherwise raise a TypeError */
+                PM_RAISE(retval, PM_RET_EX_TYPE);
+                break;
 
             case BINARY_RSHIFT:
-                /* If either arg is not an int, raise a TypeError */
-                if ((OBJ_GET_TYPE(*TOS) != OBJ_TYPE_INT)
-                    || (OBJ_GET_TYPE(*TOS1) != OBJ_TYPE_INT))
+            case INPLACE_RSHIFT:
+                /* If both objs are ints, perform the op */
+                if ((OBJ_GET_TYPE(*TOS) == OBJ_TYPE_INT)
+                    && (OBJ_GET_TYPE(*TOS1) == OBJ_TYPE_INT))
                 {
-                    PM_RAISE(retval, PM_RET_EX_TYPE);
-                    break;
+                    pobj1 = PM_POP();
+                    pobj2 = PM_POP();
+                    retval = int_new(((pPmInt_t)pobj2)->val >>
+                                     ((pPmInt_t)pobj1)->val,
+                                     &pobj3);
+                    PM_BREAK_IF_ERROR(retval);
+                    PM_PUSH(pobj3);
+                    continue;
                 }
 
-                pobj1 = PM_POP();
-                retval = int_new(
-                            ((pPmInt_t)PM_POP())->val >>
-                            ((pPmInt_t)pobj1)->val,
-                            &pobj2);
-                PM_BREAK_IF_ERROR(retval);
-                PM_PUSH(pobj2);
-                continue;
+                /* Otherwise raise a TypeError */
+                PM_RAISE(retval, PM_RET_EX_TYPE);
+                break;
 
             case BINARY_AND:
-                /* If either arg is not an int, raise a TypeError */
-                if ((OBJ_GET_TYPE(*TOS) != OBJ_TYPE_INT)
-                    || (OBJ_GET_TYPE(*TOS1) != OBJ_TYPE_INT))
+            case INPLACE_AND:
+                /* If both objs are ints, perform the op */
+                if ((OBJ_GET_TYPE(*TOS) == OBJ_TYPE_INT)
+                    && (OBJ_GET_TYPE(*TOS1) == OBJ_TYPE_INT))
                 {
-                    PM_RAISE(retval, PM_RET_EX_TYPE);
-                    break;
+                    pobj1 = PM_POP();
+                    pobj2 = PM_POP();
+                    retval = int_new(((pPmInt_t)pobj2)->val &
+                                     ((pPmInt_t)pobj1)->val,
+                                     &pobj3);
+                    PM_BREAK_IF_ERROR(retval);
+                    PM_PUSH(pobj3);
+                    continue;
                 }
 
-                pobj1 = PM_POP();
-                retval = int_new(
-                            ((pPmInt_t)PM_POP())->val &
-                            ((pPmInt_t)pobj1)->val,
-                            &pobj2);
-                PM_BREAK_IF_ERROR(retval);
-                PM_PUSH(pobj2);
-                continue;
+                /* Otherwise raise a TypeError */
+                PM_RAISE(retval, PM_RET_EX_TYPE);
+                break;
 
             case BINARY_XOR:
-                /* If either arg is not an int, raise a TypeError */
-                if ((OBJ_GET_TYPE(*TOS) != OBJ_TYPE_INT)
-                    || (OBJ_GET_TYPE(*TOS1) != OBJ_TYPE_INT))
+            case INPLACE_XOR:
+                /* If both objs are ints, perform the op */
+                if ((OBJ_GET_TYPE(*TOS) == OBJ_TYPE_INT)
+                    && (OBJ_GET_TYPE(*TOS1) == OBJ_TYPE_INT))
                 {
+                    pobj1 = PM_POP();
+                    pobj2 = PM_POP();
+                    retval = int_new(((pPmInt_t)pobj2)->val ^
+                                     ((pPmInt_t)pobj1)->val,
+                                     &pobj3);
+                    PM_BREAK_IF_ERROR(retval);
+                    PM_PUSH(pobj3);
+                    continue;
+                }
+
+                /* Otherwise raise a TypeError */
                 PM_RAISE(retval, PM_RET_EX_TYPE);
                 break;
+
+            case BINARY_OR:
+            case INPLACE_OR:
+                /* If both objs are ints, perform the op */
+                if ((OBJ_GET_TYPE(*TOS) == OBJ_TYPE_INT)
+                    && (OBJ_GET_TYPE(*TOS1) == OBJ_TYPE_INT))
+                {
+                    pobj1 = PM_POP();
+                    pobj2 = PM_POP();
+                    retval = int_new(((pPmInt_t)pobj2)->val |
+                                     ((pPmInt_t)pobj1)->val,
+                                     &pobj3);
+                    PM_BREAK_IF_ERROR(retval);
+                    PM_PUSH(pobj3);
+                    continue;
                 }
 
-                pobj1 = PM_POP();
-                retval = int_new(
-                            ((pPmInt_t)PM_POP())->val ^
-                            ((pPmInt_t)pobj1)->val,
-                            &pobj2);
-                PM_BREAK_IF_ERROR(retval);
-                PM_PUSH(pobj2);
-                continue;
-
-            case BINARY_OR:
-                /* If either arg is not an int, raise a TypeError */
-                if ((OBJ_GET_TYPE(*TOS) != OBJ_TYPE_INT)
-                    || (OBJ_GET_TYPE(*TOS1) != OBJ_TYPE_INT))
-                {
-                    PM_RAISE(retval, PM_RET_EX_TYPE);
-                    break;
-                }
-                pobj1 = PM_POP();
-                retval = int_new(
-                            ((pPmInt_t)PM_POP())->val |
-                            ((pPmInt_t)pobj1)->val,
-                            &pobj2);
-                PM_BREAK_IF_ERROR(retval);
-                PM_PUSH(pobj2);
-                continue;
+                /* Otherwise raise a TypeError */
+                PM_RAISE(retval, PM_RET_EX_TYPE);
+                break;
 
             case INPLACE_POWER:
             case PRINT_EXPR:
                 PM_RAISE(retval, PM_RET_EX_SYS);
                 break;
 
-            case INPLACE_LSHIFT:
-                /* If either arg is not an int, raise a TypeError */
-                if ((OBJ_GET_TYPE(*TOS) != OBJ_TYPE_INT)
-                    || (OBJ_GET_TYPE(*TOS1) != OBJ_TYPE_INT))
-                {
-                    PM_RAISE(retval, PM_RET_EX_TYPE);
-                    break;
-                }
-
-                /* If target obj is a constant obj */
-                if (OBJ_IS_CONST(*TOS1))
-                {
-                    pobj1 = PM_POP();
-                    retval = int_new(
-                                ((pPmInt_t)PM_POP())->val <<
-                                ((pPmInt_t)pobj1)->val,
-                                &pobj2);
-                    PM_BREAK_IF_ERROR(retval);
-                    PM_PUSH(pobj2);
-                    continue;
-                }
-
-                /* otherwise do true in-place operation */
-                else
-                {
-                    ((pPmInt_t)TOS1)->val <<=
-                            ((pPmInt_t)TOS)->val;
-                    SP--;
-                    continue;
-                }
-
-            case INPLACE_RSHIFT:
-                /* If either arg is not an int, raise a TypeError */
-                if ((OBJ_GET_TYPE(*TOS) != OBJ_TYPE_INT)
-                    || (OBJ_GET_TYPE(*TOS1) != OBJ_TYPE_INT))
-                {
-                    PM_RAISE(retval, PM_RET_EX_TYPE);
-                    break;
-                }
-
-                /* if target obj is a constant obj */
-                if (OBJ_IS_CONST(*TOS1)) {
-                    pobj1 = PM_POP();
-                    retval = int_new(
-                                ((pPmInt_t)PM_POP())->val >>
-                                ((pPmInt_t)pobj1)->val,
-                                &pobj2);
-                    PM_BREAK_IF_ERROR(retval);
-                    PM_PUSH(pobj2);
-                    continue;
-                }
-
-                /* otherwise do true in-place operation */
-                else
-                {
-                    ((pPmInt_t)TOS1)->val >>=
-                            ((pPmInt_t)TOS)->val;
-                    SP--;
-                    continue;
-                }
-
-            case INPLACE_AND:
-                /* If either arg is not an int, raise a TypeError */
-                if ((OBJ_GET_TYPE(*TOS) != OBJ_TYPE_INT)
-                    || (OBJ_GET_TYPE(*TOS1) != OBJ_TYPE_INT))
-                {
-                    PM_RAISE(retval, PM_RET_EX_TYPE);
-                    break;
-                }
-
-                /* if target obj is a constant obj */
-                if (OBJ_IS_CONST(*TOS1)) {
-                    pobj1 = PM_POP();
-                    retval = int_new(
-                                ((pPmInt_t)PM_POP())->val &
-                                ((pPmInt_t)pobj1)->val,
-                                &pobj2);
-                    PM_BREAK_IF_ERROR(retval);
-                    PM_PUSH(pobj2);
-                    continue;
-                }
-
-                /* otherwise do true in-place operation */
-                else
-                {
-                    ((pPmInt_t)TOS1)->val &=
-                            ((pPmInt_t)TOS)->val;
-                    SP--;
-                    continue;
-                }
-
-            case INPLACE_XOR:
-                /* If either arg is not an int, raise a TypeError */
-                if ((OBJ_GET_TYPE(*TOS) != OBJ_TYPE_INT)
-                    || (OBJ_GET_TYPE(*TOS1) != OBJ_TYPE_INT))
-                {
-                    PM_RAISE(retval, PM_RET_EX_TYPE);
-                    break;
-                }
-
-                /* if target obj is a constant obj */
-                if (OBJ_IS_CONST(*TOS1)) {
-                    pobj1 = PM_POP();
-                    retval = int_new(
-                                ((pPmInt_t)PM_POP())->val ^
-                                ((pPmInt_t)pobj1)->val,
-                                &pobj2);
-                    PM_BREAK_IF_ERROR(retval);
-                    PM_PUSH(pobj2);
-                    continue;
-                }
-
-                /* otherwise do true in-place operation */
-                else
-                {
-                    ((pPmInt_t)TOS1)->val ^=
-                            ((pPmInt_t)TOS)->val;
-                    SP--;
-                    continue;
-                }
-
-            case INPLACE_OR:
-                /* If either arg is not an int, raise a TypeError */
-                if ((OBJ_GET_TYPE(*TOS) != OBJ_TYPE_INT)
-                    || (OBJ_GET_TYPE(*TOS1) != OBJ_TYPE_INT))
-                {
-                    PM_RAISE(retval, PM_RET_EX_TYPE);
-                    break;
-                }
-
-                /* if target obj is a constant obj */
-                if (OBJ_IS_CONST(*TOS1)) {
-                    pobj1 = PM_POP();
-                    retval = int_new(
-                                ((pPmInt_t)PM_POP())->val |
-                                ((pPmInt_t)pobj1)->val,
-                                &pobj2);
-                    PM_BREAK_IF_ERROR(retval);
-                    PM_PUSH(pobj2);
-                    continue;
-                }
-
-                /* otherwise do true in-place operation */
-                else
-                {
-                    ((pPmInt_t)TOS1)->val |=
-                            ((pPmInt_t)TOS)->val;
-                    SP--;
-                    continue;
-                }
-
             case BREAK_LOOP:
                 {
                     pPmBlock_t pb1 = FP->fo_blockstack;

File src/vm/list.c

 
     /* incr list length */
     ((pPmList_t)plist)->length++;
-    /* XXX test for max length? */
 
     return retval;
 }
 list_getItem(pPmObj_t plist, int16_t index, pPmObj_t *r_pobj)
 {
     PmReturn_t retval;
-    int16_t segnum = 0;
-    int16_t segindx = 0;
 
     /* If it's not a list, raise TypeError */
     if (OBJ_GET_TYPE(*plist) != OBJ_TYPE_LST)
         return retval;
     }
 
-    /* convert list index into seglist index */
-    segnum = index / SEGLIST_OBJS_PER_SEG;
-    segindx = index % SEGLIST_OBJS_PER_SEG;
-
     /* get item from seglist */
-    retval = seglist_getItem(((pPmList_t)plist)->val,
-                             segnum,
-                             segindx,
-                             r_pobj);
+    retval = seglist_getItem(((pPmList_t)plist)->val, index, r_pobj);
     return retval;
 }
 
 
 PmReturn_t
-list_insert(pPmObj_t plist, int8_t index, pPmObj_t pobj)
+list_insert(pPmObj_t plist, int16_t index, pPmObj_t pobj)
 {
     PmReturn_t retval;
     int16_t len;
-    int8_t segnum;
-    int8_t segindx;
 
     C_ASSERT(plist != C_NULL);
     C_ASSERT(pobj != C_NULL);
     }
 
     /* 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);
+    retval = seglist_insertItem(((pPmList_t)plist)->val, pobj, index);
     PM_RETURN_IF_ERROR(retval);
 
     /* Increment the length of this list */

File src/vm/list.h

  * @return  Return status
  */
 PmReturn_t list_insert(pPmObj_t plist,
-                       int8_t index,
+                       int16_t index,
                        pPmObj_t pobj);
 
 /* XXX TODO - redo these using pobj / return status */
 #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__; \

File src/vm/seglist.c

  * Log
  * ---
  *
+ * 2006/11/18   #54: Change seglist API
  * 2006/08/31   #9: Fix BINARY_SUBSCR for case stringobj[intobj]
  * 2006/08/29   #15 - All mem_*() funcs and pointers in the vm should use
  *              unsigned not signed or void
 PmReturn_t
 seglist_appendItem(pSeglist_t pseglist, pPmObj_t pobj)
 {
-    PmReturn_t retval = PM_RET_OK;
-    pSegment_t pseg = C_NULL;
-    int8_t i = 0;
-    uint8_t *pchunk;
-
-    /* if this is first item in seg, alloc and link seg */
-    if (pseglist->sl_lastindx == 0)
-    {
-        /* alloc and init new segment */
-        retval = heap_getChunk(sizeof(Segment_t), &pchunk);
-        PM_RETURN_IF_ERROR(retval);
-        pseg = (pSegment_t)pchunk;
-        OBJ_SET_TYPE(*pseg, OBJ_TYPE_SEG);
-        for (i = 1; i < SEGLIST_OBJS_PER_SEG; i++)
-        {
-            pseg->s_val[i] = C_NULL;
-        }
-        pseg->next = C_NULL;
-
-        /* if this is the first seg, set as root */
-        if (pseglist->sl_rootseg == C_NULL)
-        {
-            pseglist->sl_rootseg = pseg;
-        }
-
-        /* else append the seg to the end */
-        else
-        {
-            pseglist->sl_lastseg->next = pseg;
-        }
-
-        /* either way, this is now the last segment */
-        pseglist->sl_lastseg = pseg;
-    }
-
-    /* else get last seg */
-    else
-    {
-        pseg = pseglist->sl_lastseg;
-    }
-
-    /* put object into segment */
-    pseg->s_val[pseglist->sl_lastindx] = pobj;
-
-    /* increment last index and reset if necessary */
-    if (++(pseglist->sl_lastindx) >= SEGLIST_OBJS_PER_SEG)
-    {
-        pseglist->sl_lastindx = 0;
-    }
-
-    return retval;
+    return seglist_insertItem(pseglist, pobj, pseglist->sl_length);
 }
 
 
     /* clear seglist fields */
     ((pSeglist_t)pseglist)->sl_rootseg = C_NULL;
     ((pSeglist_t)pseglist)->sl_lastseg = C_NULL;
-    ((pSeglist_t)pseglist)->sl_lastindx = 0;
+    ((pSeglist_t)pseglist)->sl_length = 0;
 
     return PM_RET_OK;
 }
 
 
 PmReturn_t
-seglist_findEqual(pSeglist_t pseglist,
-                  pPmObj_t pobj,
-                  int8_t *r_segnum,
-                  int8_t *r_indx)
+seglist_findEqual(pSeglist_t pseglist, pPmObj_t pobj, int16_t *r_index)
 {
-    pSegment_t pseg = C_NULL;
+    pSegment_t pseg;
     int8_t i = 0;
-    PmReturn_t retval;
+    uint8_t segindex;
 
     C_ASSERT(pseglist != C_NULL);
     C_ASSERT(pobj != C_NULL);
+    C_ASSERT((*r_index >= 0));
+    C_ASSERT((*r_index == 0) || (*r_index < pseglist->sl_length));
 
-    /* if index is out of bounds, raise SystemError */
-    if ((*r_indx < 0) || (*r_indx > SEGLIST_OBJS_PER_SEG))
+    /* Walk out to the starting segment */
+    pseg = pseglist->sl_rootseg;
+    for (i = (*r_index / SEGLIST_OBJS_PER_SEG); i > 0; i--)
     {
-        PM_RAISE(retval, PM_RET_EX_SYS);
-        return retval;
-    }
-
-    /* set pseg to the segnum'th segment in the list */
-    pseg = pseglist->sl_rootseg;
-    for (i = *r_segnum; i > 0; i--)
-    {
-        /*
-         * if the given segnum is larger than
-         * the number of segments, raise SystemError
-         */
-        if (pseg == C_NULL)
-        {
-            PM_RAISE(retval, PM_RET_EX_SYS);
-            return retval;
-        }
+        C_ASSERT(pseg != C_NULL);
         pseg = pseg->next;
     }
 
-    /* start search from this segment */
-    while (pseg != C_NULL)
+    /* Set the starting index within the segment */
+    segindex = *r_index % SEGLIST_OBJS_PER_SEG;
+
+    /* Search the remaining segments */
+    for ( ; pseg != C_NULL; pseg = pseg->next)
     {
-        while (*r_indx < SEGLIST_OBJS_PER_SEG)
+        while (segindex < SEGLIST_OBJS_PER_SEG)
         {
-            /* if seglist entry is null, we're past the end */
-            if (pseg->s_val[*r_indx] == C_NULL)
+            /* If past the end of the seglist, return no item found */
+            if (*r_index >= pseglist->sl_length)
             {
                 return PM_RET_NO;
             }
 
-            /*
-             * if the two objs are equal, return affirmation
-             * with segnum and indx referring to matching obj.
-             */
-            if (obj_compare(pobj, pseg->s_val[*r_indx]) == C_SAME)
+            /* If items are equal, return with index of found item */
+            if (obj_compare(pobj, pseg->s_val[segindex]) == C_SAME)
             {
                 return PM_RET_OK;
             }
-            (*r_indx)++;
+
+            /* Proceed to next item */
+            segindex++;
+            (*r_index)++;
         }
 
-        /* move on to next segment */
-        *r_indx = 0;
-        pseg = pseg->next;
-        (*r_segnum)++;
+        /* Proceed to next segment */
+        segindex = 0;
     }
     return PM_RET_NO;
 }
 
 
 PmReturn_t
-seglist_getItem(pSeglist_t pseglist,
-                int8_t segnum,
-                int8_t segindx,
-                pPmObj_t * r_pobj)
+seglist_getItem(pSeglist_t pseglist, int16_t index, pPmObj_t *r_pobj)
 {
-    pSegment_t pseg = pseglist->sl_rootseg;
-    PmReturn_t retval;
+    pSegment_t pseg;
+    int16_t i;
 
-    /* scan to proper seg, error check along the way */
-    for (; segnum > 0; segnum--)
+    C_ASSERT(pseglist != C_NULL);
+    C_ASSERT(index >= 0);
+    C_ASSERT(index < pseglist->sl_length);
+
+    /* Walk out to the proper segment */
+    pseg = pseglist->sl_rootseg;
+    C_ASSERT(pseg != C_NULL);
+    for (i = (index / SEGLIST_OBJS_PER_SEG); i > 0; i--)
     {
-        /* if went past last segment, return nothing */
-        if (pseg == C_NULL)
-        {
-            PM_RAISE(retval, PM_RET_EX_SYS);
-            return retval;
-        }
         pseg = pseg->next;
+        C_ASSERT(pseg != C_NULL);
     }
 
-    /* if indx asks for obj beyond the seglist's last one */
-    if ((pseg == pseglist->sl_lastseg)
-        && (segindx >= pseglist->sl_lastindx))
-    {
-        PM_RAISE(retval, PM_RET_EX_SYS);
-        return retval;
-    }
-
-    /* return ptr to obj in this seg at the index */
-    *r_pobj = pseg->s_val[segindx];
+    /* Return ptr to obj in this seg at the index */
+    *r_pobj = pseg->s_val[index % SEGLIST_OBJS_PER_SEG];
     return PM_RET_OK;
 }
 
 
 PmReturn_t
-seglist_insertItem(pSeglist_t pseglist,
-                   pPmObj_t pobj,
-                   int8_t segnum,
-                   int8_t segindx)
+seglist_insertItem(pSeglist_t pseglist, pPmObj_t pobj, int16_t index)
 {
     PmReturn_t retval = PM_RET_OK;
     pSegment_t pseg = C_NULL;
     pPmObj_t pobj1 = C_NULL;
     pPmObj_t pobj2 = C_NULL;
     int8_t indx = 0;
-    int8_t i = 0;
+    int16_t i = 0;
     uint8_t *pchunk;
 
-    /* if the seglist has no segment, insert one */
-    if (pseglist->sl_rootseg == C_NULL)
+    C_ASSERT(index <= pseglist->sl_length);
+
+    /* If this is first item in seg */
+    if ((pseglist->sl_length % SEGLIST_OBJS_PER_SEG) == 0)
     {
-        /* alloc and init segment */
+        /* Alloc and init new segment */
         retval = heap_getChunk(sizeof(Segment_t), &pchunk);
         PM_RETURN_IF_ERROR(retval);
-        pseglist->sl_rootseg = (pSegment_t)pchunk;
-        OBJ_SET_TYPE(*pseglist->sl_rootseg, OBJ_TYPE_SEG);
+        pseg = (pSegment_t)pchunk;
+        OBJ_SET_TYPE(*pseg, OBJ_TYPE_SEG);
+        sli_memset((unsigned char *)pseg->s_val,
+                   0,
+                   SEGLIST_OBJS_PER_SEG * sizeof(pPmObj_t));
+        pseg->next = C_NULL;
 
-        /* seglist refers to the new segment */
-        pseglist->sl_lastseg = pseglist->sl_rootseg;
-        pseglist->sl_lastindx = 0;
-
-        /* if past end of list */
-        if ((segnum != 0) || (segindx != 0))
+        /* If this is the first seg, set as root */
+        if (pseglist->sl_rootseg == C_NULL)
         {
-            PM_RAISE(retval, PM_RET_EX_SYS);
-            return retval;
+            pseglist->sl_rootseg = pseg;
         }
 
-        /* insert obj in seglist */
-        pseglist->sl_rootseg->s_val[0] = pobj;
-        pseglist->sl_lastindx++;
-        return PM_RET_OK;
+        /* Else append the seg to the end */
+        else
+        {
+            pseglist->sl_lastseg->next = pseg;
+        }
+
+        /* Either way, this is now the last segment */
+        pseglist->sl_lastseg = pseg;
     }
 
-    /* else, iterate until pseg pts to segnum'th segment */
-    for (pseg = pseglist->sl_rootseg; segnum > 0; segnum--)
+    /* Else get last seg */
+    else
+    {
+        pseg = pseglist->sl_lastseg;
+    }
+
+    /* Walk out to the proper segment */
+    pseg = pseglist->sl_rootseg;
+    C_ASSERT(pseg != C_NULL);
+    for (i = (index / SEGLIST_OBJS_PER_SEG); i > 0; i--)
     {
         pseg = pseg->next;
-
-        /* if ran past end of list */
-        /* XXX what about inserting several indices past end?
-         * Not knowing the numSegs in the seglist is a reason to dislike seglists.
-         */
-        if (pseg == C_NULL)
-        {
-            PM_RAISE(retval, PM_RET_EX_SYS);
-            return retval;
-        }
+        C_ASSERT(pseg != C_NULL);
     }
 
-    /* if indx asks for obj beyond the seglist's last one */
-    if ((pseg == pseglist->sl_lastseg)
-        && (segindx >= pseglist->sl_lastindx))
-    {
-        /* caller must convert this err to exception */
-        PM_RAISE(retval, PM_RET_EX_SYS);
-        return retval;
-    }
-
-    /* insert obj and ripple copy all those afterward */
-    indx = segindx;
+    /* Insert obj and ripple copy all those afterward */
+    indx = index % SEGLIST_OBJS_PER_SEG;;
     pobj1 = pobj;
     while (pobj1 != C_NULL)
     {
         pobj1 = pobj2;
         indx++;
 
-        /* if indx exceeds this seg and need to go to next */
+        /* If indx exceeds this seg, go to next */
         if ((indx >= SEGLIST_OBJS_PER_SEG) && (pobj1 != C_NULL))
         {
-            /* create next seg if needed */
-            if (pseg->next == C_NULL)
-            {
-                retval = heap_getChunk(sizeof(Segment_t), &pchunk);
-                PM_RETURN_IF_ERROR(retval);
-                pseg->next = (Segment_t *)pchunk;
-
-                /* init segment */
-                pseg = pseg->next;
-                OBJ_SET_TYPE(*pseg, OBJ_TYPE_SEG);
-                for (i = 1; i < SEGLIST_OBJS_PER_SEG; i++)
-                {
-                    pseg->s_val[i] = C_NULL;
-                }
-                pseg->next = C_NULL;
-                /* seglist's lastseg pts to new seg */
-                pseglist->sl_lastseg = pseg;
-                pseglist->sl_lastindx = 0; /* incr'd below */
-                /* put obj in seg */
-                pseg->s_val[0] = pobj1;
-                pobj1 = C_NULL;
-            }
-            /* else skip to next seg and continue */
-            else
-            {
-                pseg = pseg->next;
-                indx = 0;
-            }
+            pseg = pseg->next;
+            C_ASSERT(pseg != C_NULL);
+            indx = 0;
         }
     }
-    pseglist->sl_lastindx++;
+    pseglist->sl_length++;
     return retval;
 }
 
 
 PmReturn_t
-seglist_new(pSeglist_t * r_pseglist)
+seglist_new(pSeglist_t *r_pseglist)
 {
     PmReturn_t retval = PM_RET_OK;
 
     OBJ_SET_TYPE(**r_pseglist, OBJ_TYPE_SGL);
     (*r_pseglist)->sl_rootseg = C_NULL;
     (*r_pseglist)->sl_lastseg = C_NULL;
-    (*r_pseglist)->sl_lastindx = 0;
+    (*r_pseglist)->sl_length = 0;
     return retval;
 }
 
 
 PmReturn_t
-seglist_setItem(pSeglist_t pseglist,
-                pPmObj_t pobj,
-                int8_t segnum,
-                int8_t segindx)
+seglist_setItem(pSeglist_t pseglist, pPmObj_t pobj, int16_t index)
 {
-    pSegment_t pseg = pseglist->sl_rootseg;
-    PmReturn_t retval;
+    pSegment_t pseg;
+    int16_t i;
 
-    /* scan to proper seg, error check along the way */
-    for (; segnum > 0; segnum--)
+    C_ASSERT(index <= pseglist->sl_length);
+
+    /* Walk out to the proper segment */
+    pseg = pseglist->sl_rootseg;
+    C_ASSERT(pseg != C_NULL);
+    for (i = (index / SEGLIST_OBJS_PER_SEG); i > 0; i--)
     {
         pseg = pseg->next;
-
-        /* if ran past end of list, raise SystemError */
-        if (pseg == C_NULL)
-        {
-            PM_RAISE(retval, PM_RET_EX_SYS);
-            return retval;
-        }
+        C_ASSERT(pseg != C_NULL);
     }
 
-    /* if indx is beyond the seglist's end, raise SystemError */
-    if ((pseg == pseglist->sl_lastseg) &&
-        (segindx >= pseglist->sl_lastindx))
-    {
-        PM_RAISE(retval, PM_RET_EX_SYS);
-        return retval;
-    }
-
-    /* set ptr to obj in this seg at the index */
-    pseg->s_val[segindx] = pobj;
+    /* Set item in this seg at the index */
+    pseg->s_val[index % SEGLIST_OBJS_PER_SEG] = pobj;
     return PM_RET_OK;
 }
 

File src/vm/seglist.h