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