#include "../BasicCompiler_Common/common.h" #ifdef _AMD64_ #include "../BasicCompiler64/opcode.h" #else #include "../BasicCompiler32/opcode.h" #endif BOOL IsVariableTopChar(char c){ if((c>='A'&&c<='Z')||(c>='a'&&c<='z')||c=='_') return 1; return 0; } BOOL IsVariableChar(char c){ if((c>='A'&&c<='Z')||(c>='a'&&c<='z')||(c>='0'&&c<='9')|| c=='%'||c=='!'||c=='#'||c=='$'|| c=='_'||c=='.') return 1; return 0; } BOOL IsPtrType(int type){ if(type==-1) return 0; if(PTR_LEVEL(type)||type==DEF_PTR_VOID||type==DEF_PTR_PROC|| (type&FLAG_PTR) ) return 1; return 0; } BOOL IsSignedType(int type){ switch(type){ case DEF_SBYTE: case DEF_INTEGER: case DEF_LONG: case DEF_INT64: case DEF_SINGLE: case DEF_DOUBLE: case DEF_CHAR: return 1; default: break; } return 0; } BOOL IsNaturalWholeNumberType(int type){ switch(type){ case DEF_SBYTE: case DEF_BYTE: case DEF_INTEGER: case DEF_WORD: case DEF_LONG: case DEF_DWORD: case DEF_INT64: case DEF_QWORD: case DEF_CHAR: return 1; default: break; } return 0; } BOOL IsWholeNumberType(int type){ return ( IsNaturalWholeNumberType(type) || IsPtrType(type) || type == DEF_BOOLEAN ); } BOOL IsRealNumberType(int type){ switch(type){ case DEF_DOUBLE: case DEF_SINGLE: return 1; default: break; } return 0; } BOOL Is64Type(int type){ switch(type){ case DEF_INT64: case DEF_QWORD: return 1; default: break; } #ifdef _AMD64_ return IsPtrType(type); #else return 0; #endif } int GetSignedType(int type){ switch(type){ case DEF_BYTE: return DEF_SBYTE; case DEF_WORD: return DEF_INTEGER; case DEF_DWORD: return DEF_LONG; case DEF_QWORD: return DEF_INT64; default: break; } #ifdef _AMD64_ if(IsPtrType(type)) return DEF_INT64; #else if(IsPtrType(type)) return DEF_LONG; #endif return type; } int GetUnsignedType(int type){ switch(type){ case DEF_SBYTE: return DEF_BYTE; case DEF_INTEGER: return DEF_WORD; case DEF_LONG: return DEF_DWORD; case DEF_INT64: return DEF_QWORD; case DEF_CHAR: if( isUnicode ) return DEF_WORD; return DEF_BYTE; } return type; } int GetTypeSize(int type,LONG_PTR lpIndex){ if(type==DEF_LONG){ if(lpIndex==LITERAL_NULL||lpIndex==LITERAL_M128_0||lpIndex==LITERAL_0_255) return sizeof(BYTE); else if(lpIndex==LITERAL_M32768_0||lpIndex==LITERAL_0_65535) return sizeof(WORD); return sizeof(DWORD); } //整数型 if(type==DEF_INT64||type==DEF_QWORD) return sizeof(_int64); else if(type==DEF_LONG||type==DEF_DWORD) return sizeof(DWORD); else if(type==DEF_INTEGER||type==DEF_WORD) return sizeof(WORD); else if(type==DEF_SBYTE||type==DEF_BYTE || type == DEF_BOOLEAN) return sizeof(BYTE); //実数型 else if(type==DEF_DOUBLE) return sizeof(double); else if(type==DEF_SINGLE) return sizeof(float); //文字型 else if( type == DEF_CHAR ){ if( isUnicode ) return sizeof( WORD ); return sizeof( BYTE ); } //ポインタ型 else if(IsPtrType(type)) return PTR_SIZE; else if( type == DEF_STRUCT ){ if(lpIndex == 0 || lpIndex == -1){ SetError(300,NULL,cp); return 0; } const CClass *pobj_c=(CClass *)lpIndex; return pobj_c->GetSize(); } else if(type==DEF_OBJECT){ return PTR_SIZE; } else{ SetError(300,NULL,cp); } return 0; } int GetPtrType(int type){ return MAKE_PTR_TYPE(NATURAL_TYPE(type),PTR_LEVEL(type)+1); } BOOL GetTypeName(int type,LONG_PTR lpIndex,char *name){ if(PTR_LEVEL(type)){ //ポインタ型 name[0]='*'; return GetTypeName(MAKE_PTR_TYPE(NATURAL_TYPE(type),PTR_LEVEL(type)-1),lpIndex,name+1); } //整数型 if(type==DEF_SBYTE) lstrcpy(name,"SByte"); else if(type==DEF_BYTE) lstrcpy(name,"Byte"); else if(type==DEF_INTEGER) lstrcpy(name,"Integer"); else if(type==DEF_WORD) lstrcpy(name,"Word"); else if(type==DEF_LONG) lstrcpy(name,"Long"); else if(type==DEF_DWORD) lstrcpy(name,"DWord"); else if(type==DEF_INT64) lstrcpy(name,"Int64"); else if(type==DEF_QWORD) lstrcpy(name,"QWord"); //実数型 else if(type==DEF_SINGLE) lstrcpy(name,"Single"); else if(type==DEF_DOUBLE) lstrcpy(name,"Double"); //文字型 //else if(type==DEF_CHAR) lstrcpy(name,"Char"); //bool型 else if(type==DEF_BOOLEAN) lstrcpy(name,"Boolean"); //オブジェクト else if(type==DEF_OBJECT || type==DEF_STRUCT){ if(lpIndex==0) lstrcpy(name,"non"); else{ lstrcpy(name,((CClass *)lpIndex)->GetName().c_str()); } } //ポインタ型 else if(type==DEF_PTR_VOID) lstrcpy(name,"VoidPtr"); else if(type==DEF_PTR_PROC){ if(lpIndex==-1) lstrcpy(name,"VoidPtr"); else{ if( Smoothie::Meta::procPointers[lpIndex]->ReturnType().IsNull() ) lstrcpy(name,"*Sub"); else lstrcpy(name,"*Function"); } } else{ extern int cp; SetError(1,NULL,cp); return 0; } return 1; } Type GetStringTypeInfo(){ Type type( DEF_OBJECT, *pobj_DBClass->GetStringClassPtr() ); return type; } void GetWithName(char *buffer){ extern WITHINFO WithInfo; int i; buffer[0]=0; for(i=0;i0;i--){ if(variable[i]=='.'){ i++; break; } } for(;;i++){ if(variable[i]=='('||variable[i]=='\0'){ name[i]=0; break; } name[i]=variable[i]; } //変数名から選択 i--; if(name[i]=='#') return DEF_DOUBLE; if(name[i]=='!') return DEF_SINGLE; if(name[i]=='%') return DEF_INTEGER; return DEF_DOUBLE; } bool GetMemberType( const CClass &objClass, const char *lpszMember, Type &resultType, BOOL bPrivateAccess, bool isErrorEnabled){ extern int cp; int i; //クラス、配列の構成要素を解析する char VarName[VN_SIZE]; //変数名 char array[VN_SIZE]; //第1次配列 char lpPtrOffset[VN_SIZE]; //第2次配列 char NestMember[VN_SIZE]; //入れ子メンバ CClass::RefType refType = CClass::Non; lstrcpy(VarName,lpszMember); if(!GetVarFormatString(VarName,array,lpPtrOffset,NestMember,refType)) return false; for(i=0;iGetName() == VarName ){ break; } } if(i==objClass.iMemberNum){ if(isErrorEnabled) SetError(103,VarName,cp); return false; } //アクセシビリティをチェック if( &objClass == pobj_CompilingClass ){ //同一クラスオブジェクトの場合はプライベートアクセスを容認する if( objClass.ppobj_Member[i]->IsNoneAccess() ){ if(isErrorEnabled) SetError(107,VarName,cp); return false; } } else{ if(( bPrivateAccess==0 && objClass.ppobj_Member[i]->IsPrivate() )|| objClass.ppobj_Member[i]->IsNoneAccess() ){ if(isErrorEnabled) SetError(107,VarName,cp); return false; } else if( bPrivateAccess==0 && objClass.ppobj_Member[i]->IsProtected() ){ if(isErrorEnabled) SetError(108,VarName,cp); return false; } } resultType = objClass.ppobj_Member[i]->GetType(); //ポインタ変数の場合 if( resultType.IsPointer() ){ if(objClass.ppobj_Member[i]->SubScripts[0]==-1){ lstrcpy(lpPtrOffset,array); array[0]=0; } } else{ if(lpPtrOffset[0]){ if(isErrorEnabled) SetError(16,lpszMember,cp); return false; } } if( refType != CClass::Non ){ //入れ子構造の場合 return GetMemberType( objClass.ppobj_Member[i]->GetType().GetClass(), NestMember, resultType, 0, isErrorEnabled); } if(array[0]==0&&objClass.ppobj_Member[i]->SubScripts[0]!=-1){ resultType.SetBasicType( resultType.GetBasicType() | FLAG_PTR ); return true; } if(lpPtrOffset[0]){ if( resultType.PtrLevel() ){ resultType.PtrLevelDown(); } else{ //エラー if(isErrorEnabled) SetError(1,NULL,cp); return false; } } return true; } bool GetVarType( const char *nameBuffer, Type &resultType, bool isErrorEnabled){ int i; char variable[VN_SIZE]; if(nameBuffer[0]=='.'){ GetWithName(variable); lstrcat(variable,nameBuffer); } else lstrcpy(variable,nameBuffer); // 名前空間を分離 char namespaceStr[VN_SIZE]="", simpleName[VN_SIZE]; Smoothie::Meta::namespaceScopesCollection.SplitNamespace( variable, namespaceStr, simpleName ); // 先頭オブジェクトまたはクラス名と入れ子メンバに分割 CClass::RefType refType; char member[VN_SIZE],array[VN_SIZE],lpPtrOffset[VN_SIZE]; GetVarFormatString(simpleName,array,lpPtrOffset,member,refType); // 名前空間を分離していた場合は結合 char VarName[VN_SIZE]; if( namespaceStr[0] ){ sprintf( VarName, "%s.%s", namespaceStr, simpleName ); } else{ lstrcpy( VarName, simpleName ); } const Variable *pVar = NULL; const int *pSubScripts; if( UserProc::IsLocalAreaCompiling() ){ ///////////////// // ローカル変数 ///////////////// pVar = UserProc::CompilingUserProc().localVars.BackSearch( VarName ); if( pVar ){ goto ok; } } if(pobj_CompilingClass){ /////////////////////// // クラスメンバの参照 /////////////////////// if(lstrcmpi(variable,"This")==0){ //Thisオブジェクト resultType.SetType( DEF_OBJECT, pobj_CompilingClass ); return true; } if(memicmp(variable,"This.",5)==0){ //Thisオブジェクトのメンバを参照するとき SlideString(variable+5,-5); lstrcpy(VarName,variable); } else{ //クラス内メンバを参照するとき(通常) for(i=0;iiMemberNum;i++){ if( pobj_CompilingClass->ppobj_Member[i]->GetName() == VarName ){ break; } } if(i==pobj_CompilingClass->iMemberNum) goto NonClassMember; } return GetMemberType(*pobj_CompilingClass,variable,resultType,1,isErrorEnabled); } NonClassMember: ////////////////////////// // 静的ローカル変数 // ※"Static.Object.Method.Variable" ////////////////////////// char temporary[VN_SIZE]; if( UserProc::IsLocalAreaCompiling() ){ GetNowStaticVarFullName(VarName,temporary); pVar = globalVars.Find( temporary ); if( pVar ){ goto ok; } } ////////////////////////// // クラスの静的メンバ ////////////////////////// if(member[0]){ lstrcpy(temporary,member); char tempMember[VN_SIZE]; char tempArray[VN_SIZE]; { CClass::RefType refType; GetVarFormatString(temporary,tempArray,lpPtrOffset,tempMember,refType); } int typeDefIndex = Smoothie::Meta::typeDefs.GetIndex( VarName ); if( typeDefIndex != -1 ){ // TypeDef後の型名だったとき lstrcpy( VarName, Smoothie::Meta::typeDefs[typeDefIndex].GetBaseName().c_str() ); } char temp2[VN_SIZE]; sprintf(temp2,"%s.%s",VarName,temporary); pVar = globalVars.Find( temp2 ); if( pVar ){ lstrcpy(member,tempMember); lstrcpy(array,tempArray); goto ok; } } if(pobj_CompilingClass){ //自身のクラスから静的メンバを参照する場合 char temp2[VN_SIZE]; sprintf(temp2,"%s.%s",pobj_CompilingClass->GetName().c_str(),VarName); pVar = globalVars.Find( temp2 ); if( pVar ){ goto ok; } } //////////////////// // グローバル変数 //////////////////// pVar = globalVars.BackSearch( VarName ); if( pVar ){ goto ok; } //変数として見つからなかったとき if(isErrorEnabled) SetError(3,variable,cp); return false; ok: //ポインタ変数の場合 if( pVar->IsPointer() ){ if( !pVar->IsArray() ){ lstrcpy(lpPtrOffset,array); array[0]=0; } } else{ if(lpPtrOffset[0]){ if(isErrorEnabled) SetError(16,variable,cp); return false; } } resultType = (*pVar); pSubScripts=pVar->GetSubScriptsPtr(); if(member[0]){ if( NATURAL_TYPE( resultType.GetBasicType() )==DEF_OBJECT || NATURAL_TYPE( resultType.GetBasicType() )==DEF_STRUCT){ return GetMemberType(resultType.GetClass(),member,resultType,0,isErrorEnabled); } } if(array[0]==0&&pSubScripts[0]!=-1){ //配列の先頭ポインタを示す場合 resultType.SetBasicType( resultType.GetBasicType() | FLAG_PTR ); } if(lpPtrOffset[0]){ if( resultType.PtrLevel() ){ resultType.PtrLevelDown(); } else{ //エラー if(isErrorEnabled) SetError(1,NULL,cp); return false; } } return true; } bool GetVarOffsetReadOnly(const char *NameBuffer,RELATIVE_VAR *pRelativeVar,Type &resultType,int *pss ){ //読み取り専用で変数へアクセス return GetVarOffset( true, //エラー表示有効 false, //書き込みアクセスは無し NameBuffer, pRelativeVar, resultType, pss); } bool GetVarOffsetReadWrite(const char *NameBuffer,RELATIVE_VAR *pRelativeVar,Type &resultType,int *pss ){ //読み書き両用で変数へアクセス return GetVarOffset( true, //エラー表示有効 true, //書き込みアクセス NameBuffer, pRelativeVar, resultType, pss); } bool GetDimentionFormat( const char *buffer, char *VarName, int *SubScripts, Type &type, char *InitBuf, char *ConstractParameter ){ int i,i2,i3,IsStr; char variable[VN_SIZE],temporary[8192]; for(i=0;;i++){ if((buffer[i]==1&&buffer[i+1]==ESC_AS)|| buffer[i]=='='|| buffer[i]=='\0'){ variable[i]=0; break; } variable[i]=buffer[i]; } if(buffer[i]=='='){ //////////////////////////////////// // 初期化データが指定されいるとき //////////////////////////////////// i++; if( buffer[i]=='[' ){ // 構造初期データの場合 i3=GetStringInBracket(InitBuf,buffer+i); i+=i3; } else{ // 代入初期データの場合 for(i2=0,IsStr=0;;i++,i2++){ if(buffer[i]=='\"') IsStr^=1; if(buffer[i]=='('&&IsStr==0){ i3=GetStringInPare(InitBuf+i2,buffer+i); i+=i3-1; i2+=i3-1; continue; } if(buffer[i]=='['&&IsStr==0){ i3=GetStringInBracket(InitBuf+i2,buffer+i); i+=i3-1; i2+=i3-1; continue; } if((buffer[i]==','&&IsStr==0)|| buffer[i]=='\0'){ InitBuf[i2]=0; break; } InitBuf[i2]=buffer[i]; } } } else{ //初期化データなし InitBuf[0]=0; } ConstractParameter[0]=0; if(buffer[i]==1&&buffer[i+1]==ESC_AS){ ///////////////////////////// // "As 〜" による型指定あり ///////////////////////////// for(i+=2,i2=0;;i++,i2++){ if(buffer[i]==','||buffer[i]=='('||buffer[i]=='\0'){ temporary[i2]=0; break; } temporary[i2]=buffer[i]; } if(temporary[0]=='*'&& temporary[1]==1&& (temporary[2]==ESC_FUNCTION||temporary[2]==ESC_SUB)){ if(buffer[i]!='('){ SetError(10,temporary,cp); return false; } i3=GetStringInPare(temporary+3,buffer+i); i+=i3; i2+=i3; if(temporary[2]==ESC_FUNCTION&&buffer[i]==1&&buffer[i+1]==ESC_AS){ temporary[i2++]=buffer[i++]; temporary[i2++]=buffer[i++]; for(;;i++,i2++){ if(!IsVariableChar(buffer[i])){ temporary[i2]=0; break; } temporary[i2]=buffer[i]; } } } if( !Type::StringToType( temporary, type ) ){ SetError(3,temporary,cp); type.SetBasicType( DEF_LONG ); } if(buffer[i]=='('){ //コンストラクタに渡すパラメータを取得 i2=GetStringInPare(ConstractParameter,buffer+i); i+=i2; RemoveStringPare(ConstractParameter); if( !type.IsObject() ){ SetError(112,variable,cp); return false; } } } else{ ///////////////// // As指定なし ///////////////// if( InitBuf[0] == '\0' ){ //As指定も、初期値指定もない場合 type.SetBasicType( GetTypeFromSimpleName(variable) ); i2=lstrlen(variable)-1; if(i2>=0){ if(!(variable[i2]=='#'||variable[i2]=='!'||variable[i2]=='%'||variable[i2]=='$')) SetError(-103,variable,cp); } } else{ //初期値の型を判別して自動的に型情報を付加する if( !NumOpe_GetType( InitBuf, GetStringTypeInfo(), type ) ){ // エラーの場合 return false; } if( IS_LITERAL( type.GetIndex() ) ){ type.SetIndex( -1 ); } } } if( InitBuf[0] != '\0' && ConstractParameter[0] != '\0' ){ //初期値とコンストラクタパラメータが同時に呼び出されているとき SetError(132, NULL, cp); } GetArrange(variable,VarName,SubScripts); return true; } BOOL GetNowStaticVarFullName(char *VarName,char *FullName){ if( UserProc::IsGlobalAreaCompiling() ){ // グローバル領域をコンパイル中のとき return 0; } UserProc &proc = UserProc::CompilingUserProc(); //Static識別 lstrcpy(FullName,"Static%"); //クラス名 if(pobj_CompilingClass){ lstrcat(FullName,pobj_CompilingClass->GetName().c_str()); lstrcat(FullName,"%"); } //関数(またはメソッド)名 lstrcat(FullName,proc.GetName().c_str()); lstrcat(FullName,"%"); //ID char temp[255]; sprintf(temp,"%x",proc.id); lstrcat(FullName,temp); lstrcat(FullName,"%"); //変数名 lstrcat(FullName,VarName); return 1; } void AddGlobalVariable( const char *name,int *SubScripts, const Type &type,const char *InitBuf,const char *ConstractParameter,DWORD dwFlag){ ///////////////////////// // グローバル変数を追加 ///////////////////////// extern int AllInitGlobalVarSize; extern int AllGlobalVarSize; if( globalVars.DuplicateCheck( name ) ){ //2重定義のエラー SetError(15,name,cp); return; } bool isConst = ( dwFlag & DIMFLAG_CONST ) ? true:false; Variable *pVar = new Variable( Smoothie::Lexical::liveingNamespaceScopes, name, type, isConst ); if( SubScripts[0] != -1 ){ //配列あり pVar->SetArray( SubScripts ); } //コンストラクタ用パラメータ pVar->paramStrForConstructor = ConstractParameter; //レキシカルスコープ pVar->ScopeLevel=obj_LexScopes.GetNowLevel(); pVar->ScopeStartAddress=obj_LexScopes.GetStartAddress(); pVar->bLiving=TRUE; //エラー用 pVar->source_code_address=cp; // 変数を追加 globalVars.push_back( pVar ); //アラインメントを考慮 int alignment = 0; if( pVar->IsStruct() ){ alignment = pVar->GetClass().iAlign; } if(InitBuf[0]||dwFlag==DIMFLAG_INITDEBUGVAR){ //初期バッファがあるとき if( alignment ){ if( AllInitGlobalVarSize % alignment ){ AllInitGlobalVarSize += alignment - (AllInitGlobalVarSize % alignment); } } pVar->offset=AllInitGlobalVarSize; AllInitGlobalVarSize += pVar->GetMemorySize(); } else{ //初期バッファがないとき if( alignment ){ if( AllGlobalVarSize % alignment ){ AllGlobalVarSize += alignment - (AllGlobalVarSize % alignment); } } pVar->offset=AllGlobalVarSize | 0x80000000; AllGlobalVarSize += pVar->GetMemorySize(); } if(InitBuf[0]){ int result = 0; if( !pVar->IsObject() ){ //初期バッファにデータをセット extern BYTE *initGlobalBuf; initGlobalBuf=(BYTE *)HeapReAlloc(hHeap, HEAP_ZERO_MEMORY, initGlobalBuf, AllInitGlobalVarSize); result = SetInitGlobalData(pVar->offset, *pVar, pVar->GetSubScriptsPtr(), InitBuf); } if(!result){ //動的な式だった場合は代入演算を行う //初期代入時のみ、書き込みアクセスを許可する if( isConst ){ pVar->ConstOff(); } //代入 char temporary[8192]; sprintf(temporary,"%s=%s",name,InitBuf); OpcodeCalc(temporary); //アクセス制限を元に戻す if( isConst ){ pVar->ConstOn(); } } } if( type.IsObject() ){ //デストラクタの利用フラグをオンにする const CMethod *method = type.GetClass().GetDestructorMethod(); if( method ){ method->pUserProc->Using(); } } } void dim(char *Parameter,DWORD dwFlags){ extern HANDLE hHeap; int i2; char VarName[VN_SIZE]; i2 = 0; if( Parameter[i2] == 1 && Parameter[i2+1] == ESC_BYREF ){ //参照型 SetError(); Parameter += 2; } if(dwFlags & DIMFLAG_CONST){ ////////////////////////////////// // 定数変数の場合を考慮 ////////////////////////////////// for(;;i2++){ if(Parameter[i2] == '=' || Parameter[i2] == 1 && Parameter[i2] == ESC_AS || Parameter[i2] =='('){ VarName[i2] = 0; break; } VarName[i2] = Parameter[i2]; } //定数と2重定義されていないる場合は抜け出す if(CDBConst::obj.GetBasicType(VarName)){ return; } //定数マクロとして定義されている場合は抜け出す if(GetConstHash(VarName)){ return; } } //構文を解析 int SubScripts[MAX_ARRAYDIM]; Type type; char InitBuf[8192]; char ConstractParameter[VN_SIZE]; if(!GetDimentionFormat(Parameter, VarName,SubScripts,type,InitBuf,ConstractParameter)) return; //定数と2重定義されていないかを調べる if(CDBConst::obj.GetBasicType(VarName)){ SetError(15,VarName,cp); return; } //定数マクロとして定義されている場合 if(GetConstHash(VarName)){ SetError(15,VarName,cp); return; } if( type.IsObject() ){ if( type.GetClass().IsBlittableType() ){ // Blittable型のときは基本型として扱う // ※ただし、コンパイル中のメソッドがBlittable型クラスに属していないこと if( UserProc::IsLocalAreaCompiling() && UserProc::CompilingUserProc().HasParentClass() && UserProc::CompilingUserProc().GetParentClass().IsBlittableType() ) { // コンパイル中のメソッドがBlittable型クラスに属している } else{ type = type.GetClass().GetBlittableType(); } } } if(dwFlags&DIMFLAG_STATIC){ if( UserProc::IsGlobalAreaCompiling() ){ SetError(60,NULL,cp); return; } ///////////////////// // Static変数 // ※"Static.Object.Method.Variable" ///////////////////// char temporary[VN_SIZE]; GetNowStaticVarFullName(VarName,temporary); dim( temporary,SubScripts,type,InitBuf,ConstractParameter,dwFlags ); /* Note: 静的変数のコンストラクタ呼び出しは _System_InitStaticLocalVariables関数内で一括して行う */ } else{ dim( VarName,SubScripts,type,InitBuf,ConstractParameter,dwFlags ); } } void OpcodeDim(char *Parameter,DWORD dwFlags){ int i,i2,i3,IsStr=0; char temporary[8192]; for(i=0,i2=0;;i++,i2++){ if(Parameter[i]=='\"') IsStr^=1; if(Parameter[i]=='('&&IsStr==0){ i3=GetStringInPare(temporary+i2,Parameter+i); i+=i3-1; i2+=i3-1; continue; } if(Parameter[i]=='['&&IsStr==0){ i3=GetStringInBracket(temporary+i2,Parameter+i); i+=i3-1; i2+=i3-1; continue; } if((Parameter[i]==','&&IsStr==0)|| Parameter[i]=='\0'){ temporary[i2]=0; dim(temporary,dwFlags); if(Parameter[i]=='\0') break; i2=-1; continue; } temporary[i2]=Parameter[i]; } }