Commits

Anonymous committed 55b248d

#136 Mainlined directly

Comments (0)

Files changed (11)

 
 # Build configuration
 TARGET := DESKTOP
-HEAP_SIZE = 0x1000
+HEAP_SIZE = 0x2000
 
 # Changes for an embedded target
 ifeq ($(TARGET), AVR)
 #
 
 
+#### MODULES
+
+import list, dict
+
+
 #### CONSTS
 
 C = "Copyright 2002 Dean Hall.  Licensed under GPL v2."
+# PyMite - A flyweight Python interpreter for 8-bit microcontrollers and more.
+# Copyright 2009 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.
+#
+
+#
+# Provides PyMite's dict module.
+#
+
+def clear(d):
+    """__NATIVE__
+    pPmObj_t pd;
+    PmReturn_t retval = PM_RET_OK;
+
+    /* Raise TypeError if it's not a dict or wrong number of args, */
+    pd = NATIVE_GET_LOCAL(0);
+    if ((OBJ_GET_TYPE(pd) != OBJ_TYPE_DIC) || (NATIVE_GET_NUM_ARGS() != 1))
+    {
+        PM_RAISE(retval, PM_RET_EX_TYPE);
+        return retval;
+    }
+
+    /* Clear the contents of the dict */
+    retval = dict_clear(pd);
+    PM_RETURN_IF_ERROR(retval);
+
+    NATIVE_SET_TOS(PM_NONE);
+
+    return retval;
+    """
+    pass
+
+
+def has_key(d, k):
+    if k in dict.keys(d):
+        return 1
+    else:
+        return 0
+
+
+def keys(d):
+    """__NATIVE__
+    pPmObj_t pd;
+    pPmObj_t pl;
+    pPmObj_t pk;
+    pSeglist_t psl;
+    uint16_t i;
+    PmReturn_t retval = PM_RET_OK;
+
+    /* Raise TypeError if it's not a dict or wrong number of args, */
+    pd = NATIVE_GET_LOCAL(0);
+    if ((OBJ_GET_TYPE(pd) != OBJ_TYPE_DIC) || (NATIVE_GET_NUM_ARGS() != 1))
+    {
+        PM_RAISE(retval, PM_RET_EX_TYPE);
+        return retval;
+    }
+
+    /* Create empty list */
+    retval = list_new(&pl);
+    PM_RETURN_IF_ERROR(retval);
+
+    /* Iterate through the keys seglist */
+    psl = ((pPmDict_t)pd)->d_keys;
+    for (i = 0; i < ((pPmDict_t)pd)->length; i++)
+    {
+        /* Get the key and append it to the list */
+        retval = seglist_getItem(psl, i, &pk);
+        PM_RETURN_IF_ERROR(retval);
+        retval = list_append(pl, pk);
+        PM_RETURN_IF_ERROR(retval);
+    }
+
+    /* Return the list of keys to the caller */
+    NATIVE_SET_TOS(pl);
+
+    return retval;
+    """
+    pass
+
+
+def values(d):
+    """__NATIVE__
+    pPmObj_t pd;
+    pPmObj_t pl;
+    pPmObj_t pv;
+    pSeglist_t psl;
+    uint16_t i;
+    PmReturn_t retval = PM_RET_OK;
+
+    /* Raise TypeError if it's not a dict or wrong number of args, */
+    pd = NATIVE_GET_LOCAL(0);
+    if ((OBJ_GET_TYPE(pd) != OBJ_TYPE_DIC) || (NATIVE_GET_NUM_ARGS() != 1))
+    {
+        PM_RAISE(retval, PM_RET_EX_TYPE);
+        return retval;
+    }
+
+    /* Create empty list */
+    retval = list_new(&pl);
+    PM_RETURN_IF_ERROR(retval);
+
+    /* Iterate through the values seglist */
+    psl = ((pPmDict_t)pd)->d_vals;
+    for (i = 0; i < ((pPmDict_t)pd)->length; i++)
+    {
+        /* Get the value and append it to the list */
+        retval = seglist_getItem(psl, i, &pv);
+        PM_RETURN_IF_ERROR(retval);
+        retval = list_append(pl, pv);
+        PM_RETURN_IF_ERROR(retval);
+    }
+
+    /* Return the list of values to the caller */
+    NATIVE_SET_TOS(pl);
+
+    return retval;
+    """
+    pass
+
+
+# :mode=c:
+# PyMite - A flyweight Python interpreter for 8-bit microcontrollers and more.
+# Copyright 2009 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.
+#
+
+#
+# Provides PyMite's list module.
+#
+# Notes:
+#   index(l, o) does not offer start and stop arguments.
+#
+
+def append(l, o):
+    """__NATIVE__
+    pPmObj_t pl;
+    PmReturn_t retval = PM_RET_OK;
+
+    /* Raise TypeError if it's not a list or wrong number of args, */
+    pl = NATIVE_GET_LOCAL(0);
+    if ((OBJ_GET_TYPE(pl) != OBJ_TYPE_LST) || (NATIVE_GET_NUM_ARGS() != 2))
+    {
+        PM_RAISE(retval, PM_RET_EX_TYPE);
+        return retval;
+    }
+
+    /* Append the object to the list */
+    retval = list_append(pl, NATIVE_GET_LOCAL(1));
+
+    NATIVE_SET_TOS(PM_NONE);
+
+    return retval;
+    """
+    pass
+
+
+def count(l, v):
+    c = 0
+    for o in l:
+        if o == v:
+            c = c + 1
+    return c
+
+
+def extend(l, s):
+    for i in s:
+        list.append(l, i)
+
+
+def index(l, o):
+    """__NATIVE__
+    pPmObj_t pl;
+    pPmObj_t po;
+    pPmObj_t pi;
+    PmReturn_t retval = PM_RET_OK;
+    uint16_t i;
+
+    /* Raise TypeError if it's not a list or wrong number of args, */
+    pl = NATIVE_GET_LOCAL(0);
+    if ((OBJ_GET_TYPE(pl) != OBJ_TYPE_LST) || (NATIVE_GET_NUM_ARGS() != 2))
+    {
+        PM_RAISE(retval, PM_RET_EX_TYPE);
+        return retval;
+    }
+
+    /* Get the index of the object in the list */
+    po = NATIVE_GET_LOCAL(1);
+    retval = list_index(pl, po, &i);
+
+    if (retval == PM_RET_EX_VAL)
+    {
+        PM_RAISE(retval, PM_RET_EX_VAL);
+        return retval;
+    }
+
+    int_new((int32_t)i, &pi);
+    NATIVE_SET_TOS(pi);
+
+    return retval;
+    """
+    pass
+
+
+def insert(l, i, o):
+    """__NATIVE__
+    pPmObj_t pl;
+    pPmObj_t pi;
+    pPmObj_t po;
+    PmReturn_t retval = PM_RET_OK;
+    uint16_t i;
+
+    /*
+     * Raise TypeError if wrong number of args, first arg is not a list, or
+     * second arg is not an int
+     */
+    pl = NATIVE_GET_LOCAL(0);
+    pi = NATIVE_GET_LOCAL(1);
+    po = NATIVE_GET_LOCAL(2);
+    if ((NATIVE_GET_NUM_ARGS() != 3)
+        || (OBJ_GET_TYPE(pl) != OBJ_TYPE_LST)
+        || (OBJ_GET_TYPE(pi) != OBJ_TYPE_INT) )
+    {
+        PM_RAISE(retval, PM_RET_EX_TYPE);
+        return retval;
+    }
+
+    /* Insert the object before the given index */
+    i = (uint16_t)((pPmInt_t)pi)->val;
+    retval = list_insert(pl, i, po);
+
+    if (retval != PM_RET_OK)
+    {
+        PM_RAISE(retval, PM_RET_EX_SYS);
+    }
+
+    return retval;
+    """
+    pass
+
+
+def pop(l, i):
+    """__NATIVE__
+    pPmObj_t pl;
+    pPmObj_t pi;
+    pPmObj_t po;
+    PmReturn_t retval = PM_RET_OK;
+    int16_t i;
+
+    /*
+     * Raise TypeError if first arg is not a list o second arg is not an int
+     * or there are the wrong number of arguments
+     */
+    pl = NATIVE_GET_LOCAL(0);
+    if (OBJ_GET_TYPE(pl) != OBJ_TYPE_LST)
+    {
+        PM_RAISE(retval, PM_RET_EX_TYPE);
+        return retval;
+    }
+
+    pi = NATIVE_GET_LOCAL(1);
+    if (NATIVE_GET_NUM_ARGS() == 2)
+    {
+        if (OBJ_GET_TYPE(pi) != OBJ_TYPE_INT)
+        {
+            PM_RAISE(retval, PM_RET_EX_TYPE);
+            return retval;
+        }
+        i = (uint16_t)((pPmInt_t)pi)->val;
+    }
+    else
+    {
+        i = -1;
+    }
+    if ((NATIVE_GET_NUM_ARGS() < 1) || (NATIVE_GET_NUM_ARGS() > 2))
+    {
+        PM_RAISE(retval, PM_RET_EX_TYPE);
+        return retval;
+    }
+
+    /* Get the object at the given index */
+    retval = list_getItem(pl, i, &po);
+    PM_RETURN_IF_ERROR(retval);
+
+    /* Return the object to the caller */
+    NATIVE_SET_TOS(po);
+
+    /* Remove the object from the given index */
+    retval = list_delItem(pl, i);
+    PM_RETURN_IF_ERROR(retval);
+
+    return retval;
+    """
+    pass
+
+
+def remove(l, v):
+    """__NATIVE__
+    pPmObj_t pl;
+    pPmObj_t pv;
+    PmReturn_t retval = PM_RET_OK;
+
+    /* Raise TypeError if it's not a list or wrong number of args, */
+    pl = NATIVE_GET_LOCAL(0);
+    if ((OBJ_GET_TYPE(pl) != OBJ_TYPE_LST) || (NATIVE_GET_NUM_ARGS() != 2))
+    {
+        PM_RAISE(retval, PM_RET_EX_TYPE);
+        return retval;
+    }
+
+    /* Remove the value from the list */
+    pv = NATIVE_GET_LOCAL(1);
+    retval = list_remove(pl, pv);
+    if (retval != PM_RET_OK)
+    {
+        PM_RAISE(retval, retval);
+    }
+
+    NATIVE_SET_TOS(PM_NONE);
+
+    return retval;
+    """
+    pass
+
+
+
+
+# TODO:
+# L.reverse() -- reverse *IN PLACE*
+# L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*;
+#    cmp(x, y) -> -1, 0, 1
+
+# :mode=c:

src/tests/system/Makefile

 SHELL = /bin/sh
 
 TARGET ?= DESKTOP
-HEAP_SIZE ?= 0x1000
+HEAP_SIZE ?= 0x2000
 TARGET_MCU ?= atmega103
 
 PMIMGCREATOR := ../../tools/pmImgCreator.py

src/tests/system/t136.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 136
+ * Create module interface for compound datatypes
+ */
+
+#include "pm.h"
+
+
+extern unsigned char usrlib_img[];
+
+
+int main(void)
+{
+    PmReturn_t retval;
+
+    retval = pm_init(MEMSPACE_PROG, usrlib_img);
+    PM_RETURN_IF_ERROR(retval);
+
+    retval = pm_run((uint8_t *)"t136");
+    return (int)retval;
+}

src/tests/system/t136.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 136
+# Create module interface for compound datatypes
+#
+
+# Tests for list
+if 1:
+    foo = [0]
+    list.append(foo, 1)
+    print foo
+
+    list.extend(foo, [2, 2])
+    print foo
+
+
+    print list.count(foo, 1)
+    print list.count(foo, 2)
+    print list.count(foo, 42)
+
+    print list.index(foo, 0)
+
+    list.append(foo, "bob")
+    print list.index(foo, "bob")
+    #print list.index(foo, "z") # expects to raise a ValueError
+
+    list.insert(foo, 0, "zero")
+    list.insert(foo, -1, "penultimate")
+    print foo
+
+    print list.pop(foo)
+    print list.pop(foo, 2)
+    print foo
+
+    list.remove(foo, 2)
+    list.remove(foo, "zero")
+    print foo
+
+
+# Tests for dict
+if 1:
+    d = {}
+    d[0] = "zero"
+    d["one"] = 1
+    print d
+    print dict.keys(d)
+    print dict.values(d)
+    
+    dict.clear(d)
+    print d
+    d['new'] = "more"
+    print d
+
+    print "d has key 'new' = ", dict.has_key(d, 'new')
+    print "d has key 'old' = ", dict.has_key(d, 'old')
 #
 
 # Configure the contents of pmstdlib by editing this list
-PMSTDLIB_SOURCES = ../lib/__bi.py \
+PMSTDLIB_SOURCES = ../lib/list.py \
+                   ../lib/dict.py \
+                   ../lib/__bi.py \
                    ../lib/sys.py
 
 TARGET ?= DESKTOP
-HEAP_SIZE ?= 0x1000
+HEAP_SIZE ?= 0x2000
 
 PMIMGCREATOR := ../tools/pmImgCreator.py
 DEFS = -DTARGET_$(TARGET) -DHEAP_SIZE=$(HEAP_SIZE)
 }
 
 
+PmReturn_t
+list_delItem(pPmObj_t plist, int16_t index)
+{
+    PmReturn_t retval = PM_RET_OK;
+
+    /* If it's not a list, raise TypeError */
+    if (OBJ_GET_TYPE(plist) != OBJ_TYPE_LST)
+    {
+        PM_RAISE(retval, PM_RET_EX_TYPE);
+        return retval;
+    }
+
+    /* Adjust the index */
+    if (index < 0)
+    {
+        index += ((pPmList_t)plist)->length;
+    }
+
+    /* Check the bounds of the index */
+    if ((index < 0) || (index >= ((pPmList_t)plist)->length))
+    {
+        PM_RAISE(retval, PM_RET_EX_INDX);
+        return retval;
+    }
+
+    /* Remove the item and decrement the list length */
+    retval = seglist_removeItem(((pPmList_t)plist)->val, index);
+    ((pPmList_t)plist)->length--;
+    return retval;
+}
+
+
+
 #ifdef HAVE_PRINT
 PmReturn_t
 list_print(pPmObj_t plist)
  */
 PmReturn_t list_index(pPmObj_t plist, pPmObj_t pitem, uint16_t *r_index);
 
+/**
+ * Removes the item at the given index.
+ * Raises a TypeError if the first argument is not a list.
+ * Raises an IndexError if the index is out of bounds.
+ *
+ * @param   plist Ptr to list obj
+ * @param   index Index of item to remove
+ * @return  Return status
+ */
+PmReturn_t list_delItem(pPmObj_t plist, int16_t index);
+
 #ifdef HAVE_PRINT
 /**
  * Prints out a list. Uses obj_print() to print elements.
 
     C_ASSERT(index <= pseglist->sl_length);
 
-    /* If this is first item in seg */
+    /* If a new seg is needed */
     if ((pseglist->sl_length % SEGLIST_OBJS_PER_SEG) == 0)
     {
         /* Alloc and init new segment */
         pseglist->sl_lastseg = pseg;
     }
 
-    /* Else get last seg */
-    else
-    {
-        pseg = pseglist->sl_lastseg;
-    }
-
-    /* Walk out to the proper segment */
+    /* Walk out to the segment for insertion */
     pseg = pseglist->sl_rootseg;
     C_ASSERT(pseg != C_NULL);
     for (i = (index / SEGLIST_OBJS_PER_SEG); i > 0; i--)
         pobj1 = pobj2;
         indx++;
 
-        /* If indx exceeds this seg, go to next */
+        /* If indx exceeds this seg, go to next seg */
         if ((indx >= SEGLIST_OBJS_PER_SEG) && (pobj1 != C_NULL))
         {
             pseg = pseg->next;