From 96ec74e5789a747913ebe5b1a583e540e60fa94a Mon Sep 17 00:00:00 2001 From: xchaos Date: Sat, 16 Aug 2008 19:49:56 +0000 Subject: [PATCH] #3 objects-wiki.c compiles with -Wall and runs git-svn-id: https://dev.arachne.cz/repos/cll1h/trunk@77 4bb87942-c103-4e5a-b51c-0ebff58f8515 --- cll1.h | 28 ++-- demos/objects/objects-sample.c | 292 ++++++++++++++++++++++++++------- demos/objects/objects-wiki.c | 40 +++-- 3 files changed, 270 insertions(+), 90 deletions(-) diff --git a/cll1.h b/cll1.h index 9f1ca5f..5693e3c 100644 --- a/cll1.h +++ b/cll1.h @@ -61,7 +61,7 @@ typedef FILE * file; typedef int bool; extern str NIL,EOL,OFS,IFS; extern unsigned RANDOM_SEED; -#define _EXPORT_GLOBALS str NIL="(null)", EOL="\n", OFS=" ", IFS=" \t\n"; unsigned RANDOM_SEED=0; void *_PTR; +#define _EXPORT_GLOBALS str NIL="(null)", EOL="\n", OFS=" ", IFS=" \t\n"; unsigned RANDOM_SEED=0; /* .----------------------------------------------------------------------. / 1. C<<1 then buddhist section, updated 2008-02-04 xCh. '----------------------------------------------------------------------- */ @@ -100,7 +100,7 @@ extern unsigned RANDOM_SEED; #define tree(TYPE) TYPE __next; TYPE __seek #define dict(TYPE) tree(TYPE); str __key #define array(TYPE) tree(TYPE); int __key -#define interface(TYPE) TYPE __interface + /* .----------------------------------------------------------------------. / 5. C<<1 string manipulation, updated 2008-01-26 xCh. '----------------------------------------------------------------------- */ @@ -128,7 +128,7 @@ extern unsigned RANDOM_SEED; '----------------------------------------------------------------------- */ #define push(NODE,HEAD) ( NODE ? ((NODE->__next=HEAD),(HEAD=NODE)) : NULL ) #define pop(NODE,HEAD) ( HEAD ? ((NODE=HEAD->__next),free(HEAD),(HEAD=NODE)) : (NODE=NULL) ) -#define append(NODE,HEAD) { _PTR=NODE; NODE->__next=NULL; for_search(NODE,HEAD,!NODE->__next) { NODE->__next=_PTR; break; } } +#define append(NODE,HEAD) { void *_PTR=NODE; if(NODE) NODE->__next=NULL; if(HEAD) { for_search(NODE,HEAD,!NODE->__next) { NODE->__next=_PTR; break; } } else HEAD=NODE; } #define remove(NODE,HEAD,EXPR) { void **_D=NULL; /* <-' */ for_search(NODE,HEAD,EXPR) { if(_D)*_D=NODE->__next; else HEAD=NODE->__next; free(NODE); } else _D=(void *)&(NODE->__next); } #define drop(NODE,HEAD) for( NODE=HEAD; NODE || (HEAD=NULL); HEAD=NODE, NODE=NODE->__next, free(HEAD) ) //to do: seek @@ -175,23 +175,24 @@ extern unsigned RANDOM_SEED; '----------------------------------------------------------------------- */ #define def_type(TYPE) typedef struct _##TYPE##_t * TYPE; #define def_obj(TYPE) struct _##TYPE##_t +#define interface(TYPE) TYPE __interface +#define interface_of(SELF) SELF->__interface #define method(NAME) (*NAME) #define construct(TYPE) TYPE _init_##TYPE(TYPE o,void *i) { o->__interface=i; return o; } TYPE __init__##TYPE #define get_obj(TYPE,INTERFACE,...) __init__##TYPE(_init_##TYPE(get_mem(TYPE),INTERFACE),__VA_ARGS__) -#define Get_obj(ID,MEM,INTERFACE) MEM ID=get_obj(MEM,INTERFACE) -#define get_obj_as(COMMUNITY,MEM,INTERFACE) (COMMUNITY)get_obj(MEM,INTERFACE) -#define Get_obj_as(ID,COMMUNITY,MEM,INTERFACE) MEM ID=get_obj_as(COMMUNITY,MEM,INTERFACE) -//#define _(METHOD,...) /*_ASSERT(ARG1(__VA_ARGS__,)), */(*( ARG1(__VA_ARGS__,)->__interface->METHOD )) ( __VA_ARGS__ ) -#define _(METHOD,OBJ) ( OBJ?(*( OBJ->__interface->METHOD )) ( OBJ ):0 ) +#define Get_obj(ID,MEM,...) MEM ID=get_obj(MEM,__VA_ARGS__) +#define get_obj_as(COMMUNITY,MEM,INTERFACE,...) (COMMUNITY)get_obj(MEM,INTERFACE,__VA_ARGS__) +#define Get_obj_as(ID,COMMUNITY,MEM,...) MEM ID=get_obj_as(COMMUNITY,MEM,INTERFACE,__VA_ARGS__) +#define _(METHOD,...) (((_ARG1(__VA_ARGS__,)) && (_ARG1(__VA_ARGS__,))->__interface->METHOD)?(*( (_ARG1(__VA_ARGS__,))->__interface->METHOD )) ((void *)__VA_ARGS__):0 ) #define __(METHOD,...) ( _ASSERT(ARG1(__VA_ARGS__,)), (*( __cll1_seekmethod(ARG1(__VA_ARGS__,),METHOD) )) ( __VA_ARGS__ ) ) #define call(OBJTYPE,METHOD,...) { int _N=0; OBJTYPE _OBJ; /* <-' */ while( (_OBJ=(OBJTYPE)_cll1_for_ptrs(_N++,__VA_ARGS__,NIL))!=(OBJTYPE)NIL ) _(_OBJ,METHOD); } -#define def_community(TYPE,INTERFACE) def_mem(TYPE) { INTERFACE __interface; }; +#define def_community(TYPE,INTERFACE) def_obj(TYPE) { INTERFACE __interface; }; #define anonymous void * #define I_am(MEM) MEM self=(MEM)community /* .----------------------------------------------------------------------. / 9. implementation of C<<1 library functions, updated 2008-01-26 xCh. '----------------------------------------------------------------------- */ -//#define _MALLOC void *_cll1_malloc(size_t size) { return malloc(size); } */ +/* later... #define _MALLOC void *_cll1_malloc(size_t size) { return malloc(size); } */ #define _CLL1_FPRINT(IOSTREAM) { int ofs=0; va_list ap; /* <-' */ for(va_start(ap,s);s!=NIL;s=va_arg(ap,char *)) { if(ofs)fputs(OFS,IOSTREAM);else ofs=1;/**/fputs(coalesce(s,NIL),IOSTREAM); } va_end(ap); fputs(EOL,IOSTREAM); } #define _DECLARE_PRINT void _cll1_print(char *s,...) #define _PRINT _DECLARE_PRINT _CLL1_FPRINT(stdout) @@ -210,7 +211,7 @@ extern unsigned RANDOM_SEED; #define _STRCMPI _DECLARE_STRCMPI { if(a && b) return strcasecmp(a,b); else return (int)(a-b); } #define _DECLARE_STRSTR str _cll1_str_str(str h, str n) #define _STRSTR _DECLARE_STRSTR { if(h && n) return strstr(h,n); else return NULL; } -//#define _WORDINSTR char *_cll1_wordinstr(char *a,char *b,int ign) { char *IFS=a; for(;a&&*a;a++) for(;*ifs||ifs=IFS;ifs++) if(*a=b);) for return strcasestr(a,b); else return NULL; } +// later... #define _WORDINSTR char *_cll1_wordinstr(char *a,char *b,int ign) { char *IFS=a; for(;a&&*a;a++) for(;*ifs||ifs=IFS;ifs++) if(*a=b);) for return strcasestr(a,b); else return NULL; } extern _DECLARE_PRINT; extern _DECLARE_FPRINT; extern _DECLARE_STRCOLL; @@ -228,9 +229,8 @@ extern _DECLARE_STRSTR; #define _F (_Fatom->F) #define _CTX (_CTXatom->CTX) #define _ARG1(ARG1,...) ARG1 -//#define _ARG2(ARG1,ARG2,...) ARG2 -#define _ASSERT(EXPR) assert(EXPR) //later: _cll1_assert(EXPR,handler) -#define _GET_MEM(TYPE) ((TYPE)malloc(sizeof(struct _##TYPE##_t))) //((TYPE)_cll1_malloc(sizeof(struct _##TYPE##_t))) +#define _ASSERT(EXPR) assert(EXPR) /* later... _cll1_assert(EXPR,handler) */ +#define _GET_MEM(TYPE) ((TYPE)malloc(sizeof(struct _##TYPE##_t))) /* later... ((TYPE)_cll1_malloc(sizeof(struct _##TYPE##_t))) */ #define _ANYATOM(TYPE,NAME) def_mem(_##NAME##Atom ) { TYPE NAME; int c; list( _##NAME##Atom ); } #define _FOR_COLUMNS(A,B,C) _NEW(I,0) for( prefix(A,B,C) ; A ; ((A!=B)&&prefix(A,B,C)||(A=NULL) ),_I++ ) #define _FOR_VALID_COLUMNS(A,B,C) _NEW(I,0) for( prefix(A,B,C) ; A ; ((A!=B)&&prefix(A,B,C))||(A=NULL) ) if(*A&&++_I) diff --git a/demos/objects/objects-sample.c b/demos/objects/objects-sample.c index cee195e..e0e8914 100644 --- a/demos/objects/objects-sample.c +++ b/demos/objects/objects-sample.c @@ -1,106 +1,156 @@ -#include +#include "cll1.h" -def_community(Drawable_object,Actions); +/* This is example of advanced C<<1 object oriented features... */ -def_mem(Actions) +def_type(Shape); + +def_mem(Interface) { - void method(init) (Drawable_object self, ...); - void method(draw) (Drawable_object self); - int method(desc) (Drawable_object self,int something); + void method(draw) (Shape self); + void method(move) (Shape self, int x, int y); + str method(desc) (Shape self); + void method(rename) (Shape self, str name); + void method(reset) (Shape self, int x1, int y1, int x2, int y2, int x3, int y3); + int method(area) (Shape self); + int count; }; +/* We intentionaly define heterogenous objects, which share only the interface + binding. Not only we can use different order of variables, and different + names - but we can even store these data on remote systems, etc. */ + def_mem(Tri) { - interface(Actions); + interface(Interface); int x1, y1, x2, y2, x3, y3; + str name; }; def_mem(Rect) { - interface(Actions); + interface(Interface); + str desc; int x1, y1, x2, y2; }; -construct_obj(Tri,Actions); +def_mem(Circ) +{ + interface(Interface); + int x1, y1; + str comment; + int r; +}; -construct_obj(Rect,Actions); +def_community(Shape, Interface); +/* Note: interface(Interface); has to be at first position in all objects asociated in community */ def_mem(Object_list) { - Drawable_object object; + Shape object; list(Object_list); }; -Actions init_tri_interface(Actions this) -{ - this->init = init_tri; - this->draw = draw_tri; - this->desc = desc_tri; - - return this; -} - -Actions init_rect_interface(Actions this) -{ - this->init = init_tri; - this->draw = draw_rect; - this->desc = desc_rect; - return this; -} +/* implementation of methods */ -void draw_tri(Drawable_object community) +void drawTri(Shape community) { 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); + printf("Drawing %s: %d,%d - %d,%d - %d,%d .\n", + self->name, self->x1, self->y1, self->x2, self->y2, self->x3, self->y3); }; -void draw_rect(Drawable_object community) +void drawRect(Shape community) { I_am(Rect); - printf("imagine I am drawing %d,%d - %d,%d\n", - self->x1,self->y1,self->x2,self->y2); + printf("Drawing %s: %d,%d - %d,%d .\n", + self->desc, self->x1, self->y1, self->x2, self->y2); }; -int desc_tri(Drawable_object community,int something) +void drawCirc(Shape community) { - I_am(Tri); + I_am(Circ); - 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); + printf("Drawing %s: %d,%d - r=%d .\n", + self->comment, self->x1, self->y1, self->r); +}; - return something; +void moveTri(Shape community, int x, int y) +{ + I_am(Tri); + + self->x1 += x; + self->y1 += y; + self->x2 += x; + self->y2 += y; + self->x3 += x; + self->y3 += y; }; -int desc_rect(Drawable_object community,int something) +void moveRect(Shape community, int x, int y) { 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); + self->x1 += x; + self->y1 += y; + self->x2 += x; + self->y2 += y; +}; - return something; +void moveCirc(Shape community, int x, int y) +{ + I_am(Circ); + + self->x1 += x; + self->y1 += y; }; -Tri init_tri(Drawable_object self, int x1, int y1, int x2, int y2, int x3, int y3) +str descTri(Shape community) +{ + return ""; +} + +str descRect(Shape community) +{ + return ""; +} + +str descCirc(Shape community) +{ + return ""; +} + +int calcAreaTri(Shape community) +{ + return 0; +} + +int calcAreaRect(Shape community) +{ + return 0; +} + +int calcAreaCirc(Shape community) +{ + return 0; +} + +void setTri(Shape community, int x1, int y1, int x2, int y2, int x3, int y3) { I_am(Tri); - + self->x1 = x1; self->y1 = y1; self->x2 = x2; self->y2 = y2; self->x3 = x3; self->y3 = y3; - - return self; } -Rect init_rect(Drawable_object self, int x1, int y1, int x2, int y2) +void setRect(Shape community, int x1, int y1, int x2, int y2, int dummy1, int dummy2) { I_am(Rect); @@ -108,26 +158,148 @@ Rect init_rect(Drawable_object self, int x1, int y1, int x2, int y2) self->y1 = y1; self->x2 = x2; self->y2 = y2; +} + +void setCirc(Shape community, int x1, int y1, int r, int dummy1, int dummy2, int dummy3) +{ + I_am(Circ); + + self->x1 = x1; + self->y1 = y1; + self->r = r; +} + +void nameRect(Shape community, str name) +{ + I_am(Rect); + + self->desc = name; +} + +/* Example of using object interface methods from inside constructor methods */ + +construct(Tri) (Tri self, int x1, int y1, int x2, int y2, int x3, int y3) +{ + self->name = "TRIANGLE"; + interface_of(self)->count++; + _(reset, self, x1, y1, x2, y2, x3, y3); + + return self; +} + +construct(Rect) (Rect self, int x1, int y1, int x2, int y2) +{ + self->desc = "rectangle"; + interface_of(self)->count++; + _(reset, self, x1, y1, x2, y2, 0, 0); + + return self; +} + +construct(Circ) (Circ self, int x1, int y1, int r) +{ + self->comment = "Circle"; + interface_of(self)->count++; + _(reset, self, x1, y1, r, 0, 0, 0); return self; } +/* registration of implemented methods to three interfaces of the same type */ + +Interface triInterface(void) +{ + Get_mem(this, Interface); + + this->draw = drawTri; + this->move = moveTri; + this->desc = descTri; + this->rename = NULL; + this->reset = setTri; + this->area = calcAreaTri; + this->count = 0; + + return this; +} + +Interface rectInterface(void) +{ + Get_mem(this, Interface); + + this->draw = drawRect; + this->move = moveRect; + this->desc = descRect; + this->rename = nameRect; + this->reset = setRect; + this->area = calcAreaRect; + this->count = 0; + + return this; +} + +Interface circInterface(void) +{ + Get_mem(this, Interface); + + this->draw = drawCirc; + this->move = moveCirc; + this->desc = descCirc; + this->rename = NULL; + this->reset = setCirc; + this->area = calcAreaCirc; + this->count = 0; + + return this; +} + +/* usage of objects inside C<<1 program */ + program { - Init_mem(tri_interface,Actions,init_tri_interface); - Init_mem(rect_interface,Actions,init_rect_interface); - Object_list all = NULL, one = get_mem(Object_list); + Interface triangles = triInterface(); + Interface rectangles = rectInterface(); + Interface circles = circInterface(); + Object_list all = NULL, one; - one->object = init_obj_as(Drawable_data, Rect, rect_interface, 0, 10, 1, 11); - append(one,all); - one->object = init_obj_as(Drawable_data, Tri, tri_interface, 0, 0, 0, 4, 3, 0); - append(one,all); - one->object = init_obj_as(Drawable_data, Rect, rect_interface, 10, 0, 11, 1); - append(one,all); - - for_each(one,all) + one = get_mem(Object_list); + one->object = get_obj_as(Shape, Rect, rectangles, 0, 10, 1, 11); + append(one, all); + + one = get_mem(Object_list); + one->object = get_obj_as(Shape, Tri, triangles, 0, 0, 0, 4, 3, 0); + append(one, all); + + one = get_mem(Object_list); + one->object = get_obj_as(Shape, Rect, rectangles, 10, 0, 11, 1); + append(one, all); + + one = get_mem(Object_list); + one->object = get_obj_as(Shape, Circ, circles, 10, 0, 5); + append(one, all); + + printf("We have created %d triangles, %d rectangles and %d circles:\n", + triangles->count, rectangles->count, circles->count); + + for_each(one, all) { - printf("(return value %d)\n", _(one->object,desc)); - _(one->object,draw); + _(draw, one->object); + printf("Area of this %s is %d (square pixels).\n", _(desc, one->object), _(area, one->object)); + printf("We have created %d instances of this type of object.\n", interface_of(one->object)->count); + + if(interface_of(one->object) == rectangles) + { + _(reset, one->object, 0, 0, 1, 1, 0, 0); + _(rename, one->object, "Renamed rectangle"); + } + else + { + _(move, one->object, 10, 10); + } } + + print("Rectangles were reset to new size and renamed, other objects were moved:"); + for_each(one, all) + { + _(draw, one->object); + } } diff --git a/demos/objects/objects-wiki.c b/demos/objects/objects-wiki.c index 50e1288..f603514 100644 --- a/demos/objects/objects-wiki.c +++ b/demos/objects/objects-wiki.c @@ -6,12 +6,14 @@ Of course there are easier ways to do the same thing... :-) (G)2008 xChas */ +def_type(Animal); + def_mem(Actions) { - str method(talk) (anonymous self); + str method(talk) (Animal self); }; -def_mem(Animal) +def_obj(Animal) { interface(Actions); char *name; @@ -23,45 +25,51 @@ construct(Animal) (Animal self, str name) return self; } -str cat_talk(anonymous self) +/* implementation of methods */ + +str catTalk(Animal self) { return "Meow!"; } -str dog_talk(anonymous self) +str dogTalk(Animal self) { return "Arf! Arf!"; } -Actions cat_actions(void) +/* registration of methods to object interface */ + +Actions catActions(void) { - Get_mem(this,Actions); + Get_mem(this, Actions); - this->talk = cat_talk; + this->talk = catTalk; return this; } -Actions dog_actions(void) +Actions dogActions(void) { - Get_mem(this,Actions); + Get_mem(this, Actions); - this->talk = dog_talk; + this->talk = dogTalk; return this; } +/* usage of objects inside C<<1 program */ + program { int i; Animal animal[3]; - Actions cat = cat_actions(); - Actions dog = dog_actions(); + Actions cat = catActions(); + Actions dog = dogActions(); - animal[0] = get_obj(Animal,cat,"Missy"); - animal[1] = get_obj(Animal,cat,"Mr. Bojangles"); - animal[2] = get_obj(Animal,dog,"Lassie"); + animal[0] = get_obj(Animal, cat, "Missy"); + animal[1] = get_obj(Animal, cat, "Mr. Bojangles"); + animal[2] = get_obj(Animal, dog, "Lassie"); for_range(i, 0, 2) { - print(animal[i]->name,":",_(talk,animal[i])); + print(animal[i]->name, ":", _(talk,animal[i])); } } -- 2.30.2