#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); } int GetTypeFixed(const char *TypeName,LONG_PTR *lpNum){ int type; if(lpNum) *lpNum=-1; if(TypeName[0]=='*'){ if(TypeName[1]==1&&(TypeName[2]==ESC_FUNCTION||TypeName[2]==ESC_SUB)){ //関数ポインタ(*Function) return DEF_PTR_PROC; } type=GetTypeFixed(TypeName+1,lpNum); if(type==-1) return -1; return GetPtrType(type); } //整数型 if(lstrcmpi(TypeName,"SByte")==0) return DEF_SBYTE; else if(lstrcmpi(TypeName,"Byte")==0) return DEF_BYTE; else if(lstrcmpi(TypeName,"Integer")==0) return DEF_INTEGER; else if(lstrcmpi(TypeName,"WORD")==0) return DEF_WORD; else if(lstrcmpi(TypeName,"Long")==0) return DEF_LONG; else if(lstrcmpi(TypeName,"DWORD")==0) return DEF_DWORD; else if(lstrcmpi(TypeName,"Int64")==0) return DEF_INT64; else if(lstrcmpi(TypeName,"QWORD")==0) return DEF_QWORD; //実数型 else if(lstrcmpi(TypeName,"Single")==0) return DEF_SINGLE; else if(lstrcmpi(TypeName,"Double")==0) return DEF_DOUBLE; //文字型 //else if( lstrcmpi( TypeName, "Char" ) == 0 ) return DEF_CHAR; //bool型 else if( lstrcmpi( TypeName, "Boolean" ) == 0 ) return DEF_BOOLEAN; //ポインタ型 //※VoidPtr型以外のポインタ型はTypeDef宣言により定義される else if(lstrcmpi(TypeName,"VoidPtr")==0) return DEF_PTR_VOID; //その他 else if(lstrcmpi(TypeName,"Any")==0) return DEF_ANY; //////////////////// // TypeDefされた型 //////////////////// int i; i=pobj_DBTypeDef->check(TypeName); if(i!=-1){ return GetTypeFixed(pobj_DBTypeDef->ppobj_TypeDef[i]->lpszBaseName,lpNum); } if(!lpNum) return -1; //クラス CClass *pobj_c; pobj_c=pobj_DBClass->check(TypeName); if(pobj_c){ *lpNum=(LONG_PTR)pobj_c; if( pobj_c->IsStructure() ){ return DEF_STRUCT; } else{ return DEF_OBJECT; } } return -1; } void GetOriginalTypeName(char *buffer){ // TypeDefされた型に対して、オリジナルの型の名前に変更する if(buffer[0]=='*'){ if(buffer[1]==1&&(buffer[2]==ESC_FUNCTION||buffer[2]==ESC_SUB)) return; GetOriginalTypeName(buffer+1); return; } int i; i=pobj_DBTypeDef->check(buffer); if(i!=-1){ lstrcpy(buffer,pobj_DBTypeDef->ppobj_TypeDef[i]->lpszBaseName); GetOriginalTypeName(buffer); } } 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)->name); } } //ポインタ型 else if(type==DEF_PTR_VOID) lstrcpy(name,"VoidPtr"); else if(type==DEF_PTR_PROC){ if(lpIndex==-1) lstrcpy(name,"VoidPtr"); else{ extern ProcPointer **ppProcPointer; if( ppProcPointer[lpIndex]->ReturnType().IsNull() ) lstrcpy(name,"*Sub"); else lstrcpy(name,"*Function"); } } else{ extern int cp; SetError(1,NULL,cp); return 0; } return 1; } Type GetStringTypeInfo(){ extern CClass *pobj_StringClass; Type type( DEF_OBJECT, *pobj_StringClass ); return type; } bool FormatUseProcReturnObject( const char *term, char *procName, char *parameter, CClass::RefType &refType, char *member ){ int p1 = 0, p2 = 0; for( int i=0; term[i]!='\0' ; i++ ){ if( term[i] == '[' ){ i = JumpStringInBracket( term, i + 1 ); if( term[i] == '\0' ) break; continue; } if( term[i] == '(' ){ int temp_p = i; i = JumpStringInPare( term, i + 1 ) + 1; if( term[i] == '\0' ) break; if( term[i] == '.' || term[i] == 1 && term[i] == ESC_PSMEM ){ p1 = temp_p; p2 = i; } continue; } } if( !p1 ) return false; //メソッド名 memcpy( procName, term, p1 ); procName[p1] = 0; //パラメータ memcpy( parameter, term + p1 + 1, p2 - p1 - 2 ); parameter[ p2 - p1 - 2 ] = 0; //参照タイプ if( term[p2] == '.' ){ refType = CClass::Dot; } else{ refType = CClass::Pointer; p2++; } //メンバ lstrcpy( member, term + p2 + 1 ); return true; } BOOL GetVarFormatString(char *buffer,char *array,char *array2,char *NestMember,CClass::RefType &refType){ extern int cp; int i,i2,i3; char cPare_Open,cPare_Close; array[0]=0; array2[0]=0; NestMember[0]=0; for(i=0;;i++){ if(buffer[i]=='\"'){ for(i++;;i++){ if(IsDBCSLeadByte(buffer[i])){ i++; continue; } if(buffer[i]=='\"') break; } } if(buffer[i]=='['||buffer[i]=='('){ if(buffer[i]=='['){ cPare_Open='['; cPare_Close=']'; } else{ cPare_Open='('; cPare_Close=')'; } buffer[i]=0; for(i++,i2=0;;i++,i2++){ if(buffer[i]==cPare_Open){ if(cPare_Open=='[') i3=GetStringInBracket(array+i2,buffer+i); else i3=GetStringInPare(array+i2,buffer+i); i+=i3-1; i2+=i3-1; continue; } if(buffer[i]==cPare_Close){ array[i2]=0; break; } array[i2]=buffer[i]; } if(buffer[i+1]==cPare_Open){ for(i+=2,i2=0;;i++,i2++){ if(buffer[i]==cPare_Open){ if(cPare_Open=='[') i3=GetStringInBracket(array2+i2,buffer+i); else i3=GetStringInPare(array2+i2,buffer+i); i+=i3-1; i2+=i3-1; continue; } if(buffer[i]==cPare_Close){ array2[i2]=0; break; } array2[i2]=buffer[i]; } if(buffer[i+1]==cPare_Open){ SetError(14,buffer,cp); return 0; } } continue; } if(buffer[i]=='.'){ lstrcpy(NestMember,buffer+i+1); refType = CClass::Dot; buffer[i]=0; break; } if(buffer[i]==1&&buffer[i+1]==ESC_PSMEM){ lstrcpy(NestMember,buffer+i+2); refType = CClass::Pointer; buffer[i]=0; break; } if(buffer[i]=='\0') break; } return 1; } void GetArrayElement( const char *buffer,char *variable,char *array_element){ array_element[0]=0; if(buffer[lstrlen(buffer)-1]!=']'){ lstrcpy(variable,buffer); return; } int i,i2; for(i=0;;i++){ if(buffer[i]=='\0') break; if(buffer[i]=='['){ i2=GetStringInBracket(array_element,buffer+i); i+=i2-1; continue; } } lstrcpy(variable,buffer); variable[lstrlen(variable)-lstrlen(array_element)]=0; RemoveStringBracket(array_element); } BOOL CheckVarNameError(char *name,int nowLine){ int i2; if(!IsVariableTopChar(name[0])){ SetError(1,NULL,nowLine); return 0; } for(i2=1;;i2++){ if(name[i2]=='\0') break; if(!IsVariableChar(name[i2])){ SetError(1,NULL,nowLine); return 0; } } return 1; } int JumpSubScripts(const int *ss){ //DIMで定義された並んだ配列の数だけアドレスを進める int i,i2; for(i=0,i2=1;i<255;i++){ if(ss[i]==-1) break; i2*=ss[i]+1; } return i2; } void GetArrange(char *variable,char *variAnswer,int *SubScripts){ extern int cp; int i,i2,i3,i4; double dbl; _int64 i64data; BOOL bBracket; char temporary[VN_SIZE]; for(i=0;;i++){ if(variable[i]=='('||variable[i]=='['){ if(variable[i]=='[') bBracket=1; else bBracket=0; variAnswer[i]=0; for(i++,i2=0,i3=0;;i++,i2++){ if(variable[i]==','){ temporary[i2]=0; Type resultType; if( !StaticCalculation(true, temporary,0,&i64data,resultType) ){ return; } if(resultType.IsReal()){ memcpy(&dbl,&i64data,sizeof(double)); i64data=(_int64)dbl; } if(i64data<0){ //error SubScripts[i3]=0; } else SubScripts[i3]=(int)i64data; i3++; i2=-1; continue; } if(variable[i]=='('){ i4=GetStringInPare(temporary+i2,variable+i); i2+=i4-1; i+=i4-1; continue; } if(variable[i]=='['){ i4=GetStringInBracket(temporary+i2,variable+i); i2+=i4-1; i+=i4-1; continue; } if(variable[i]==')'&&bBracket==0|| variable[i]==']'&&bBracket){ temporary[i2]=0; if(i2==0){ SubScripts[i3]=-2; break; } Type resultType; if( !StaticCalculation(true, temporary,0,&i64data,resultType) ){ return; } if(resultType.IsReal()){ memcpy(&dbl,&i64data,sizeof(double)); i64data=(_int64)dbl; } if(i64data<0){ //error SubScripts[i3]=0; } else SubScripts[i3]=(int)i64data; SubScripts[i3+1]=-1; break; } if(variable[i]=='\"'){ SetError(1,NULL,cp); return; } temporary[i2]=variable[i]; } break; } variAnswer[i]=variable[i]; if(variable[i]=='\0'){ SubScripts[0]=-1; break; } } } int GetTypeFromSimpleName(char *variable){ extern char DefIntVari[26],DefSngVari[26],DefStrVari[26],divNum,dsvNum,dStrvNum; int i; char name[VN_SIZE]; //構造体メンバの場合を考慮 for(i=lstrlen(variable);i>0;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;iname,VarName)==0) break; } if(i==objClass.iMemberNum){ if(isErrorEnabled) SetError(103,VarName,cp); return false; } //アクセシビリティをチェック if( &objClass == pobj_CompilingClass ){ //同一クラスオブジェクトの場合はプライベートアクセスを容認する if(objClass.ppobj_Member[i]->dwAccess==ACCESS_NON){ if(isErrorEnabled) SetError(107,VarName,cp); return false; } } else{ if((bPrivateAccess==0&&objClass.ppobj_Member[i]->dwAccess==ACCESS_PRIVATE)|| objClass.ppobj_Member[i]->dwAccess==ACCESS_NON){ if(isErrorEnabled) SetError(107,VarName,cp); return false; } else if(bPrivateAccess==0&&objClass.ppobj_Member[i]->dwAccess==ACCESS_PROTECTED){ if(isErrorEnabled) SetError(108,VarName,cp); return false; } } resultType = *objClass.ppobj_Member[i]; //ポインタ変数の場合 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]->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],member[VN_SIZE],VarName[VN_SIZE],array[VN_SIZE],lpPtrOffset[VN_SIZE]; if(nameBuffer[0]=='.'){ GetWithName(variable); lstrcat(variable,nameBuffer); } else lstrcpy(variable,nameBuffer); CClass::RefType refType; if( FormatUseProcReturnObject( variable, VarName, array, refType, member ) ){ // 戻り値オブジェクトのメンバを直接参照しているとき //例: func().member void *pProc; int idProc=GetProc(VarName,(void **)&pProc); if(idProc){ Type type; if( !CallProc( idProc, pProc, VarName, array,type, false) ){ return false; } return GetMemberType( type.GetClass() ,member,resultType,1,isErrorEnabled); } } lstrcpy(VarName,variable); GetVarFormatString(VarName,array,lpPtrOffset,member,refType); 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(lstrcmp(VarName,pobj_CompilingClass->ppobj_Member[i]->name)==0) 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); } 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->name,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]=='='){ //////////////////////////////////// // 初期化データが指定されいるとき //////////////////////////////////// for(i++,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]==1&&buffer[i+1]==ESC_AS)|| (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( !Type::StringToType( temporary, type ) ){ SetError(3,temporary,cp); type.SetBasicType( DEF_LONG ); } if( type.IsProcPtr() ){ 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]; } } } else{ //TypeDefをする前のベース型を取得 GetOriginalTypeName(temporary); } if(temporary[3]!='('){ SetError(10,temporary,cp); return false; } //関数ポインタ type.SetIndex( AddProcPtrInfo(temporary+3,temporary[2], cp) ); } 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( 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->name); 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(bool isRef, const char *name,int *SubScripts, const Type &type,char *InitBuf,char *ConstractParameter,DWORD dwFlag){ ///////////////////////// // グローバル変数を追加 ///////////////////////// extern int MaxGlobalVarNum; 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( name, type, isConst, isRef ); 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() ){ //デストラクタの利用フラグをオンにする 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]; //参照型かどうか bool isRef = false; i2 = 0; if( Parameter[i2] == 1 && Parameter[i2+1] == ESC_BYREF ){ //参照型 isRef = true; 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.GetType(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.GetType(VarName)){ SetError(15,VarName,cp); return; } //定数マクロとして定義されている場合 if(GetConstHash(VarName)){ SetError(15,VarName,cp); return; } 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( isRef,temporary,SubScripts,type,InitBuf,ConstractParameter,dwFlags ); /* Note: 静的変数のコンストラクタ呼び出しは _System_InitStaticLocalVariables関数内で一括して行う */ } else{ dim( isRef,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]; } }