source: dev/BasicCompiler_Common/preprocessor.cpp@ 31

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

_System_LocalThis(見えないThisポインタパラメータ)を通常のパラメータ保有領域ではなく、リアルパラメータ保有領域に移動した。
メソッドとグローバル関数のオーバーロードに対応(DLL関数オーバーロードには未対応)。

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