source: dev/BasicCompiler_Common/preprocessor.cpp@ 67

Last change on this file since 67 was 67, checked in by dai_9181, 17 years ago

[32bit Compiler]op_push_value → op_push_V
Nothingに対応。

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