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