#include "stdafx.h" #include #include "../BasicCompiler_Common/common.h" #include "Opcode.h" using namespace ActiveBasic::Compiler; void PushReturnValue( const Type &type ) { //関数の戻り値をスタックへプッシュする //※この処理内では、esi、ediは使用不可 if( type.IsObject() || type.IsStruct() ) { //push eax compiler.codeGenerator.op_push(REG_EAX); } else if( type.IsDouble() ) { //sub esp,8 compiler.codeGenerator.op_sub_esp(8); //fstp qword ptr[esp] compiler.codeGenerator.op_fstp_basereg( DEF_DOUBLE, REG_ESP ); } else if( type.IsSingle() ) { //sub esp,4 compiler.codeGenerator.op_sub_esp(4); //fstp dword ptr[esp] compiler.codeGenerator.op_fstp_basereg( DEF_SINGLE, REG_ESP ); } else if( type.Is64() ) { //push edx compiler.codeGenerator.op_push(REG_EDX); //push eax compiler.codeGenerator.op_push(REG_EAX); } else if( type.IsInteger() || ( compiler.IsUnicode() && type.GetBasicType() == DEF_CHAR ) ) { //movsx ebx,ax compiler.codeGenerator.op_movsx_R32R16( REG_EBX, REG_EAX ); //push ebx compiler.codeGenerator.op_push(REG_EBX); } else if( type.IsSByte() || ( !compiler.IsUnicode() && type.GetBasicType() == DEF_CHAR ) ) { //movsx ebx,al compiler.codeGenerator.op_movsx_R32R8( REG_EBX, REG_EAX ); //push ebx compiler.codeGenerator.op_push(REG_EBX); } else if( type.IsLong() || type.IsDWord() || type.IsWord() || type.IsByte() || type.IsBoolean() || type.IsPointer() ) { //push eax compiler.codeGenerator.op_push(REG_EAX); } else{ compiler.errorMessenger.OutputFatalError(); } } void NewStringObject( const char *str ){ /////////////////////////////////////////////////////// // lpszTextを元にStringオブジェクトを生成し、 // オブジェクトポインタをregに格納する /////////////////////////////////////////////////////// char *parameter = (char *)malloc( lstrlen( str ) + 32 ); sprintf( parameter, "%s%c%c*Char", str, 1, ESC_AS ); Operator_New( *compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr(), "", parameter, Type( DEF_OBJECT, *compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr() ) ); free( parameter ); } void ExtendRegToBigType( int reg, int bigBasicType, int baseBasicType ){ if( reg != REG_EAX ){ compiler.errorMessenger.OutputFatalError(); } switch( Type::GetBasicSize( bigBasicType ) ){ case sizeof(_int64): ExtendTypeTo64(baseBasicType); break; case sizeof(long): ExtendTypeTo32(baseBasicType,reg); break; case sizeof(short): ExtendTypeTo16(baseBasicType,reg); break; } } bool VarToReg( RELATIVE_VAR &relativeVar, const Type &baseType, Type &resultType ){ const int useReg = REG_EAX; //大きな型への暗黙の変換 int bigType = AutoBigCast(baseType.GetBasicType(),resultType.GetBasicType()); if(resultType.GetBasicType()&FLAG_PTR){ //配列ポインタ resultType.SetBasicType( GetPtrType(resultType.GetBasicType()^FLAG_PTR) ); SetVarPtrToReg(useReg, &relativeVar); } else if( resultType.IsStruct() ){ //構造体ポインタをeaxへ格納(構造体は値型) SetVarPtrToReg(useReg, &relativeVar); } else if( resultType.IsReal() ){ // 実数 SetReg_RealVariable( resultType.GetBasicType(), &relativeVar ); } else if( resultType.IsWhole() || resultType.IsObject()){ //整数型 SetReg_WholeVariable(resultType,&relativeVar,useReg); } else if( resultType.IsStruct() ){ //構造体ポインタをUseRegへ格納(構造体は値型) SetVarPtrToReg(useReg,&relativeVar); } else{ return false; } if( resultType.GetBasicType() != bigType ){ // 大きな型へ変換された場合 // ※レジスタの値をキャストする ExtendRegToBigType( useReg, bigType, resultType.GetBasicType() ); resultType.SetBasicType( bigType ); } return true; } bool TermMemberOpe( const Type &leftType, bool &isNeedHeapFreeStructure, const Type &baseType, Type &resultType, const char *termFull, const char *termLeft, const char *member, bool &isVariable, RELATIVE_VAR &relativeVar ) { const CClass &objClass = leftType.GetClass(); const int useReg = REG_EAX; //////////////////////////////// // インデクサ(getアクセサ) //////////////////////////////// char VarName[VN_SIZE],ArrayElements[VN_SIZE]; GetArrayElement(member,VarName,ArrayElements); if(ArrayElements[0]){ Type classType; if( VarName[0] == '\0' ) { classType = leftType; if( classType.IsObject() ) { // 既にuseRegにオブジェクトポインタが格納されており、それに対するインデクサを呼び出す場合 // ※「プロパティ値として返ってきたオブジェクトインスタンスのインデクサを呼び出す」場合にここにくる //オブジェクトポインタをスタックに入れておく //push useReg compiler.codeGenerator.op_push( useReg ); } } else { GetMemberType( leftType, VarName, classType, 0, false ); if( classType.IsObject() ) { // クラス型のメンバに対するインデクサを呼び出す場合 //オブジェクトポインタをecxにコピー compiler.codeGenerator.op_mov_RR( REG_ECX, useReg ); RELATIVE_VAR tempRelativeVar; tempRelativeVar.dwKind=VAR_DIRECTMEM; if( !_member_offset( true, //エラー表示あり false, //読み込み専用 leftType, VarName,&tempRelativeVar,classType,0)){ return false; } // オブジェクトメンバのポインタをeaxにコピー if( !VarToReg( tempRelativeVar, baseType, resultType ) ){ compiler.errorMessenger.Output(11,termFull,cp); } //オブジェクトポインタをスタックに入れておく //push eax compiler.codeGenerator.op_push( REG_EAX ); } } if( classType.IsObject() ) { char objectFullName[VN_SIZE], dummyArrayElements[VN_SIZE]; GetArrayElement(termFull,objectFullName,dummyArrayElements); CallIndexerGetterProc(/*UseReg,*/classType,objectFullName, ArrayElements,resultType, PROCFLAG_NEW ); compiler.codeGenerator.op_pop(); return true; } } /////////////////////////////////////////////////////////////////// // メンバを検索 /////////////////////////////////////////////////////////////////// if( GetMemberType( leftType, member, resultType, 0, false ) ){ // メンバが見つかったとき if( isNeedHeapFreeStructure ) { if( !leftType.IsStruct() ) { compiler.errorMessenger.OutputFatalError(); } // 親となる構造体が一時メモリに存在していた場合、後ほど解放する必要がある compiler.codeGenerator.op_AddNeedFreeTempStructure( useReg ); isNeedHeapFreeStructure = false; } //オブジェクトポインタをecxにコピー compiler.codeGenerator.op_mov_RR( REG_ECX, useReg ); relativeVar.dwKind=VAR_DIRECTMEM; if( !_member_offset( true, //エラー表示あり false, //読み込み専用 leftType, member,&relativeVar,resultType,0)){ return false; } // 変数として扱う isVariable = true; return true; } /////////////////////////////////////////////////////////////////// // 動的メソッドを検索 /////////////////////////////////////////////////////////////////// std::vector userProcs; char methodName[VN_SIZE], lpPtrOffset[VN_SIZE], parameter[VN_SIZE], dummy[1]; ReferenceKind refType; PareOrBracket pareOrBracket = None; lstrcpy( methodName, member ); GetVarFormatString( methodName, parameter, lpPtrOffset, dummy, refType, &pareOrBracket ); objClass.EnumDynamicMethodsOrInterfaceMethods( methodName, userProcs ); if(userProcs.size()){ //オーバーロードを解決 const UserProc *pUserProc = OverloadSolutionWithStrParam(termFull,userProcs,parameter,termLeft); if( pUserProc ) { if( pUserProc->Params().size() == 0 // 仮引数の個数は0 && parameter[0] // 実引数は1つ以上 && pUserProc->ReturnType().IsObject() // 戻り値がクラス型の場合 && pareOrBracket == Bracket ) // 実引数は[]で囲まれている { // プロパティ値として返ってきたオブジェクトインスタンスのインデクサを呼び出す // まずはプロパティ値を取得 bool dummyIsVariable; RELATIVE_VAR dummyRelativeVar; TermMemberOpe( leftType, isNeedHeapFreeStructure, baseType, resultType, termFull, termLeft, methodName, dummyIsVariable, dummyRelativeVar ); // 戻り値のオブジェクトインスタンスのインデクサを呼び出す char temporary[VN_SIZE], temp2[VN_SIZE]; sprintf( temporary, "[%s]", parameter ); sprintf( temp2, "%s.%s", termLeft, methodName ); Type classType = resultType; return TermMemberOpe( classType, isNeedHeapFreeStructure, baseType, resultType, termFull, temp2, temporary, isVariable, relativeVar ); } resultType = pUserProc->ReturnType(); { //オブジェクトポインタをスタックに入れておく //push reg compiler.codeGenerator.op_push( useReg ); if( !Opcode_CallProc(parameter,pUserProc,PROCFLAG_NEW,termLeft) ){ return false; } compiler.codeGenerator.op_pop(); ///////////////////// // 戻り値の処理 ///////////////////// //大きな型への暗黙の変換 int bigType = AutoBigCast(baseType.GetBasicType(), resultType.GetBasicType() ); if( resultType.GetBasicType() != bigType ){ // 大きな型へ変換された場合 // ※レジスタの値をキャストする ExtendRegToBigType( REG_EAX, bigType, resultType.GetBasicType() ); resultType.SetBasicType( bigType ); } //SetUseRegFromRax(resultType.GetBasicType(),UseReg,XmmReg); // 型パラメータを解決 ResolveFormalGenericTypeParameter( resultType, leftType, pUserProc ); } return true; } } else if( pareOrBracket == Pare ) { // 関数ポインタ compiler.errorMessenger.OutputFatalError(); /////////////////////////////////////////////////////////////////// // メンバを検索 /////////////////////////////////////////////////////////////////// if( GetMemberType( leftType, methodName, resultType, 0, false ) ){ // メンバが見つかったとき } } compiler.errorMessenger.OutputFatalError(); return false; } bool _TermOpe( const char *term, const Type &baseType, Type &resultType, bool &isLiteral, bool &isNeedHeapFreeStructure, bool *pIsClassName, bool isProcedureCallOnly, bool &isVariable, RELATIVE_VAR &relativeVar, bool isWriteAccess ) { char parameter[VN_SIZE]; // Withを解決 char termFull[VN_SIZE]; if(term[0]=='.'){ GetWithName(termFull); lstrcat(termFull,term); } else lstrcpy(termFull,term); char termLeft[VN_SIZE]; lstrcpy(termLeft,termFull); // パース char member[VN_SIZE]; ReferenceKind refType; if( SplitMemberName( termFull, termLeft, member, refType ) ){ /////////////////////////////////////////////////////////////////// // オブジェクトとメンバに分解できるとき // termLeft.member /////////////////////////////////////////////////////////////////// isLiteral = false; // オブジェクト側の型を取得 bool isClassName = false; Type leftType; if( GetTermType( termLeft, Type(), leftType, isLiteral, &isClassName ) ){ if( isClassName == false && compiler.GetObjectModule().meta.GetBlittableTypes().IsExist( leftType ) ){ // 左側のオブジェクト部分がBlittable型のとき char temporary[VN_SIZE]; lstrcpy( temporary, termLeft ); sprintf( termLeft, "%s(%s)", compiler.GetObjectModule().meta.GetBlittableTypes().Find( leftType ).GetCreateStaticMethodFullName().c_str(), temporary ); } } if( !TermOpe( termLeft, baseType, leftType, isLiteral, isNeedHeapFreeStructure, &isClassName ) ){ goto globalArea; } if( isClassName ){ // 静的メンバ/メソッドの場合 goto globalArea; } if( !leftType.HasMember() ){ // メンバを持たない型の場合 if( isProcedureCallOnly ) { compiler.errorMessenger.Output(1,NULL,cp); } return false; } return TermMemberOpe( leftType, isNeedHeapFreeStructure, baseType, resultType, termFull, termLeft, member, isVariable, relativeVar ); } globalArea: ////////////////////////////////////////////// // クラス名かどうかをチェック(静的メンバ用) ////////////////////////////////////////////// if( pIsClassName ){ if( compiler.GetObjectModule().meta.FindClassSupportedTypeDef( LexicalAnalyzer::FullNameToSymbol( termFull ) ) ){ *pIsClassName = true; return true; } } ///////////////////////////////////////////////////////////////// // グローバル属性エリア ///////////////////////////////////////////////////////////////// const int useReg = REG_EAX; if(lstrcmpi(termFull,"This")==0 && isProcedureCallOnly == false ){ if( !compiler.IsCompilingClass() ) { compiler.errorMessenger.Output(142,NULL,cp); return false; } //Thisオブジェクト resultType.SetType( DEF_OBJECT, &compiler.GetCompilingClass() ); SetThisPtrToReg( useReg ); isLiteral = false; return true; } ////////////////////////////////////// // 関数(DLL、ユーザー定義、組み込み) ////////////////////////////////////// char procName[VN_SIZE]; char temporary[8192]; int i2=GetCallProcName(termFull,procName); if(termFull[i2]=='('){ int i4=GetStringInPare_RemovePare(parameter,termFull+i2+1); void *pInfo; int idProc=GetProc(procName,(void **)&pInfo); if(idProc) { if(termFull[i2+1+i4+1]!='\0') { //閉じカッコ")"に続く文字がNULLでないとき compiler.errorMessenger.Output(42,NULL,cp); } { //////////////// // 呼び出し //////////////// CallProc(idProc,pInfo,procName,parameter, baseType,resultType); ///////////////////// // 戻り値の処理 ///////////////////// //大きな型への暗黙の変換 int bigType = AutoBigCast(baseType.GetBasicType(), resultType.GetBasicType() ); /* ※後でNumOpe内でプッシュする //スタックへプッシュ PushReturnValue( resultType.GetBasicType() ); */ if( resultType.GetBasicType() != bigType ){ // 大きな型へ変換された場合 // ※レジスタの値をキャストする ExtendRegToBigType( useReg, bigType, resultType.GetBasicType() ); resultType.SetBasicType( bigType ); } //SetUseRegFromRax(resultType.GetBasicType(),UseReg,XmmReg); } if(resultType.IsStruct()) { //構造体が戻ったときはヒープ領域にインスタンスが格納されている //※後にfreeする必要あり // TODO: 解放はGCに任せる isNeedHeapFreeStructure = true; } isLiteral = false; return true; } ConstMacro *pConstMacro = compiler.GetObjectModule().meta.GetGlobalConstMacros().Find( ActiveBasic::Compiler::LexicalAnalyzer::FullNameToSymbol( procName ) ); if( pConstMacro ) { if( ActiveBasic::Compiler::LexicalAnalyzer::ConstMacroToExpression( *pConstMacro, parameter, temporary ) ) { ///////////////////////// // マクロ関数 ///////////////////////// //閉じカッコ")"に続く文字がNULLでないときはエラーにする if(termFull[i2+1+i4+1]!='\0') compiler.errorMessenger.Output(42,NULL,cp); //マクロ関数の場合 NumOpe(useReg, temporary,Type(),resultType); if(!IS_LITERAL(resultType.GetIndex())){ //リテラル値ではなかったとき isLiteral = false; } return true; } } } else if( isProcedureCallOnly ){ // 関数呼び出し以外は受け付けない return false; } //////////////////////////////// // インデクサ(getアクセサ) //////////////////////////////// char VarName[VN_SIZE],ArrayElements[VN_SIZE]; GetArrayElement(termFull,VarName,ArrayElements); if(ArrayElements[0]){ Type classType; GetVarType(VarName,classType,false); if( classType.IsObject() ) { CallIndexerGetterProc(/*UseReg,*/classType,VarName, ArrayElements,resultType); isLiteral = false; return true; } } //////////////////////////////// // 変数 //////////////////////////////// if(GetVarOffset( false, //エラー表示なし isWriteAccess, termFull, &relativeVar,resultType)){ ////////// // 変数 ////////// // 変数として扱う isVariable = true; isLiteral = false; return true; } ///////////////////////////////// // プロパティ用のメソッド ///////////////////////////////// //配列要素を排除 GetArrayElement(termFull,VarName,ArrayElements); if(GetSubHash(VarName,0)){ { CallPropertyMethod(termFull,NULL,resultType); //大きな型への暗黙の変換 int bigType = AutoBigCast(baseType.GetBasicType(), resultType.GetBasicType() ); if( resultType.GetBasicType() != bigType ){ // 大きな型へ変換された場合 // ※レジスタの値をキャストする ExtendRegToBigType( REG_EAX, bigType, resultType.GetBasicType() ); resultType.SetBasicType( bigType ); } //SetUseRegFromRax(resultType.GetBasicType(),UseReg,XmmReg); } if(resultType.IsStruct()) { //構造体が戻ったときはヒープ領域にインスタンスが格納されている //※後にfreeする必要あり // TODO: 解放はGCに任せる isNeedHeapFreeStructure = true; } isLiteral = false; return true; } if( isProcedureCallOnly ) { compiler.errorMessenger.Output(3, termFull, cp ); } return false; } bool TermOpe( const char *term, const Type &baseType, Type &resultType, bool &isLiteral, bool &isNeedHeapFreeStructure, bool *pIsClassName, bool isProcedureCallOnly, bool isWriteAccess ) { RELATIVE_VAR relativeVar; bool isVariable = false; bool result = _TermOpe( term, baseType, resultType, isLiteral, isNeedHeapFreeStructure, pIsClassName, isProcedureCallOnly, isVariable, relativeVar, isWriteAccess ); if( isVariable ) { // 変数の場合はeaxに変数ポインタを格納する if( !VarToReg( relativeVar, baseType, resultType ) ){ compiler.errorMessenger.Output(11,term,cp); } } return result; } bool TermOpeOnlyVariable( const char *term, Type &resultType, RELATIVE_VAR &relativeVar, bool isWriteAccess ) { bool isLiteral, isVariable = false, isNeedHeapFreeStructure = false; bool result = _TermOpe( term, Type(), resultType, isLiteral, isNeedHeapFreeStructure, NULL, false, isVariable, relativeVar, isWriteAccess ); if( !isVariable ) { compiler.errorMessenger.OutputFatalError(); } return result; } bool NumOpe( int reg, const char *expression, const Type &baseType, Type &resultType, bool *pbIsNeedHeapFreeStructure ){ if( !NumOpe( expression, baseType, resultType, pbIsNeedHeapFreeStructure ) ) { return false; } if( reg != REG_EAX ){ // TODO: 未実装 compiler.errorMessenger.OutputFatalError(); } if( resultType.IsReal() ){ //fld ptr[esp] compiler.codeGenerator.op_fld_ptr_esp( resultType.GetBasicType() ); //add esp,size compiler.codeGenerator.op_add_esp( resultType.GetBasicSize() ); } else{ //pop eax compiler.codeGenerator.op_pop(REG_EAX); if( resultType.Is64() ){ //pop edx compiler.codeGenerator.op_pop(REG_EDX); } } return true; } bool NumOpe( const char *expression, const Type &baseType, Type &resultType, bool *pbIsNeedHeapFreeStructure ) { int i,i2,i3; char temporary[1024],temp2[1024]; if(expression[0]=='\0'){ compiler.errorMessenger.Output(1,NULL,cp); return false; } if( !baseType.IsNull() && expression[0] == '[' ){ // リテラル配列の場合 int dataTableOffset; if( !ActiveBasic::Compiler::DataTableGenerator::MakeLiteralArrayBuffer( compiler.GetObjectModule().dataTable, expression, baseType, dataTableOffset ) ) { return false; } //mov eax,i2 compiler.codeGenerator.op_mov_RV(REG_EAX,dataTableOffset, Schedule::DataTable ); resultType = baseType; //push eax compiler.codeGenerator.op_push( REG_EAX ); return true; } bool isLiteralCalculation; if( NumOpe_GetType( expression, baseType, resultType, &isLiteralCalculation ) ) { if( isLiteralCalculation ) { //右辺値が数値の定数式の場合 _int64 i64data; StaticCalculation(true, expression,baseType.GetBasicType(),&i64data,resultType); if( resultType.GetBasicSize() == sizeof(_int64) ){ //64ビット(符号有り整数/実数) //push HILONG(i64data) compiler.codeGenerator.op_push_V((long)*(long *)(((char *)(&i64data))+4)); //push LOLONG(i64data) compiler.codeGenerator.op_push_V(*(long *)(&i64data)); } else if( resultType.IsSingle() ){ //single実数 double dbl; memcpy(&dbl,&i64data,sizeof(_int64)); float flt; flt=(float)dbl; long l; memcpy(&l,&flt,sizeof(long)); //push flt compiler.codeGenerator.op_push_V(l); } else{ //整数(符号有り/無し) long l = (long)i64data; if(resultType.GetBasicSize()==sizeof(char)) l = l & 0x000000FF; if(resultType.GetBasicSize()==sizeof(short)) l = l & 0x0000FFFF; //push term compiler.codeGenerator.op_push_V(l); } return true; } } if(expression[0]==1 ) { if( expression[1]==ESC_NEW ){ //New演算子(オブジェクト生成) if( !Operator_New( expression+2, baseType, resultType ) ){ return false; } return true; } else if( expression[1] == ESC_SYSTEM_STATIC_NEW ) { // 静的領域にオブジェクトを作る // 静的領域にオブジェクトを生成 int dataTableOffset; if( !ActiveBasic::Compiler::DataTableGenerator::MakeConstObjectToProcessStaticBuffer( compiler.GetObjectModule().dataTable, expression + 2, resultType, dataTableOffset ) ) { return false; } // push value compiler.codeGenerator.op_push_V( dataTableOffset, Schedule::DataTable ); return true; } } ///////////////////////////////// // 式要素を逆ポーランド式で取得 ///////////////////////////////// char *values[255]; long calc[255]; long stack[255]; int pnum; if(!GetNumOpeElements(expression,&pnum,values,calc,stack)){ for(i=0;iIsEqualsOrSubClass( (CClass *)index_stack[sp-2] ) || ((CClass *)index_stack[sp-2])->IsEqualsOrSubClass( (CClass *)index_stack[sp-1] ) )){ // ダウンキャストを許可する } else{ //オーバーロードされたオペレータを呼び出す i2=CallOperatorProc(idCalc,baseType,type_stack,index_stack,isNeedHeapFreeStructureStack,sp); if(i2==0){ if(idCalc==CALC_EQUAL) lstrcpy(temp2,"=="); else GetCalcName(idCalc,temp2); sprintf(temporary,"Operator %s",temp2); compiler.errorMessenger.Output(27,temporary,cp); goto error; } else if(i2==-1) goto error; continue; } } if(!CheckCalcType(idCalc,type_stack,sp)) goto error; } switch(idCalc){ //数値 case 0: index_stack[sp]=-1; isNothing_stack[sp] = false; isNeedHeapFreeStructureStack[sp] = false; char *term; term=values[i]; if( calc[i+1]%100 == CALC_AS ){ // As演算子の右辺値 //型名 if( compiler.StringToType( term, resultType ) ){ resultType.SetBasicType( resultType.GetBasicType() | FLAG_CAST ); } else{ compiler.errorMessenger.Output(3, term, cp ); goto error; } type_stack[sp] = resultType.GetBasicType(); index_stack[sp] = resultType.GetIndex(); sp++; break; } if( (term[0]=='e'||term[0]=='E') && (term[1]=='x'||term[1]=='X') && term[2]=='\"' || term[0] == '\"' ) { bool isEx = true; if( term[0] == '\"' ) { isEx = false; } if( isEx ) { // 拡張版リテラル文字列(エスケープシーケンス可能) if(!RemoveStringQuotes(term+2)){ compiler.errorMessenger.Output(43,NULL,cp); goto error; } i3=FormatString_EscapeSequence(term+2); term+=2; } else { // 通常文字列 if(!RemoveStringQuotes(term)){ compiler.errorMessenger.Output(43,NULL,cp); goto error; } i3=lstrlen(term); } if( !baseType.IsPointer() ) { //要求タイプがオブジェクト、または未定のとき //String型オブジェクトを生成 i2 = ActiveBasic::Compiler::DataTableGenerator::MakeConstStringObjectToProcessStaticBuffer( compiler.GetObjectModule().dataTable, term ); // push value compiler.codeGenerator.op_push_V( i2, Schedule::DataTable ); type_stack[sp]=DEF_OBJECT; index_stack[sp]=(LONG_PTR)compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr(); bLiteralCalculation=0; sp++; break; } StrLiteral: type_stack[sp]=typeOfPtrChar; bLiteralCalculation=0; if( compiler.IsUnicode() ) { i2 = compiler.GetObjectModule().dataTable.AddWString( Jenga::Common::ToWString( std::string( term, i3 ) ) ); } else { i2 = compiler.GetObjectModule().dataTable.AddString( std::string( term, i3 ) ); } //push DataSize compiler.codeGenerator.op_push_V( i2, Schedule::DataTable ); } else if(IsVariableTopChar(term[0])|| term[0]=='*'|| (term[0]=='.'&&IsVariableTopChar(term[1]))){ ////////////////// // 何らかの識別子 bool isLiteral; if( TermOpe( term, baseType, resultType, isLiteral, isNeedHeapFreeStructureStack[sp] ) ){ if(resultType.IsNull()){ //戻り値が存在しないとき for(i2=0;;i2++){ if(term[i2]=='('||term[i2]=='\0'){ term[i2]=0; break; } } compiler.errorMessenger.Output(38,term,cp); goto error; } type_stack[sp] = resultType.GetBasicType(); index_stack[sp] = resultType.GetIndex(); if( !isLiteral ){ bLiteralCalculation=0; } if( resultType.GetBasicType() & FLAG_CAST ){ // 型名のみ compiler.errorMessenger.OutputFatalError(); } else{ if( resultType.IsReal() ){ //sub esp,size //fstp ptr[esp] compiler.codeGenerator.op_fstp_push( resultType ); } else{ if( resultType.Is64() ){ //push edx compiler.codeGenerator.op_push( REG_EDX ); } else{ ExtendTypeTo32( resultType.GetBasicType(), REG_EAX ); } //push eax compiler.codeGenerator.op_push( REG_EAX ); } } sp++; break; } // Nothing if( lstrcmp( term, "Nothing" ) == 0 ){ isNothing_stack[sp] = true; if( baseType.IsObject() ){ type_stack[sp] = DEF_OBJECT; index_stack[sp] = baseType.GetIndex(); } else{ type_stack[sp] = baseType.GetBasicType(); index_stack[sp] = baseType.GetIndex(); } bLiteralCalculation = 0; //push 0 compiler.codeGenerator.op_push_V( 0 ); sp++; break; } ////////////// // 定数の場合 ////////////// i3 = compiler.GetObjectModule().meta.GetGlobalConsts().GetBasicType( ActiveBasic::Compiler::LexicalAnalyzer::FullNameToSymbol( term ) ); if(i3){ if( compiler.GetObjectModule().meta.GetGlobalConsts().IsStringPtr( ActiveBasic::Compiler::LexicalAnalyzer::FullNameToSymbol( term ), compiler.IsUnicode() ) ){ //リテラル文字列 if( baseType.IsObject() || baseType.IsNull() ) { //要求タイプがオブジェクト、または未定のとき //String型オブジェクトを生成 NewStringObject(term); type_stack[sp]=DEF_OBJECT; index_stack[sp]=(LONG_PTR)compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr(); bLiteralCalculation=0; sp++; break; } double dbl = compiler.GetObjectModule().meta.GetGlobalConsts().GetDoubleData( ActiveBasic::Compiler::LexicalAnalyzer::FullNameToSymbol( term ) ); memcpy(&i64data,&dbl,sizeof(double)); //バイト数 i3=lstrlen((char *)i64data); memcpy(term,(char *)i64data,i3); term[i3]=0; goto StrLiteral; } type_stack[sp]=i3; if(IsRealNumberType(i3)){ //実数 double dbl = compiler.GetObjectModule().meta.GetGlobalConsts().GetDoubleData( ActiveBasic::Compiler::LexicalAnalyzer::FullNameToSymbol( term ) ); memcpy(&i64data,&dbl,sizeof(double)); goto Literal; } else if(IsWholeNumberType(i3)){ //整数 i64data = compiler.GetObjectModule().meta.GetGlobalConsts().GetWholeData( ActiveBasic::Compiler::LexicalAnalyzer::FullNameToSymbol( term ) ); goto Literal; } else{ compiler.errorMessenger.Output(300,NULL,cp); goto error; } } //該当する識別子が見当たらないときはエラー扱いにする bError=1; compiler.errorMessenger.Output(3,term,cp); type_stack[sp]=DEF_DOUBLE; } else{ //リテラル値 type_stack[sp]=GetLiteralValue(term,&i64data,baseType.GetBasicType()); Literal: if(type_stack[sp]==DEF_INT64|| type_stack[sp]==DEF_QWORD|| type_stack[sp]==DEF_DOUBLE){ //64ビット(符号有り整数/実数) //push HILONG(dbl) compiler.codeGenerator.op_push_V((long)*(long *)(((char *)(&i64data))+4)); //push LOLONG(dbl) compiler.codeGenerator.op_push_V(*(long *)(&i64data)); } else if(type_stack[sp]==DEF_SINGLE){ //single実数 float flt; memcpy(&dbl,&i64data,sizeof(double)); flt=(float)dbl; memcpy(&i3,&flt,sizeof(long)); //push term compiler.codeGenerator.op_push_V(i3); } else{ //その他 //push term compiler.codeGenerator.op_push_V((long)i64data); if((long)i64data==0) index_stack[sp]=LITERAL_NULL; } //リテラル値の種類 if(Is64Type(type_stack[sp])==0&&IsRealNumberType(type_stack[sp])==0){ //整数(符号有り/無し) index_stack[sp]=GetLiteralIndex(i64data); } } sp++; break; //論理演算子 case CALC_XOR: //value[sp-2] xor= value[sp-1] //xor演算 if(!Calc_Xor(type_stack,index_stack,&sp)) goto error; break; case CALC_OR: //value[sp-2] or= value[sp-1] //or演算 if(!Calc_Or(type_stack,index_stack,&sp)) goto error; break; case CALC_AND: //value[sp-2] and= value[sp-1] //and演算 if(!Calc_And(type_stack,index_stack,&sp)) goto error; break; case CALC_NOT: //value[sp-1]=Not value[sp-1] //NOT演算子 if(!Calc_Not(type_stack,sp)) goto error; break; //比較演算子 case CALC_PE: //value[sp-2]<=value[sp-1] if(!Calc_Relation_PE(type_stack,index_stack,&sp)) goto error; break; case CALC_QE: //value[sp-2]>=value[sp-1] if(!Calc_Relation_QE(type_stack,index_stack,&sp)) goto error; break; case CALC_P: //value[sp-2]value[sp-1] if(!Calc_Relation_Q(type_stack,index_stack,&sp)) goto error; break; case CALC_NOTEQUAL: //value[sp-2]<>value[sp-1] if(!Calc_Relation_NotEqual(type_stack,&sp)) goto error; break; case CALC_EQUAL: //value[sp-2]=value[sp-1] if(!Calc_Relation_Equal(type_stack,&sp)) goto error; break; //ビットシフト case CALC_SHL: //value[sp-2]=value[sp-2]<>value[sp-1] if(!Calc_SHR(type_stack,&sp)) goto error; break; //算術演算 case CALC_ADDITION: case CALC_SUBTRACTION: case CALC_PRODUCT: if(!CalcTwoTerm_Arithmetic(idCalc,type_stack,index_stack,&sp)) goto error; break; case CALC_MOD: //value[sp-2]%=value[sp-1] //剰余演算 if(!Calc_Mod(type_stack,&sp)) goto error; break; case CALC_QUOTIENT: //value[sp-2]/=value[sp-1]; //除算 if(!Calc_Divide(type_stack,&sp,baseType.GetBasicType())) goto error; break; case CALC_INTQUOTIENT: //value[sp-2]/=value[sp-1] //整数除算 if(!Calc_IntDivide(type_stack,index_stack,&sp)) goto error; break; case CALC_MINUSMARK: //value[sp-1]=-value[sp-1] //符号反転 if(!Calc_MinusMark(type_stack,sp)) goto error; index_stack[sp-1]=-1; break; case CALC_POWER: //べき乗演算(浮動小数点演算のみ) if(!Calc_Power(type_stack,&sp)) goto error; break; case CALC_AS: //キャスト if(!Calc_Cast(type_stack,index_stack,&sp)) goto error; break; case CALC_BYVAL: //ポインタ型→参照型 if( PTR_LEVEL( type_stack[sp-1] ) <= 0 ){ //ポインタ型ではないとき compiler.errorMessenger.Output( 1, NULL, cp ); goto error; } type_stack[sp-1] = PTR_LEVEL_DOWN( type_stack[sp-1] ); break; default: compiler.errorMessenger.Output(300,NULL,cp); goto error; } } if(bError) goto error; if(sp!=1){ compiler.errorMessenger.Output(1,NULL,cp); goto error; } if(bLiteralCalculation){ //右辺値が数値の定数式の場合 compiler.errorMessenger.OutputFatalError(); } else{ //右辺値が数値の定数式ではないとき if(IS_LITERAL(index_stack[0])) index_stack[0]=-1; } if(pbIsNeedHeapFreeStructure) { *pbIsNeedHeapFreeStructure = isNeedHeapFreeStructureStack[0]; } resultType.SetType( type_stack[0], index_stack[0] ); bool isSuccessful = true; goto finish; error: isSuccessful = false; goto finish; finish: for(i=0;i