📄 object.dc
字号:
#include <signal.h>#include <stdlib.h>#include <string.h>// Object% Object new {%casts return ctor(allocate(self), app);}% Object ctor {%casts return self;}% Object dtor {%casts return self;}% Object puto { const struct Class * class;%casts class = classOf(self); return fprintf(fp, "%s at %p\n", class -> name, self);}% Object delete {%casts free(dtor(self));}% Object geto { void * dummy;%casts if (fscanf(fp, " at %p\n", & dummy) != 1) assert(0); return self;}% classOf {%casts return self -> class;}% sizeOf { const struct Class * class = classOf(_self); return class -> size;}% isA { if (_self) {%casts return classOf(self) == class; } return 0;}% isOf { if (_self) { const struct Class * myClass;%casts myClass = classOf(self); if (class != Object()) { while (myClass != class) if (myClass != Object()) myClass = super(myClass); else return 0; } return 1; } return 0;}static void catch (int sig) // signal handler: bad pointer{ assert(sig == 0); // bad pointer, should not happen}#define isObject(p) \ ( assert(p), \ assert(((struct Object *) p) -> magic == MAGIC), p )% cast { void (* sigsegv)(int) = signal(SIGSEGV, catch);#ifdef SIGBUS void (* sigbus)(int) = signal(SIGBUS, catch);#endif const struct Object * self = isObject(_self); const struct Class * myClass = isObject(self -> class); if (class != Object()) { isObject(class); while (myClass != class) { assert(myClass != Object()); // illegal cast myClass = myClass -> super; } }#ifdef SIGBUS signal(SIGBUS, sigbus);#endif signal(SIGSEGV, sigsegv); return (void *) self;}% respondsTo { if (tag && * tag) { const struct Class * class = classOf(_self); const struct Method * p = & class -> ctor; // first int nmeth = (sizeOf(class) - offsetof(struct Class, ctor)) / sizeof(struct Method); // # of Methods do if (p -> tag && strcmp(p -> tag, tag) == 0) return p -> method ? p -> selector : 0; while (++ p, -- nmeth); } return 0;}struct classList { const char * name; const void * class; };static int cmp (const struct classList * a, const struct classList * b){ return strcmp(a -> name, b -> name);}void * retrieve (FILE * fp){ char buf [BUFSIZ]; extern const void * (* classes[]) (void); // munch static struct classList * cL; // local copy static int cD = -1; // # classes if (cD < 0) { for (cD = 0; classes[cD]; ++ cD) ; // count classes if (cD > 0) // collect name/desc { cL = malloc(cD * sizeof(struct classList)); assert(cL); for (cD = 0; classes[cD]; ++ cD) cL[cD].class = classes[cD](), cL[cD].name = nameOf(cL[cD].class); } } if (! cD) fputs("no classes known\n", stderr); else if (fp && ! feof(fp) && fscanf(fp, "%s", buf) == 1) { struct classList key, * p; key.name = buf; if ((p = bsearch(& key, cL, cD, sizeof key, (int (*) (const void *, const void *)) cmp))) return geto(allocate(p -> class), fp); fprintf(stderr, "%s: cannot retrieve\n", buf); } return 0;}// Class% Class dtor { assert(0); return 0;}% Class delete {%casts fprintf(stderr, "%s: cannot delete class\n", self -> name);}% Class geto { assert(0); return 0; // cannot happen}% allocate { struct Object * object;%casts assert(self -> size); object = calloc(1, self -> size); assert(object); object -> magic = MAGIC; object -> class = self; return object;}% super {%casts return self -> super;}% nameOf {%casts return self -> name;}// initialization// _Class and _Object are statically initialized structuresextern const struct Class _Object;extern const struct Class _Class;%initstatic const struct Class _Object = { { MAGIC, & _Class }, "Object", & _Object, sizeof(struct Object), { "", (Method) 0, (Method) Object_ctor }, { "", (Method) 0, (Method) Object_dtor }, { "puto", (Method) puto, (Method) Object_puto }, { "delete", (Method) delete,(Method) Object_delete }, { "", (Method) geto, (Method) Object_geto }, { "", (Method) 0, (Method) Object_new },};static const struct Class _Class = { { MAGIC, & _Class }, "Class", & _Object, sizeof(struct Class), { "", (Method) 0, (Method) Class_ctor }, { "", (Method) 0, (Method) Class_dtor }, { "puto", (Method) puto, (Method) Object_puto }, { "delete", (Method) delete,(Method) Class_delete }, { "", (Method) 0, (Method) Class_geto }, { "", (Method) 0, (Method) Object_new },};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -