#include "stdafx.h" using namespace ActiveBasic::Compiler; void LexicalAnalyzer::AddConstEnum( Consts &consts, const NamespaceScopes &namespaceScopes, const char *buffer ) { extern int cp; int i=0,i2; if(!(buffer[i]==1&&buffer[i+1]==ESC_ENUM)) return; i+=2; //列挙体の名前を取得 char temporary[VN_SIZE]; for(i2=0;;i++,i2++){ if(IsCommandDelimitation(buffer[i])){ temporary[i2]=0; break; } if(!IsVariableChar(buffer[i])){ compiler.errorMessenger.Output(1,NULL,i); break; } temporary[i2]=buffer[i]; } if(buffer[i]=='\0'){ compiler.errorMessenger.Output(22,"Enum",cp); return; } int NextValue=0; while(1){ i++; if(buffer[i]==1&&buffer[i+1]==ESC_ENDENUM) break; for(i2=0;;i2++,i++){ if(IsCommandDelimitation(buffer[i])){ temporary[i2]=0; break; } if(buffer[i]=='='){ temporary[i2]=0; break; } temporary[i2]=buffer[i]; } if(temporary[0]=='\0'){ if(buffer[i]=='\0'){ compiler.errorMessenger.Output(22,"Enum",cp); break; } continue; } if(buffer[i]!='='){ NextValue++; } else{ char temp2[VN_SIZE]; for(i++,i2=0;;i2++,i++){ if(IsCommandDelimitation(buffer[i])){ temp2[i2]=0; break; } temp2[i2]=buffer[i]; } _int64 i64data; StaticCalculation(true, temp2,DEF_LONG,&i64data,Type()); NextValue=(int)i64data; } //定数を追加 consts.Add( Symbol( namespaceScopes, temporary ), NextValue); } } void LexicalAnalyzer::CollectConsts( const char *source, Consts &consts, ConstMacros &constMacros ) { //////////////////////////////////////////// // Const命令の情報を取得 //////////////////////////////////////////// int i2; // 名前空間管理 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes(); namespaceScopes.clear(); for (int i = 0; ; ++i) { if( source[i] == '\0' ) break; if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){ i+=2; char const* p = &source[i]; while (!IsCommandDelimitation(source[i])) { ++i; } namespaceScopes.push_back(std::string(p, &source[i])); 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; } if( source[i] == 1 ){ if(source[i]==1&&source[i+1]==ESC_CONST){ i+=2; extern int cp; cp=i; //エラー用 if(source[i]==1&&source[i+1]==ESC_ENUM){ AddConstEnum( consts, namespaceScopes, source+i); continue; } char const* beginTemp = &source[i]; char const* endTemp = &source[i]; for(i2=0;;i++,i2++){ if(source[i]=='\"'){ for(i++,i2++;;i++,i2++){ if(source[i]=='\"') break; } continue; } if(IsCommandDelimitation(source[i])){ endTemp = beginTemp + i2; break; } } //名前を取得 char const* nameEnd; for(i2=0;;i2++){ if(beginTemp[i2]=='\0'){ compiler.errorMessenger.Output(10,"Const",cp); return; } if(beginTemp[i2]=='='||beginTemp[i2]=='('){ nameEnd = beginTemp + i2; break; } } std::string name(beginTemp, nameEnd); //重複チェック if( compiler.GetObjectModule().meta.GetGlobalConstMacros().IsExistDuplicationKeyName( name ) || compiler.GetObjectModule().meta.GetGlobalConsts().IsExistDuplicationKeyName( name ) ) { compiler.errorMessenger.Output(15, name, cp); return; } if( beginTemp[i2] == '=' ) { // 定数 std::string expression(beginTemp + i2 + 1, endTemp); _int64 i64data; Type resultType; if( StaticCalculation(false, expression.c_str(), 0, &i64data, resultType) ) { consts.Add( Symbol( namespaceScopes, name ), i64data, resultType ); } } else { // 定数マクロ std::string params(beginTemp + i2, endTemp); if( !constMacros.Add( Symbol( namespaceScopes, name ), params.c_str() ) ) { compiler.errorMessenger.Output( 1, NULL, i ); } } if(source[i]=='\0') break; } else{ int result = JumpStatement( source, i ); if( result == -1 ){ //エラー return; } else if( result == 1 ){ //ジャンプした場合 i--; } } } } } bool LexicalAnalyzer::ConstMacroToExpression( const ConstMacro &constMacro, const char *parameterStr, char *dest, std::size_t destSize ) { std::string s; auto ret = ConstMacroToExpression(constMacro, parameterStr, s); strcpy_s(dest, destSize, s.c_str()); return ret; } bool LexicalAnalyzer::ConstMacroToExpression( const ConstMacro &constMacro, const char *parameterStr, std::string& dest ) { int i2,i3; char temporary[VN_SIZE]; std::vector Parms; dest.reserve(8192); i2=0; while(1){ i2=GetOneParameter(parameterStr,i2,temporary); Parms.push_back(temporary); if(parameterStr[i2]=='\0') break; } if( Parms.size() != constMacro.GetParameters().size() ){ extern int cp; compiler.errorMessenger.Output(10,constMacro.GetName().c_str(),cp); dest = '0'; return true; } i2=0; while(1){ //数式内の項を取得 for(i3=0;;i2++,i3++){ if(!IsVariableChar( constMacro.GetExpression()[i2] )){ temporary[i3]=0; break; } temporary[i3] = constMacro.GetExpression()[i2]; } //パラメータと照合する for( i3=0; i3<(int)constMacro.GetParameters().size(); i3++ ){ if( constMacro.GetParameters()[i3] == temporary ) break; } if( i3 == (int)constMacro.GetParameters().size() ){ //パラメータでないとき dest += temporary; } else{ //パラメータのとき dest += Parms[i3]; } //演算子をコピー for(;;i2++){ if( constMacro.GetExpression()[i2] == 1 ){ dest += constMacro.GetExpression()[i2++]; dest += constMacro.GetExpression()[i2]; continue; } if(IsVariableTopChar( constMacro.GetExpression()[i2] )) break; dest += constMacro.GetExpression()[i2]; if( constMacro.GetExpression()[i2] == '\0' ) break; } if( constMacro.GetExpression()[i2] == '\0' ) break; } return true; }