File: class/Workbook/Examples/Lecture15/stacktyp.c

/****************************************************
 * stacktyp.c: a character-string stack data-type;
 * a C extension type, for use in Python programs;
 * stacktype module clients can make multiple stacks;
 * similar to stackmod, but 'self' is the instance,
 * and we can overload sequence operators here;
 ****************************************************/

#include "Python.h"

static PyObject *ErrorObject;      /* local exception */
#define onError(message) \
       { PyErr_SetString(ErrorObject, message); return NULL; }


/**********************************************************
 * STACK-TYPE INFORMATION
 **********************************************************/

#define MAXCHARS 2048
#define MAXSTACK MAXCHARS

typedef struct {                 /* stack instance object */
    PyObject_HEAD                /* python header */
    int top, len;                /* + per-instance info */
    char *stack[MAXSTACK];       
    char strings[MAXCHARS];
} stackobject;

staticforward PyTypeObject Stacktype;  /* type descriptor */

#define is_stackobject(v)  ((v)->ob_type == &Stacktype)
 
/**********************************************************
 * INSTANCE METHODS
 **********************************************************/

static PyObject *             /* on "instance.push(arg)" */
stack_push(self, args)        /* 'self' is the instance */
    stackobject *self;        /* 'args' passed to method */
    PyObject    *args; 
{
    char *pstr;
    if (!PyArg_ParseTuple(args, "s", &pstr)) 
        return NULL;
    /*[. . .]*/      
    Py_INCREF(Py_None);  
    return Py_None;
}

static PyObject *
stack_pop(self, args)
    stackobject *self;
    PyObject    *args;        /* on "instance.pop()" */
{   /*[. . .]*/
    return Py_BuildValue("s", "not implemented");
}

static PyObject *
stack_top(self, args)
    stackobject *self;
    PyObject    *args;
{   /*[. . .]*/
}

static PyObject *
stack_empty(self, args)
    stackobject *self;
    PyObject    *args;
{   /*[. . .]*/
}

/* instance methods */
static struct PyMethodDef stack_methods[] = { 
 {"push",       stack_push,     1},      /* name, addr */
 {"pop",        stack_pop,      1},   
 {"top",        stack_top,      1},         
 {"empty",      stack_empty,    1}, 
 {NULL,         NULL}
};
 
/**********************************************************
 * BASIC TYPE-OPERATIONS
 **********************************************************/

static stackobject *       /* on "x = stacktype.Stack()" */
newstackobject()           /* instance constructor */    
{                          
    stackobject *self;
    self = PyObject_NEW(stackobject, &Stacktype);
    if (self == NULL)
        return NULL;            /* raise exception */
    self->top = 0;
    self->len = 0;
    return self;                /* a new type-instance */
}

static void                     /* instance destructor */
stack_dealloc(self)             /* frees instance struct */
    stackobject *self;
{                    
    PyMem_DEL(self); 
}

static int
stack_print(self, fp, flags)
    stackobject *self;
    FILE *fp;
    int flags;                      /* print self to file */
{   /*[. . .]*/
}

static PyObject *
stack_getattr(self, name)       /* on "instance.attr" */
    stackobject *self;          /* bound-method or member */
    char *name; 
{                            
    if (strcmp(name, "len") == 0) 
       return Py_BuildValue("i", self->len); 
    return 
       Py_FindMethod(stack_methods, (PyObject *)self, name);
}

static int
stack_compare(v, w)
    stackobject *v, *w;    /* return -1, 0 or 1 */
{   /*[. . .]*/
}
 
/**********************************************************
 * SEQUENCE TYPE-OPERATIONS
 **********************************************************/

static int
stack_length(self)
    stackobject *self;       /* on "len(instance)" */
{
    /*[. . .]*/
}

static PyObject *
stack_concat(self, other)
    stackobject *self;       /* on "instance + other" */
    PyObject    *other;
{   /*[. . .]*/              /* return new stack instance */
}

static PyObject *
stack_repeat(self, n)        /* on "instance * N" */
    stackobject *self;             
    int n;      
{   /*[. . .]*/
}

static PyObject *
stack_item(self, index)      /* on x[i], for, in */
    stackobject *self;
    int index;
{  
    if (index < 0 || index >= self->top) { 
        PyErr_SetString(PyExc_IndexError, "out-of-bounds"); 
        return NULL; 
    } 
    else                                
        return Py_BuildValue("s", self->stack[index]); 
}

static PyObject *
stack_slice(self, ilow, ihigh)
    stackobject *self;          
    int ilow, ihigh;            
{
    /* return ilow..ihigh slice of self--new object */
    onError("slicing not yet implemented")
}
 

/**********************************************************
 * TYPE DESCRIPTORS: MORE REGISTRATION 
 **********************************************************/

static PySequenceMethods stack_as_sequence = {
      (inquiry)       stack_length,      
      (binaryfunc)    stack_concat, 
      (intargfunc)    stack_repeat,
      (intargfunc)    stack_item, 
      (intintargfunc) stack_slice, 
      (intobjargproc)     0,           /* setitem */
      (intintobjargproc)  0,           /* setslice */
};

static PyTypeObject Stacktype = {      /* type descriptor */
  /* type header */
      PyObject_HEAD_INIT(&PyType_Type)         
      0,                               /* ob_size */
      "stack",                         /* name */
      sizeof(stackobject),             /* basicsize */
      0,                               /* itemsize */

  /* standard methods */
      (destructor)  stack_dealloc,     /* dealloc */
      (printfunc)   stack_print,       /* print */
      (getattrfunc) stack_getattr,     /* getattr */
      (setattrfunc) 0,                 /* setattr */
      (cmpfunc)     stack_compare,     /* compare */
      (reprfunc)    0,                 /* repr */

  /* type categories */
      0,                               /* number ops */
      &stack_as_sequence,              /* sequence ops */
      0,                               /* mapping ops */

  /* more methods */
      (hashfunc)   0,                  /* "dict[x]" */
      (binaryfunc) 0,                  /* "x()"     */
      (reprfunc)   0,                  /* "str(x)"  */

};  /* plus others: see Include/object.h */

 

/*********************************************************
 * MODULE LOGIC: CONSTRUCTOR FUNCTION
 **********************************************************/

static PyObject *
stacktype_new(self, args)   /* on "x = stacktype.Stack()" */
    PyObject *self; 
    PyObject *args;
{
    if (!PyArg_ParseTuple(args, ""))     /* Module func */
        return NULL;
    return (PyObject *)newstackobject();
}                                      

static struct PyMethodDef stacktype_methods[] = {
    {"Stack",  stacktype_new,  1}, 
    {NULL,     NULL}            
};

void
initstacktype()           /* on first "import stacktype" */
{
    PyObject *m, *d;
    m = Py_InitModule("stacktype", stacktype_methods);
    d = PyModule_GetDict(m);
    ErrorObject = Py_BuildValue("s", "stacktype.error");
    PyDict_SetItemString(d, "error", ErrorObject);
    if (PyErr_Occurred())
        Py_FatalError("can't initialize module stacktype");
}




[Home page] Books Code Blog Python Author Train Find ©M.Lutz