source: dev/BasicCompiler_Common/Intermediate_Step2.cpp@ 7

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

Constステートメントで定数変数を宣言できるように改良。

File size: 15.3 KB
Line 
1#include "../BasicCompiler_Common/common.h"
2
3CONSTINFO *GetNewConstHash(char *name){
4 extern int cp;
5 CONSTINFO *pci;
6
7 int key;
8 key=hash_default(name);
9
10 extern CONSTINFO **ppConstHash;
11 if(ppConstHash[key]){
12 pci=ppConstHash[key];
13 while(1){
14 if(lstrcmp(pci->name,name)==0){
15 //重複エラー
16 SetError(15,name,cp);
17 return 0;
18 }
19
20 if(pci->pNextData==0){
21 pci->pNextData=(CONSTINFO *)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,sizeof(CONSTINFO));
22 break;
23 }
24 pci=pci->pNextData;
25 }
26 pci=pci->pNextData;
27 }
28 else{
29 ppConstHash[key]=(CONSTINFO *)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,sizeof(CONSTINFO));
30 pci=ppConstHash[key];
31 }
32
33 return pci;
34}
35void AddConstData(char *Command){
36 extern HANDLE hHeap;
37 extern int cp;
38 int i,i2;
39 char temporary[VN_SIZE];
40
41 for(i=0;;i++){
42 if(Command[i]=='\0'){
43 SetError(10,"Const",cp);
44 return;
45 }
46 if(Command[i]=='='){
47 //定数定義は新しいクラスモジュール(CDBConst)へ移行
48 return;
49 }
50 if(Command[i]=='('){
51 temporary[i]=0;
52 break;
53 }
54 temporary[i]=Command[i];
55 }
56
57
58 /////////////////////////////////
59 // 格納位置を計算してpciにセット
60 /////////////////////////////////
61
62 CONSTINFO *pci;
63 pci=GetNewConstHash(temporary);
64 if(!pci) return;
65
66
67
68 ////////////////////
69 // 定数情報を取得
70 ////////////////////
71
72 //定数名
73 pci->name=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
74 lstrcpy(pci->name,temporary);
75
76 if(Command[i]=='('){
77 pci->ppParm=(char **)HeapAlloc(hHeap,0,1);
78 pci->ParmNum=0;
79 for(i++,i2=0;;i++,i2++){
80 if(Command[i]=='\0'){
81 SetError(1,NULL,cp);
82 return;
83 }
84 if(Command[i]==','||Command[i]==')'){
85 temporary[i2]=0;
86 pci->ppParm=(char **)HeapReAlloc(hHeap,0,pci->ppParm,(pci->ParmNum+1)*sizeof(char *));
87 pci->ppParm[pci->ParmNum]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
88 lstrcpy(pci->ppParm[pci->ParmNum],temporary);
89 pci->ParmNum++;
90 if(Command[i]==')'){
91 i++;
92 if(Command[i]!='='){
93 SetError(1,NULL,cp);
94 return;
95 }
96 break;
97 }
98
99 i2=-1;
100 continue;
101 }
102 temporary[i2]=Command[i];
103 }
104 }
105 else pci->ParmNum=0;
106
107 //データ
108 lstrcpy(temporary,Command+i+1);
109 if(pci->ParmNum){
110 pci->StrValue=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
111 lstrcpy(pci->StrValue,temporary);
112 }
113 else if(temporary[0]=='\"'){
114 //文字列定数
115 RemoveStringQuotes(temporary);
116 i2=lstrlen(temporary);
117
118 pci->StrValue=(char *)HeapAlloc(hHeap,0,i2+1);
119 memcpy(pci->StrValue,temporary,i2);
120 pci->StrValue[i2]=0;
121
122 pci->DblValue=(double)i2;
123
124 pci->type=DEF_STRING;
125 pci->lpIndex=-1;
126 }
127 else if((temporary[0]=='e'||temporary[0]=='E')&&
128 (temporary[1]=='x'||temporary[1]=='X')&&
129 temporary[2]=='\"'){
130 //文字列定数
131 RemoveStringQuotes(temporary+2);
132 i2=FormatString_EscapeSequence(temporary+2);
133 pci->StrValue=(char *)HeapAlloc(hHeap,0,i2+1);
134 memcpy(pci->StrValue,temporary+2,i2);
135 pci->StrValue[i2]=0;
136
137 pci->DblValue=(double)i2;
138
139 pci->type=DEF_STRING;
140 pci->lpIndex=-1;
141 }
142 else{
143 //数値定数
144 _int64 i64data;
145 pci->type=StaticCalculation(true, temporary,0,&i64data,&pci->lpIndex);
146 if(IsRealNumberType(pci->type)){
147 //実数型
148 memcpy(&pci->DblValue,&i64data,sizeof(double));
149 }
150 else if(Is64Type(pci->type)){
151 //64ビット型
152 pci->i64Value=i64data;
153 }
154 else if(IsWholeNumberType(pci->type)){
155 //その他整数型
156 pci->DblValue=(double)i64data;
157 }
158
159 pci->StrValue=0;
160 }
161}
162void AddConstEnum(char *buffer){
163 extern int cp;
164 int i=0,i2;
165
166 if(!(buffer[i]==1&&buffer[i+1]==ESC_ENUM)) return;
167 i+=2;
168
169 //列挙体の名前を取得
170 char temporary[VN_SIZE];
171 for(i2=0;;i++,i2++){
172 if(IsCommandDelimitation(buffer[i])){
173 temporary[i2]=0;
174 break;
175 }
176 if(!IsVariableChar(buffer[i])){
177 SetError(1,NULL,i);
178 break;
179 }
180 temporary[i2]=buffer[i];
181 }
182
183 //新しい型情報を追加
184 pobj_DBTypeDef->add(temporary,"Long");
185
186 if(buffer[i]=='\0'){
187 SetError(22,"Enum",cp);
188 return;
189 }
190
191 int NextValue=0;
192 while(1){
193 i++;
194
195 if(buffer[i]==1&&buffer[i+1]==ESC_ENDENUM) break;
196
197 for(i2=0;;i2++,i++){
198 if(IsCommandDelimitation(buffer[i])){
199 temporary[i2]=0;
200 break;
201 }
202 if(buffer[i]=='='){
203 temporary[i2]=0;
204 break;
205 }
206 temporary[i2]=buffer[i];
207 }
208 if(temporary[0]=='\0'){
209 if(buffer[i]=='\0'){
210 SetError(22,"Enum",cp);
211 break;
212 }
213 continue;
214 }
215
216 if(buffer[i]!='='){
217 NextValue++;
218 }
219 else{
220 char temp2[VN_SIZE];
221 for(i++,i2=0;;i2++,i++){
222 if(IsCommandDelimitation(buffer[i])){
223 temp2[i2]=0;
224 break;
225 }
226 temp2[i2]=buffer[i];
227 }
228
229 _int64 i64data;
230 LONG_PTR lpIndex;
231 StaticCalculation(true, temp2,DEF_LONG,&i64data,&lpIndex);
232 NextValue=(int)i64data;
233 }
234
235 //定数を追加
236 CDBConst::obj.AddConst(temporary, NextValue);
237 }
238}
239void GetConstInfo(void){
240 ////////////////////////////////////////////
241 // Const命令の情報を取得
242 ////////////////////////////////////////////
243
244 int i,i2;
245 char temporary[1024];
246
247 //定数に関する情報
248 extern CONSTINFO **ppConstHash;
249 ppConstHash=(CONSTINFO **)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,MAX_HASH*sizeof(CONSTINFO *));
250
251 extern char *basbuf;
252 for(i=0;;i++){
253 if(basbuf[i]=='\0') break;
254 else if(basbuf[i]==1&&basbuf[i+1]==ESC_CONST){
255 i+=2;
256
257 extern int cp;
258 cp=i; //エラー用
259
260
261 if(basbuf[i]==1&&basbuf[i+1]==ESC_ENUM){
262 AddConstEnum(basbuf+i);
263 continue;
264 }
265
266 for(i2=0;;i++,i2++){
267 if(basbuf[i]=='\"'){
268 temporary[i2]=basbuf[i];
269 for(i++,i2++;;i++,i2++){
270 temporary[i2]=basbuf[i];
271 if(basbuf[i]=='\"') break;
272 }
273 continue;
274 }
275 if(IsCommandDelimitation(basbuf[i])){
276 temporary[i2]=0;
277 break;
278 }
279 temporary[i2]=basbuf[i];
280 }
281 CDBConst::obj.Add(temporary);
282 if(basbuf[i]=='\0') break;
283 }
284 }
285}
286
287char ConstructorDestructorSchedule[MAX_PATH];
288void MakeConstructorAndDestructor(char *buffer,int NowLine,char *ClassName){
289 int i,i2;
290 char temporary[MAX_PATH],*pTemp;
291 BOOL bConstructor,bDestructor;
292
293 ConstructorDestructorSchedule[0]=0;
294 bConstructor=0;
295 bDestructor=0;
296
297 for(i=NowLine;;i++){
298 if(buffer[i]=='\0') break;
299 if(buffer[i]==1&&buffer[i+1]==ESC_ENDCLASS){
300 if((!bConstructor)||(!bDestructor)){
301 pTemp=ConstructorDestructorSchedule;
302
303 lstrcpy(pTemp,"Public:");
304
305 if(!bConstructor){
306 //コンストラクタが無いときは生成する
307 sprintf(pTemp+lstrlen(pTemp),"%c%c%s():%c%c:",
308 1,ESC_SUB,
309 ClassName,
310 1,ESC_ENDSUB);
311 }
312
313 if(!bDestructor){
314 //デストラクタが無いときは生成する
315 sprintf(pTemp+lstrlen(pTemp),"%c%c~%s():%c%c:",
316 1,ESC_SUB,
317 ClassName,
318 1,ESC_ENDSUB);
319 }
320 }
321 break;
322 }
323
324 if(buffer[i]==1&&(buffer[i+1]==ESC_SUB||buffer[i+1]==ESC_FUNCTION)){
325 i+=2;
326 while(IsBlank(buffer[i])) i++;
327 if(buffer[i]=='~'){
328 //デストラクタ
329 bDestructor=1;
330 }
331 else{
332 //コンストラクタかどうかをチェック
333 for(i2=0;;i++,i2++){
334 if(!IsVariableChar(buffer[i])){
335 temporary[i2]=0;
336 break;
337 }
338 temporary[i2]=buffer[i];
339 }
340 if(lstrcmp(temporary,ClassName)==0) bConstructor=1;
341 }
342 }
343 }
344}
345void ChangeCommand(char *buffer,int NowLine,char *Command){
346 int i,i2,IsStr;
347 unsigned _int16 ComNum;
348 char com[8192],pam[8192];
349
350 if(Command[0]==1){
351 switch(Command[1]){
352 case ESC_SELECTCASE:
353 case ESC_CASE:
354 KillStringSpaces(Command+2);
355 break;
356 case ESC_WITH:
357 KillStringSpaces(Command+2);
358 break;
359 case ESC_CONST:
360 KillStringSpaces(Command+2);
361 break;
362 case ESC_TYPEDEF:
363 KillStringSpaces(Command+2);
364 AddTypeDefData(Command+2);
365 break;
366 case ESC_DECLARE:
367 KillStringSpaces(Command+2);
368 break;
369 case ESC_IF:
370 KillStringSpaces(Command+2);
371 break;
372
373 case ESC_CLASS:
374 KillStringSpaces(Command+2);
375
376 //コンストラクタ、デストラクタを暗黙的に生成
377 MakeConstructorAndDestructor(buffer,NowLine,Command+2);
378 break;
379 case ESC_INTERFACE:
380 KillStringSpaces(Command+2);
381 break;
382 case ESC_ENDCLASS:
383 if(ConstructorDestructorSchedule[0]){
384 //生成されたコンストラクタ、デストラクタを挿入
385 sprintf(Command,"%s%c%c",ConstructorDestructorSchedule,1,ESC_ENDCLASS);
386 }
387 break;
388
389 case ESC_TYPE:
390 KillStringSpaces(Command+2);
391 break;
392 case ESC_ENUM:
393 case ESC_INHERITS:
394 case ESC_VIRTUAL:
395 case ESC_OVERRIDE:
396 case ESC_ABSTRACT:
397 case ESC_SUB:
398 case ESC_FUNCTION:
399 case ESC_MACRO:
400 case ESC_STATIC:
401 KillStringSpaces(Command+2);
402 break;
403 }
404 return;
405 }
406
407 for(i=0;;i++){
408 if(Command[i]==' '||Command[i]=='\t'||Command[i]=='('||Command[i]=='\"'||Command[i]=='@'||Command[i]=='-'){
409 com[i]=0;
410 while(Command[i]==' '||Command[i]=='\t') i++;
411 break;
412 }
413 if(Command[i]=='='){
414 KillStringSpaces(Command);
415 return;
416 }
417 com[i]=Command[i];
418 if(Command[i]=='\0') break;
419 }
420
421 //マクロによるコマンド
422 i2=1;
423 if(lstrcmpi(com,"Open")==0) ComOpen(Command+i,pam,NowLine);
424 else if(lstrcmpi(com,"Close")==0) ComClose(Command+i,pam);
425 else if(lstrcmpi(com,"Field")==0||
426 lstrcmpi(com,"Get")==0||
427 lstrcmpi(com,"Put")==0) ComField(Command+i,pam);
428 else if(lstrcmpi(com,"Line")==0) ComLine(Command+i,pam,NowLine);
429 else if(lstrcmpi(com,"Circle")==0) ComCircle(Command+i,pam,NowLine);
430 else if(lstrcmpi(com,"PSet")==0) ComPSet(Command+i,pam,NowLine);
431 else if(lstrcmpi(com,"Paint")==0) ComPaint(Command+i,pam,NowLine);
432
433 else if(
434 lstrcmpi(com,"EXEC")==0||
435 lstrcmpi(com,"INPUT")==0||
436 lstrcmpi(com,"PRINT")==0||
437 lstrcmpi(com,"RANDOMIZE")==0||
438 lstrcmpi(com,"WRITE")==0||
439 lstrcmpi(com,"MSGBOX")==0||
440 lstrcmpi(com,"WINDOW")==0||
441 lstrcmpi(com,"DELWND")==0||
442 lstrcmpi(com,"INSMENU")==0||
443 lstrcmpi(com,"CHDIR")==0||
444 lstrcmpi(com,"MKDIR")==0||
445 lstrcmpi(com,"KILL")==0||
446 lstrcmpi(com,"CLS")==0||
447 lstrcmpi(com,"COLOR")==0||
448 lstrcmpi(com,"LOCATE")==0
449 ){
450 KillSpaces(Command+i,pam);
451
452 //大文字に変換
453 CharUpper(com);
454
455 sprintf(Command,"%s(%s)",com,pam);
456 return;
457 }
458
459 else i2=0;
460 if(i2){
461 //大文字に変換
462 CharUpper(com);
463
464 sprintf(Command,"%s(%s)",com,pam);
465 return;
466 }
467
468
469
470 //コンパイラに搭載されるコマンド
471 if(lstrcmpi(com,"Do")==0){
472 KillSpaces(Command+i,pam);
473 ComNum=COM_DO;
474 }
475 else if(lstrcmpi(com,"goto")==0){
476 KillSpaces(Command+i,pam);
477 ComNum=COM_GOTO;
478 }
479 else if(lstrcmpi(com,"gosub")==0){
480 KillSpaces(Command+i,pam);
481 ComNum=COM_GOSUB;
482 }
483 else if(lstrcmpi(com,"Loop")==0){
484 if((Command[i]=='w'||Command[i]=='W')&&(Command[i+1]=='h'||Command[i+1]=='H')&&(Command[i+2]=='i'||Command[i+2]=='I')&&(Command[i+3]=='l'||Command[i+3]=='L')&&(Command[i+4]=='e'||Command[i+4]=='E')){
485 lstrcpy(pam,"0,");
486 KillSpaces(Command+i+5,pam+2);
487 }
488 else if((Command[i]=='u'||Command[i]=='U')&&(Command[i+1]=='n'||Command[i+1]=='N')&&(Command[i+2]=='t'||Command[i+2]=='T')&&(Command[i+3]=='i'||Command[i+3]=='I')&&(Command[i+4]=='l'||Command[i+4]=='L')){
489 lstrcpy(pam,"1,");
490 KillSpaces(Command+i+5,pam+2);
491 }
492 else pam[0]=0;
493 ComNum=COM_LOOP;
494 }
495 else if(lstrcmpi(com,"For")==0){
496 for(i2=0,IsStr=0;;i++,i2++){
497 while(Command[i]==' '||Command[i]=='\t') i++;
498 if(Command[i]=='\"') IsStr^=1;
499 if((Command[i-1]==' '||Command[i-1]=='\t')&&(Command[i]=='t'||Command[i]=='T')&&(Command[i+1]=='o'||Command[i+1]=='O')&&(Command[i+2]==' '||Command[i+2]=='\t')&&IsStr==0){
500 pam[i2]=',';
501 break;
502 }
503 pam[i2]=Command[i];
504 if(Command[i]=='\0') break;
505 }
506 if(Command[i]){
507 for(i+=3,i2++,IsStr=0;;i++,i2++){
508 while(Command[i]==' '||Command[i]=='\t') i++;
509 if((Command[i-1]==' '||Command[i-1]=='\t')&&(Command[i]=='s'||Command[i]=='S')&&(Command[i+1]=='t'||Command[i+1]=='T')&&(Command[i+2]=='e'||Command[i+2]=='E')&&(Command[i+3]=='p'||Command[i+3]=='P')&&(Command[i+4]==' '||Command[i+4]=='\t')){
510 pam[i2]=',';
511 i+=4;
512 continue;
513 }
514 pam[i2]=Command[i];
515 if(Command[i]=='\0') break;
516 }
517 }
518 ComNum=COM_FOR;
519 }
520 else if(lstrcmpi(com,"Next")==0){
521 KillSpaces(Command+i,pam);
522 ComNum=COM_NEXT;
523 }
524 else if(lstrcmpi(com,"Return")==0){
525 KillSpaces(Command+i,pam);
526 ComNum=COM_RETURN;
527 }
528 else if(lstrcmpi(com,"While")==0){
529 KillSpaces(Command+i,pam);
530 ComNum=COM_WHILE;
531 }
532 else if(lstrcmpi(com,"Wend")==0){
533 pam[0]=0;
534 ComNum=COM_WEND;
535 }
536
537 //変数、データ操作
538 else if(lstrcmpi(com,"dim")==0){
539 KillSpaces(Command+i,pam);
540 ComNum=COM_DIM;
541 }
542 else if(lstrcmpi(com,"Delete")==0){
543 KillSpaces(Command+i,pam);
544 ComNum=COM_DELETE;
545 }
546
547 //その他
548 else if(lstrcmpi(com,"Debug")==0){
549 pam[0]=0;
550 ComNum=COM_DEBUG;
551 }
552 else if(lstrcmpi(com,"let")==0){
553 KillSpaces(Command+i,pam);
554 ComNum=COM_LET;
555 }
556 else if(lstrcmpi(com,"rem")==0){
557 Command[0]=0;
558 return;
559 }
560
561 //ポインタ
562 else if(lstrcmpi(com,"SetDouble")==0){
563 KillSpaces(Command+i,pam);
564 ComNum=COM_SETDOUBLE;
565 }
566 else if(lstrcmpi(com,"SetSingle")==0){
567 KillSpaces(Command+i,pam);
568 ComNum=COM_SETSINGLE;
569 }
570 else if(lstrcmpi(com,"SetQWord")==0){
571 KillSpaces(Command+i,pam);
572 ComNum=COM_SETQWORD;
573 }
574 else if(lstrcmpi(com,"SetDWord")==0){
575 KillSpaces(Command+i,pam);
576 ComNum=COM_SETDWORD;
577 }
578 else if(lstrcmpi(com,"SetWord")==0){
579 KillSpaces(Command+i,pam);
580 ComNum=COM_SETWORD;
581 }
582 else if(lstrcmpi(com,"SetByte")==0){
583 KillSpaces(Command+i,pam);
584 ComNum=COM_SETBYTE;
585 }
586
587 else{
588 //その他のコマンド(一般コード)
589 lstrcpy(com,Command);
590 KillSpaces(com,Command);
591 return;
592 }
593
594 i=lstrlen(pam);
595 while(pam[i-1]==' '||pam[i-1]=='\t') i--;
596 pam[i]=0;
597 if(pam[0]) sprintf(Command,"%c%c%s",HIBYTE(ComNum),LOBYTE(ComNum),pam);
598 else sprintf(Command,"%c%c",HIBYTE(ComNum),LOBYTE(ComNum));
599
600 return;
601}
602
603void ChangeCommandToCode(char *buffer){
604 extern HANDLE hHeap;
605 int i,i2,i3,IsStr,CommandBufferSize;
606 char *temporary,*tempBase,temp2[VN_SIZE],*lpCommand;
607
608 tempBase=(char *)HeapAlloc(hHeap,0,(lstrlen(buffer)+1)*2+8192);
609 temporary=tempBase+1;
610 temporary[0]=0;
611 i=0;
612 i3=0;
613
614 CommandBufferSize=512;
615 lpCommand=(char *)HeapAlloc(hHeap,0,CommandBufferSize);
616
617 while(1){
618 i2=0;
619 while(buffer[i]==' '||buffer[i]=='\t') i++;
620 while(buffer[i]>='0'&&buffer[i]<='9'){
621 temp2[i2]=buffer[i];
622 i++;
623 i2++;
624 }
625 temp2[i2]=0;
626 while(buffer[i]==' '||buffer[i]=='\t') i++;
627 for(i2=0,IsStr=0;;i++,i2++){
628 if(i2>=CommandBufferSize){ //バッファ領域が足りなくなった場合はバッファを増量する
629 CommandBufferSize+=512;
630 lpCommand=(char *)HeapReAlloc(hHeap,0,lpCommand,CommandBufferSize);
631 }
632 if(buffer[i]=='\"') IsStr^=1;
633 if(buffer[i]=='\n'||(buffer[i]==':'&&IsStr==0)||buffer[i]=='\0'){
634 lpCommand[i2]=0;
635
636 if(temp2[0]){
637 //行番号ラベル
638 sprintf(temporary+i3,"%c%c%s,",1,ESC_LINENUM,temp2);
639 i3+=lstrlen(temporary+i3);
640
641 temp2[0]=0;
642 }
643
644 //命令コードへ変換
645 if(i2){
646 //エラー用
647 extern int cp;
648 cp=i;
649
650 ChangeCommand(buffer,i,lpCommand);
651
652 lstrcpy(temporary+i3,lpCommand);
653 i3+=lstrlen(temporary+i3);
654 }
655
656 if(!(lpCommand[0]=='\0'&&buffer[i]==':')){
657 temporary[i3++]=buffer[i];
658 temporary[i3]=0;
659 }
660
661 if(buffer[i]=='\n'){
662 i++;
663 break;
664 }
665 else if(buffer[i]==':'){
666 while(buffer[i+1]==' '||buffer[i+1]=='\t') i++;
667 }
668 if(buffer[i]=='\0') break;
669 i2=-1;
670 continue;
671 }
672 lpCommand[i2]=buffer[i];
673 }
674 if(buffer[i]=='\0') break;
675 }
676 HeapDefaultFree(lpCommand);
677 lstrcpy(buffer,temporary);
678
679 HeapDefaultFree(tempBase);
680}
Note: See TracBrowser for help on using the repository browser.