#include "stdafx.h" #include #include #include #include "../BasicCompiler_Common/common.h" void AddConstEnum( const NamespaceScopes &namespaceScopes, 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]; } 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; StaticCalculation(true, temp2,DEF_LONG,&i64data,Type()); NextValue=(int)i64data; } //定数を追加 compiler.GetObjectModule().meta.GetGlobalConsts().Add( namespaceScopes, temporary, NextValue); } } bool GetConstInfo(void){ //////////////////////////////////////////// // Const命令の情報を取得 //////////////////////////////////////////// int i2; char temporary[1024]; // 名前空間管理 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes(); namespaceScopes.clear(); extern char *basbuf; for(int i=0;;i++){ if( basbuf[i] == '\0' ) break; if( basbuf[i] == 1 && basbuf[i+1] == ESC_NAMESPACE ){ for(i+=2,i2=0;;i2++,i++){ if( IsCommandDelimitation( basbuf[i] ) ){ temporary[i2]=0; break; } temporary[i2]=basbuf[i]; } namespaceScopes.push_back( temporary ); continue; } else if( basbuf[i] == 1 && basbuf[i+1] == ESC_ENDNAMESPACE ){ if( namespaceScopes.size() <= 0 ){ SetError(12, "End Namespace", i ); } else{ namespaceScopes.pop_back(); } i += 2; continue; } 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( namespaceScopes, 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]; } AddConst( namespaceScopes, temporary); if(basbuf[i]=='\0') break; } else{ int result = JumpStatement( basbuf, i ); if( result == -1 ){ //エラー return false; } else if( result == 1 ){ //ジャンプした場合 i--; } } } } // イテレータを初期化 compiler.GetObjectModule().meta.GetGlobalConsts().Iterator_Init(); compiler.GetObjectModule().meta.GetGlobalConstMacros().Iterator_Init(); 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_TYPEDEF: KillStringSpaces(Command+2); break; case ESC_DECLARE: KillStringSpaces(Command+2); break; case ESC_IF: KillStringSpaces(Command+2); break; case ESC_CLASS: KillStringSpaces(Command+2); i2 = 2; if( Command[i2] == 1 && Command[i2+1] == ESC_ENUM ) { i2 += 2; } else if( Command[i2] == 1 && Command[i2+1] == ESC_DELEGATE ) { i2 += 2; } else if( memicmp( Command + i2, "Blittable(", 10 ) == 0 ) { i2 += 10; i2 = JumpStringInPare(Command,i2)+1; } // クラス名を取得 char className[VN_SIZE]; GetIdentifierToken( className, Command, i2 ); //コンストラクタ、デストラクタを暗黙的に生成 MakeConstructorAndDestructor(buffer,nowLine,className); 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_CONST: KillStringSpaces(Command+2); if( Command[2] == 1 && Command[3] == ESC_ENUM ){ nCountOfNonGlobalScope++; } 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: case ESC_NAMESPACE: case ESC_IMPORTS: case ESC_DELEGATE: 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, "_System_SweepingDelete" ) == 0 ){ KillSpaces(Command+i,pam); ComNum=COM_SWEEPINGDELETE; } //その他 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); }