source: dev/BasicCompiler_Common/preprocessor.cpp@ 14

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

LexicalAnalysisのベース部分を用意。

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