include stdio include stdlib include stddef define A_UID define B_UID

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#define A_UID 1
#define B_UID 2
#define C_UID 3
#define D_UID 4
typedef struct TypeId {
char *name;
int (*cast)(int);
} TYPE_ID;
typedef struct Info {
TYPE_ID *id;
int offset ;
} INFO;
typedef struct Object { INFO *info; } OBJECT;
void *perform_cast(int uid, OBJECT *obj) {
int offs=obj->info->id->cast(uid);
if (offs==-1)
return NULL;
else
return (char*)obj+obj->info->offset+offs;
}
typedef struct A_info A_INFO;
typedef struct A_class A;
typedef struct A_fld {
int q;
} A_FLD;
struct A_class {
A_INFO *info;
A_FLD fld;
};
typedef struct A_vt {
void (*m1)(A*, int);
int (*m2)(A*);
} A_VT;
struct A_info {
TYPE_ID *id;
int offset ;
A_VT a_vt;
};
void a_m1(A *self, int p){
self->fld.q+=p;
}
int a_m2(A *self){
return self->fld.q;
}
int a_cast(int uid) {
return uid==A_UID?0:-1;
}
TYPE_ID a_id={"A", a_cast};
A_INFO a_info = {
&a_id, 0,
{a_m1, a_m2}
};
A *new_A() {
A *a;
a=(A*)malloc(sizeof(A));
a->info=&a_info;
return a;
}
void A_ctor(A *self){
self->fld.q=10;
}
typedef struct B_info B_INFO;
typedef struct B_class B;
typedef struct C_class C;
C* new_C();
void C_ctor(C *self, int p);
typedef struct D_class D;
D* new_D();
void D_ctor(D *self, int o, int p);
typedef struct B_fld {
A *a_ptr;
C *w;
D *e;
} B_FLD;
struct B_class {
B_INFO *info;
B_FLD b_fld;
A_INFO *info2;
A_FLD a_fld;
};
typedef struct B_vt {
int (*m3)(B*);
} B_VT;
struct B_info {
TYPE_ID *id;
int offset ;
A_VT a_vt;
B_VT b_vt;
};
void b_m1(A *self_a, int p);
int b_m3(B *self){
return self->info2->a_vt.m2((A*)self);
}
int b_cast(int uid) {
switch (uid) {
case A_UID: return offsetof(B, info2);
case B_UID: return 0;
default: return -1;
}
}
TYPE_ID b_id={ "B", b_cast };
B_INFO b_info={
&b_id, 0,
{b_m1, a_m2},
{b_m3}
};
A_INFO b_info2={
&b_id, -offsetof(B, info2),
{b_m1, a_m2}
};
B *new_B(){
B *b;
b=(B*)malloc(sizeof(B));
b->info=&b_info;
b->info2=&b_info2;
b->b_fld.a_ptr=(A*)((char*)b+offsetof(B, info2));
A_ctor(b->b_fld.a_ptr);
return b;
}
void B_ctor(B *self, int f) {
if (f==1) {
self->b_fld.w=new_C();
C_ctor(self->b_fld.w, 8);
self->b_fld.e=new_D();
D_ctor(self->b_fld.e, 16, 24);
}
}
typedef struct C_info C_INFO;
typedef struct C_fld {
A *a_ptr;
int r;
} C_FLD;
struct C_class {
C_INFO *info;
C_FLD c_fld;
A_INFO *info2;
A_FLD a_fld;
B_FLD b_fld;
};
typedef struct C_vt {
} C_VT;
struct C_info {
TYPE_ID *id;
int offset;
A_VT a_vt;
B_VT b_vt;
C_VT c_vt;
};
void c_m1(A *self_a, int p){
C *self=(C*)perform_cast(C_UID, (OBJECT*)self_a);
self->c_fld.r = p;
}
int c_cast(int uid) {
switch(uid) {
case A_UID: return offsetof(C, info2);
case C_UID: return 0;
default: return -1;
}
}
TYPE_ID c_id={"C",c_cast};
C_INFO c_info={
&c_id, 0,
{c_m1, a_m2},
{b_m3},
{ }
};
A_INFO c_info2={
&c_id, -offsetof(C, info2),
{c_m1, a_m2}
};
C* new_C(){
C* c;
c=(C*)malloc(sizeof(C));
c->info=&c_info;
c->info2=&c_info2;
c->c_fld.a_ptr=(A*)((char*)c-c->info2->offset);
A_ctor(c->c_fld.a_ptr);
return c;
}
void C_ctor(C *self, int p) {
B_ctor((B*)(self), 0);
self->c_fld.r=p;
}
void b_m1(A *self_a, int p) {
B *self = (B*)perform_cast(B_UID, (OBJECT*)self_a);
if (self->b_fld.w!=NULL){
self->b_fld.w->info->a_vt.m1((A*)self->b_fld.w, p);
};
}
typedef struct D_info D_INFO;
typedef struct D_fld {
int t, y;
} D_FLD;
struct D_class {
D_INFO *info;
D_FLD d_fld;
C_INFO *info2;
C_FLD c_fld;
};
typedef struct D_vt {
} D_VT;
struct D_info {
TYPE_ID *id;
int offset;
A_VT a_vt;
B_VT b_vt;
C_VT c_vt;
D_VT d_bt;
};
int d_cast(int uid) {
switch(uid) {
case A_UID: return offsetof(D, info2);
case D_UID: return 0;
default: return -1;
}
}
int d_m3(B *self_b){
D *self=(D*)perform_cast(D_UID, (OBJECT*)self_b);
return self->d_fld.t-self->d_fld.y;
}
TYPE_ID d_id={"D", d_cast};
D_INFO d_info={
&d_id, 0,
{c_m1, a_m2},
{d_m3},
{},
{}
};
C_INFO d_info2={
&d_id, -offsetof(D, info2),
{c_m1, a_m2},
{b_m3}
};
D* new_D() {
D *d;
d=(D*)malloc(sizeof(D));
d->info=&d_info;
d->info2=&d_info2;
return d;
}
void D_ctor(D *self, int o, int p) {
C_ctor((C*)(self), 0);
self->d_fld.t=o;
self->d_fld.y=p;
}
int main() {
int i;
A *a=new_A();
A_ctor(a);
a->info->a_vt.m1(a, 1);
i=a->info->a_vt.m2(a);
B *b=new_B();
B_ctor(b, 1);
b->info->a_vt.m1((A*)b, 2);
i=b->info->b_vt.m3(b);
C *c=new_C();
C_ctor(c, 2);
c->info->a_vt.m1((A*)c, 3);
D *d=new_D();
D_ctor(d, 3, 4);
i=d->info->b_vt.m3((B*)d);
free(a);
free(b->b_fld.w);
free(b->b_fld.e);
free(b);
free(c);
free(d);
return 0;
}