msgQ: use typedef bktidx_t uniformly everywhere
[charm.git] / src / xlatcpm / conv-cpm.flex
1 %{
2 #include <stdio.h>
3 #include <string.h>
4 int tok_lineno = 0;
5 int yytoktype;
6
7 /******************************************************************************
8  *
9  * Files
10  *
11  *****************************************************************************/
12
13 FILE *file_src;
14 FILE *file_cpm;
15
16 /******************************************************************************
17  *
18  * Lexical Analyzer
19  *
20  *****************************************************************************/
21 %}
22
23 %e 1500
24 %p 3900
25
26 STR    ([^"\\\n]|\\(['"?\\abfnrtv\n]|[0-7]{1,3}|[xX][0-9a-fA-F]{1,3}))
27 EXP    ([eE][+-]?[0-9]+)
28 FS     [flFL]
29 IS     ([uU][lL]?|[lL][uU]?)
30 ID     [_a-zA-Z][_a-zA-Z0-9]*
31
32 %%
33
34 "CpmDeclarePointer1"        { return 'P'; }
35 "CpmDeclareSimple1"         { return 'S'; }
36 "CpmInvokable"              { return 'I'; }
37 {ID}                        { return 'i'; }
38 [0-9]+"."[0-9]*{EXP}?{FS}?  { return '0'; }
39 "."[0-9]+{EXP}?{FS}?        { return '0'; }
40 [0-9]+{EXP}{FS}?            { return '0'; }
41 [1-9][0-9]*{IS}?            { return '0'; }
42 0[0-7]*{IS}?                { return '0'; }
43 0[xX][0-9a-fA-F]+{IS}?      { return '0'; }
44 \"{STR}*\"                  { return '"'; }
45 \'{STR}+\"                  { return 'c'; }
46 [ \t\f]+                    { }
47 [\n]                        { tok_lineno++; }
48 .                           { return yytext[0]; }
49
50 %%
51
52
53 #ifdef yywrap
54 #undef yywrap
55 #endif
56 yywrap(){ return(1); }
57
58 void yytokget()
59 {
60   yytoktype=yylex();
61 }
62
63 void yychkword(char *s)
64 {
65   if (strcmp(yytext, s)) {
66     fprintf(stderr,"%s expected\n", s);
67     exit(1);
68   }
69 }
70
71 void yychktype(char c)
72 {
73   if (yytoktype == c) return;
74   if (c=='i') {
75     fprintf(stderr,"identifier expected\n");
76     exit(1);
77   } else {
78     fprintf(stderr,"%c expected\n",c);
79     exit(1);
80   }
81 }
82
83 /******************************************************************************
84  *
85  * The 'symbol table', such as it is.
86  *
87  *****************************************************************************/
88
89 char *mod_funcs[1000];
90 int   mod_len;
91
92 char *type_name[1000];
93 int   type_kind[1000];
94 int   type_count;
95
96 char *func_name;
97 char *func_args[1000];
98 int   func_array[1000];
99 int   func_pointer[1000];
100 int   func_len;
101 int   func_static;
102
103 int type_simple(char *type)
104 {
105   int i;
106   for (i=0; i<type_count; i++) {
107     if (strcmp(type, type_name[i])==0)
108       return (type_kind[i]=='S') ? 1:0;
109   }
110   fprintf(stderr,"Unknown type %s\n", type);
111   exit(1); return 0;
112 }
113
114 void type_declare(char *type, int kind)
115 {
116   if (type_count==1000) {
117     fprintf(stderr,"error: type table overflow.\n");
118     exit(1);
119   }
120   type_name[type_count] = strdup(type);
121   type_kind[type_count] = kind;
122   type_count++;
123 }
124
125 /******************************************************************************
126  *
127  * Code Generation
128  *
129  *****************************************************************************/
130
131 void gen_actual_args(FILE *f)
132 {
133   int i;
134   fprintf(f, "(");
135   if (func_len) {
136     fprintf(f, "CpmA0");
137     for (i=1; i<func_len; i++) {
138       fprintf(f, ",CpmA%d", i);
139     }
140   }
141   fprintf(f,");\n");
142 }
143
144 void gen_dimension_required()
145 {
146   fprintf(stderr,"CpmDim required before array.\n");
147   exit(1);
148 }
149
150 void gen_func_struct()
151 {
152   int i;
153   fprintf(file_cpm, "struct CpmSt_%s\n", func_name);
154   fprintf(file_cpm, "{\n");
155   fprintf(file_cpm, "char convcore[CmiMsgHeaderSizeBytes];\n");
156   fprintf(file_cpm, "unsigned int envpos;\n");
157   for (i=0; i<func_len; i++) {
158     if ((func_pointer[i]==0) && (func_array[i]==0)) {
159       fprintf(file_cpm, "%s f%d;\n",func_args[i],i);
160     } else {
161       fprintf(file_cpm, "int f%d;\n",i);
162     }
163   }
164   fprintf(file_cpm, "};\n");
165 }
166
167 void gen_func_recv()
168 {
169   int i;
170   fprintf(file_cpm, "static void CpmRecv_%s(char *CpmM)\n", func_name);
171   fprintf(file_cpm, "{\n");
172   fprintf(file_cpm, "struct CpmSt_%s *CpmS=(struct CpmSt_%s *)CpmM;\n",
173           func_name, func_name);
174   fprintf(file_cpm, "char *CpmX = (char *)CpmS;\n");
175   fprintf(file_cpm, "int i;\n");
176   for (i=0; i<func_len; i++) {
177     fprintf(file_cpm, "%s %sCpmA%d;\n", func_args[i], func_array[i]?"*":"", i);
178   }
179   for (i=0; i<func_len; i++) {
180     int mode = (func_pointer[i] ? 2 : 0) + (func_array[i] ? 1 : 0);
181     switch(mode) {
182     case 0: /* simple */
183       fprintf(file_cpm, "CpmA%d = CpmS->f%d;\n", i, i);
184       fprintf(file_cpm, "CpmUnpack_%s(CpmA%d);\n", func_args[i], i);
185       break;
186     case 1: /* array of simple */
187       if ((i==0)||(func_array[i-1])||(strcmp(func_args[i-1],"CpmDim")))
188         gen_dimension_required();
189       fprintf(file_cpm, "CpmA%d = (%s *)(CpmX+(CpmS->f%d));\n", i, func_args[i], i);
190       fprintf(file_cpm, "for (i=0; i<CpmA%d; i++)\n", i-1);
191       fprintf(file_cpm, "  CpmUnpack_%s(CpmA%d[i]);\n", func_args[i], i);
192       break;
193     case 2: /* pointer */
194       fprintf(file_cpm, "CpmA%d = (%s)(CpmX+(CpmS->f%d));\n", i, func_args[i], i);
195       fprintf(file_cpm, "CpmPtrUnpack_%s(CpmA%d);\n", func_args[i], i);
196       break;
197     case 3: /* array of pointer */
198       if ((i==0)||(func_array[i-1])||(strcmp(func_args[i-1],"CpmDim")))
199         gen_dimension_required();
200       fprintf(file_cpm, "CpmA%d = (%s *)(CpmX+(CpmS->f%d));\n", i, func_args[i], i);
201       fprintf(file_cpm, "for (i=0; i<CpmA%d; i++) {\n", i-1);
202       fprintf(file_cpm, "  CpmA%d[i] = CpmM + (size_t)(CpmA%d[i]);\n", i, i);
203       fprintf(file_cpm, "  CpmPtrUnpack_%s(CpmA%d[i]);\n", func_args[i], i);
204       fprintf(file_cpm, "}\n");
205       break;
206     }
207   }
208   fprintf(file_cpm,"%s", func_name);
209   gen_actual_args(file_cpm);
210   fprintf(file_cpm, "}\n");
211 }
212
213 void gen_func_send()
214 {
215   int i;
216   if (func_static) fprintf(file_cpm, "static ");
217
218   fprintf(file_cpm,"void *Cpm_%s(CpmDestination ctrl",func_name);
219   for (i=0; i<func_len; i++) {
220     fprintf(file_cpm, ",%s %sa%d", func_args[i], func_array[i]?"*":"", i);
221   }
222   fprintf(file_cpm, ")\n");
223   fprintf(file_cpm, "{\n");
224   fprintf(file_cpm, "struct CpmSt_%s *msg;\n",func_name);
225   fprintf(file_cpm, "char *data; int size, i, envpos; void *result;\n");
226   fprintf(file_cpm, "int offs = CpmAlign(sizeof(struct CpmSt_%s), double);\n",func_name);
227   for (i=0; i<func_len; i++) {
228     if (func_array[i])
229       fprintf(file_cpm, "int aoffs%d;\n",i);
230     if (func_pointer[i]) {
231       if (func_array[i]) {
232         fprintf(file_cpm, "size_t *poffs%d = (size_t *)malloc(a%d*sizeof(size_t));\n",i,i-1);
233       } else {
234         fprintf(file_cpm, "int poffs%d;\n",i);
235       }
236     }
237   }
238   fprintf(file_cpm, "envpos=offs; offs=CpmAlign(offs+(ctrl->envsize),double);\n");
239   for (i=0; i<func_len; i++) {
240     if (func_array[i]) {
241       fprintf(file_cpm, "size=a%d*sizeof(%s);\n",i-1,func_args[i]);
242       fprintf(file_cpm, "aoffs%d=offs; offs=CpmAlign(offs+size,double);\n",i);
243     }
244   }
245   for (i=0; i<func_len; i++) {
246     if (func_pointer[i]) {
247       if (func_array[i]) {
248         fprintf(file_cpm, "for (i=0; i<a%d; i++) {\n",i-1) ;
249         fprintf(file_cpm, "  size = CpmPtrSize_%s(a%d[i]);\n",func_args[i],i);
250         fprintf(file_cpm, "  poffs%d[i]=offs; offs=CpmAlign(offs+size,double);\n",i);
251         fprintf(file_cpm, "}\n");
252       } else {
253         fprintf(file_cpm, "size = CpmPtrSize_%s(a%d);\n",func_args[i],i);
254         fprintf(file_cpm, "poffs%d=offs; offs=CpmAlign(offs+size, double);\n",i);
255       }
256     }
257   }
258   fprintf(file_cpm, "data = (char *)CmiAlloc(offs);\n");
259   fprintf(file_cpm, "msg = (struct CpmSt_%s *)data;\n",func_name);
260   fprintf(file_cpm, "msg->envpos = envpos;\n");
261   for (i=0; i<func_len; i++) {
262     int mode = (func_array[i]?2:0) | (func_pointer[i]?1:0);
263     switch(mode) {
264     case 0: /* one simple */
265       fprintf(file_cpm, "CpmPack_%s(a%d);\n",func_args[i],i);
266       fprintf(file_cpm, "msg->f%d = a%d;\n",i,i);
267       break;
268     case 1: /* one pointer */
269       fprintf(file_cpm, "msg->f%d = poffs%d;\n",i,i);
270       fprintf(file_cpm, "CpmPtrPack_%s(((%s)(data+poffs%d)), a%d);\n",
271               func_args[i],func_args[i],i,i);
272       break;
273     case 2: /* array simple */
274       fprintf(file_cpm, "msg->f%d = aoffs%d;\n",i,i);
275       fprintf(file_cpm, "memcpy(data+aoffs%d, a%d, a%d*sizeof(%s));\n",
276               i,i,i-1,func_args[i]);
277       fprintf(file_cpm, "for(i=0; i<a%d; i++)\n",i-1);
278       fprintf(file_cpm, "  CpmPack_%s(((%s *)(data+aoffs%d))[i]);\n",
279               func_args[i],func_args[i],i);
280       break;
281     case 3: /* array pointer */
282       fprintf(file_cpm, "msg->f%d = aoffs%d;\n",i,i);
283       fprintf(file_cpm, "memcpy(data+aoffs%d, poffs%d, a%d*sizeof(size_t));\n",
284               i,i,i-1);
285       fprintf(file_cpm, "for(i=0; i<a%d; i++)\n",i-1);
286       fprintf(file_cpm, "  CpmPtrPack_%s(((%s)(data+(poffs%d[i]))), a%d[i]);\n",
287               func_args[i],func_args[i], i,i);
288       break;
289     }
290   }
291   fprintf(file_cpm,"CmiSetHandler(msg, CpvAccess(CpmIndex_%s));\n",func_name);
292   fprintf(file_cpm,"result = (ctrl->sendfn)(ctrl, offs, msg);\n");
293   for (i=0; i<func_len; i++)
294     if ((func_pointer[i])&&(func_array[i]))
295       fprintf(file_cpm, "free(poffs%d);\n", i);
296   fprintf(file_cpm,"return result;\n");
297   fprintf(file_cpm,"}\n");
298 }
299
300 void gen_func_protos()
301 {
302   int i;
303
304   fprintf(file_cpm, "CpvStaticDeclare(int, CpmIndex_%s);\n", func_name);
305
306   fprintf(file_cpm,"void %s(",func_name);
307   if (func_len) {
308     fprintf(file_cpm, "%s %s", func_args[0], func_array[0]?"*":"");
309     for (i=1; i<func_len; i++)
310       fprintf(file_cpm, ",%s %s", func_args[i], func_array[i]?"*":"");
311   }
312   fprintf(file_cpm,");\n");
313 }
314
315 void gen_func_c()
316 {
317   gen_func_protos();
318   gen_func_struct();
319   gen_func_recv();
320   gen_func_send();
321 }
322
323 void gen_mod_head()
324 {
325   fprintf(file_cpm, "CpvStaticDeclare(int, CpmIPRIO);\n");
326 }
327
328 void gen_mod_tail()
329 {
330   int i;
331   fprintf(file_cpm, "static void CpmInitializeThisModule()\n");
332   fprintf(file_cpm, "{\n");
333   fprintf(file_cpm, "CpvInitialize(int, CpmIPRIO);\n");
334   for (i=0; i<mod_len; i++) {
335     fprintf(file_cpm, "CpvInitialize(int, CpmIndex_%s);\n", mod_funcs[i]);
336     fprintf(file_cpm, "CpvAccess(CpmIndex_%s) = CmiRegisterHandler(CpmRecv_%s);\n",
337           mod_funcs[i], mod_funcs[i]);
338   }
339   fprintf(file_cpm, "}\n");
340 }
341
342 /******************************************************************************
343  *
344  * The Parser
345  *
346  *****************************************************************************/
347
348 void parse_type()
349 {
350   int kind = yytoktype;
351   yytokget();
352   if (strncmp(yytext,"CpmType_",8)==0) {
353     type_declare(yytext+8, kind);
354   }
355   yytokget();
356 }
357
358 void parse_list()
359 {
360   int level=1;
361   yychktype('{');
362   yytokget();
363   while (level) {
364     if (yytoktype == '{') level++;
365     if (yytoktype == '}') level--;
366     if (yytoktype==0) return;
367     yytokget();
368   }
369 }
370
371 void parse_func()
372 {
373   yychkword("CpmInvokable");
374   yytokget();
375   if (yytoktype==';')
376     return;
377   func_len=0;
378   func_static=0;
379   if (strcmp(yytext,"static")==0) {
380     func_static=1;
381     yytokget();
382   }
383   yychktype('i');
384   func_name = strdup(yytext);
385   yytokget();
386   yychktype('(');
387   yytokget();
388   if (yytoktype != ')') {
389     while (1) {
390       yychktype('i');
391       func_args[func_len] = strdup(yytext);
392       func_array[func_len] = 0;
393       yytokget();
394       if (yytoktype == '*') {
395         yytokget();
396         func_array[func_len] = 1;
397       }
398       func_pointer[func_len] = !type_simple(func_args[func_len]);
399       func_len++;
400       yychktype('i');
401       yytokget();
402       if (yytoktype == ')') break;
403       yychktype(',');
404       yytokget();
405     }
406   }
407   yytokget();
408   mod_funcs[mod_len++] = func_name;
409   gen_func_c();
410 }
411
412 void parse_all()
413 {  
414   yyin = file_src;
415   yytokget();
416   gen_mod_head();
417   top:
418   switch (yytoktype) {
419   case 0: break;
420   case 'P': parse_type(); goto top;
421   case 'S': parse_type(); goto top;
422   case 'I': parse_func(); goto top;
423   case '{': parse_list(); goto top;
424   default: yytokget(); goto top; 
425   }
426   gen_mod_tail();
427 }
428
429 /******************************************************************************
430  *
431  * Setup
432  *
433  *****************************************************************************/
434
435 void usage()
436 {
437   fprintf(stderr,"usage: cpm <modulename>\n");
438   exit(1);
439 }
440
441 FILE *fopen_nofail(char *path, char *mode)
442 {
443   FILE *res = fopen(path, mode);
444   if (res==0) {
445     fprintf(stderr,"Couldn't open %s with mode %s\n",path,mode);
446     exit(1);
447   }
448   return res;
449 }
450
451 void disclaim(FILE *f, char *src)
452 {
453   fprintf(f,"/* WARNING: This file generated by Converse */\n");
454   fprintf(f,"/* Marshalling System from source-file %s. */\n",src);
455   fprintf(f,"\n");
456 }
457
458 main(int argc, char **argv)
459 {
460   if (argc != 3) usage();
461   file_src = fopen_nofail(argv[1], "r");
462   file_cpm = fopen_nofail(argv[2], "w");
463   disclaim(file_cpm, argv[1]);
464   parse_all();
465   exit(0);
466 }