#include "stdafx.h" #include #include #include #include #include #include #include #include "../BasicCompiler_Common/common.h" #ifdef _AMD64_ #include "../BasicCompiler64/opcode.h" #else #include "../BasicCompiler32/opcode.h" #endif #include //ラベルアドレス LABEL *pLabelNames; int MaxLabelNum; //Caseスケジュール DWORD *pCaseSchedule; int CaseScheduleNum; int NowCaseSchedule; //グローバル変数初期バッファ BYTE *initGlobalBuf; //With情報 WITHINFO WithInfo; /////////////////////////////////////////////////// // トークンを取得 /////////////////////////////////////////////////// void GetIdentifierToken( char *token, const char *source, int &pos ){ for( int i=0; ; i++, pos++ ){ if( ! IsVariableChar( source[pos] ) ){ token[i] = 0; break; } token[i] = source[pos]; } } /////////////////////////////////////////////////// // 対になっているステートメントを飛び越す // ※グローバル領域用 /////////////////////////////////////////////////// int JumpStatement(const char *source, int &pos){ if( source[pos] != 1 ) return 0; if( ! IsCommandDelimitation( source[pos - 1] ) ){ //直前がコマンド区切りではない場合 return 0; } char cStatement = source[pos + 1]; char cEnd = GetEndXXXCommand( cStatement ); if( cEnd == 0 ) return 0; pos += 2; while( ! ( source[pos] == 1 && source[pos + 1] == cEnd ) ){ if( source[pos] == '\0' ){ char temporary[64]; GetDefaultNameFromES( cStatement, temporary ); SetError( 22, temporary, pos ); return -1; } pos++; } if( ! ( source[pos] == '\0' || source[pos + 2] == '\0' ) ){ pos += 2; } return 1; } void NextLine(void){ extern HANDLE hHeap; extern int MaxLineInfoNum; extern LINEINFO *pLineInfo; if(MaxLineInfoNum){ if(pLineInfo[MaxLineInfoNum-1].TopObp==obp){ pLineInfo[MaxLineInfoNum-1].TopCp=cp; return; } } pLineInfo=(LINEINFO *)HeapReAlloc(hHeap,0,pLineInfo,(MaxLineInfoNum+1)*sizeof(LINEINFO)); pLineInfo[MaxLineInfoNum].TopCp=cp; pLineInfo[MaxLineInfoNum].TopObp=obp; extern BOOL bDebugSupportProc; extern BOOL bSystemProc; pLineInfo[MaxLineInfoNum].dwCodeType=0; if(bDebugSupportProc) pLineInfo[MaxLineInfoNum].dwCodeType|=CODETYPE_DEBUGPROC; if(bSystemProc) pLineInfo[MaxLineInfoNum].dwCodeType|=CODETYPE_SYSTEMPROC; MaxLineInfoNum++; } void ChangeOpcode(char *Command){ extern HANDLE hHeap; if(Command[0]=='\0') { return; } trace_for_sourcecodestep( FormatEscapeSequenceStringToDefaultString(Command) ); if(Command[0]=='*'&&IsVariableTopChar(Command[1])){ //Goto先ラベル pLabelNames=(LABEL *)HeapReAlloc(hHeap,0,pLabelNames,(MaxLabelNum+1)*sizeof(LABEL)); pLabelNames[MaxLabelNum].pName=(char *)HeapAlloc(hHeap,0,lstrlen(Command+1)+1); lstrcpy(pLabelNames[MaxLabelNum].pName,Command+1); pLabelNames[MaxLabelNum].address=obp; MaxLabelNum++; //書き込みスケジュール std::vector::iterator it = compiler.codeGenerator.gotoLabelSchedules.begin(); while( it != compiler.codeGenerator.gotoLabelSchedules.end() ) { if( it->GetName() == Command+1 ) { *((long *)( OpBuffer + it->GetNativeCodePos() ))=obp-(it->GetNativeCodePos()+sizeof(long)); //詰める it = compiler.codeGenerator.gotoLabelSchedules.erase( it ); } else { it++; } } return; } if(Command[0]==1){ switch(Command[1]){ case ESC_CONST: OpcodeDim(Command+2, DIMFLAG_CONST); break; case ESC_TYPEDEF: if( UserProc::IsLocalAreaCompiling() ){ // ローカル領域をコンパイルしているとき SetError(65,"TypeDef",cp ); } //既に収集済み break; case ESC_STATIC: OpcodeDim(Command+2,DIMFLAG_STATIC); break; case ESC_IF: OpcodeIf(Command+2); break; case ESC_EXITWHILE: { LexicalScope *pScope = compiler.codeGenerator.lexicalScopes.SearchScope( LexicalScope::SCOPE_TYPE_WHILE ); if( !pScope ){ SetError(12,"Exit While",cp); return; } pScope->Break(); } break; case ESC_EXITFOR: { LexicalScope *pScope = compiler.codeGenerator.lexicalScopes.SearchScope( LexicalScope::SCOPE_TYPE_FOR ); if( !pScope ){ SetError(12,"Exit For",cp); return; } pScope->Break(); } break; case ESC_EXITDO: { LexicalScope *pScope = compiler.codeGenerator.lexicalScopes.SearchScope( LexicalScope::SCOPE_TYPE_DO ); if( !pScope ){ SetError(12,"Exit Do",cp); return; } pScope->Break(); } break; case ESC_CONTINUE: OpcodeContinue(); break; case ESC_EXITSUB: case ESC_EXITFUNCTION: case ESC_EXITMACRO: OpcodeExitSub(); break; case ESC_SELECTCASE: OpcodeSelect(Command+2); break; case ESC_CASE: case ESC_CASEELSE: OpcodeCase(Command+2); break; case ESC_WITH: extern WITHINFO WithInfo; WithInfo.ppName=(char **)HeapReAlloc(hHeap,0,WithInfo.ppName,(WithInfo.num+1)*sizeof(char **)); WithInfo.ppName[WithInfo.num]=(char *)HeapAlloc(hHeap,0,lstrlen(Command+2)+1); lstrcpy(WithInfo.ppName[WithInfo.num],Command+2); WithInfo.pWithCp=(int *)HeapReAlloc(hHeap,0,WithInfo.pWithCp,(WithInfo.num+1)*sizeof(int)); WithInfo.pWithCp[WithInfo.num]=cp; WithInfo.num++; break; case ESC_ENDWITH: if(WithInfo.num<=0){ SetError(12,"End With",cp); return; } WithInfo.num--; HeapDefaultFree(WithInfo.ppName[WithInfo.num]); break; case ESC_DECLARE: if( UserProc::IsLocalAreaCompiling() ){ // ローカル領域をコンパイルしているとき SetError(65,"Declare",cp ); } break; case ESC_NAMESPACE: compiler.GetNamespaceSupporter().GetLivingNamespaceScopes().push_back( Command + 2 ); break; case ESC_ENDNAMESPACE: if( compiler.GetNamespaceSupporter().GetLivingNamespaceScopes().size() <= 0 ){ SetError(12,"End Namespace",cp); } compiler.GetNamespaceSupporter().GetLivingNamespaceScopes().pop_back(); break; case ESC_IMPORTS: compiler.GetNamespaceSupporter().ImportsNamespace( Command + 2 ); break; case ESC_CLEARNAMESPACEIMPORTED: compiler.GetNamespaceSupporter().GetImportedNamespaces().clear(); break; //Tryによる例外処理 case ESC_TRY: Exception::TryCommand(); break; case ESC_CATCH: Exception::CatchCommand(); break; case ESC_FINALLY: Exception::FinallyCommand(); break; case ESC_ENDTRY: Exception::EndTryCommand(); break; case ESC_THROW: Exception::ThrowCommand( Command + 2 ); break; default: char temporary[64]; GetDefaultNameFromES(Command[1],temporary); SetError(30,temporary,cp); break; } return; } switch(MAKEWORD(Command[1],Command[0])){ case COM_DIM: OpcodeDim(Command+2,0); break; case COM_DELETE: OpcodeDelete(Command+2, false); break; case COM_SWEEPINGDELETE: OpcodeDelete(Command+2, true); break; case COM_GOTO: OpcodeGoto(Command+2); break; case COM_WHILE: OpcodeWhile(Command+2); break; case COM_FOR: OpcodeFor(Command+2); break; case COM_DO: OpcodeDo(Command+2); break; case COM_GOSUB: OpcodeGosub(Command+2); break; case COM_RETURN: OpcodeReturn(Command+2); break; case COM_SETDOUBLE: OpcodeSetPtrData(Command+2,DEF_DOUBLE); break; case COM_SETSINGLE: OpcodeSetPtrData(Command+2,DEF_SINGLE); break; case COM_SETQWORD: OpcodeSetPtrData(Command+2,DEF_QWORD); break; case COM_SETDWORD: OpcodeSetPtrData(Command+2,DEF_DWORD); break; case COM_SETWORD: OpcodeSetPtrData(Command+2,DEF_WORD); break; case COM_SETBYTE: OpcodeSetPtrData(Command+2,DEF_BYTE); break; case COM_DEBUG: extern BOOL bDebugCompile; //int 3 if(bDebugCompile) OpBuffer[obp++]=(char)0xCC; #if defined(_DEBUG) else OpBuffer[obp++]=(char)0xCC; #endif break; case COM_LET: OpcodeCalc(Command+2); break; default: OpcodeOthers(Command); break; } } void GetGlobalDataForDll(void){ extern char *basbuf; extern HANDLE hHeap; int i2,BufferSize; char *Command; DWORD dwRetCode; dwRetCode=0; BufferSize=128; Command=(char *)HeapAlloc(hHeap,0,BufferSize); for(cp++,i2=0;;cp++,i2++){ if(i2>=BufferSize){ //バッファ領域が足りなくなった場合はバッファを増量する BufferSize+=128; Command=(char *)HeapReAlloc(hHeap,0,Command,BufferSize); } if(basbuf[cp]=='\"'){ Command[i2]=basbuf[cp]; for(cp++,i2++;;cp++,i2++){ if(i2>=BufferSize){ //バッファ領域が足りなくなった場合はバッファを増量する BufferSize+=128; Command=(char *)HeapReAlloc(hHeap,0,Command,BufferSize); } Command[i2]=basbuf[cp]; if(basbuf[cp]=='\"') break; } continue; } if(IsCommandDelimitation(basbuf[cp])){ Command[i2]=0; if(Command[0]==1&&Command[1]==ESC_SUB){ i2=cp; while(!(basbuf[cp]==1&&basbuf[cp+1]==ESC_ENDSUB)){ if(basbuf[cp]=='\0'){ SetError(22,"Sub",i2); break; } cp++; } if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break; cp+=2; i2=-1; continue; } if(Command[0]==1&&Command[1]==ESC_FUNCTION){ i2=cp; while(!(basbuf[cp]==1&&basbuf[cp+1]==ESC_ENDFUNCTION)){ if(basbuf[cp]=='\0'){ SetError(22,"Function",i2); break; } cp++; } if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break; cp+=2; i2=-1; continue; } if(Command[0]==1&&Command[1]==ESC_MACRO){ i2=cp; while(!(basbuf[cp]==1&&basbuf[cp+1]==ESC_ENDMACRO)){ if(basbuf[cp]=='\0'){ SetError(22,"Macro",i2); break; } cp++; } if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break; cp+=2; i2=-1; continue; } if(Command[0]==1&&Command[1]==ESC_TYPE){ i2=cp; while(!(basbuf[cp]==1&&basbuf[cp+1]==ESC_ENDTYPE)){ if(basbuf[cp]=='\0'){ SetError(22,"Type",i2); break; } cp++; } if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break; cp+=2; i2=-1; continue; } if(Command[0]==1&&Command[1]==ESC_CLASS){ i2=cp; while(!(basbuf[cp]==1&&basbuf[cp+1]==ESC_ENDCLASS)){ if(basbuf[cp]=='\0'){ SetError(22,"Class",i2); break; } cp++; } if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break; cp+=2; i2=-1; continue; } if(Command[0]==1&&Command[1]==ESC_INTERFACE){ i2=cp; while(!(basbuf[cp]==1&&basbuf[cp+1]==ESC_ENDINTERFACE)){ if(basbuf[cp]=='\0'){ SetError(22,"Interface",i2); break; } cp++; } if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break; cp+=2; i2=-1; continue; } //DLLのグローバルデータに必要なコマンドだけ if(MAKEWORD(Command[1],Command[0])==COM_DIM) OpcodeDim(Command+2,0); // ネイティブコードバッファの再確保 ReallocNativeCodeBuffer(); if(basbuf[cp]=='\0') break; i2=-1; continue; } Command[i2]=basbuf[cp]; } HeapDefaultFree(Command); } DWORD CompileBuffer(char Return_Sequence,WORD Return_Command){ extern char *basbuf; extern HANDLE hHeap; int i,i2,i3,i4,BufferSize,ScopeStart; char *Command,temporary[VN_SIZE],*temp2,temp3[32]; DWORD dwRetCode; ScopeStart=cp; dwRetCode=0; BufferSize=128; Command=(char *)HeapAlloc(hHeap,0,BufferSize); for(cp++,i2=0;;cp++,i2++){ if(i2>=BufferSize){ //バッファ領域が足りなくなった場合はバッファを増量する BufferSize+=128; Command=(char *)HeapReAlloc(hHeap,0,Command,BufferSize); } if(basbuf[cp]=='\"'){ Command[i2]=basbuf[cp]; for(cp++,i2++;;cp++,i2++){ if(i2>=BufferSize){ //バッファ領域が足りなくなった場合はバッファを増量する BufferSize+=128; Command=(char *)HeapReAlloc(hHeap,0,Command,BufferSize); } Command[i2]=basbuf[cp]; if(basbuf[cp]=='\"') break; } continue; } if(IsCommandDelimitation(basbuf[cp])){ Command[i2]=0; if(Command[0]==1&&Command[1]==ESC_LINENUM){ for(i=2,i2=0;;i++,i2++){ if(Command[i]==','){ temporary[i2]=0; break; } temporary[i2]=Command[i]; } i3=atoi(temporary); i4=i+1; //Goto先ラベル pLabelNames=(LABEL *)HeapReAlloc(hHeap,0,pLabelNames,(MaxLabelNum+1)*sizeof(LABEL)); pLabelNames[MaxLabelNum].pName=0; pLabelNames[MaxLabelNum].line=i3; pLabelNames[MaxLabelNum].address=obp; MaxLabelNum++; //書き込みスケジュール std::vector::iterator it = compiler.codeGenerator.gotoLabelSchedules.begin(); while( it != compiler.codeGenerator.gotoLabelSchedules.end() ) { if( it->GetName().size() == 0 && it->GetLineNum() == i3 ) { *((long *)( OpBuffer + it->GetNativeCodePos() ))=obp-(it->GetNativeCodePos()+sizeof(long)); //詰める it = compiler.codeGenerator.gotoLabelSchedules.erase( it ); } else { it++; } } temp2=(char *)HeapAlloc(hHeap,0,lstrlen(Command+i4)+1); lstrcpy(temp2,Command+i4); lstrcpy(Command,temp2); HeapDefaultFree(temp2); } if(Command[0]==1&& (((Command[1]==ESC_VIRTUAL||Command[1]==ESC_OVERRIDE)&&Command[2]==1&&(Command[3]==ESC_SUB||Command[3]==ESC_FUNCTION))|| Command[1]==ESC_SUB|| Command[1]==ESC_FUNCTION|| Command[1]==ESC_MACRO|| Command[1]==ESC_TYPE|| Command[1]==ESC_CLASS|| Command[1]==ESC_INTERFACE|| Command[1]==ESC_ENUM|| (Command[1]==ESC_CONST&&Command[2]==1&&Command[3]==ESC_ENUM) ) ){ if(Command[1]==ESC_VIRTUAL||Command[1]==ESC_OVERRIDE||Command[1]==ESC_CONST){ GetDefaultNameFromES(Command[3],temporary); } else{ GetDefaultNameFromES(Command[1],temporary); } if(Return_Sequence){ SetError(12,temporary,cp); break; } if(Command[1]==ESC_CONST) i3=GetEndXXXCommand(Command[3]); else i3=GetEndXXXCommand(Command[1]); for(i2=cp;;cp++){ if(basbuf[cp]==1){ if(basbuf[cp+1]==i3) break; if(Command[1]==ESC_CLASS||Command[1]==ESC_INTERFACE){ //クラス、インターフェイスではSub、Functionの定義を可能にしておく if(basbuf[cp+1]==ESC_MACRO|| basbuf[cp+1]==ESC_TYPE|| basbuf[cp+1]==ESC_CLASS|| basbuf[cp+1]==ESC_INTERFACE|| basbuf[cp+1]==ESC_ENUM){ GetDefaultNameFromES(basbuf[cp+1],temp3); SetError(12,temp3,cp); } } else{ if(basbuf[cp-1]!='*'&&( basbuf[cp+1]==ESC_VIRTUAL|| basbuf[cp+1]==ESC_OVERRIDE|| basbuf[cp+1]==ESC_SUB|| basbuf[cp+1]==ESC_FUNCTION|| basbuf[cp+1]==ESC_MACRO|| basbuf[cp+1]==ESC_TYPE|| basbuf[cp+1]==ESC_CLASS|| basbuf[cp+1]==ESC_INTERFACE|| basbuf[cp+1]==ESC_ENUM)){ GetDefaultNameFromES(basbuf[cp+1],temp3); SetError(12,temp3,cp); } } } if(basbuf[cp]=='\0'){ //error //既にエラー発行済みのため、何もせずに抜ける break; } } if(basbuf[cp+2]=='\0'||basbuf[cp]=='\0') break; cp+=2; i2=-1; continue; } if(Command[0]==0x10||Command[0]==0x11){ //Wend、Next、Loopなど if(Return_Command==MAKEWORD(Command[1],Command[0])){ if(Return_Command==COM_NEXT){ //Nextの場合は、パラメータ(省略化)の整合性を判断する必要がある(OpcodeFor関数を参照) extern char szNextVariable[VN_SIZE]; if(Command[2]) lstrcpy(szNextVariable,Command+2); else szNextVariable[0]=0; } break; } } NextLine(); if(Command[0]==1){ if(Return_Sequence==ESC_ENDIF&&Command[1]==ESC_ELSE){ dwRetCode=ESC_ELSE; break; } if(Command[1]==Return_Sequence){ dwRetCode=Command[1]; break; } } try { ChangeOpcode(Command); } catch( const SmoothieException &smoothieException ) { SetError( smoothieException.GetErrorCode(), smoothieException.GetKeyword(), smoothieException.GetNowLine() ); } epi_check(); //コンパイルを中断するとき extern BOOL bStopCompile; if(bStopCompile) return 0; ReallocNativeCodeBuffer(); if(basbuf[cp]=='\0'){ switch(Return_Command){ case COM_WEND: SetError(4,"\"While\" - \"Wend\" ",ScopeStart); break; case COM_NEXT: SetError(4,"\"For\" - \"Next\" ",ScopeStart); break; case COM_LOOP: SetError(4,"\"Do\" - \"Loop\" ",ScopeStart); break; } switch(Return_Sequence){ case ESC_ENDSUB: SetError(4,"\"Sub\" - \"End Sub\" ",ScopeStart); break; case ESC_ENDFUNCTION: SetError(4,"\"Function\" - \"End Function\" ",ScopeStart); break; case ESC_ENDMACRO: SetError(4,"\"Macro\" - \"End Macro\" ",ScopeStart); break; case ESC_ENDIF: SetError(22,"If",ScopeStart); break; } break; } i2=-1; continue; } Command[i2]=basbuf[cp]; } HeapDefaultFree(Command); return dwRetCode; }