blob: 513d20c5a14c839fef6d252be81e320740d02a8b [file] [log] [blame]
PulkoMandy17fc7592022-07-28 18:27:54 +02001#include <stdio.h>
2#include <string.h>
3#include <stdlib.h>
4#include <ctype.h>
5#include <limits.h>
6
7#ifndef __STDC_VERSION__
8#ifdef __GNUC__
9#define __STDC_VERSION__ 199901L
10#endif
11#endif
12
13struct dtlist {char *spec,*descr;} dts[]={
14#include "datatypes.h"
15};
16
17struct dtconvlist {char *from,*to,*filef,*filet;int size;} cnvs[]={
18#include "dtconv.h"
19};
20
21int dtcnt=sizeof(dts)/sizeof(dts[0]);
22int cnvcnt=sizeof(cnvs)/sizeof(cnvs[0]);
23
24signed char *have;
25
26#define CHAR 1
27#define UCHAR 2
28#define SHORT 3
29#define USHORT 4
30#define INT 5
31#define UINT 6
32#define LONG 7
33#define ULONG 8
34#define LLONG 9
35#define ULLONG 10
36#define FLOAT 11
37#define DOUBLE 12
38#define LDOUBLE 13
39#define POINTER 14
40
41#define TYPECNT POINTER
42
43char *typen[TYPECNT+1]={"error","char","uchar","short","ushort","int","uint",
44 "long","ulong","llong","ullong","float","double","ldouble",
45 "pointer"};
46char *ftypen[TYPECNT+1]={"error","char","unsigned char","short","unsigned short",
47 "int","unsigned int","long","unsigned long",
48 "long long","unsigned long long",
49 "float","double","long double",
50 "char *"};
51
52int dt[TYPECNT+1],cnv[TYPECNT+1];
53char *nt[TYPECNT+1];
54FILE *fin,*cout,*hout;
55int crosscompiler;
56
57void *mymalloc(size_t size)
58{
59 void *p=malloc(size);
60 if(!p){
61 printf("Out of memory!\n");
62 exit(EXIT_FAILURE);
63 }
64 return p;
65}
66
67#define TESTTYPE(type,VALA,VALB) \
68 if(sizeof(type)*CHAR_BIT==bits){\
69 type tst=VALA;\
70 if(islittle&&*((unsigned char *)&tst)==VALB)\
71 return yn?"y":#type;\
72 if(isbig&&*(((unsigned char *)(&tst+1))-1)==VALB)\
73 return yn?"y":#type;\
74 }\
75
76
77char *yndefault(char *spec,int yn)
78{
79 int isieee=0,isunsigned=0,issigned,islittle=0,isbig=0,bits=0;
80 char *none;
81 if(yn) none="n"; else none="";
82 if(*spec++!='S') return none;
83 while(isdigit(*(unsigned char *)spec))
84 bits=bits*10+*spec++-'0';
85 if(*spec++!='B') return none;
86 if(!strncmp(spec,"IEEE",4))
87 {isieee=1;spec+=4;}
88 else if(*spec=='U')
89 {isunsigned=1;spec++;}
90 else if(*spec=='S')
91 {issigned=1;spec++;}
92 else
93 return none;
94 if(spec[0]=='B'&&spec[1]=='E')
95 {isbig=1;spec++;}
96 else if(spec[0]=='L'&&spec[1]=='E')
97 {islittle=1;spec++;}
98 else
99 islittle=isbig=1;
100 if(isieee){
101 TESTTYPE(float,1.0,0);
102 TESTTYPE(double,1.0,0);
103 TESTTYPE(long double,1.0,0);
104 return none;
105 }
106 if(isunsigned){
107 TESTTYPE(unsigned char,123,123);
108 TESTTYPE(unsigned short,123,123);
109 TESTTYPE(unsigned int,123,123);
110 TESTTYPE(unsigned long,123,123);
111#if __STDC_VERSION__==199901L
112 TESTTYPE(unsigned long long,123,123);
113#endif
114 return none;
115 }
116 if(issigned){
117 TESTTYPE(signed char,123,123);
118 TESTTYPE(signed short,123,123);
119 TESTTYPE(signed int,123,123);
120 TESTTYPE(signed long,123,123);
121#if __STDC_VERSION__==199901L
122 TESTTYPE(signed long long,123,123);
123#endif
124 return none;
125 }
126 return none;
127}
128
129
130int askyn(char *def)
131{
132 char in[8];
133 do{
134 printf("Type y or n [%s]: ",def);
135 fflush(stdout);
136 fgets(in,sizeof(in),stdin);
137 if(*in=='\n') strcpy(in,def);
138 }while(*in!='y'&&*in!='n');
139 return *in=='y';
140}
141
142char *asktype(char *def)
143{
144 char *in=mymalloc(128);
145 printf("Enter that type[%s]: ",def);
146 fflush(stdout);
147 fgets(in,127,stdin);
148 if(in[strlen(in)-1]=='\n') in[strlen(in)-1]=0;
149 if(!*in) strcpy(in,def);
150 return in;
151}
152
153int tst(int type,char *spec)
154{
155 int i,j;
156 for(i=0;i<dtcnt;i++){
157 if(strstr(spec,dts[i].spec)){
158 if(have[i]==-2) continue;
159 if(have[i]>=0){
160/* printf("auto: %s == %s\n",dts[i].spec,nt[have[i]]); */
161 dt[type]=i;
162 nt[type]=nt[have[i]];
163 cnv[type]=-1;
164 return 1;
165 }else{
166 printf("Does your system/compiler support a type implemented as\n%s?\n",dts[i].descr);
167 if(askyn(yndefault(dts[i].spec,1))){
168 dt[type]=i;
169 nt[type]=asktype(yndefault(dts[i].spec,0));
170 have[i]=type;
171 cnv[type]=-1;
172 return 1;
173 }else{
174 have[i]=-2;
175 }
176 }
177 }
178 }
179 for(j=0;j<cnvcnt;j++){
180 char *s=0;
181 if(strstr(spec,cnvs[j].from)) s=cnvs[j].to;
182/* if(strstr(spec,cnvs[j].to)) s=cnvs[j].from; */
183 if(s){
184 for(i=0;i<dtcnt;i++){
185 if(!strcmp(s,dts[i].spec)){
186 if(have[i]==-2) continue;
187 if(have[i]>=0){
188 dt[type]=i;
189 nt[type]=nt[have[i]];
190 cnv[type]=j;
191 return 2;
192 }else{
193 printf("Does your system/compiler support a type implemented as\n%s?\n",dts[i].descr);
194 if(askyn(yndefault(dts[i].spec,1))){
195 dt[type]=i;
196 nt[type]=asktype(yndefault(dts[i].spec,0));
197 have[i]=type;
198 cnv[type]=j;
199 return 2;
200 }else{
201 have[i]=-2;
202 }
203 }
204 }
205 }
206 }
207 }
208 return 0;
209}
210
211char *castfrom(int type)
212{
213 if(cnv[type]>=0){
214 char *s=mymalloc(16);
215 sprintf(s,"dtcnv%df",type);
216 return s;
217 }else{
218 return "";
219 }
220}
221char *castto(int type)
222{
223 if(cnv[type]>=0){
224 char *s=mymalloc(16);
225 sprintf(s,"dtcnv%dt",type);
226 return s;
227 }else{
228 return "";
229 }
230}
231void gen_cast(char *name,int from,int to)
232{
233 fprintf(hout,"#define %s(x) %s((%s)%s(x))\n",name,castto(to),nt[to],castfrom(from));
234}
235void gen_2op(char *name,char *op,int type)
236{
237 fprintf(hout,"#define %s(a,b) %s(%s(a)%s%s(b))\n",name,castto(type),castfrom(type),op,castfrom(type));
238}
239void gen_1op(char *name,char *op,int type)
240{
241 fprintf(hout,"#define %s(a) %s(%s%s(a))\n",name,castto(type),op,castfrom(type));
242}
243void gen_cmp(char *name,char *op,int type)
244{
245 fprintf(hout,"#define %s(a,b) (%s(a)%s%s(b))\n",name,castfrom(type),op,castfrom(type));
246}
247int main(int argc,char **argv)
248{
249 char type[128],spec[128];
250 int i,r;
251 if(argc!=4){ printf("Usage: dtgen <config-file> <output-file.h> <output-file.c>\n");exit(EXIT_FAILURE);}
252/* printf("%d datatypes, %d conversions\n",dtcnt,cnvcnt); */
253 have=mymalloc(dtcnt*sizeof(*have));
254 memset(have,-1,sizeof(*have)*dtcnt);
255 fin=fopen(argv[1],"r");
256 if(!fin){ printf("Could not open <%s> for input!\n",argv[1]);exit(EXIT_FAILURE);}
257 hout=fopen(argv[2],"w");
258 if(!hout){ printf("Could not open <%s> for output!\n",argv[2]);exit(EXIT_FAILURE);}
259 cout=fopen(argv[3],"w");
260 if(!hout){ printf("Could not open <%s> for output!\n",argv[3]);exit(EXIT_FAILURE);}
261 printf("Are you building a cross-compiler?\n");
262 crosscompiler=askyn("y");
263 for(i=1;i<=TYPECNT;i++){
264 fgets(spec,127,fin);
265/* printf("Specs for z%s:\n%s\n",typen[i],spec); */
266 if(!crosscompiler){
267 dt[i]=i;
268 nt[i]=ftypen[i];
269 have[i]=i;
270 cnv[i]=-1;
271 }else{
272 if(!tst(i,spec)){
273 printf("Problem! Your system does not seem to provide all of the data types\n"
274 "this version of vbcc needs.\nWrite to vb@compilers.de!\n");
275 exit(EXIT_FAILURE);
276 }
277 }
278 }
279 fprintf(hout,"\n\n/* Machine generated file. DON'T TOUCH ME! */\n\n\n");
280 fprintf(cout,"\n\n/* Machine generated file. DON'T TOUCH ME! */\n\n\n");
281 fprintf(hout,"#ifndef DT_H\n");
282 fprintf(hout,"#define DT_H 1\n");
283 fprintf(cout,"#include \"dt.h\"\n\n");
284 for(i=1;i<=TYPECNT;i++){
285 if(cnv[i]>=0){
286 int bits;
287 sscanf(cnvs[cnv[i]].from,"S%dB",&bits);
288 fprintf(hout,"typedef struct {char a[%d];} dt%df;\n",cnvs[cnv[i]].size,i);
289 fprintf(hout,"typedef dt%df z%s;\n",i,typen[i]);
290 fprintf(hout,"typedef %s dt%dt;\n",nt[i],i);
291 fprintf(hout,"dt%dt dtcnv%df(dt%df);\n",i,i,i);
292 fprintf(hout,"dt%df dtcnv%dt(dt%dt);\n",i,i,i);
293 fprintf(cout,"#undef BITSIZE\n#define BITSIZE %d\n",bits);
294 fprintf(cout,"#undef DTTTYPE\n#define DTTTYPE dt%dt\n",i);
295 fprintf(cout,"#undef DTFTYPE\n#define DTFTYPE dt%df\n",i);
296 fprintf(cout,"dt%dt dtcnv%df(dt%df\n",i,i,i);
297 fprintf(cout,"#include \"%s\"\n",cnvs[cnv[i]].filef);
298 fprintf(cout,"dt%df dtcnv%dt(dt%dt\n",i,i,i);
299 fprintf(cout,"#include \"%s\"\n",cnvs[cnv[i]].filet);
300 }else{
301 fprintf(hout,"typedef %s z%s;\n",nt[i],typen[i]);
302 }
303 }
304
305 gen_cast("zc2zm",CHAR,LLONG);
306 gen_cast("zs2zm",SHORT,LLONG);
307 gen_cast("zi2zm",INT,LLONG);
308 gen_cast("zl2zm",LONG,LLONG);
309 gen_cast("zll2zm",LLONG,LLONG);
310 gen_cast("zm2zc",LLONG,CHAR);
311 gen_cast("zm2zs",LLONG,SHORT);
312 gen_cast("zm2zi",LLONG,INT);
313 gen_cast("zm2zl",LLONG,LONG);
314 gen_cast("zm2zll",LLONG,LLONG);
315
316 gen_cast("zuc2zum",UCHAR,ULLONG);
317 gen_cast("zus2zum",USHORT,ULLONG);
318 gen_cast("zui2zum",UINT,ULLONG);
319 gen_cast("zul2zum",ULONG,ULLONG);
320 gen_cast("zull2zum",ULLONG,ULLONG);
321 gen_cast("zum2zuc",ULLONG,UCHAR);
322 gen_cast("zum2zus",ULLONG,USHORT);
323 gen_cast("zum2zui",ULLONG,UINT);
324 gen_cast("zum2zul",ULLONG,ULONG);
325 gen_cast("zum2zull",ULLONG,ULLONG);
326
327 gen_cast("zum2zm",ULLONG,LLONG);
328 gen_cast("zm2zum",LLONG,ULLONG);
329 gen_cast("zf2zld",FLOAT,LDOUBLE);
330 gen_cast("zd2zld",DOUBLE,LDOUBLE);
331 gen_cast("zld2zf",LDOUBLE,FLOAT);
332 gen_cast("zld2zd",LDOUBLE,DOUBLE);
333 gen_cast("zld2zm",LDOUBLE,LLONG);
334 gen_cast("zm2zld",LLONG,LDOUBLE);
335 gen_cast("zld2zum",LDOUBLE,ULLONG);
336 gen_cast("zum2zld",ULLONG,LDOUBLE);
337 gen_cast("zp2zum",POINTER,ULLONG);
338 gen_cast("zum2zp",ULLONG,POINTER);
339
340 fprintf(hout,"#define l2zm(x) %s((%s)(x))\n",castto(LLONG),nt[LLONG]);
341 fprintf(hout,"#define ul2zum(x) %s((%s)(x))\n",castto(ULLONG),nt[ULLONG]);
342 fprintf(hout,"#define d2zld(x) %s((%s)(x))\n",castto(LDOUBLE),nt[LDOUBLE]);
343 fprintf(hout,"#define zm2l(x) ((long)%s(x))\n",castfrom(LLONG));
344 fprintf(hout,"#define zum2ul(x) ((unsigned long)%s(x))\n",castfrom(ULLONG));
345 fprintf(hout,"#define zld2d(x) ((double)%s(x))\n",castfrom(LDOUBLE));
346
347 gen_2op("zmadd","+",LLONG);
348 gen_2op("zumadd","+",ULLONG);
349 gen_2op("zldadd","+",LDOUBLE);
350 gen_2op("zmsub","-",LLONG);
351 gen_2op("zumsub","-",ULLONG);
352 gen_2op("zldsub","-",LDOUBLE);
353 gen_2op("zmmult","*",LLONG);
354 gen_2op("zummult","*",ULLONG);
355 gen_2op("zldmult","*",LDOUBLE);
356 gen_2op("zmdiv","/",LLONG);
357 gen_2op("zumdiv","/",ULLONG);
358 gen_2op("zlddiv","/",LDOUBLE);
359 gen_2op("zmmod","%",LLONG);
360 gen_2op("zummod","%",ULLONG);
361 gen_2op("zmlshift","<<",LLONG);
362 gen_2op("zumlshift","<<",ULLONG);
363 gen_2op("zmrshift",">>",LLONG);
364 gen_2op("zumrshift",">>",ULLONG);
365 gen_2op("zmand","&",LLONG);
366 gen_2op("zumand","&",ULLONG);
367 gen_2op("zmor","|",LLONG);
368 gen_2op("zumor","|",ULLONG);
369 gen_2op("zmxor","^",LLONG);
370 gen_2op("zumxor","^",ULLONG);
371 gen_2op("zmmod","%",LLONG);
372 gen_2op("zummod","%",ULLONG);
373
374 gen_1op("zmkompl","~",LLONG);
375 gen_1op("zumkompl","~",ULLONG);
376
377 gen_cmp("zmleq","<=",LLONG);
378 gen_cmp("zumleq","<=",ULLONG);
379 gen_cmp("zldleq","<=",LDOUBLE);
380 gen_cmp("zmeqto","==",LLONG);
381 gen_cmp("zumeqto","==",ULLONG);
382 gen_cmp("zldeqto","==",LDOUBLE);
383
384 fprintf(hout,"#endif\n");
385
386 fclose(fin);
387 fclose(hout);
388 fclose(cout);
389 free(have);
390 return 0;
391}
392
393
394
395
396
397