Index: BasicCompiler_Common/src/Source.cpp
===================================================================
--- BasicCompiler_Common/src/Source.cpp	(revision 87)
+++ BasicCompiler_Common/src/Source.cpp	(revision 88)
@@ -1,26 +1,843 @@
 #include <Source.h>
 
+#include "../common.h"
+#include <windows.h>
+
+
+
+class CDefine{
+	vector<string> names;
+public:
+	CDefine();
+	~CDefine();
+	void Free();
+	void Init();
+
+	BOOL add(char *name);
+	BOOL undef(char *name);
+	BOOL check(char *name);
+	void preprocessor_ifdef(char *buffer,bool isNot);
+	void DirectiveIfdef(char *buffer);
+};
+CDefine objDefine;
+
+
+//////////////////////////////////////
+// #requireの管理
+//////////////////////////////////////
+class CRequireFiles{
+	char **ppFilePath;
+	int count;
+public:
+	CRequireFiles(){
+		ppFilePath = (char **)malloc( 1 );
+		count = 0;
+	}
+	~CRequireFiles(){
+		for( int i = 0; i < count; i++ ){
+			free( ppFilePath[i] );
+		}
+		free( ppFilePath );
+	}
+	void clear(){
+		for( int i = 0; i < count; i++ ){
+			free( ppFilePath[i] );
+		}
+		free( ppFilePath );
+
+		ppFilePath = (char **)malloc( 1 );
+		count = 0;
+	}
+	bool IsIncluded( const char *includeFilePath ){
+		// '/' → '\\'
+		char tempPath[MAX_PATH];
+		lstrcpy( tempPath, includeFilePath );
+		for( int i=0; tempPath[i]; i++ ){
+			if( tempPath[i] == '/' ){
+				tempPath[i] = '\\';
+			}
+		}
+
+		for( int i=0; i<count; i++ ){
+			if( lstrcmpi( ppFilePath[i], tempPath ) == 0 ){
+				return true;
+			}
+		}
+		return false;
+	}
+	void Add( const char *includeFilePath ){
+		// '/' → '\\'
+		char tempPath[MAX_PATH];
+		lstrcpy( tempPath, includeFilePath );
+		for( int i=0; tempPath[i]; i++ ){
+			if( tempPath[i] == '/' ){
+				tempPath[i] = '\\';
+			}
+		}
+
+		//既に読み込まれているとき
+		if( IsIncluded( tempPath ) ) return;
+
+		//追加
+		ppFilePath = (char **)realloc(ppFilePath, ( count + 1 ) * sizeof(char *) );
+		ppFilePath[count] = (char *)malloc( lstrlen(tempPath) + 1 );
+		lstrcpy( ppFilePath[count], tempPath );
+		count++;
+	}
+};
+CRequireFiles requireFiles;
+
+
+//////////////////////////////////////
+// #define間するクラス
+//////////////////////////////////////
+
+CDefine::CDefine(){
+	Init();
+}
+CDefine::~CDefine(){
+}
+void CDefine::Init(){
+	names.clear();
+
+	extern BOOL bDebugCompile;
+	if(bDebugCompile) add("_DEBUG");
+
+#ifdef _AMD64_
+	add("_WIN64");
+#endif
+
+	extern BOOL bDll;
+	if( bDll ){
+		add("_DLL");
+	}
+
+	extern bool isUnicode;
+	if( isUnicode ){
+		add( "UNICODE" );
+	}
+
+	char temporary[255];
+	sprintf(temporary,"_AB_VER%d",MAJOR_VER);
+	add(temporary);
+}
+BOOL CDefine::add(char *name){
+	extern HANDLE hHeap;
+
+	//重複チェック
+	if(check(name)) return 0;
+
+	//追加
+	names.push_back( name );
+
+	return 1;
+}
+BOOL CDefine::undef(char *name){
+	vector<string>::iterator i = names.begin();
+	foreach( const string &temp, names ){
+		if( temp == name ){
+			names.erase( i );
+			return 1;
+		}
+		i++;
+	}
+
+	return 0;
+}
+BOOL CDefine::check(char *name){
+
+	//重複チェック
+	foreach( const string &temp, names ){
+		if( temp == name ){
+			return 1;
+		}
+	}
+	return 0;
+}
+
+int Search_endif(char *buffer,int i, int *pLine = 0){
+	for(;;i++){
+		if(buffer[i]=='\0') break;
+
+		if( buffer[i] == '\n' ){
+			if( pLine ){
+				(*pLine)++;
+			}
+		}
+
+		if(buffer[i-1]=='\n'){
+			if(memicmp(buffer+i,"#ifdef",6)==0||memicmp(buffer+i,"#ifndef",7)==0){
+				i=Search_endif(buffer,i+6, pLine);
+				if(buffer[i]=='\0') break;
+				continue;
+			}
+			else if(memicmp(buffer+i,"#endif",6)==0){
+				break;
+			}
+		}
+	}
+	return i;
+}
+
+void CDefine::preprocessor_ifdef(char *buffer,bool isNot){
+	int i,i2,i3;
+	char temporary[VN_SIZE];
+
+	if(isNot) i=lstrlen("#ifndef");
+	else i=lstrlen("#ifdef");
+	while(buffer[i]==' '||buffer[i]=='\t') i++;
+
+	for(i2=0;;i++,i2++){
+		if(buffer[i]=='\n'||buffer[i]=='\0'){
+			temporary[i2]=0;
+			break;
+		}
+		temporary[i2]=buffer[i];
+	}
+
+	int sw=0;
+	if(check(temporary)) sw=1;
+
+	if(isNot){
+		//#ifndefのとき（反対にする）
+		if(sw) sw=0;
+		else sw=1;
+	}
+
+	//#ifdefの行を消去
+	SlideString(buffer+i,-i);
+	i=0;
+
+	BOOL bElse=0;
+	if(sw){
+		//TRUEのとき
+
+		//#else、#endifを探索
+		for(;;i++){
+			if(buffer[i]=='\0') break;
+
+			if(i==0||buffer[i-1]=='\n'){
+				if(memicmp(buffer+i,"#ifdef",6)==0||memicmp(buffer+i,"#ifndef",7)==0){
+					i=Search_endif(buffer,i+6);
+					if(buffer[i]=='\0') break;
+					continue;
+				}
+				else if(memicmp(buffer+i,"#else",5)==0){
+					i2=5;
+					bElse=1;
+					break;
+				}
+				else if(memicmp(buffer+i,"#endif",6)==0){
+					i2=6;
+					bElse=0;
+					break;
+				}
+			}
+		}
+
+		//行を消去
+		SlideString(buffer+i+i2,-i2);
+
+		if(bElse){
+			//#elseがある場合はその区間を消去
+
+			for(i2=i,i3=0;;i2++){
+				if(buffer[i2]=='\0') break;
+
+				if(buffer[i2]=='\n') i3++;
+
+				if(i2==0||buffer[i2-1]=='\n'){
+					if(memicmp(buffer+i2,"#ifdef",6)==0||memicmp(buffer+i2,"#ifndef",7)==0){
+						i2=Search_endif(buffer,i2+6, &i3 );
+						if(buffer[i2]=='\0') break;
+						continue;
+					}
+					if(memicmp(buffer+i2,"#endif",6)==0){
+						i2+=6;
+						break;
+					}
+				}
+			}
+
+			//ソースコード区間を消去し、改行コードを挿入
+			SlideString(buffer+i2,i-i2+i3);
+			memset(buffer+i,'\n',i3);
+		}
+	}
+	else{
+		//FALSEのとき
+
+		//#else、#endifを探索
+		for(i2=i,i3=0;;i2++){
+			if(buffer[i2]=='\0') break;
+
+			if(buffer[i2]=='\n') i3++;
+
+			if(i2==0||buffer[i2-1]=='\n'){
+				if(memicmp(buffer+i2,"#ifdef",6)==0||memicmp(buffer+i2,"#ifndef",7)==0){
+					i2=Search_endif(buffer,i2+6, &i3 );
+					if(buffer[i2]=='\0') break;
+					continue;
+				}
+				else if(memicmp(buffer+i2,"#else",5)==0){
+					i2+=5;
+					bElse=1;
+					break;
+				}
+				else if(memicmp(buffer+i2,"#endif",6)==0){
+					i2+=6;
+					bElse=0;
+					break;
+				}
+			}
+		}
+
+		//ソースコード区間を消去し、改行コードを挿入
+		SlideString(buffer+i2,i-i2+i3);
+		memset(buffer+i,'\n',i3);
+
+		if(bElse){
+			//#endifを探索
+			for(;;i++){
+				if(buffer[i]=='\0') break;
+
+				if(i==0||buffer[i-1]=='\n'){
+					if(memicmp(buffer+i,"#ifdef",6)==0||memicmp(buffer+i,"#ifndef",7)==0){
+						i=Search_endif(buffer,i+6);
+						if(buffer[i]=='\0') break;
+						continue;
+					}
+					else if(memicmp(buffer+i,"#endif",6)==0){
+						i2=6;
+						bElse=0;
+						break;
+					}
+				}
+			}
+
+			//行を消去
+			SlideString(buffer+i+i2,-i2);
+		}
+	}
+}
+
+
+void CDefine::DirectiveIfdef(char *buffer){
+	int i,i2,i3,sw;
+	char temporary[VN_SIZE];
+
+	for(i=0;;i++){
+		if(buffer[i]=='\0') break;
+
+		if(i==0||(i>=1&&buffer[i-1]=='\n')){
+			sw=0;
+			if(memicmp(buffer+i,"#define",7)==0){
+				i2=i+7;
+				while(buffer[i2]==' '||buffer[i2]=='\t') i2++;
+
+				for(i3=0;;i2++,i3++){
+					if(buffer[i2]=='\n'||buffer[i2]=='\0'){
+						temporary[i3]=0;
+						break;
+					}
+					temporary[i3]=buffer[i2];
+				}
+
+				add(temporary);
+
+				i2-=i;
+
+				//ディレクティブを消去
+				SlideString(buffer+i+i2,-i2);
+			}
+			if(memicmp(buffer+i,"#undef",6)==0){
+				i2=i+7;
+				while(buffer[i2]==' '||buffer[i2]=='\t') i2++;
+
+				for(i3=0;;i2++,i3++){
+					if(buffer[i2]=='\n'||buffer[i2]=='\0'){
+						temporary[i3]=0;
+						break;
+					}
+					temporary[i3]=buffer[i2];
+				}
+
+				undef(temporary);
+
+				i2-=i;
+
+				//ディレクティブを消去
+				SlideString(buffer+i+i2,-i2);
+			}
+			else if(memicmp(buffer+i,"#ifdef",6)==0){
+				preprocessor_ifdef(buffer+i,false);
+				continue;
+			}
+			else if(memicmp(buffer+i,"#ifndef",7)==0){
+				preprocessor_ifdef(buffer+i,true);
+				continue;
+			}
+			else continue;
+		}
+	}
+}
+
+
+
+
 bool Text::ReadFile( const string &filePath ){
+	//ファイルオープン
+	HANDLE hFile=CreateFile(filePath.c_str(),GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
+	if(hFile==INVALID_HANDLE_VALUE){
+		return false;
+	}
+
+	length = GetFileSize( hFile, NULL );
+
+	buffer = (char *)realloc( buffer, length + 1 );
+
+	//読み込み
+	DWORD dwAccBytes;
+	::ReadFile(hFile,buffer,length,&dwAccBytes,0);
+	buffer[dwAccBytes]=0;
+
+	//ファイルクローズ
+	CloseHandle(hFile);
+
 	return true;
 }
 
-void Text::ChangeReturnLineChar(){
-}
-
+void BasicSource::ChangeReturnLineChar(){
+#ifdef _DEBUG
+	//改行コードの整合性チェック
+	for( int i=0; ; i++ ){
+		if( buffer[i] == '\0' ){
+			break;
+		}
+		if( buffer[i]!='\r' && buffer[i+1]=='\n'
+			||  buffer[i]=='\r' && buffer[i+1]!='\n' ){
+				char temporary[255];
+				strncpy( temporary, buffer + i-100, 130 );
+				temporary[130] = 0;
+				for(int i2=0; ;i2++){
+					if(temporary[i2]=='\r') temporary[i2]='A';
+					if(temporary[i2]=='\n') temporary[i2]='B';
+					if(temporary[i2]=='\0') break;
+				}
+
+				extern HWND hOwnerEditor;
+				MessageBox( hOwnerEditor, temporary, "改行コードの整合性チェック", MB_OK | MB_ICONEXCLAMATION );
+		}
+	}
+#endif
+
+	//改行コードのCRLFをLFに変換
+	int i,i2;
+	for(i=0,i2=0;;i++,i2++){
+		if(buffer[i]=='\r'&&buffer[i+1]=='\n') i++;
+		buffer[i2]=buffer[i];
+		if(buffer[i]=='\0') break;
+	}
+
+	length = i;
+}
 
 void BasicSource::RemoveComments(){
-}
-
-void BasicSource::DirectiveIfdef(){
-}
+	int i,i2,i3,IsStr;
+	char *temporary;
+	temporary=(char *)GlobalAlloc(GMEM_FIXED,lstrlen(buffer)+1);
+	for(i=0,i2=0,i3=0,IsStr=0;;i++,i2++){
+		if(buffer[i]=='\"') IsStr^=1;
+		if(buffer[i]=='\n'||buffer[i]=='\0'){
+			i2--;
+			while(temporary[i2]==' '||temporary[i2]=='\t') i2--;
+			i2++;
+
+			if(i3){
+				//複数行に渡る注釈文の中に改行が存在するとき
+				memset(temporary+i2,'\n',i3);
+				i2+=i3;
+				i3=0;
+			}
+		}
+		if(buffer[i]=='\''&&IsStr==0){
+			//注釈文
+			i2--;
+			while(temporary[i2]==' '||temporary[i2]=='\t') i2--;
+			i2++;
+			while(buffer[i]!='\n'&&buffer[i]!='\0') i++;
+		}
+		if(buffer[i]=='/'&&buffer[i+1]=='*'&&IsStr==0){
+			//注釈文（複数行）
+			i+=2;
+			i3=0;
+			while(!(buffer[i]=='*'&&buffer[i+1]=='/')){
+				if(buffer[i]=='\n') i3++;
+				if(buffer[i]=='\0') break;
+				i++;
+			}
+			if(buffer[i]){
+				i+=2;
+			}
+			i--;
+			i2--;
+			continue;
+		}
+		temporary[i2]=buffer[i];
+		if(buffer[i]=='\0') break;
+	}
+	lstrcpy(buffer,temporary);
+	GlobalFree(temporary);
+}
+
+bool BasicSource::ReadFile_InIncludeDirective( const string &filePath ){
+	if( !Text::ReadFile( filePath ) ){
+		return false;
+	}
+
+	// 改行コードをCRLFからLFに変換
+	ChangeReturnLineChar();
+
+	// コメントを削除
+	RemoveComments();
+
+	// #ifdefディレクティブを処理
+	objDefine.DirectiveIfdef( buffer );
+
+	// アンダーバーによる改行を正規表現に戻す
+	RemoveReturnLineUnderbar();
+
+	// ダミー改行をセット
+	Realloc( length + 2 );
+	SlideString( buffer, 2 );
+	buffer[0] = '\n';
+	buffer[1] = '\n';
+
+	return true;
+}
+
 void BasicSource::DirectiveIncludeOrRequire(){
-}
-
+	extern HANDLE hHeap;
+	extern char szIncludeDir[MAX_PATH];
+	extern char BasicCurDir[MAX_PATH];
+	extern INCLUDEFILEINFO IncludeFileInfo;
+	int i,i2,i3,sw1,LineNum,FileLayer[255],layer,LastFileByte[255];
+	char temporary[MAX_PATH],temp2[MAX_PATH+255],*LayerDir[255];
+
+	IncludeFileInfo.ppFileNames=(char **)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,sizeof(char *));
+	extern char SourceFileName[MAX_PATH];
+	IncludeFileInfo.ppFileNames[0]=(char *)HeapAlloc(hHeap,0,lstrlen(SourceFileName)+1);
+	lstrcpy(IncludeFileInfo.ppFileNames[0],SourceFileName);
+	IncludeFileInfo.FilesNum=1;
+
+	layer=0;
+	FileLayer[layer]=0;
+	LastFileByte[layer]=GetLength();
+	LineNum=0;
+
+	//参照ディレクトリ
+	LayerDir[0]=(char *)HeapAlloc(hHeap,0,lstrlen(BasicCurDir)+1);
+	lstrcpy(LayerDir[0],BasicCurDir);
+
+	for(i=0;;i++){
+		if(buffer[i]=='\0'){
+			IncludeFileInfo.LineOfFile[LineNum]=-1;
+			break;
+		}
+		if(buffer[i]=='\n'){
+			IncludeFileInfo.LineOfFile[LineNum]=FileLayer[layer];
+			LineNum++;
+		}
+		if(i>LastFileByte[layer]){
+			HeapDefaultFree(LayerDir[layer]);
+			layer--;
+		}
+		if((buffer[i-1]=='\n'||i==0)&&buffer[i]=='#'){
+			bool isRequire = false;
+			if(memcmp( buffer + i + 1, "include", 7 ) == 0
+				|| memcmp( buffer + i + 1, "require", 7 ) == 0){
+
+					//#requireの場合
+					if( buffer[i + 1] == 'r' ) isRequire = true;
+
+					i2=i+8;
+					while(buffer[i2]==' '||buffer[i2]=='\t') i2++;
+
+					if(buffer[i2]=='\"') sw1=0;
+					else if(buffer[i2]=='<') sw1=1;
+					i2++;
+
+					for(i3=0;;i2++,i3++){
+						if((buffer[i2]=='\"'&&sw1==0)||(buffer[i2]=='>'&&sw1==1)||buffer[i2]=='\n'||buffer[i2]=='\0'){
+							temporary[i3]=0;
+							break;
+						}
+						temporary[i3]=buffer[i2];
+					}
+					while(buffer[i2]!='\n'&&buffer[i2]!='\0') i2++;
+
+					if(sw1){
+						sprintf(temp2,"%s%s",szIncludeDir,temporary);
+						lstrcpy(temporary,temp2);
+					}
+					else GetFullPath(temporary,LayerDir[layer]);
+			}
+			else if(memcmp(buffer+i+1,"prompt",6)==0){
+				i2=i+7;
+				sprintf(temporary,"%sbasic\\prompt.sbp",szIncludeDir);
+			}
+			else if(memcmp(buffer+i+1,"N88BASIC",8)==0){
+				i2=i+9;
+				sprintf(temporary,"%sbasic\\prompt.sbp",szIncludeDir);
+			}
+			else if(memcmp(buffer+i+1,"console",7)==0){
+				//サブシステム タイプをCUIに変更
+				extern unsigned short TypeOfSubSystem;
+				TypeOfSubSystem=IMAGE_SUBSYSTEM_WINDOWS_CUI;
+
+				i2=i+8;
+				sprintf(temporary,"%sbasic\\dos_console.sbp",szIncludeDir);
+			}
+			else continue;
+
+			if(i){
+				//ディレクティブが消えるため、一行減ってしまうのを防ぐ（basic.sbpを除く）
+				SlideString(buffer+i2,1);
+				buffer[i2]='\n';
+				for(i3=0;i3<=layer;i3++) LastFileByte[i3]++;
+			}
+
+			IncludeFileInfo.ppFileNames=(char **)HeapReAlloc(hHeap,0,IncludeFileInfo.ppFileNames,(IncludeFileInfo.FilesNum+1)*sizeof(char *));
+			IncludeFileInfo.ppFileNames[IncludeFileInfo.FilesNum]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
+			lstrcpy(IncludeFileInfo.ppFileNames[IncludeFileInfo.FilesNum],temporary);
+
+			layer++;
+			FileLayer[layer]=IncludeFileInfo.FilesNum;
+			IncludeFileInfo.FilesNum++;
+
+			//#requireの場合では、既に読み込まれているファイルは読み込まないようにする
+			bool isFake = false;
+			if( isRequire ){
+				if( requireFiles.IsIncluded( temporary ) ){
+					//既に読み込まれているとき
+					isFake = true;
+				}
+			}
+
+			BasicSource source;
+
+			if( isFake ){
+				//既に読み込まれているときは空データ
+				source.SetBuffer( "" );
+			}
+			else{
+				//取り込まれたファイルを収集する
+				requireFiles.Add( temporary );
+
+				//インクルードファイルを読み込む
+				if( !source.ReadFile_InIncludeDirective( temporary ) ){
+					sprintf(temp2,"インクルードファイル \"%s\" をオープンできません",temporary);
+					SetError(-1,temp2,i);
+					break;
+				}
+			}
+
+			i3=lstrlen(buffer)+source.GetLength();
+			Realloc( i3 );
+			SlideString(buffer+i2,source.GetLength()+(i-i2));
+			memcpy(buffer+i,source.GetBuffer(),source.GetLength());
+
+			//新しい参照ディレクトリをセット
+			char temp4[MAX_PATH];
+			_splitpath(temporary,temp2,temp4,0,0);
+			lstrcat(temp2,temp4);
+			LayerDir[layer]=(char *)HeapAlloc(hHeap,0,lstrlen(temp2)+1);
+			lstrcpy(LayerDir[layer],temp2);
+
+			//ファイル範囲をスライド
+			LastFileByte[layer]=i+source.GetLength()-1;
+			for(i3=0;i3<layer;i3++) LastFileByte[i3]+=source.GetLength()+(i-i2);
+
+			i--;
+		}
+	}
+
+	HeapDefaultFree(LayerDir[0]);
+
+	length = lstrlen(buffer);
+}
+
+int KillReturnCode_InParameter(char *buffer,int *pRnum,char cBeginPare,char cEndPare){
+	int i,i2,i3,IsStr;
+
+	//カッコ'('直下の改行
+	while(buffer[0]=='\n'){
+		SlideString(buffer+1,-1);
+		(*pRnum)++;
+	}
+
+	for(i=0,IsStr=0;;i++){
+		if(IsDBCSLeadByte(buffer[i])&&buffer[i+1]){
+			i++;
+			continue;
+		}
+
+		if(buffer[i]=='\"') IsStr^=1;
+
+		if(buffer[i]=='\0') break;	//エラー
+		if(buffer[i]=='\n'){
+			i2=0;
+			i3=0;
+			while(buffer[i+i2]=='\n'){
+				i2++;
+				i3++;
+				while(buffer[i+i2]==' '||buffer[i+i2]=='\t') i2++;
+			}
+			while(buffer[i+i2]==' '||buffer[i+i2]=='\t') i2++;
+
+			if(buffer[i+i2]==cEndPare){
+				SlideString(buffer+i+i2,-i2);
+				(*pRnum)+=i3;
+				break;
+			}
+
+			//エラー
+			break;
+		}
+
+		if(buffer[i]==cBeginPare&&IsStr==0){
+			i++;
+			i2=KillReturnCode_InParameter(buffer+i,pRnum,cBeginPare,cEndPare);
+			i+=i2;
+			if(buffer[i]!=cEndPare) break;
+			continue;
+		}
+		if(buffer[i]==cEndPare&&IsStr==0) break;
+
+		if(buffer[i]==','&&buffer[i+1]=='\n'&&IsStr==0){
+			i++;
+			while(buffer[i]=='\n'){
+				SlideString(buffer+i+1,-1);
+				(*pRnum)++;
+			}
+			i--;
+		}
+	}
+	return i;
+}
 void BasicSource::RemoveReturnLineUnderbar(){
-}
-
-void BasicSource::FormatDefStatement(){
-}
-void BasicSource::FormatIfStatement(){
+	int i,i2;
+
+	//アンダーバーによる改行
+	for(i=0;;i++){
+		i2=0;
+		while(buffer[i]=='_'&&buffer[i+1]=='\n'){
+			i2++;
+			SlideString(buffer+i+2,-2);
+			while(buffer[i]=='\n'){
+				SlideString(buffer+i+1,-1);
+				i2++;
+			}
+			for(;;i++){
+				if(buffer[i]=='_'&&buffer[i+1]=='\n') break;
+				if(buffer[i]=='\n'||buffer[i]=='\0'){
+					SlideString(buffer+i,i2);
+					memset(buffer+i,'\n',i2);
+					break;
+				}
+			}
+		}
+		if(buffer[i]=='\0') break;
+	}
+
+	//カッコ内パラメータの改行
+	int IsStr,rnum;
+	for(i=0,IsStr=0,rnum=0;;i++){
+		if(IsDBCSLeadByte(buffer[i])&&buffer[i+1]){
+			i++;
+			continue;
+		}
+		if(buffer[i]=='\0') break;
+		if(buffer[i]=='\n'){
+			if(rnum){
+				SlideString(buffer+i+1,rnum);
+				memset(buffer+i+1,'\n',rnum);
+				rnum=0;
+			}
+		}
+		if(buffer[i]=='\"') IsStr^=1;
+		if(buffer[i]=='('&&IsStr==0){
+			i++;
+			i2=KillReturnCode_InParameter(buffer+i,&rnum,'(',')');
+			i+=i2;
+			if(buffer[i]!=')') break;
+		}
+		if(buffer[i]=='['&&IsStr==0){
+			i++;
+			i2=KillReturnCode_InParameter(buffer+i,&rnum,'[',']');
+			i+=i2;
+			if(buffer[i]!=']') break;
+		}
+	}
+
+	length = lstrlen(buffer);
+}
+
+void BasicSource::SetBuffer( const char *buffer ){
+	this->buffer = (char *)calloc( lstrlen(buffer) + 1, 1 );
+	lstrcpy( this->buffer, buffer );
+	length = lstrlen(buffer);
+
+	// ダミー改行をセット
+	Realloc( length + 2 );
+	SlideString( this->buffer, 2 );
+	this->buffer[0] = '\n';
+	this->buffer[1] = '\n';
+}
+
+bool BasicSource::ReadFile( const string &filePath ){
+	if( !Text::ReadFile( filePath ) ){
+		return false;
+	}
+
+	// 改行コードをCRLFからLFに変換
+	ChangeReturnLineChar();
+
+	// basic.sbpをインクルード
+	const char *headCode = "#include <basic.sbp>\n";
+	Realloc( length + lstrlen(headCode) );
+	SlideString( buffer, lstrlen(headCode) );
+	memcpy( buffer, headCode, lstrlen(headCode) );
+
+	// #defineと#requireを初期化
+	objDefine.Init();
+	requireFiles.clear();
+
+	// コメントを削除
+	RemoveComments();
+
+	// #ifdefディレクティブを処理
+	objDefine.DirectiveIfdef( buffer );
+
+	//最終行には文字を含ませないようにする
+	Realloc( length + 1 );
+	lstrcat( buffer, "\n" );
+
+	// #include / #require ディレクティブを処理
+	DirectiveIncludeOrRequire();
+
+	// アンダーバーによる改行を正規表現に戻す
+	RemoveReturnLineUnderbar();
+
+	// ダミー改行をセット
+	Realloc( length + 2 );
+	SlideString( buffer, 2 );
+	buffer[0] = '\n';
+	buffer[1] = '\n';
+
+	extern char *basbuf;
+	basbuf = GetBuffer();
+
+	return true;
 }
 
@@ -28,2 +845,7 @@
 	return true;
 }
+
+void BasicSource::Addition( const char *buffer ){
+	Realloc( length + lstrlen(buffer) );
+	lstrcat( this->buffer, buffer );
+}
