#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; //Continueアドレス DWORD dwContinueAddress; //Caseスケジュール DWORD *pCaseSchedule; int CaseScheduleNum; int NowCaseSchedule; //プロシージャ抜け出しスケジュール(Exit Sub/Function) DWORD *pExitSubSchedule; int ExitSubScheduleNum; //Goto未知ラベル スケジュール GOTOLABELSCHEDULE *pGotoLabelSchedule; int GotoLabelScheduleNum; //グローバル変数初期バッファ 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; int i,i2; if(Command[0]=='\0') return; 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++; //書き込みスケジュール for(i=0;iBreak(); } break; case ESC_EXITFOR: { CScope *pScope = GetLexicalScopes().SearchScope( SCOPE_TYPE_FOR ); if( !pScope ){ SetError(12,"Exit For",cp); return; } pScope->Break(); } break; case ESC_EXITDO: { CScope *pScope = GetLexicalScopes().SearchScope( 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: Smoothie::Temp::liveingNamespaceScopes.push_back( Command + 2 ); break; case ESC_ENDNAMESPACE: if( Smoothie::Temp::liveingNamespaceScopes.size() <= 0 ){ SetError(12,"End Namespace",cp); } Smoothie::Temp::liveingNamespaceScopes.pop_back(); break; case ESC_IMPORTS: compiler.ImportsNamespace( Command + 2 ); break; case ESC_CLEARNAMESPACEIMPORTED: compiler.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++; //書き込みスケジュール for(i=0;i