lot of work has been done, but lists are currently broken
[svn/Cll1h/.git] / demos / ansi-c / objects-c99.c
diff --git a/demos/ansi-c/objects-c99.c b/demos/ansi-c/objects-c99.c
new file mode 100644 (file)
index 0000000..f9884ff
--- /dev/null
@@ -0,0 +1,134 @@
+#include <stdio.h>
+#include <malloc.h>
+#include <assert.h>
+
+#define CONFEDERATION(IFACE,TYPE) struct IFACE *interface;struct TYPE *next
+#define CREATE(TYPE) (struct TYPE *)malloc(sizeof(struct TYPE))
+#define APPEND(TYPE,MEMBER,LIST) (MEMBER?MEMBER->next=(struct TYPE *)LIST:0,LIST=(struct TYPE *)MEMBER)
+#define SELF void *_self, void *_dummy
+#define I_AM(TYPE) struct TYPE *self=(struct TYPE *)_self;
+
+struct Drawable_data
+{
+ CONFEDERATION(Drawable_interface,Drawable_data);
+};
+
+struct Drawable_interface
+{
+ void (*draw)(SELF);
+ int (*desc)(SELF, int something);
+};
+
+struct Tri
+{
+ CONFEDERATION(Drawable_interface,Drawable_data);
+ int x1; int y1; int x2; int y2; int x3; int y3;
+};
+
+struct Rect
+{
+ CONFEDERATION(Drawable_interface,Drawable_data);
+ int x1; int y1; int x2; int y2;
+};
+
+void draw_tri(SELF)
+{
+ I_AM(Tri);
+ printf("imagine I am drawing %d,%d - %d,%d - %d,%d\n",self->x1,self->y1,self->x2,self->y2,self->x3,self->y3);
+};
+
+void draw_rect(SELF)
+{
+ I_AM(Rect);
+ printf("imagine I am drawing %d,%d - %d,%d\n",self->x1,self->y1,self->x2,self->y2);
+};
+
+int desc_tri(SELF, int something)
+{
+ I_AM(Tri);
+ printf("I am triangle %d,%d - %d,%d - %d,%d, method draw called with argument: %d\n",self->x1,self->y1,self->x2,self->y2,self->x3,self->y3, something);
+ return something;
+};
+
+int desc_rect(SELF, int something)
+{
+ I_AM(Rect);
+ printf("I am rectangle %d,%d - %d,%d, method draw called with argument: %d\n",self->x1,self->y1,self->x2,self->y2, something);
+ return something;
+};
+
+struct Drawable_interface *init_tri_interface(void)
+{
+ struct Drawable_interface *i=CREATE(Drawable_interface); 
+ /* vsechny metody je bohuzel potreba bindnout rucne, neda se svitit... */
+ if(i) { i->draw=draw_tri; i->desc=desc_tri; }  
+ return i;
+}
+
+struct Drawable_interface *init_rect_interface(void)
+{
+ struct Drawable_interface *i=CREATE(Drawable_interface); 
+ /* vsechny metody je bohuzel potreba bindnout rucne, neda se svitit... */
+ if(i) { i->draw=draw_rect; i->desc=desc_rect; }
+ return i;
+}
+
+struct Tri *create_tri(struct Drawable_interface *i, int x1, int y1, int x2, int y2, int x3, int y3)
+{
+ struct Tri *t=CREATE(Tri);
+ if(i && t) 
+ {
+  t->interface=i;
+  t->x1=x1;t->y1=y1;t->x2=x2;t->y2=y2;t->x3=x3;t->y3=y3;
+ }
+ return t;
+}
+
+struct Rect *create_rect(struct Drawable_interface *i, int x1, int y1, int x2, int y2)
+{
+ struct Rect *r=CREATE(Rect);
+ if(i && r) 
+ {
+  r->interface=i;
+  r->x1=x1;r->y1=y1;r->x2=x2;r->y2=y2;
+ }
+ return r;
+}
+
+int main(void) 
+{
+ struct Drawable_interface *tri_interface=init_tri_interface();
+ struct Drawable_interface *rect_interface=init_rect_interface();
+ struct Drawable_data *all=NULL,*one;
+ struct Tri *t;
+ struct Rect *r; 
+ r=create_rect(rect_interface,0,10,1,11);
+ APPEND(Drawable_data,r,all);
+ t=create_tri(tri_interface,0,0,0,4,3,0);
+ APPEND(Drawable_data,t,all);
+ r=create_rect(rect_interface,10,0,11,1);
+ APPEND(Drawable_data,r,all);
+
+ /* a nyni ... bylo to hodne prace, ale povedlo se ... ! */
+
+ for(one=all;one;one=one->next)
+ {
+  printf("(return value %d)\n",(*(one->interface->desc)) (one,NULL,0));
+  (*(one->interface->draw)) (one,NULL);
+ }
+
+ /* ...a nakonec pro efekt jeste instatni nudlovy kod s kanci prichuti dle ANSI C99: */
+
+#define _ARG1(ARG1,...) ARG1
+#define _(OBJECT,...) (assert(OBJECT),/**/(*(OBJECT->interface->_ARG1(__VA_ARGS__,)))/**/(OBJECT,OBJECT->interface->__VA_ARGS__)/**/)
+#define FOR_EACH(ONE,ALL) for(ONE=ALL;ONE;ONE=ONE->next)
+
+ FOR_EACH(one,all)
+ {
+    printf("(return value %d)\n",_(one,desc,1));
+   _(one,draw);
+ }
+
+ return 0;
+}
This page took 0.161026 seconds and 4 git commands to generate.