#include "stdafx.h" using namespace ActiveBasic::Compiler; LexicalAnalyzer::SourceTemplate::SourceTemplate( const std::string &filePath ) { Jenga::Common::File file = Jenga::Common::File( GetApplicationBaseFullPath( filePath ) ); source = file.Read(); } std::string LexicalAnalyzer::SourceTemplate::GetResult( const std::map &values ) { std::string result = source; std::map::const_iterator it = values.begin(); while( it != values.end() ) { while( true ) { std::string::size_type index = result.find( it->first ); if( index == std::string::npos ) { break; } result = result.substr( 0, index ) + it->second + result.substr( index + it->first.length() ); } it++; } return result; } bool LexicalAnalyzer::CollectNamespaces( const char *source, NamespaceScopesCollection &namespaceScopesCollection ) { int i, i2; char temporary[1024]; bool isSuccessful = true; // 名前空間管理 NamespaceScopes namespaceScopes; for(i=0;;i++){ if(source[i]=='\0') break; if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){ for(i+=2,i2=0;;i2++,i++){ if( IsCommandDelimitation( source[i] ) ){ temporary[i2]=0; break; } temporary[i2]=source[i]; } namespaceScopes.push_back( temporary ); if( !namespaceScopesCollection.IsExist( namespaceScopes ) ){ namespaceScopesCollection.push_back( namespaceScopes ); } continue; } else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){ if( namespaceScopes.size() <= 0 ){ compiler.errorMessenger.Output( 12, "End Namespace", i ); isSuccessful = false; } else{ namespaceScopes.pop_back(); } i += 2; continue; } } if( namespaceScopes.size() > 0 ){ compiler.errorMessenger.Output( 63, NULL, cp ); isSuccessful = false; } return isSuccessful; } Symbol LexicalAnalyzer::FullNameToSymbol( const char *fullName ) { char areaName[VN_SIZE] = ""; //オブジェクト変数 char nestName[VN_SIZE] = ""; //入れ子メンバ bool isNest = SplitMemberName( fullName, areaName, nestName ); return Symbol( NamespaceScopes( areaName ), nestName ); } Symbol LexicalAnalyzer::FullNameToSymbol( const std::string &fullName ) { return FullNameToSymbol( fullName.c_str() ); } void LexicalAnalyzer::CollectClassesForNameOnly( const char *source, Classes &classes ) { int i, i2; char temporary[VN_SIZE]; // 名前空間管理 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes(); namespaceScopes.clear(); // Importsされた名前空間の管理 NamespaceScopesCollection &importedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces(); importedNamespaces.clear(); for(i=0;;i++){ if(source[i]=='\0') break; if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){ for(i+=2,i2=0;;i2++,i++){ if( IsCommandDelimitation( source[i] ) ){ temporary[i2]=0; break; } temporary[i2]=source[i]; } namespaceScopes.push_back( temporary ); continue; } else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){ if( namespaceScopes.size() <= 0 ){ compiler.errorMessenger.Output(12, "End Namespace", i ); } else{ namespaceScopes.pop_back(); } i += 2; continue; } else if( source[i] == 1 && source[i+1] == ESC_IMPORTS ){ for(i+=2,i2=0;;i2++,i++){ if( IsCommandDelimitation( source[i] ) ){ temporary[i2]=0; break; } temporary[i2]=source[i]; } if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) ) { compiler.errorMessenger.Output(64,temporary,i ); } continue; } else if( source[i] == 1 && source[i+1] == ESC_CLEARNAMESPACEIMPORTED ){ importedNamespaces.clear(); continue; } if(source[i]==1&&( source[i+1]==ESC_CLASS|| source[i+1]==ESC_TYPE|| source[i+1]==ESC_INTERFACE )) { int nowLine = i; i += 2; Type blittableType; if(memicmp(source+i,"Align(",6)==0){ //アラインメント修飾子 i+=6; i=JumpStringInPare(source,i)+1; } else if( memicmp( source + i, "Blittable(", 10 ) == 0 ){ // Blittable修飾子 i+=10; i+=GetStringInPare_RemovePare(temporary,source+i)+1; compiler.StringToType( temporary, blittableType ); } bool isEnum = false; bool isDelegate = false; if( source[i] == 1 && source[i+1] == ESC_ENUM ){ // 列挙型の場合 isEnum = true; i += 2; } else if( source[i] == 1 && source[i+1] == ESC_DELEGATE ) { // デリゲートの場合 isDelegate = true; i += 2; } for(i2=0;;i++,i2++){ if(!IsVariableChar(source[i])){ temporary[i2]=0; break; } temporary[i2]=source[i]; } //クラスを追加 CClass *pClass = classes.Add(namespaceScopes, importedNamespaces, temporary,nowLine); if( pClass ){ if( source[nowLine+1] == ESC_CLASS ){ if( isEnum ) { pClass->SetClassType( CClass::Enum ); } else if( isDelegate ) { pClass->SetClassType( CClass::Delegate ); } else{ pClass->SetClassType( CClass::Class ); } } else if( source[nowLine+1] == ESC_INTERFACE ){ pClass->SetClassType( CClass::Interface ); } else{ pClass->SetClassType( CClass::Structure ); } } // Blittable型の場合 if( !blittableType.IsNull() ){ pClass->SetBlittableType( blittableType ); // Blittable型として登録 compiler.GetObjectModule().meta.GetBlittableTypes().push_back( BlittableType( blittableType, pClass ) ); } } } } void LexicalAnalyzer::AddTypeDef( TypeDefCollection &typeDefs, const NamespaceScopes &namespaceScopes, const std::string &expression, int nowLine ) { int i; char temporary[VN_SIZE]; for(i=0;;i++){ if(expression[i]=='='||expression[i]=='\0'){ temporary[i]=0; break; } temporary[i]=expression[i]; } if(expression[i]!='='){ compiler.errorMessenger.Output(10,"TypeDef",nowLine); return; } const char *pTemp=expression.c_str()+i+1; //識別文字のエラーチェック(新しい型) i=0; for(;;i++){ if(temporary[i]=='\0') break; if( !( IsVariableChar( temporary[i], true) ) ){ compiler.errorMessenger.Output(10,"TypeDef",nowLine); return; } } //識別文字のエラーチェック(コピー元の型) if(pTemp[0]=='*'&&pTemp[1]==1&&(pTemp[2]==ESC_FUNCTION||pTemp[2]==ESC_SUB)){ //関数ポインタ if(pTemp[3]!='('){ compiler.errorMessenger.Output(10,"TypeDef",nowLine); return; } } else{ i=0; while(pTemp[i]=='*') i++; for(;;i++){ if(pTemp[i]=='\0') break; if( !( IsVariableChar( pTemp[i], true) ) ) { compiler.errorMessenger.Output(10,"TypeDef",nowLine); return; } } } //識別子が重複している場合はエラーにする if(lstrcmp(temporary,pTemp)==0){ compiler.errorMessenger.Output(1,NULL,nowLine); return; } ////////////////////////// // TypeDef情報を追加 ////////////////////////// Type baseType; if( !compiler.StringToType( pTemp, baseType ) ) { compiler.errorMessenger.Output(3, pTemp, nowLine ); return; } typeDefs.push_back( TypeDef( namespaceScopes, temporary, pTemp, baseType ) ); } void LexicalAnalyzer::CollectTypeDefs( const char *source, TypeDefCollection &typeDefs ) { // 名前空間管理 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes(); namespaceScopes.clear(); // Importsされた名前空間の管理 NamespaceScopesCollection &importedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces(); importedNamespaces.clear(); int i=-1, i2; char temporary[VN_SIZE]; while(1){ extern char *basbuf; i++; 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 ){ compiler.errorMessenger.Output(12, "End Namespace", i ); } else{ namespaceScopes.pop_back(); } i += 2; continue; } else if( basbuf[i] == 1 && basbuf[i+1] == ESC_IMPORTS ){ for(i+=2,i2=0;;i2++,i++){ if( IsCommandDelimitation( basbuf[i] ) ){ temporary[i2]=0; break; } temporary[i2]=basbuf[i]; } if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) ) { compiler.errorMessenger.Output(64,temporary,i ); } continue; } else if( basbuf[i] == 1 && basbuf[i+1] == ESC_CLEARNAMESPACEIMPORTED ){ importedNamespaces.clear(); continue; } if( basbuf[i]==1 ){ char temporary[VN_SIZE]; if(basbuf[i+1]==ESC_TYPEDEF){ int i2 = 0; for(i+=2;;i2++,i++){ if(basbuf[i]=='\n'){ temporary[i2]=0; break; } temporary[i2]=basbuf[i]; if(basbuf[i]=='\0') break; } AddTypeDef( typeDefs, namespaceScopes, temporary, i ); continue; } else if( basbuf[i+1] == ESC_CONST && basbuf[i+2] == 1 && basbuf[i+3] == ESC_ENUM ){ int i2 = 0; for(i+=4;;i2++,i++){ if(!IsVariableChar(basbuf[i])){ temporary[i2]=0; break; } temporary[i2]=basbuf[i]; if(basbuf[i]=='\0') break; } Type baseType; if( !compiler.StringToType( "Long", baseType ) ) { throw; } typeDefs.push_back( TypeDef( namespaceScopes, temporary, "Long", baseType ) ); } } //次の行 for(;;i++){ if(IsCommandDelimitation(basbuf[i])) break; } if(basbuf[i]=='\0') break; } } UserProc* LexicalAnalyzer::ParseUserProc( const NamespaceScopes &namespaceScopes, const NamespaceScopesCollection &importedNamespaces, char *buffer,int nowLine,bool isVirtual,CClass *pobj_c, bool isStatic, char *interfaceName ) { int i2,i3; char temporary[8192]; int i=1; Procedure::Kind kind = Procedure::Sub; bool isMacro = false; if(buffer[i]==ESC_FUNCTION) kind = Procedure::Function; if(buffer[i]==ESC_MACRO){ isMacro = true; } i++; bool isCdecl = false; bool isExport = false; while(1){ if(buffer[i]==1&&buffer[i+1]==ESC_CDECL&& isCdecl == false ){ isCdecl = true; i+=2; } else if(buffer[i]==1&&buffer[i+1]==ESC_EXPORT&& isExport == false ){ isExport = true; i+=2; } else break; } i2=0; if(buffer[i]==1&&buffer[i+1]==ESC_OPERATOR){ if(!pobj_c){ compiler.errorMessenger.Output(126,NULL,nowLine); return 0; } //オペレータの場合 temporary[i2++]=buffer[i++]; temporary[i2++]=buffer[i++]; int iCalcId; if(buffer[i]=='='&&buffer[i+1]=='='){ iCalcId=CALC_EQUAL; i3=2; } else if(buffer[i]=='='){ iCalcId=CALC_SUBSITUATION; i3=1; } else if(buffer[i]=='('){ iCalcId=CALC_AS; i3=0; } else if(buffer[i]=='['&&buffer[i+1]==']'&&buffer[i+2]=='='){ iCalcId=CALC_ARRAY_SET; i3=3; } else if(buffer[i]=='['&&buffer[i+1]==']'){ iCalcId=CALC_ARRAY_GET; i3=2; } else{ iCalcId=GetCalcId(buffer+i,&i3); i3++; } if(!iCalcId){ compiler.errorMessenger.Output(1,NULL,nowLine); return 0; } temporary[i2++]=iCalcId; temporary[i2]=0; i+=i3; } else{ if(pobj_c){ //クラスメンバの場合、デストラクタには~が付くことを考慮 if(buffer[i]=='~'){ temporary[i2]='~'; i++; i2++; } } for(;;i++,i2++){ if(!IsVariableChar(buffer[i])){ temporary[i2]=0; break; } temporary[i2]=buffer[i]; } char parentName[VN_SIZE], memberName[VN_SIZE]; ReferenceKind refKind; if( SplitMemberName( temporary, parentName, memberName, refKind ) ) { if( pobj_c ) { if( interfaceName ) { lstrcpy( interfaceName, parentName ); } else { compiler.errorMessenger.OutputFatalError(); return NULL; } char dummyMemberName[VN_SIZE]; if( SplitMemberName( memberName, parentName, dummyMemberName, refKind ) ) { compiler.errorMessenger.Output(69,temporary,nowLine); return NULL; } } else { compiler.errorMessenger.Output(68,temporary,nowLine); return NULL; } lstrcpy( temporary, memberName ); } } if( isMacro ){ //大文字に変換 CharUpper(temporary); } if(!pobj_c){ //クラスメンバ以外の場合のみ //重複チェック if(GetDeclareHash(temporary)){ compiler.errorMessenger.Output(15,temporary,nowLine); return 0; } } UserProc *pUserProc = new UserProc( namespaceScopes, importedNamespaces, temporary, kind, isMacro, isCdecl, isExport ); pUserProc->SetParentClass( pobj_c ); // 親インターフェイスをセット if( interfaceName && interfaceName[0] ) { ::Interface *pTargetInterface = NULL; BOOST_FOREACH( ::Interface *pInterface, pobj_c->GetInterfaces() ) { if( pInterface->GetClass().GetName() == interfaceName ) { pTargetInterface = pInterface; break; } } pUserProc->SetInterface( pTargetInterface ); } if(isExport){ pUserProc->Using(); } // パラメータを解析 // ※第1パラメータにに指定するデータの例:"( s As String ) As String" pUserProc->SetParamsAndReturnType( buffer + i, nowLine, isStatic ); pUserProc->_paramStr = buffer + i; return pUserProc; } void LexicalAnalyzer::CollectProcedures( const BasicSource &source, UserProcs &userProcs, DllProcs &dllProcs ) { extern HANDLE hHeap; int i,i2,i3; char temporary[8192]; // 名前空間管理 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes(); namespaceScopes.clear(); // Importsされた名前空間の管理 NamespaceScopesCollection &importedNamespaces = compiler.GetNamespaceSupporter().GetImportedNamespaces(); importedNamespaces.clear(); i=-1; while(1){ i++; if(source[i]==1&&(source[i+1]==ESC_CLASS||source[i+1]==ESC_INTERFACE)){ /* Class 〜 End Class Interface 〜 End Interface を飛び越す */ i3=GetEndXXXCommand(source[i+1]); for(i+=2,i2=0;;i++,i2++){ if(source[i]=='\0') break; if(source[i]==1&&source[i+1]==(char)i3){ i++; break; } } if(source[i]=='\0') break; continue; } if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){ for(i+=2,i2=0;;i2++,i++){ if( IsCommandDelimitation( source[i] ) ){ temporary[i2]=0; break; } temporary[i2]=source[i]; } namespaceScopes.push_back( temporary ); continue; } else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){ if( namespaceScopes.size() <= 0 ){ compiler.errorMessenger.Output(12, "End Namespace", i ); } else{ namespaceScopes.pop_back(); } i += 2; continue; } else if( source[i] == 1 && source[i+1] == ESC_IMPORTS ){ for(i+=2,i2=0;;i2++,i++){ if( IsCommandDelimitation( source[i] ) ){ temporary[i2]=0; break; } temporary[i2]=source[i]; } if( !compiler.GetNamespaceSupporter().ImportsNamespace( temporary ) ) { compiler.errorMessenger.Output(64,temporary,cp ); } continue; } else if( source[i] == 1 && source[i+1] == ESC_CLEARNAMESPACEIMPORTED ){ importedNamespaces.clear(); continue; } if(source[i]==1&&source[i+1]==ESC_DECLARE){ for(i+=2,i2=0;;i2++,i++){ if(source[i]=='\n'){ temporary[i2]=0; break; } temporary[i2]=source[i]; if(source[i]=='\0') break; } dllProcs.Add(namespaceScopes,temporary,i); continue; } if(source[i]==1&&(source[i+1]==ESC_SUB||source[i+1]==ESC_FUNCTION||source[i+1]==ESC_MACRO)){ char statementChar = source[i+1]; for(i2=0;;i2++,i++){ if(IsCommandDelimitation(source[i])){ temporary[i2]=0; break; } temporary[i2]=source[i]; if(source[i]=='\0') break; } UserProc *pUserProc = ParseUserProc( namespaceScopes, importedNamespaces, temporary, i, false, NULL, false ); userProcs.Insert( pUserProc, i ); /* Sub 〜 End Sub Function 〜 End Function Macro 〜 End Macro を飛び越す */ char endStatementChar = GetEndXXXCommand( statementChar ); for(i2=0;;i++,i2++){ if( source[i] == '\0' ) break; if( source[i] == 1 && source[i+1] == endStatementChar ){ i++; break; } } if(source[i]=='\0') break; continue; } //次の行 for(;;i++){ if(IsCommandDelimitation(source[i])) break; } if(source[i]=='\0') break; } //////////// // 特殊関数 //////////// namespaceScopes.clear(); importedNamespaces.clear(); compiler.globalAreaProcName = "_System_GlobalArea_" + compiler.GetModuleName(); sprintf(temporary,"%c%c%s()",1,ESC_SUB,compiler.globalAreaProcName.c_str()); UserProc *pUserProc = ParseUserProc( namespaceScopes, importedNamespaces, temporary, 0, false, NULL, false ); userProcs.Insert( pUserProc, i ); }