source: dev/BasicCompiler_Common/preprocessor.cpp@ 23

Last change on this file since 23 was 15, checked in by dai_9181, 18 years ago

LexicalAnalysisを廃止。

File size: 11.1 KB
Line 
1#include "../BasicCompiler_Common/common.h"
2
3#ifdef _AMD64_
4#include "../BasicCompiler64/opcode.h"
5#else
6#include "../BasicCompiler32/opcode.h"
7#endif
8
9
10class CDefine{
11 int num;
12 char **ppNames;
13public:
14 CDefine();
15 ~CDefine();
16
17 BOOL add(char *name);
18 BOOL undef(char *name);
19 BOOL check(char *name);
20};
21CDefine::CDefine(){
22 extern HANDLE hHeap;
23 ppNames=(char **)HeapAlloc(hHeap,0,1);
24 num=0;
25
26 extern BOOL bDebugCompile;
27 if(bDebugCompile) add("_DEBUG");
28
29#ifdef _AMD64_
30 add("_WIN64");
31#endif
32
33 char temporary[255];
34 sprintf(temporary,"_AB_VER%d",MAJOR_VER);
35 add(temporary);
36}
37CDefine::~CDefine(){
38 int i;
39 for(i=0;i<num;i++){
40 HeapDefaultFree(ppNames[i]);
41 }
42 HeapDefaultFree(ppNames);
43}
44BOOL CDefine::add(char *name){
45 extern HANDLE hHeap;
46
47 //重複チェック
48 if(check(name)) return 0;
49
50 //追加
51 ppNames=(char **)HeapReAlloc(hHeap,0,ppNames,(num+1)*sizeof(char *));
52 ppNames[num]=(char *)HeapAlloc(hHeap,0,lstrlen(name)+1);
53 lstrcpy(ppNames[num],name);
54
55 num++;
56
57 return 1;
58}
59BOOL CDefine::undef(char *name){
60 extern HANDLE hHeap;
61 int i;
62
63 for(i=0;i<num;i++){
64 if(lstrcmp(ppNames[i],name)==0) break;
65 }
66 if(i==num) return 0;
67
68 HeapDefaultFree(ppNames[i]);
69
70 num--;
71 for(;i<num;i++){
72 ppNames[i]=ppNames[i+1];
73 }
74
75 return 1;
76}
77BOOL CDefine::check(char *name){
78 extern HANDLE hHeap;
79 int i;
80
81 //重複チェック
82 for(i=0;i<num;i++){
83 if(lstrcmp(ppNames[i],name)==0) return 1;
84 }
85 return 0;
86}
87
88//#define情報
89CDefine *pobj_define;
90
91int Search_endif(char *buffer,int i){
92 for(;;i++){
93 if(buffer[i]=='\0') break;
94
95 if(buffer[i-1]=='\n'){
96 if(_memicmp(buffer+i,"#ifdef",6)==0||_memicmp(buffer+i,"#ifndef",7)==0){
97 i=Search_endif(buffer,i+6);
98 if(buffer[i]=='\0') break;
99 continue;
100 }
101 else if(_memicmp(buffer+i,"#endif",6)==0){
102 break;
103 }
104 }
105 }
106 return i;
107}
108
109void preprocessor_ifdef(char *buffer,BOOL bndef){
110 int i,i2,i3;
111 char temporary[VN_SIZE];
112
113 if(bndef) i=lstrlen("#ifndef");
114 else i=lstrlen("#ifdef");
115 while(buffer[i]==' '||buffer[i]=='\t') i++;
116
117 for(i2=0;;i++,i2++){
118 if(buffer[i]=='\n'||buffer[i]=='\0'){
119 temporary[i2]=0;
120 break;
121 }
122 temporary[i2]=buffer[i];
123 }
124
125 int sw=0;
126 if(pobj_define->check(temporary)) sw=1;
127
128 if(bndef){
129 //#ifndefのとき(反対にする)
130 if(sw) sw=0;
131 else sw=1;
132 }
133
134 //#ifdefの行を消去
135 SlideString(buffer+i,-i);
136 i=0;
137
138 BOOL bElse=0;
139 if(sw){
140 //TRUEのとき
141
142 //#else、#endifを探索
143 for(;;i++){
144 if(buffer[i]=='\0') break;
145
146 if(i==0||buffer[i-1]=='\n'){
147 if(_memicmp(buffer+i,"#ifdef",6)==0||_memicmp(buffer+i,"#ifndef",7)==0){
148 i=Search_endif(buffer,i+6);
149 if(buffer[i]=='\0') break;
150 continue;
151 }
152 else if(_memicmp(buffer+i,"#else",5)==0){
153 i2=5;
154 bElse=1;
155 break;
156 }
157 else if(_memicmp(buffer+i,"#endif",6)==0){
158 i2=6;
159 bElse=0;
160 break;
161 }
162 }
163 }
164
165 //行を消去
166 SlideString(buffer+i+i2,-i2);
167
168 if(bElse){
169 //#elseがある場合はその区間を消去
170
171 for(i2=i,i3=0;;i2++){
172 if(buffer[i2]=='\0') break;
173
174 if(buffer[i2]=='\n') i3++;
175
176 if(i2==0||buffer[i2-1]=='\n'){
177 if(_memicmp(buffer+i2,"#ifdef",6)==0||_memicmp(buffer+i2,"#ifndef",7)==0){
178 i2=Search_endif(buffer,i2+6);
179 if(buffer[i2]=='\0') break;
180 continue;
181 }
182 if(_memicmp(buffer+i2,"#endif",6)==0){
183 i2+=6;
184 break;
185 }
186 }
187 }
188
189 //ソースコード区間を消去し、改行コードを挿入
190 SlideString(buffer+i2,i-i2+i3);
191 memset(buffer+i,'\n',i3);
192 }
193 }
194 else{
195 //FALSEのとき
196
197 //#else、#endifを探索
198 for(i2=i,i3=0;;i2++){
199 if(buffer[i2]=='\0') break;
200
201 if(buffer[i2]=='\n') i3++;
202
203 if(i2==0||buffer[i2-1]=='\n'){
204 if(_memicmp(buffer+i2,"#ifdef",6)==0||_memicmp(buffer+i2,"#ifndef",7)==0){
205 i2=Search_endif(buffer,i2+6);
206 if(buffer[i2]=='\0') break;
207 continue;
208 }
209 else if(_memicmp(buffer+i2,"#else",5)==0){
210 i2+=5;
211 bElse=1;
212 break;
213 }
214 else if(_memicmp(buffer+i2,"#endif",6)==0){
215 i2+=6;
216 bElse=0;
217 break;
218 }
219 }
220 }
221
222 //ソースコード区間を消去し、改行コードを挿入
223 SlideString(buffer+i2,i-i2+i3);
224 memset(buffer+i,'\n',i3);
225
226 if(bElse){
227 //#endifを探索
228 for(;;i++){
229 if(buffer[i]=='\0') break;
230
231 if(i==0||buffer[i-1]=='\n'){
232 if(_memicmp(buffer+i,"#ifdef",6)==0||_memicmp(buffer+i,"#ifndef",7)==0){
233 i=Search_endif(buffer,i+6);
234 if(buffer[i]=='\0') break;
235 continue;
236 }
237 else if(_memicmp(buffer+i,"#endif",6)==0){
238 i2=6;
239 bElse=0;
240 break;
241 }
242 }
243 }
244
245 //行を消去
246 SlideString(buffer+i+i2,-i2);
247 }
248 }
249}
250
251
252void DirectiveIfdef(char *buffer){
253 int i,i2,i3,sw;
254 char temporary[VN_SIZE];
255
256 for(i=0;;i++){
257 if(buffer[i]=='\0') break;
258
259 if(i==0||buffer[i-1]=='\n'){
260 sw=0;
261 if(_memicmp(buffer+i,"#define",7)==0){
262 i2=i+7;
263 while(buffer[i2]==' '||buffer[i2]=='\t') i2++;
264
265 for(i3=0;;i2++,i3++){
266 if(buffer[i2]=='\n'||buffer[i2]=='\0'){
267 temporary[i3]=0;
268 break;
269 }
270 temporary[i3]=buffer[i2];
271 }
272
273 pobj_define->add(temporary);
274
275 i2-=i;
276
277 //ディレクティブを消去
278 SlideString(buffer+i+i2,-i2);
279 }
280 if(_memicmp(buffer+i,"#undef",6)==0){
281 i2=i+7;
282 while(buffer[i2]==' '||buffer[i2]=='\t') i2++;
283
284 for(i3=0;;i2++,i3++){
285 if(buffer[i2]=='\n'||buffer[i2]=='\0'){
286 temporary[i3]=0;
287 break;
288 }
289 temporary[i3]=buffer[i2];
290 }
291
292 pobj_define->undef(temporary);
293
294 i2-=i;
295
296 //ディレクティブを消去
297 SlideString(buffer+i+i2,-i2);
298 }
299 else if(_memicmp(buffer+i,"#ifdef",6)==0){
300 preprocessor_ifdef(buffer+i,0);
301 continue;
302 }
303 else if(_memicmp(buffer+i,"#ifndef",7)==0){
304 preprocessor_ifdef(buffer+i,1);
305 continue;
306 }
307 else continue;
308 }
309 }
310}
311
312char *IncludeFiles(char *base){
313 extern HANDLE hHeap;
314 extern char szIncludeDir[MAX_PATH];
315 extern char BasicCurDir[MAX_PATH];
316 extern INCLUDEFILEINFO IncludeFileInfo;
317 int i,i2,i3,sw1,FileSize,LineNum,FileLayer[255],layer,LastFileByte[255];
318 char *buffer,temporary[MAX_PATH],temp2[MAX_PATH+255],*LayerDir[255];
319 DWORD AccBytes;
320 HANDLE hFile;
321
322 IncludeFileInfo.ppFileNames=(char **)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,sizeof(char *));
323 extern char SourceFileName[MAX_PATH];
324 IncludeFileInfo.ppFileNames[0]=(char *)HeapAlloc(hHeap,0,lstrlen(SourceFileName)+1);
325 lstrcpy(IncludeFileInfo.ppFileNames[0],SourceFileName);
326 IncludeFileInfo.FilesNum=1;
327
328 buffer=base+2;
329 layer=0;
330 FileLayer[layer]=0;
331 LastFileByte[layer]=lstrlen(buffer);
332 LineNum=0;
333
334 //参照ディレクトリ
335 LayerDir[0]=(char *)HeapAlloc(hHeap,0,lstrlen(BasicCurDir)+1);
336 lstrcpy(LayerDir[0],BasicCurDir);
337
338 for(i=0;;i++){
339 if(buffer[i]=='\0'){
340 IncludeFileInfo.LineOfFile[LineNum]=-1;
341 break;
342 }
343 if(buffer[i]=='\n'){
344 IncludeFileInfo.LineOfFile[LineNum]=FileLayer[layer];
345 LineNum++;
346 }
347 if(i>LastFileByte[layer]){
348 HeapDefaultFree(LayerDir[layer]);
349 layer--;
350 }
351 if(buffer[i-1]=='\n'&&buffer[i]=='#'){
352 if(memcmp(buffer+i+1,"include",7)==0){
353 i2=i+8;
354 while(buffer[i2]==' '||buffer[i2]=='\t') i2++;
355
356 if(buffer[i2]=='\"') sw1=0;
357 else if(buffer[i2]=='<') sw1=1;
358 i2++;
359
360 for(i3=0;;i2++,i3++){
361 if((buffer[i2]=='\"'&&sw1==0)||(buffer[i2]=='>'&&sw1==1)||buffer[i2]=='\n'||buffer[i2]=='\0'){
362 temporary[i3]=0;
363 break;
364 }
365 temporary[i3]=buffer[i2];
366 }
367 while(buffer[i2]!='\n'&&buffer[i2]!='\0') i2++;
368
369 if(sw1){
370 sprintf(temp2,"%s%s",szIncludeDir,temporary);
371 lstrcpy(temporary,temp2);
372 }
373 else GetFullPath(temporary,LayerDir[layer]);
374 }
375 else if(memcmp(buffer+i+1,"prompt",6)==0){
376 i2=i+7;
377 sprintf(temporary,"%sbasic\\prompt.sbp",szIncludeDir);
378 }
379 else if(memcmp(buffer+i+1,"N88BASIC",8)==0){
380 i2=i+9;
381 sprintf(temporary,"%sbasic\\prompt.sbp",szIncludeDir);
382 }
383 else if(memcmp(buffer+i+1,"console",7)==0){
384 //サブシステム タイプをCUIに変更
385 extern unsigned short TypeOfSubSystem;
386 TypeOfSubSystem=IMAGE_SUBSYSTEM_WINDOWS_CUI;
387
388 i2=i+8;
389 sprintf(temporary,"%sbasic\\dos_console.sbp",szIncludeDir);
390 }
391 else continue;
392
393 if(i){
394 //ディレクティブが消えるため、一行減ってしまうのを防ぐ(basic.sbpを除く)
395 SlideString(buffer+i2,1);
396 buffer[i2]='\n';
397 for(i3=0;i3<=layer;i3++) LastFileByte[i3]++;
398 }
399
400 IncludeFileInfo.ppFileNames=(char **)HeapReAlloc(hHeap,0,IncludeFileInfo.ppFileNames,(IncludeFileInfo.FilesNum+1)*sizeof(char *));
401 IncludeFileInfo.ppFileNames[IncludeFileInfo.FilesNum]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
402 lstrcpy(IncludeFileInfo.ppFileNames[IncludeFileInfo.FilesNum],temporary);
403
404 layer++;
405 FileLayer[layer]=IncludeFileInfo.FilesNum;
406 IncludeFileInfo.FilesNum++;
407
408 //インクルードファイルを読み込む
409 hFile=CreateFile(temporary,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
410 if(hFile==INVALID_HANDLE_VALUE){
411 sprintf(temp2,"インクルードファイル \"%s\" をオープンできません",temporary);
412 extern char *basbuf;
413 basbuf=base+2;
414 SetError(-1,temp2,i);
415 break;
416 }
417 FileSize=GetFileSize(hFile,NULL);
418
419 //読み込み
420 char *temp3;
421 temp3=(char *)HeapAlloc(hHeap,0,FileSize+1);
422 ReadFile(hFile,temp3,FileSize,&AccBytes,NULL);
423 temp3[AccBytes]=0;
424
425 //CRLFをLFに変換
426 ChangeReturnCode(temp3);
427
428 //コメント削除
429 DeleteComment(temp3);
430
431 //#ifdefディレクティブ
432 DirectiveIfdef(temp3);
433
434 FileSize=lstrlen(temp3);
435
436 i3=lstrlen(buffer)+FileSize;
437 base=(char *)HeapReAlloc(hHeap,HEAP_ZERO_MEMORY,base,i3*2);
438 buffer=base+2;
439 SlideString(buffer+i2,FileSize+(i-i2));
440 memcpy(buffer+i,temp3,FileSize);
441
442 //クローズ
443 CloseHandle(hFile);
444 HeapDefaultFree(temp3);
445
446 //新しい参照ディレクトリをセット
447 char temp4[MAX_PATH];
448 _splitpath(temporary,temp2,temp4,0,0);
449 lstrcat(temp2,temp4);
450 LayerDir[layer]=(char *)HeapAlloc(hHeap,0,lstrlen(temp2)+1);
451 lstrcpy(LayerDir[layer],temp2);
452
453 //ファイル範囲をスライド
454 LastFileByte[layer]=i+FileSize-1;
455 for(i3=0;i3<layer;i3++) LastFileByte[i3]+=FileSize+(i-i2);
456
457 i--;
458 }
459 }
460
461 HeapDefaultFree(LayerDir[0]);
462
463 return base;
464}
465char *OpenBasicFile(char *FileName){
466 extern HANDLE hHeap;
467 char *base,*buffer;
468 DWORD dwFileSize,dwAccBytes;
469 HANDLE hFile;
470
471 //ファイルオープン
472 hFile=CreateFile(FileName,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
473 if(hFile==INVALID_HANDLE_VALUE) return 0;
474
475 //#define情報を初期化
476 pobj_define=new CDefine;
477
478 //バッファ領域確保
479 dwFileSize=GetFileSize(hFile,0);
480 base=(char *)HeapAlloc(hHeap,0,dwFileSize*2+255);
481 base[0]='\n';
482 base[1]='\n';
483 buffer=base+2;
484 lstrcpy(buffer,"#include <basic.sbp>\n");
485 buffer+=lstrlen(buffer);
486
487 //読み込み
488 ReadFile(hFile,buffer,dwFileSize,&dwAccBytes,0);
489 buffer[dwAccBytes]=0;
490
491 //CRLFをLFに変換
492 ChangeReturnCode(buffer);
493
494 //コメント削除
495 DeleteComment(buffer);
496
497 //#ifdefディレクティブ
498 DirectiveIfdef(buffer);
499
500 //最終行には文字を含ませないようにする
501 lstrcat(buffer,"\n");
502
503 //ファイルクローズ
504 CloseHandle(hFile);
505
506 //インクルードファイルを読み込む
507 base=IncludeFiles(base);
508
509 //#define情報を破棄
510 delete pobj_define;
511 pobj_define=0;
512
513 return base;
514}
Note: See TracBrowser for help on using the repository browser.