davide carboni / Mbed 2 deprecated pymite_http_get

Dependencies:   mbed

src/vm/pmstdlib_nat.c

Committer:
dadaista
Date:
2010-07-21
Revision:
0:14e5e829dffe

File content as of revision 0:14e5e829dffe:

#undef __FILE_ID__
#define __FILE_ID__ 0x0A
/**
 * PyMite std native function file
 *
 * automatically created by pmImgCreator.py
 * on Wed Jul 21 11:21:27 2010
 *
 * DO NOT EDIT THIS FILE.
 * ANY CHANGES WILL BE LOST.
 *
 * @file    pmstdlib_nat.c
 */

#define __IN_LIBNATIVE_C__
#include "pm.h"

/* From: ../lib/string.py */
#include <stdlib.h>
#include <string.h>

PmReturn_t
nat_00_list_append(pPmFrame_t *ppframe)
{

    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;
    
}

PmReturn_t
nat_01_list_index(pPmFrame_t *ppframe)
{

    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;
    
}

PmReturn_t
nat_02_list_insert(pPmFrame_t *ppframe)
{

    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);
    }

    NATIVE_SET_TOS(PM_NONE);

    return retval;
    
}

PmReturn_t
nat_03_list_pop(pPmFrame_t *ppframe)
{

    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;
    
}

PmReturn_t
nat_04_list_remove(pPmFrame_t *ppframe)
{

    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;
    
}

PmReturn_t
nat_05_dict_clear(pPmFrame_t *ppframe)
{

    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;
    
}

PmReturn_t
nat_06_dict_keys(pPmFrame_t *ppframe)
{

    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;
    
}

PmReturn_t
nat_07_dict_values(pPmFrame_t *ppframe)
{

    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;
    
}

PmReturn_t
nat_08___bi_chr(pPmFrame_t *ppframe)
{

    pPmObj_t ps;
    pPmObj_t pn;
    int32_t n;
    PmReturn_t retval;

    /* If wrong number of args, raise TypeError */
    if (NATIVE_GET_NUM_ARGS() != 1)
    {
        PM_RAISE(retval, PM_RET_EX_TYPE);
        return retval;
    }

    /* Raise TypeError if arg is not an int */
    pn = NATIVE_GET_LOCAL(0);
    if (OBJ_GET_TYPE(pn) != OBJ_TYPE_INT)
    {
        PM_RAISE(retval, PM_RET_EX_TYPE);
        return retval;
    }

    /* Raise ValueError if arg is not int within range(256) */
    n = ((pPmInt_t)pn)->val;
    if ((n < 0) || (n > 255))
    {
        PM_RAISE(retval, PM_RET_EX_VAL);
        return retval;
    }

    /* Create char string from  integer value */
    retval = string_newFromChar((uint8_t)n, &ps);
    NATIVE_SET_TOS(ps);
    return retval;
    
}

PmReturn_t
nat_09___bi_dir(pPmFrame_t *ppframe)
{

    PmReturn_t retval = PM_RET_OK;
    pPmObj_t po;
    pPmObj_t pk;
    pPmObj_t pl;
    pSeglist_t psl;
    int16_t i;

    /* Use globals if no arg given */
    if (NATIVE_GET_NUM_ARGS() == 0)
    {
        /* Get the globals dict */
        po = (pPmObj_t)NATIVE_GET_PFRAME()->fo_globals;
    }

    /* Otherwise use the given arg */
    else if (NATIVE_GET_NUM_ARGS() == 1)
    {
        po = NATIVE_GET_LOCAL(0);

        /* If object is a function or module, use its attrs dict */
        if ((OBJ_GET_TYPE(po) == OBJ_TYPE_FXN)
            || (OBJ_GET_TYPE(po) == OBJ_TYPE_MOD))
        {
            po = (pPmObj_t)((pPmFunc_t)po)->f_attrs;
        }

#ifdef HAVE_CLASSES
        else if (OBJ_GET_TYPE(po) == OBJ_TYPE_CLO)
        {
            po = (pPmObj_t)((pPmClass_t)po)->cl_attrs;
        }
        else if (OBJ_GET_TYPE(po) == OBJ_TYPE_CLI)
        {
            po = (pPmObj_t)((pPmInstance_t)po)->cli_attrs;
        }
        else if (OBJ_GET_TYPE(po) == OBJ_TYPE_MTH)
        {
            po = (pPmObj_t)((pPmMethod_t)po)->m_attrs;
        }
#endif /* HAVE_CLASSES */

        else
        {
            po = C_NULL;
        }
    }

    /* Raise TypeError if wrong number of args */
    else
    {
        PM_RAISE(retval, PM_RET_EX_TYPE);
        return retval;
    }

    if (po == C_NULL)
    {
        pl = PM_NONE;
    }
    else
    {
        /* Create new list */
        retval = list_new(&pl);
        PM_RETURN_IF_ERROR(retval);

        /* Copy dict's keys to the list */
        psl = ((pPmDict_t)po)->d_keys;
        for (i = 0; i < ((pPmDict_t)po)->length; i++)
        {
            retval = seglist_getItem(psl, i, &pk);
            PM_RETURN_IF_ERROR(retval);
            retval = list_append(pl, pk);
            PM_RETURN_IF_ERROR(retval);
        }
    }

    NATIVE_SET_TOS(pl);
    return retval;
    
}

PmReturn_t
nat_10___bi_eval(pPmFrame_t *ppframe)
{

    PmReturn_t retval;
    pPmObj_t pco;
    pPmObj_t pfunc;
    pPmObj_t pnewframe;
    pPmObj_t pg = C_NULL;
    pPmObj_t pl = C_NULL;

    /* If wrong number of args, raise TypeError */
    if ((NATIVE_GET_NUM_ARGS() == 0) || (NATIVE_GET_NUM_ARGS() > 3))
    {
        PM_RAISE(retval, PM_RET_EX_TYPE);
        return retval;
    }

    /* Raise ValueError if first arg is not a Code Object */
    pco = NATIVE_GET_LOCAL(0);
    if (OBJ_GET_TYPE(pco) != OBJ_TYPE_COB)
    {
        PM_RAISE(retval, PM_RET_EX_VAL);
        return retval;
    }

    /* If 2nd arg exists, raise ValueError if it is not a Dict */
    if (NATIVE_GET_NUM_ARGS() >= 2)
    {
        pg = NATIVE_GET_LOCAL(1);
        if (OBJ_GET_TYPE(pg) != OBJ_TYPE_DIC)
        {
            PM_RAISE(retval, PM_RET_EX_VAL);
            return retval;
        }
    }

    /* If no args are given, use the caller's globals for the function's */
    else
    {
        pg = (pPmObj_t)NATIVE_GET_PFRAME()->fo_globals;
    }

    /* If 3rd arg exists, raise ValueError if it is not a Dict */
    if (NATIVE_GET_NUM_ARGS() >= 3)
    {
        pl = NATIVE_GET_LOCAL(2);
        if (OBJ_GET_TYPE(pl) != OBJ_TYPE_DIC)
        {
            PM_RAISE(retval, PM_RET_EX_VAL);
            return retval;
        }
    }

    /* Create func from code object */
    retval = func_new(pco, pg, &pfunc);
    PM_RETURN_IF_ERROR(retval);

    /* Create frame from module object; globals is set to null */
    retval = frame_new(pfunc, &pnewframe);
    PM_RETURN_IF_ERROR(retval);

    /* TODO: Reclaim pnewframe's attrs dict created in frame_new */
    /*
     * By default use calling frame's attrs as local namespace.
     * This works for ipm because the interactive mode
     * needs a locals namespace that persists across calls to eval()
     */
    ((pPmFrame_t)pnewframe)->fo_attrs = NATIVE_GET_PFRAME()->fo_attrs;

    /* If 2nd arg exists, use it as the global namespace for the new func */
    if (NATIVE_GET_NUM_ARGS() >= 2)
    {
        ((pPmFrame_t)pnewframe)->fo_globals = (pPmDict_t)pg;

        /* If only globals is given, locals defaults to it */
        ((pPmFrame_t)pnewframe)->fo_attrs = (pPmDict_t)pg;
    }

    /* If 3rd arg exists, use it as the local namespace for the new func */
    if (NATIVE_GET_NUM_ARGS() >= 3)
    {
        ((pPmFrame_t)pnewframe)->fo_attrs = (pPmDict_t)pl;
    }

    /*
     * Set the fo_back frame so flow returns to eval()'s caller when completed.
     * Set the frame pointer so the new frame is interpreted immediately
     * after this function returns.
     */
    ((pPmFrame_t)pnewframe)->fo_back = NATIVE_GET_PFRAME();
    NATIVE_GET_PFRAME() = (pPmFrame_t)pnewframe;
    retval = PM_RET_FRAME_SWITCH;

    return retval;
    
}

PmReturn_t
nat_11___bi_globals(pPmFrame_t *ppframe)
{

    pPmObj_t pr = C_NULL;
    PmReturn_t retval;

    /* If wrong number of args, raise TypeError */
    if (NATIVE_GET_NUM_ARGS() != 0)
    {
        PM_RAISE(retval, PM_RET_EX_TYPE);
        return retval;
    }

    /* Return calling frame's globals dict  on stack*/
    pr = (pPmObj_t)NATIVE_GET_PFRAME()->fo_globals;
    NATIVE_SET_TOS(pr);

    return PM_RET_OK;
    
}

PmReturn_t
nat_12___bi_id(pPmFrame_t *ppframe)
{

    PmReturn_t retval;
    pPmObj_t pr = C_NULL;

    /* If wrong number of args, raise TypeError */
    if (NATIVE_GET_NUM_ARGS() != 1)
    {
        PM_RAISE(retval, PM_RET_EX_TYPE);
        return retval;
    }

    /* Return object's address as an int on the stack */
    retval = int_new((intptr_t)NATIVE_GET_LOCAL(0), &pr);
    NATIVE_SET_TOS(pr);

    return retval;
    
}

PmReturn_t
nat_13___bi_len(pPmFrame_t *ppframe)
{

    PmReturn_t retval;
    pPmObj_t ps = C_NULL;
    pPmObj_t pr = C_NULL;

    /* If wrong number of args, raise TypeError */
    if (NATIVE_GET_NUM_ARGS() != 1)
    {
        PM_RAISE(retval, PM_RET_EX_TYPE);
        return retval;
    }

    /* Get first arg */
    ps = NATIVE_GET_LOCAL(0);

#ifdef HAVE_BYTEARRAY
    /* If object is an instance, get the thing it contains */
    if (OBJ_GET_TYPE(ps) == OBJ_TYPE_CLI)
    {
        retval = dict_getItem((pPmObj_t)((pPmInstance_t)ps)->cli_attrs,
                              PM_NONE,
                              &pr);

        /* If None wasn't in attributes, obj is wrong type for len() */
        if (retval == PM_RET_EX_KEY) retval = PM_RET_EX_TYPE;
        PM_RETURN_IF_ERROR(retval);
        ps = pr;
    }
#endif /* HAVE_BYTEARRAY */

    /* Get the length of the arg based on its type */
    switch (OBJ_GET_TYPE(ps))
    {
        case OBJ_TYPE_STR:
            retval = int_new(((pPmString_t)ps)->length, &pr);
            break;

        case OBJ_TYPE_TUP:
            retval = int_new(((pPmTuple_t)ps)->length, &pr);
            break;

        case OBJ_TYPE_LST:
            retval = int_new(((pPmList_t)ps)->length, &pr);
            break;

        case OBJ_TYPE_DIC:
            retval = int_new(((pPmDict_t)ps)->length, &pr);
            break;

#ifdef HAVE_BYTEARRAY
        case OBJ_TYPE_BYA:
            retval = int_new(((pPmBytearray_t)ps)->length, &pr);
            break;
#endif /* HAVE_BYTEARRAY */

        default:
            /* If not a string or sequence type, raise TypeError */
            PM_RAISE(retval, PM_RET_EX_TYPE);
    }

    NATIVE_SET_TOS(pr);
    return retval;
    
}

PmReturn_t
nat_14___bi_locals(pPmFrame_t *ppframe)
{

    pPmObj_t pr = C_NULL;
    PmReturn_t retval;

    /* If wrong number of args, raise TypeError */
    if (NATIVE_GET_NUM_ARGS() != 0)
    {
        PM_RAISE(retval, PM_RET_EX_TYPE);
        return retval;
    }

    /* Return calling frame's local attrs dict on the stack */
    pr = (pPmObj_t)NATIVE_GET_PFRAME()->fo_attrs;
    NATIVE_SET_TOS(pr);

    return PM_RET_OK;
    
}

PmReturn_t
nat_15___bi_ord(pPmFrame_t *ppframe)
{

    pPmObj_t ps;
    pPmObj_t pn;
    int32_t n;
    PmReturn_t retval;

    /* If wrong number of args, raise TypeError */
    if (NATIVE_GET_NUM_ARGS() != 1)
    {
        PM_RAISE(retval, PM_RET_EX_TYPE);
        return retval;
    }

    ps = NATIVE_GET_LOCAL(0);

    /* Raise TypeError if arg is not string of length 1 */
    if ((OBJ_GET_TYPE(ps) != OBJ_TYPE_STR)
        || (((pPmString_t)ps)->length != 1))

    {
        PM_RAISE(retval, PM_RET_EX_TYPE);
        return retval;
    }

    /* Get integer value of character */
    n = ((pPmString_t)ps)->val[0];
    retval = int_new(n, &pn);
    NATIVE_SET_TOS(pn);
    return retval;
    
}

PmReturn_t
nat_16___bi_range(pPmFrame_t *ppframe)
{

    PmReturn_t retval;
    pPmObj_t pa = C_NULL;
    pPmObj_t pb = C_NULL;
    pPmObj_t pc = C_NULL;
    pPmObj_t pi = C_NULL;
    pPmObj_t pr = C_NULL;
    int16_t i = 0;

    switch (NATIVE_GET_NUM_ARGS())
    {
        case 1:
            pa = PM_ZERO;
            pb = NATIVE_GET_LOCAL(0);
            pc = PM_ONE;
            break;

        case 2:
            pa = NATIVE_GET_LOCAL(0);
            pb = NATIVE_GET_LOCAL(1);
            pc = PM_ONE;
            break;

        case 3:
            pa = NATIVE_GET_LOCAL(0);
            pb = NATIVE_GET_LOCAL(1);
            pc = NATIVE_GET_LOCAL(2);

            /* If 3rd arg is 0, ValueError */
            if (((pPmInt_t)pc)->val == 0)
            {
                PM_RAISE(retval, PM_RET_EX_VAL);
                return retval;
            }
            break;

        default:
            /* If wrong number of args, raise TypeError */
            PM_RAISE(retval, PM_RET_EX_TYPE);
            return retval;
    }

    /* Allocate list */
    retval = list_new(&pr);
    PM_RETURN_IF_ERROR(retval);

    /* Iterate depending on counting direction */
    if (((pPmInt_t)pc)->val > 0)
    {
        for (i = ((pPmInt_t)pa)->val;
             i < ((pPmInt_t)pb)->val;
             i += ((pPmInt_t)pc)->val)
        {
            retval = int_new(i, &pi);
            PM_RETURN_IF_ERROR(retval);

            retval = list_append(pr, pi);
            PM_RETURN_IF_ERROR(retval);
        }
    }
    else
    {
        for (i = ((pPmInt_t)pa)->val;
             i > ((pPmInt_t)pb)->val;
             i += ((pPmInt_t)pc)->val)
        {
            retval = int_new(i, &pi);
            PM_RETURN_IF_ERROR(retval);

            retval = list_append(pr, pi);
            PM_RETURN_IF_ERROR(retval);
        }
    }

    /* Return list */
    NATIVE_SET_TOS(pr);
    return retval;
    
}

PmReturn_t
nat_17___bi_sum(pPmFrame_t *ppframe)
{

    pPmObj_t ps;
    pPmObj_t pn;
    pPmObj_t po;
    int32_t n;
    uint16_t len;
    uint16_t i;
    PmReturn_t retval;
#ifdef HAVE_FLOAT
    float f;
    uint8_t usefloat = C_FALSE;
#endif /* HAVE_FLOAT */

    /* If wrong number of args, raise TypeError */
    if (NATIVE_GET_NUM_ARGS() != 1)
    {
        PM_RAISE(retval, PM_RET_EX_TYPE);
        return retval;
    }

    /* Get the length of the sequence */
    ps = NATIVE_GET_LOCAL(0);
    if (OBJ_GET_TYPE(ps) == OBJ_TYPE_TUP)
    {
        len = ((pPmTuple_t)ps)->length;
    }
    else if (OBJ_GET_TYPE(ps) == OBJ_TYPE_LST)
    {
        len = ((pPmTuple_t)ps)->length;
    }

    /* Raise TypeError if arg is not a sequence */
    else
    {
        PM_RAISE(retval, PM_RET_EX_TYPE);
        return retval;
    }

    /* Calculate the sum of the sequence */
    n = 0;
#ifdef HAVE_FLOAT
    f = 0.0;
#endif
    for (i = 0; i < len; i++)
    {
        retval = seq_getSubscript(ps, i, &po);

        if (OBJ_GET_TYPE(po) == OBJ_TYPE_INT)
        {
            /* Add value to sum */
            n += ((pPmInt_t)po)->val;
#ifdef HAVE_FLOAT
            f += (float)((pPmInt_t)po)->val;
#endif /* HAVE_FLOAT */
        }

#ifdef HAVE_FLOAT
        else if (OBJ_GET_TYPE(po) == OBJ_TYPE_FLT)
        {
            /* Add value to sum */
            f += ((pPmFloat_t)po)->val;
            usefloat = C_TRUE;
        }
#endif /* HAVE_FLOAT */

        /* Raise TypeError if item is not an integer */
        else
        {
            PM_RAISE(retval, PM_RET_EX_TYPE);
            return retval;
        }
    }

#ifdef HAVE_FLOAT
    if (usefloat)
    {
        retval = float_new(f, &pn);
    }
    else
#endif /* HAVE_FLOAT */
    {
        retval = int_new(n, &pn);
    }
    NATIVE_SET_TOS(pn);
    return retval;
    
}

PmReturn_t
nat_18___bi_type(pPmFrame_t *ppframe)
{

    PmReturn_t retval;
    pPmObj_t po = C_NULL;
    pPmObj_t pr = C_NULL;

    /* If wrong number of args, raise TypeError */
    if (NATIVE_GET_NUM_ARGS() != 1)
    {
        PM_RAISE(retval, PM_RET_EX_TYPE);
        return retval;
    }

    /* Get arg */
    po = NATIVE_GET_LOCAL(0);

    /* Create int from type enum */
    retval = int_new(OBJ_GET_TYPE(po), &pr);
    NATIVE_SET_TOS(pr);
    return retval;
    
}

PmReturn_t
nat_19___bi_Co(pPmFrame_t *ppframe)
{

    PmReturn_t retval;
    pPmObj_t pimg;
    pPmObj_t pco;

    /* If wrong number of args, raise TypeError */
    if (NATIVE_GET_NUM_ARGS() != 1)
    {
        PM_RAISE(retval, PM_RET_EX_TYPE);
        return retval;
    }

    /* Raise ValueError if arg is not a string */
    pimg = NATIVE_GET_LOCAL(0);
    if (OBJ_GET_TYPE(pimg) != OBJ_TYPE_CIO)
    {
        PM_RAISE(retval, PM_RET_EX_VAL);
        return retval;
    }

    /* Create a code object from the image */
    retval = obj_loadFromImgObj(pimg, &pco);
    PM_RETURN_IF_ERROR(retval);

    /* Return the code object */
    NATIVE_SET_TOS(pco);
    return retval;
    
}

PmReturn_t
nat_20___bi___init__(pPmFrame_t *ppframe)
{

        PmReturn_t retval;
        pPmObj_t pself;
        pPmObj_t pfa;
        pPmObj_t pfunc;
        pPmObj_t pframe;
        uint8_t i;

        /* Raise TypeError if wrong number of args */
        if (NATIVE_GET_NUM_ARGS() != 2)
        {
            PM_RAISE(retval, PM_RET_EX_TYPE);
            return retval;
        }

        /* Raise ValueError if first args are not: instance, tuple */
        pself = NATIVE_GET_LOCAL(0);
        pfa = NATIVE_GET_LOCAL(1);
        if ((OBJ_GET_TYPE(pself) != OBJ_TYPE_CLI)
            || (OBJ_GET_TYPE(pfa) != OBJ_TYPE_TUP))
        {
            PM_RAISE(retval, PM_RET_EX_VAL);
            return retval;
        }

        /* Create a new frame for the function */
        pfunc = ((pPmTuple_t)pfa)->val[0];
        retval = frame_new(pfunc, &pframe);
        PM_RETURN_IF_ERROR(retval);

        /* Copy args into frame's locals */
        for (i = 0; i < ((pPmTuple_t)pfa)->length - 1; i++)
        {
            /* The pfa tuple is (func, [arg0, ... argN]) */
            ((pPmFrame_t)pframe)->fo_locals[i] = ((pPmTuple_t)pfa)->val[i + 1];
        }

        /* Store frame in None attr of instance */
        retval = dict_setItem((pPmObj_t)((pPmInstance_t)pself)->cli_attrs,
                              PM_NONE, pframe);

        NATIVE_SET_TOS(PM_NONE);
        return retval;
        
}

PmReturn_t
nat_21___bi_send(pPmFrame_t *ppframe)
{

        PmReturn_t retval;
        pPmObj_t pself;
        pPmObj_t parg;
        pPmObj_t pgenframe;

        /* Raise TypeError if wrong number of args */
        if (NATIVE_GET_NUM_ARGS() != 2)
        {
            PM_RAISE(retval, PM_RET_EX_TYPE);
            return retval;
        }

        /* Raise ValueError if first arg is not an instance */
        pself = NATIVE_GET_LOCAL(0);
        parg = NATIVE_GET_LOCAL(1);
        if (OBJ_GET_TYPE(pself) != OBJ_TYPE_CLI)
        {
            PM_RAISE(retval, PM_RET_EX_VAL);
            return retval;
        }

        /* Get the generator's frame */
        retval = dict_getItem((pPmObj_t)((pPmInstance_t)pself)->cli_attrs,
                              PM_NONE, &pgenframe);
        PM_RETURN_IF_ERROR(retval);

        /* Push argument onto generator's frame's stack */
        *(((pPmFrame_t)pgenframe)->fo_sp) = parg;
        ((pPmFrame_t)pgenframe)->fo_sp++;

        /* Set generator's frame's fo_back so yielded value goes to caller */
        ((pPmFrame_t)pgenframe)->fo_back = NATIVE_GET_PFRAME();

        /* Set active frame to run generator */
        NATIVE_GET_PFRAME() = (pPmFrame_t)pgenframe;

        return PM_RET_FRAME_SWITCH;
        
}

PmReturn_t
nat_22___bi_ismain(pPmFrame_t *ppframe)
{


    NATIVE_SET_TOS((NATIVE_GET_PFRAME()->fo_isImport) ? PM_FALSE : PM_TRUE);

    return PM_RET_OK;
    
}

PmReturn_t
nat_23___bi___init__(pPmFrame_t *ppframe)
{

        PmReturn_t retval;
        pPmObj_t pself;
        pPmObj_t po;
        pPmObj_t pba;

        /* If only the self arg, create zero-length bytearray */
        if (NATIVE_GET_NUM_ARGS() == 1)
        {
            po = PM_ZERO;
        }

        /* If two args, get the second arg */
        else if (NATIVE_GET_NUM_ARGS() == 2)
        {
            po = NATIVE_GET_LOCAL(1);
        }

        /* Raise TypeError if wrong number of args */
        else
        {
            PM_RAISE(retval, PM_RET_EX_TYPE);
            return retval;
        }
        pself = NATIVE_GET_LOCAL(0);

        /* Create new bytearray object */
        retval = bytearray_new(po, &pba);
        PM_RETURN_IF_ERROR(retval);

        /* Store bytearray in None attr of instance */
        retval = dict_setItem((pPmObj_t)((pPmInstance_t)pself)->cli_attrs,
                              PM_NONE, pba);

        NATIVE_SET_TOS(PM_NONE);
        return retval;
        
}

PmReturn_t
nat_24_sys_exit(pPmFrame_t *ppframe)
{

    pPmObj_t pval = C_NULL;
    PmReturn_t retval;

    /* If no arg given, assume return 0 */
    if (NATIVE_GET_NUM_ARGS() == 0)
    {
        NATIVE_SET_TOS(PM_ZERO);
    }

    /* If 1 arg given, put it on stack */
    else if (NATIVE_GET_NUM_ARGS() == 1)
    {
        pval = NATIVE_GET_LOCAL(0);
        NATIVE_SET_TOS(pval);
    }

    /* If wrong number of args, raise TypeError */
    else
    {
        PM_RAISE(retval, PM_RET_EX_TYPE);
        return retval;
    }

    /* Raise the SystemExit exception */
    PM_RAISE(retval, PM_RET_EX_EXIT);
    return retval;
    
}

PmReturn_t
nat_25_sys_getb(pPmFrame_t *ppframe)
{

    uint8_t b;
    pPmObj_t pb;
    PmReturn_t retval;

    /* If wrong number of args, raise TypeError */
    if (NATIVE_GET_NUM_ARGS() != 0)
    {
        PM_RAISE(retval, PM_RET_EX_TYPE);
        return retval;
    }

    retval = plat_getByte(&b);
    PM_RETURN_IF_ERROR(retval);

    retval = int_new((int32_t)b, &pb);
    NATIVE_SET_TOS(pb);
    return retval;
    
}

PmReturn_t
nat_26_sys_heap(pPmFrame_t *ppframe)
{

    PmReturn_t retval;
    pPmObj_t pavail;
    pPmObj_t pmax;
    pPmObj_t ptup;

    /* If wrong number of args, raise TypeError */
    if (NATIVE_GET_NUM_ARGS() != 0)
    {
        PM_RAISE(retval, PM_RET_EX_TYPE);
        return retval;
    }

    /* Allocate a tuple to store the return values */
    retval = tuple_new(2, &ptup);
    PM_RETURN_IF_ERROR(retval);

    /* Get the maximum heap size */
    retval = int_new(PM_HEAP_SIZE, &pmax);
    PM_RETURN_IF_ERROR(retval);

    /* Allocate an int to hold the amount of heap available */
    retval = int_new(heap_getAvail() - sizeof(PmInt_t), &pavail);
    PM_RETURN_IF_ERROR(retval);

    /* Put the two heap values in the tuple */
    ((pPmTuple_t)ptup)->val[0] = pavail;
    ((pPmTuple_t)ptup)->val[1] = pmax;

    /* Return the tuple on the stack */
    NATIVE_SET_TOS(ptup);

    return retval;
    
}

PmReturn_t
nat_27_sys_putb(pPmFrame_t *ppframe)
{

    uint8_t b;
    pPmObj_t pb;
    PmReturn_t retval;

    pb = NATIVE_GET_LOCAL(0);

    /* If wrong number of args, raise TypeError */
    if (NATIVE_GET_NUM_ARGS() != 1)
    {
        PM_RAISE(retval, PM_RET_EX_TYPE);
        return retval;
    }

    /* If arg is not an int, raise TypeError */
    if (OBJ_GET_TYPE(pb) != OBJ_TYPE_INT)
    {
        PM_RAISE(retval, PM_RET_EX_TYPE);
        return retval;
    }

    b = ((pPmInt_t)pb)->val & 0xFF;
    retval = plat_putByte(b);
    NATIVE_SET_TOS(PM_NONE);
    return retval;
    
}

PmReturn_t
nat_28_sys_runInThread(pPmFrame_t *ppframe)
{

    PmReturn_t retval;
    pPmObj_t pf;

    /* If wrong number of args, raise TypeError */
    if (NATIVE_GET_NUM_ARGS() != 1)
    {
        PM_RAISE(retval, PM_RET_EX_TYPE);
        return retval;
    }

    /* If arg is not a function, raise TypeError */
    pf = NATIVE_GET_LOCAL(0);
    if (OBJ_GET_TYPE(pf) != OBJ_TYPE_FXN)
    {
        PM_RAISE(retval, PM_RET_EX_TYPE);
        return retval;
    }

    retval = interp_addThread((pPmFunc_t)pf);
    NATIVE_SET_TOS(PM_NONE);
    return retval;
    
}

PmReturn_t
nat_29_sys_time(pPmFrame_t *ppframe)
{

    uint32_t t;
    pPmObj_t pt;
    PmReturn_t retval;

    /* If wrong number of args, raise TypeError */
    if (NATIVE_GET_NUM_ARGS() != 0)
    {
        PM_RAISE(retval, PM_RET_EX_TYPE);
        return retval;
    }

    /* Get the system time (milliseconds since init) */
    retval = plat_getMsTicks(&t);
    PM_RETURN_IF_ERROR(retval);

    /*
     * Raise ValueError if there is an overflow
     * (plat_getMsTicks is unsigned; int is signed)
     */
    if ((int32_t)t < 0)
    {
        PM_RAISE(retval, PM_RET_EX_VAL);
        return retval;
    }

    /* Return an int object with the time value */
    retval = int_new((int32_t)t, &pt);
    NATIVE_SET_TOS(pt);
    return retval;
    
}

PmReturn_t
nat_30_string_atoi(pPmFrame_t *ppframe)
{

    pPmObj_t pa;
    pPmObj_t pb;
    char const *pc;
    char *pend;
    long i;
    int8_t base;
    pPmObj_t pi;
    PmReturn_t retval = PM_RET_OK;

    /* Raise TypeError if it's not a string or wrong number of args, */
    pa = NATIVE_GET_LOCAL(0);
    if ((OBJ_GET_TYPE(pa) != OBJ_TYPE_STR) || (NATIVE_GET_NUM_ARGS() < 1)
        || (NATIVE_GET_NUM_ARGS() > 2))
    {
        PM_RAISE(retval, PM_RET_EX_TYPE);
        return retval;
    }

    /* Get the base, if it exists; otherwise assume 10 */
    base = 10;
    if (NATIVE_GET_NUM_ARGS() == 2)
    {
        pb = NATIVE_GET_LOCAL(1);

        /* Raise a TypeError if 2nd arg is not an int */
        if (OBJ_GET_TYPE(pb) != OBJ_TYPE_INT)
        {
            PM_RAISE(retval, PM_RET_EX_TYPE);
            return retval;
        }

        base = ((pPmInt_t)pb)->val;

        /* Raise ValueError if base is out of range */
        if ((base < 0) || (base == 1) || (base > 36))
        {
            PM_RAISE(retval, PM_RET_EX_VAL);
            return retval;
        }
    }

    /* Perform conversion */
    pend = C_NULL;
    pc = (char const *)&(((pPmString_t)pa)->val);
    i = strtol(pc, &pend, base);

    /* Raise ValueError if there was a conversion error */
    if (*pend != C_NULL)
    {
        PM_RAISE(retval, PM_RET_EX_VAL);
        return retval;
    }

    /* Create an int object to hold the result of the conversion */
    retval = int_new(i, &pi);

    NATIVE_SET_TOS(pi);

    return retval;
    
}

PmReturn_t
nat_31_string_count(pPmFrame_t *ppframe)
{

    pPmObj_t ps1;
    pPmObj_t ps2;
    uint8_t *pc1;
    uint8_t *pc2;
    uint8_t *pscan;
    uint16_t pc1len;
    uint16_t pc2len;
    uint16_t n;
    pPmObj_t pn;
    PmReturn_t retval = PM_RET_OK;

    /* Raise TypeError if it's not a string or wrong number of args, */
    ps1 = NATIVE_GET_LOCAL(0);
    ps2 = NATIVE_GET_LOCAL(1);
    if ((OBJ_GET_TYPE(ps1) != OBJ_TYPE_STR) || (NATIVE_GET_NUM_ARGS() != 2)
        || (OBJ_GET_TYPE(ps2) != OBJ_TYPE_STR))
    {
        PM_RAISE(retval, PM_RET_EX_TYPE);
        return retval;
    }

    pc1 = ((pPmString_t)ps1)->val;
    pc2 = ((pPmString_t)ps2)->val;
    pc1len = ((pPmString_t)ps1)->length;
    pc2len = ((pPmString_t)ps2)->length;
    n = 0;

    if (*pc2 != C_NULL)
    {
        pscan = (uint8_t *)strstr((const char *)pc1, (const char *)pc2);
        while (pscan != C_NULL)
        {
            n++;
            pscan += pc2len;
            if (pscan > pc1 + pc1len) break;
            pscan = (uint8_t *)strstr((const char *)pscan, (const char *)pc2);
        }
    }

    retval = int_new(n, &pn);

    NATIVE_SET_TOS(pn);

    return retval;
    
}

PmReturn_t
nat_32_string_find(pPmFrame_t *ppframe)
{

    pPmObj_t ps1;
    pPmObj_t ps2;
    uint8_t *pc1;
    uint8_t *pc2;
    uint8_t *pscan;
    int32_t n;
    pPmObj_t pn;
    PmReturn_t retval = PM_RET_OK;

    /* Raise TypeError if it's not a string or wrong number of args, */
    ps1 = NATIVE_GET_LOCAL(0);
    ps2 = NATIVE_GET_LOCAL(1);
    if ((OBJ_GET_TYPE(ps1) != OBJ_TYPE_STR) || (NATIVE_GET_NUM_ARGS() != 2)
        || (OBJ_GET_TYPE(ps2) != OBJ_TYPE_STR))
    {
        PM_RAISE(retval, PM_RET_EX_TYPE);
        return retval;
    }

    pc1 = ((pPmString_t)ps1)->val;
    pc2 = ((pPmString_t)ps2)->val;
    n = -1;

    /* If the strings are non-null, try to find the index of the substring */
    if ((*pc1 != C_NULL) && (*pc2 != C_NULL))
    {
        pscan = (uint8_t *)strstr((const char *)pc1, (const char *)pc2);
        if (pscan != C_NULL)
        {
            n = pscan - pc1;
        }
    }

    retval = int_new(n, &pn);

    NATIVE_SET_TOS(pn);

    return retval;
    
}

PmReturn_t
nat_33_ipm__getImg(pPmFrame_t *ppframe)
{

    PmReturn_t retval;
    uint8_t imgType;
    uint16_t imgSize;
    uint8_t *pchunk;
    pPmCodeImgObj_t pimg;
    uint16_t i;
    uint8_t b;

    /* Get the image type */
    retval = plat_getByte(&imgType);
    PM_RETURN_IF_ERROR(retval);

    /* Quit if a code image type was not received */
    if (imgType != OBJ_TYPE_CIM)
    {
        PM_RAISE(retval, PM_RET_EX_STOP);
        return retval;
    }

    /* Get the image size (little endien) */
    retval = plat_getByte(&b);
    PM_RETURN_IF_ERROR(retval);
    imgSize = b;
    retval = plat_getByte(&b);
    PM_RETURN_IF_ERROR(retval);
    imgSize |= (b << 8);

    /* Get space for CodeImgObj */
    retval = heap_getChunk(sizeof(PmCodeImgObj_t) + imgSize, &pchunk);
    PM_RETURN_IF_ERROR(retval);
    pimg = (pPmCodeImgObj_t)pchunk;
    OBJ_SET_TYPE(pimg, OBJ_TYPE_CIO);

    /* Start the image with the bytes that have already been received */
    i = 0;
    pimg->val[i++] = imgType;
    pimg->val[i++] = imgSize & 0xFF;
    pimg->val[i++] = (imgSize >> 8) & 0xFF;

    /* Get the remaining bytes in the image */
    for(; i < imgSize; i++)
    {
        retval = plat_getByte(&b);
        PM_RETURN_IF_ERROR(retval);

        pimg->val[i] = b;
    }

    /* Return the image as a string object on the stack */
    NATIVE_SET_TOS((pPmObj_t)pimg);
    return retval;
    
}

/* native function lookup table */
PmReturn_t (* std_nat_fxn_table[])(pPmFrame_t *) =
{
    nat_00_list_append,
    nat_01_list_index,
    nat_02_list_insert,
    nat_03_list_pop,
    nat_04_list_remove,
    nat_05_dict_clear,
    nat_06_dict_keys,
    nat_07_dict_values,
    nat_08___bi_chr,
    nat_09___bi_dir,
    nat_10___bi_eval,
    nat_11___bi_globals,
    nat_12___bi_id,
    nat_13___bi_len,
    nat_14___bi_locals,
    nat_15___bi_ord,
    nat_16___bi_range,
    nat_17___bi_sum,
    nat_18___bi_type,
    nat_19___bi_Co,
    nat_20___bi___init__,
    nat_21___bi_send,
    nat_22___bi_ismain,
    nat_23___bi___init__,
    nat_24_sys_exit,
    nat_25_sys_getb,
    nat_26_sys_heap,
    nat_27_sys_putb,
    nat_28_sys_runInThread,
    nat_29_sys_time,
    nat_30_string_atoi,
    nat_31_string_count,
    nat_32_string_find,
    nat_33_ipm__getImg,
};