#include "../BasicCompiler_Common/common.h" CONSTINFO *GetNewConstHash(char *name){ extern int cp; CONSTINFO *pci; int key; key=hash_default(name); extern CONSTINFO **ppConstHash; if(ppConstHash[key]){ pci=ppConstHash[key]; while(1){ if(lstrcmp(pci->name,name)==0){ //重複エラー SetError(15,name,cp); return 0; } if(pci->pNextData==0){ pci->pNextData=(CONSTINFO *)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,sizeof(CONSTINFO)); break; } pci=pci->pNextData; } pci=pci->pNextData; } else{ ppConstHash[key]=(CONSTINFO *)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,sizeof(CONSTINFO)); pci=ppConstHash[key]; } return pci; } // マクロ定数を追加するための関数 void AddConstData(char *Command){ extern HANDLE hHeap; extern int cp; int i,i2; char temporary[VN_SIZE]; for(i=0;;i++){ if(Command[i]=='\0'){ SetError(10,"Const",cp); return; } if(Command[i]=='=' || Command[i] == 1 && Command[i+1] == ESC_AS ){ //定数定義は新しいクラスモジュール(CDBConst)へ移行 // ※この関数はマクロ定数のみを扱う return; } if(Command[i]=='('){ temporary[i]=0; break; } temporary[i]=Command[i]; } ///////////////////////////////// // 格納位置を計算してpciにセット ///////////////////////////////// CONSTINFO *pci; pci=GetNewConstHash(temporary); if(!pci) return; //////////////////// // 定数情報を取得 //////////////////// //定数名 pci->name=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1); lstrcpy(pci->name,temporary); if(Command[i]=='('){ pci->ppParm=(char **)HeapAlloc(hHeap,0,1); pci->ParmNum=0; for(i++,i2=0;;i++,i2++){ if(Command[i]=='\0'){ SetError(1,NULL,cp); return; } if(Command[i]==','||Command[i]==')'){ temporary[i2]=0; pci->ppParm=(char **)HeapReAlloc(hHeap,0,pci->ppParm,(pci->ParmNum+1)*sizeof(char *)); pci->ppParm[pci->ParmNum]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1); lstrcpy(pci->ppParm[pci->ParmNum],temporary); pci->ParmNum++; if(Command[i]==')'){ i++; if(Command[i]!='='){ SetError(1,NULL,cp); return; } break; } i2=-1; continue; } temporary[i2]=Command[i]; } } else pci->ParmNum=0; //データ lstrcpy(temporary,Command+i+1); if(pci->ParmNum){ pci->StrValue=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1); lstrcpy(pci->StrValue,temporary); } else if(temporary[0]=='\"'){ //文字列定数 RemoveStringQuotes(temporary); i2=lstrlen(temporary); pci->StrValue=(char *)HeapAlloc(hHeap,0,i2+1); memcpy(pci->StrValue,temporary,i2); pci->StrValue[i2]=0; pci->DblValue=(double)i2; pci->type=DEF_STRING; pci->lpIndex=-1; } else if((temporary[0]=='e'||temporary[0]=='E')&& (temporary[1]=='x'||temporary[1]=='X')&& temporary[2]=='\"'){ //文字列定数 RemoveStringQuotes(temporary+2); i2=FormatString_EscapeSequence(temporary+2); pci->StrValue=(char *)HeapAlloc(hHeap,0,i2+1); memcpy(pci->StrValue,temporary+2,i2); pci->StrValue[i2]=0; pci->DblValue=(double)i2; pci->type=DEF_STRING; pci->lpIndex=-1; } else{ //数値定数 _int64 i64data; pci->type=StaticCalculation(true, temporary,0,&i64data,&pci->lpIndex); if(IsRealNumberType(pci->type)){ //実数型 memcpy(&pci->DblValue,&i64data,sizeof(double)); } else if(Is64Type(pci->type)){ //64ビット型 pci->i64Value=i64data; } else if(IsWholeNumberType(pci->type)){ //その他整数型 pci->DblValue=(double)i64data; } pci->StrValue=0; } } void AddConstEnum(char *buffer){ extern int cp; int i=0,i2; if(!(buffer[i]==1&&buffer[i+1]==ESC_ENUM)) return; i+=2; //列挙体の名前を取得 char temporary[VN_SIZE]; for(i2=0;;i++,i2++){ if(IsCommandDelimitation(buffer[i])){ temporary[i2]=0; break; } if(!IsVariableChar(buffer[i])){ SetError(1,NULL,i); break; } temporary[i2]=buffer[i]; } //新しい型情報を追加 pobj_DBTypeDef->add(temporary,"Long"); if(buffer[i]=='\0'){ SetError(22,"Enum",cp); return; } int NextValue=0; while(1){ i++; if(buffer[i]==1&&buffer[i+1]==ESC_ENDENUM) break; for(i2=0;;i2++,i++){ if(IsCommandDelimitation(buffer[i])){ temporary[i2]=0; break; } if(buffer[i]=='='){ temporary[i2]=0; break; } temporary[i2]=buffer[i]; } if(temporary[0]=='\0'){ if(buffer[i]=='\0'){ SetError(22,"Enum",cp); break; } continue; } if(buffer[i]!='='){ NextValue++; } else{ char temp2[VN_SIZE]; for(i++,i2=0;;i2++,i++){ if(IsCommandDelimitation(buffer[i])){ temp2[i2]=0; break; } temp2[i2]=buffer[i]; } _int64 i64data; LONG_PTR lpIndex; StaticCalculation(true, temp2,DEF_LONG,&i64data,&lpIndex); NextValue=(int)i64data; } //定数を追加 CDBConst::obj.AddConst(temporary, NextValue); } } bool GetConstInfo(void){ //////////////////////////////////////////// // Const命令の情報を取得 //////////////////////////////////////////// int i,i2; char temporary[1024]; //定数に関する情報 extern CONSTINFO **ppConstHash; ppConstHash=(CONSTINFO **)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,MAX_HASH*sizeof(CONSTINFO *)); extern char *basbuf; for(i=0;;i++){ if( basbuf[i] == '\0' ) break; if( basbuf[i] == 1 ){ if(basbuf[i]==1&&basbuf[i+1]==ESC_CONST){ i+=2; extern int cp; cp=i; //エラー用 if(basbuf[i]==1&&basbuf[i+1]==ESC_ENUM){ AddConstEnum(basbuf+i); continue; } for(i2=0;;i++,i2++){ if(basbuf[i]=='\"'){ temporary[i2]=basbuf[i]; for(i++,i2++;;i++,i2++){ temporary[i2]=basbuf[i]; if(basbuf[i]=='\"') break; } continue; } if(IsCommandDelimitation(basbuf[i])){ temporary[i2]=0; break; } temporary[i2]=basbuf[i]; } CDBConst::obj.Add(temporary); if(basbuf[i]=='\0') break; } else{ int result = JumpStatement( basbuf, i ); if( result == -1 ){ //エラー return false; } else if( result == 1 ){ //ジャンプした場合 i--; } } } } return true; } char ConstructorDestructorSchedule[MAX_PATH]; void MakeConstructorAndDestructor(char *buffer,int NowLine,char *ClassName){ int i,i2; char temporary[MAX_PATH],*pTemp; BOOL bConstructor,bDestructor; ConstructorDestructorSchedule[0]=0; bConstructor=0; bDestructor=0; for(i=NowLine;;i++){ if(buffer[i]=='\0') break; if(buffer[i]==1&&buffer[i+1]==ESC_ENDCLASS){ if((!bConstructor)||(!bDestructor)){ pTemp=ConstructorDestructorSchedule; lstrcpy(pTemp,"Public:"); if(!bConstructor){ //コンストラクタが無いときは生成する sprintf(pTemp+lstrlen(pTemp),"%c%c%s():%c%c:", 1,ESC_SUB, ClassName, 1,ESC_ENDSUB); } if(!bDestructor){ //デストラクタが無いときは生成する sprintf(pTemp+lstrlen(pTemp),"%c%c~%s():%c%c:", 1,ESC_SUB, ClassName, 1,ESC_ENDSUB); } } break; } if(buffer[i]==1&&(buffer[i+1]==ESC_SUB||buffer[i+1]==ESC_FUNCTION)){ i+=2; while(IsBlank(buffer[i])) i++; if(buffer[i]=='~'){ //デストラクタ bDestructor=1; } else{ //コンストラクタかどうかをチェック for(i2=0;;i++,i2++){ if(!IsVariableChar(buffer[i])){ temporary[i2]=0; break; } temporary[i2]=buffer[i]; } if(lstrcmp(temporary,ClassName)==0) bConstructor=1; } } } } void ChangeCommand(char *buffer,int NowLine,char *Command){ int i,i2,IsStr; unsigned _int16 ComNum; char com[8192],pam[8192]; static int nCountOfNonGlobalScope = 0; if(Command[0]==1){ switch(Command[1]){ case ESC_SELECTCASE: case ESC_CASE: KillStringSpaces(Command+2); break; case ESC_WITH: KillStringSpaces(Command+2); break; case ESC_CONST: case ESC_BYREF: KillStringSpaces(Command+2); break; case ESC_TYPEDEF: KillStringSpaces(Command+2); AddTypeDefData(Command+2); break; case ESC_DECLARE: KillStringSpaces(Command+2); break; case ESC_IF: KillStringSpaces(Command+2); break; case ESC_CLASS: KillStringSpaces(Command+2); //コンストラクタ、デストラクタを暗黙的に生成 MakeConstructorAndDestructor(buffer,NowLine,Command+2); break; case ESC_INTERFACE: KillStringSpaces(Command+2); break; case ESC_ENDCLASS: if(ConstructorDestructorSchedule[0]){ //生成されたコンストラクタ、デストラクタを挿入 sprintf(Command,"%s%c%c",ConstructorDestructorSchedule,1,ESC_ENDCLASS); } break; case ESC_TYPE: KillStringSpaces(Command+2); break; case ESC_ENUM: nCountOfNonGlobalScope++; KillStringSpaces(Command+2); break; case ESC_ENDENUM: nCountOfNonGlobalScope--; break; case ESC_INHERITS: case ESC_VIRTUAL: case ESC_OVERRIDE: case ESC_ABSTRACT: case ESC_SUB: case ESC_FUNCTION: case ESC_MACRO: case ESC_STATIC: KillStringSpaces(Command+2); break; } return; } bool isPare = false; for(i=0;;i++){ if(Command[i]==' '||Command[i]=='\t'||Command[i]=='('||Command[i]=='\"'||Command[i]=='@'||Command[i]=='-'){ com[i]=0; while(Command[i]==' '||Command[i]=='\t') i++; if( Command[i] == '(' ) isPare = true; break; } if(Command[i]=='='){ KillStringSpaces(Command); return; } com[i]=Command[i]; if(Command[i]=='\0') break; } //マクロによるコマンド i2=1; if( nCountOfNonGlobalScope == 0 ){ //グローバル if(lstrcmpi(com,"Open")==0) ComOpen(Command+i,pam,NowLine); else if(lstrcmpi(com,"Close")==0) ComClose(Command+i,pam); else if(lstrcmpi(com,"Field")==0|| lstrcmpi(com,"Get")==0|| lstrcmpi(com,"Put")==0) ComField(Command+i,pam); else if(lstrcmpi(com,"Line")==0) ComLine(Command+i,pam,NowLine); else if(lstrcmpi(com,"Circle")==0) ComCircle(Command+i,pam,NowLine); else if(lstrcmpi(com,"PSet")==0) ComPSet(Command+i,pam,NowLine); else if(lstrcmpi(com,"Paint")==0) ComPaint(Command+i,pam,NowLine); else if( lstrcmpi(com,"EXEC")==0|| lstrcmpi(com,"INPUT")==0|| lstrcmpi(com,"PRINT")==0|| lstrcmpi(com,"RANDOMIZE")==0|| ( lstrcmpi(com,"WRITE")==0 && isPare == false )|| lstrcmpi(com,"MSGBOX")==0|| lstrcmpi(com,"WINDOW")==0|| lstrcmpi(com,"DELWND")==0|| lstrcmpi(com,"INSMENU")==0|| lstrcmpi(com,"CHDIR")==0|| lstrcmpi(com,"MKDIR")==0|| lstrcmpi(com,"KILL")==0|| lstrcmpi(com,"CLS")==0|| lstrcmpi(com,"COLOR")==0|| lstrcmpi(com,"LOCATE")==0 ){ KillSpaces(Command+i,pam); //大文字に変換 CharUpper(com); sprintf(Command,"%s(%s)",com,pam); return; } else i2=0; } else i2=0; if(i2){ //大文字に変換 CharUpper(com); sprintf(Command,"%s(%s)",com,pam); return; } //コンパイラに搭載されるコマンド if(lstrcmpi(com,"Do")==0){ KillSpaces(Command+i,pam); ComNum=COM_DO; } else if(lstrcmpi(com,"goto")==0){ KillSpaces(Command+i,pam); ComNum=COM_GOTO; } else if(lstrcmpi(com,"gosub")==0){ KillSpaces(Command+i,pam); ComNum=COM_GOSUB; } else if(lstrcmpi(com,"Loop")==0){ 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')){ lstrcpy(pam,"0,"); KillSpaces(Command+i+5,pam+2); } 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')){ lstrcpy(pam,"1,"); KillSpaces(Command+i+5,pam+2); } else pam[0]=0; ComNum=COM_LOOP; } else if(lstrcmpi(com,"For")==0){ for(i2=0,IsStr=0;;i++,i2++){ while(Command[i]==' '||Command[i]=='\t') i++; if(Command[i]=='\"') IsStr^=1; 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){ pam[i2]=','; break; } pam[i2]=Command[i]; if(Command[i]=='\0') break; } if(Command[i]){ for(i+=3,i2++,IsStr=0;;i++,i2++){ while(Command[i]==' '||Command[i]=='\t') i++; 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')){ pam[i2]=','; i+=4; continue; } pam[i2]=Command[i]; if(Command[i]=='\0') break; } } ComNum=COM_FOR; } else if(lstrcmpi(com,"Next")==0){ KillSpaces(Command+i,pam); ComNum=COM_NEXT; } else if(lstrcmpi(com,"Return")==0){ KillSpaces(Command+i,pam); ComNum=COM_RETURN; } else if(lstrcmpi(com,"While")==0){ KillSpaces(Command+i,pam); ComNum=COM_WHILE; } else if(lstrcmpi(com,"Wend")==0){ pam[0]=0; ComNum=COM_WEND; } //変数、データ操作 else if(lstrcmpi(com,"dim")==0){ KillSpaces(Command+i,pam); ComNum=COM_DIM; } else if(lstrcmpi(com,"Delete")==0){ KillSpaces(Command+i,pam); ComNum=COM_DELETE; } //その他 else if(lstrcmpi(com,"Debug")==0){ pam[0]=0; ComNum=COM_DEBUG; } else if(lstrcmpi(com,"let")==0){ KillSpaces(Command+i,pam); ComNum=COM_LET; } else if(lstrcmpi(com,"rem")==0){ Command[0]=0; return; } //ポインタ else if(lstrcmpi(com,"SetDouble")==0){ KillSpaces(Command+i,pam); ComNum=COM_SETDOUBLE; } else if(lstrcmpi(com,"SetSingle")==0){ KillSpaces(Command+i,pam); ComNum=COM_SETSINGLE; } else if(lstrcmpi(com,"SetQWord")==0){ KillSpaces(Command+i,pam); ComNum=COM_SETQWORD; } else if(lstrcmpi(com,"SetDWord")==0){ KillSpaces(Command+i,pam); ComNum=COM_SETDWORD; } else if(lstrcmpi(com,"SetWord")==0){ KillSpaces(Command+i,pam); ComNum=COM_SETWORD; } else if(lstrcmpi(com,"SetByte")==0){ KillSpaces(Command+i,pam); ComNum=COM_SETBYTE; } else{ //その他のコマンド(一般コード) lstrcpy(com,Command); KillSpaces(com,Command); return; } i=lstrlen(pam); while(pam[i-1]==' '||pam[i-1]=='\t') i--; pam[i]=0; if(pam[0]) sprintf(Command,"%c%c%s",HIBYTE(ComNum),LOBYTE(ComNum),pam); else sprintf(Command,"%c%c",HIBYTE(ComNum),LOBYTE(ComNum)); return; } void ChangeCommandToCode(char *buffer){ extern HANDLE hHeap; int i,i2,i3,IsStr,CommandBufferSize; char *temporary,*tempBase,temp2[VN_SIZE],*lpCommand; tempBase=(char *)HeapAlloc(hHeap,0,(lstrlen(buffer)+1)*2+8192); temporary=tempBase+1; temporary[0]=0; i=0; i3=0; CommandBufferSize=512; lpCommand=(char *)HeapAlloc(hHeap,0,CommandBufferSize); while(1){ i2=0; while(buffer[i]==' '||buffer[i]=='\t') i++; while(buffer[i]>='0'&&buffer[i]<='9'){ temp2[i2]=buffer[i]; i++; i2++; } temp2[i2]=0; while(buffer[i]==' '||buffer[i]=='\t') i++; for(i2=0,IsStr=0;;i++,i2++){ if(i2>=CommandBufferSize){ //バッファ領域が足りなくなった場合はバッファを増量する CommandBufferSize+=512; lpCommand=(char *)HeapReAlloc(hHeap,0,lpCommand,CommandBufferSize); } if(buffer[i]=='\"') IsStr^=1; if(buffer[i]=='\n'||(buffer[i]==':'&&IsStr==0)||buffer[i]=='\0'){ lpCommand[i2]=0; if(temp2[0]){ //行番号ラベル sprintf(temporary+i3,"%c%c%s,",1,ESC_LINENUM,temp2); i3+=lstrlen(temporary+i3); temp2[0]=0; } //命令コードへ変換 if(i2){ //エラー用 extern int cp; cp=i; ChangeCommand(buffer,i,lpCommand); lstrcpy(temporary+i3,lpCommand); i3+=lstrlen(temporary+i3); } if(!(lpCommand[0]=='\0'&&buffer[i]==':')){ temporary[i3++]=buffer[i]; temporary[i3]=0; } if(buffer[i]=='\n'){ i++; break; } else if(buffer[i]==':'){ while(buffer[i+1]==' '||buffer[i+1]=='\t') i++; } if(buffer[i]=='\0') break; i2=-1; continue; } lpCommand[i2]=buffer[i]; } if(buffer[i]=='\0') break; } HeapDefaultFree(lpCommand); lstrcpy(buffer,temporary); HeapDefaultFree(tempBase); }