Скачиваний:
13
Добавлен:
01.05.2014
Размер:
10.16 Кб
Скачать
// CompilerDoc.cpp : implementation of the CCompilerDoc class
//
#include "stdafx.h"
#include "Compiler.h"
#include "CompilerDoc.h"

#include "Interfaces.h"
#include "LexAn.h"
#include "CodeGen.h"
#include "ErrorHandler.h"
#include "GenAsm.h"

#include <memory>

// Полезные операции с путями файлов
#include <shlwapi.h>
#pragma comment( lib, "shlwapi.lib" )


using namespace std;

//-----------------------------------------------------------------------------

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CCompilerDoc

IMPLEMENT_DYNCREATE(CCompilerDoc, CDocument)

BEGIN_MESSAGE_MAP(CCompilerDoc, CDocument)
	//{{AFX_MSG_MAP(CCompilerDoc)
	ON_COMMAND(ID_BUTTON_COMPILE, OnCompile)
	ON_COMMAND(ID_BUTTON_COMPILE_STOP, OnCompileStop)
	ON_COMMAND(ID_BUTTON_RUN, OnRun)
	ON_UPDATE_COMMAND_UI(ID_BUTTON_COMPILE, OnUpdateCompile)
	ON_UPDATE_COMMAND_UI(ID_BUTTON_COMPILE_STOP, OnUpdateCompileStop)
	ON_UPDATE_COMMAND_UI(ID_BUTTON_RUN, OnUpdateRun)
	ON_COMMAND(ID_VIEW_VIEWTABLES, OnViewtables)
    ON_COMMAND(ID_VIEW_TETRADS, OnViewTetrads)
    ON_COMMAND(ID_VIEW_ASM, OnViewAsm)

	ON_UPDATE_COMMAND_UI(ID_VIEW_VIEWTABLES, OnUpdateViewFiles)
    ON_UPDATE_COMMAND_UI(ID_VIEW_TETRADS,    OnUpdateViewFiles)
	ON_UPDATE_COMMAND_UI(ID_VIEW_ASM,        OnUpdateViewFiles)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CCompilerDoc construction/destruction

CCompilerDoc::CCompilerDoc()
{
	// TODO: add one-time construction code here
    m_bWorking     = false;
    m_bStopWorking = false;
}

CCompilerDoc::~CCompilerDoc()
{
}

BOOL CCompilerDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

	((CEditView*)m_viewList.GetHead())->SetWindowText(NULL);
    
	// TODO: add reinitialization code here
	// (SDI documents will reuse this document)

	return TRUE;
}

CEditView * CCompilerDoc::GetView()
{
    return (CEditView*)m_viewList.GetHead();
}


/////////////////////////////////////////////////////////////////////////////
// CCompilerDoc serialization

void CCompilerDoc::Serialize(CArchive& ar)
{
	// CEditView contains an edit control which handles all serialization
	((CEditView*)m_viewList.GetHead())->SerializeRaw(ar);
}

/////////////////////////////////////////////////////////////////////////////
// CCompilerDoc diagnostics

#ifdef _DEBUG
void CCompilerDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CCompilerDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CCompilerDoc commands

unsigned ThreadFunction(void *pVoid)
{
    CCompilerDoc *pDoc = (CCompilerDoc *) pVoid;

    CString SourceText;
    string  OutText;
    CLexAn  LexAn;
    CGenAsm GenAsm;
    std::auto_ptr<CCodeGen> pCodeGen(new CCodeGen);
    bool bCorrect = false;

    pDoc->GetView()->GetWindowText(SourceText);
    
    try
    {    
        LexAn.ProcessText(SourceText.GetBuffer(0), OutText);
        g_TableMgr.FPrintTables(  pDoc->GetFileNameTables() );
    
        pCodeGen->Analyze(g_TableMgr.GetTokenBegin(), g_TableMgr.GetTokenEnd(),
                          pDoc->GetFileNameTetrads());
        
        bCorrect = true;
    }
    catch(CCompilerException)
    {
        // ничего не делаем
    }

 //   g_pOutput->Printf("\r\nПрограмма синтаксически %sкорректна", bCorrect ? "" : "не");
    if (bCorrect)
    {
       // g_pOutput->Printf("\r\n\r\nГенерация ассемблерного кода...");
        GenAsm.GenerateAsmFile(pDoc->GetFileNameAsm(), pCodeGen->GetNameTable(), pCodeGen->GetTetrads());
        pDoc->CompileAndLink();
        //g_pOutput->Printf("\r\n\r\nВсе задачи выполнены");
    }

    g_TableMgr.Clear();
    g_ErrorHandler.Reset();

    pDoc->SetWorking(false);    // it must be last operator in this function

    return 0;
}
//-----------------------------------------------------------------------------
void CCompilerDoc::OnCompile() 
{
    if (!SaveFileIfNotSaved()) return;

    if (IsModified())
        AfxGetApp()->SaveAllModified();

    SetWorking( true );
//   g_pOutput->Clear();
//    g_pOutput->Printf("Starting compiler...\r\n\r\n");

    ::AfxBeginThread(ThreadFunction, this, NULL);
}

//-----------------------------------------------------------------------------

void CCompilerDoc::OnCompileStop() 
{
    m_bStopWorking = true;
}

void CCompilerDoc::OnRun() 
{
    CString sParams = "/K " + GetFileNameBase() + ".exe";

	if ( 32 >= (int)::ShellExecute(NULL, "open", "cmd", sParams, NULL, SW_SHOW) )
    {
        CString mes;
        mes.Format(_T("Can't execute %s"), (GetFileNameBase()+".exe").GetBuffer(0));
        AfxMessageBox(mes);
    }
}

//-----------------------------------------------------------------------------

void CCompilerDoc::OnUpdateCompile(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable( !IsWorking() );
}

void CCompilerDoc::OnUpdateCompileStop(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable( IsWorking() );
}

void CCompilerDoc::OnUpdateRun(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable( (!IsWorking()) && (GetPathName().GetLength() > 0) );
}

//-----------------------------------------------------------------------------

void CCompilerDoc::SetWorking( bool bWorking )
{ 
    m_bWorking = bWorking;
    m_bStopWorking = false;
    AfxGetMainWnd()->SendMessage(WM_USER_APP_SET_BUSY, bWorking ? 1 : 0);
}

//-----------------------------------------------------------------------------

void CCompilerDoc::OpenTextFile(const char * FileName)
{
    if (strlen(FileName) == 0) return;

    if ( 32 >= (int)::ShellExecute(NULL, "open", FileName, NULL, NULL, SW_SHOW) )
    {
        CString mes;
        mes.Format(_T("Can't open file %s"), FileName);
        AfxMessageBox(mes);
    }
}

//-----------------------------------------------------------------------------

void CCompilerDoc::OnViewtables() 
{
    OpenTextFile(GetFileNameTables());
}

//-----------------------------------------------------------------------------
void CCompilerDoc::OnViewTetrads() 
{
    OpenTextFile(GetFileNameTetrads());
}
//-----------------------------------------------------------------------------
void CCompilerDoc::OnViewAsm() 
{
    if ( 32 >= (int)::ShellExecute(NULL, "open", "notepad", GetFileNameAsm(), NULL, SW_SHOW) )
    {
        CString mes;
        mes.Format(_T("Can't open file %s"), GetFileNameAsm().GetBuffer(0));
        AfxMessageBox(mes);
    }
}
//-----------------------------------------------------------------------------
CString CCompilerDoc::GetFileNameBase()
{
    CString path = GetPathName();
    PathRemoveExtension(path.GetBuffer(0));
    path.ReleaseBuffer();
    return path;
}
//-----------------------------------------------------------------------------
CString CCompilerDoc::GetFileNameTables()
{   
    return GetFileNameBase() + "_tables.txt";
}
//-----------------------------------------------------------------------------
CString CCompilerDoc::GetFileNameTetrads()
{
    return GetFileNameBase() + "_tetrads.txt";
}
//-----------------------------------------------------------------------------
CString CCompilerDoc::GetFileNameAsm()
{
    return GetFileNameBase() + ".asm";
}
//-----------------------------------------------------------------------------
// Пока исходный файл не сохранен неизвестно какие файлы открывать
void CCompilerDoc::OnUpdateViewFiles(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable( GetPathName().GetLength() > 0 );
}
//-----------------------------------------------------------------------------
bool CCompilerDoc::SaveFileIfNotSaved()
{
	if (!IsModified() && (GetPathName().GetLength() > 0) )
		return true;        // ok to continue

    return (DoFileSave() == TRUE);
}
//-----------------------------------------------------------------------------
void CCompilerDoc::CompileAndLink()
{
    CString sOldPath, sFileBase, sFilePath, sBinPath, sParams;
    GetCurrentDirectory(MAX_PATH, sOldPath.GetBuffer(MAX_PATH));

    sFilePath = GetPathName();
    sFileBase = PathFindFileName(sFilePath.GetBuffer(0));
    GetModuleFileName(AfxGetApp()->m_hInstance, sBinPath.GetBuffer(MAX_PATH), MAX_PATH);

    PathRemoveFileSpec(sBinPath.GetBuffer(0));
    PathRemoveExtension(sFileBase.GetBuffer(0));
    PathRemoveFileSpec(sFilePath.GetBuffer(0));
    sBinPath.ReleaseBuffer();
    sFileBase.ReleaseBuffer();
    sFilePath.ReleaseBuffer();

    sBinPath += "\\bin\\";
    SetCurrentDirectory(sBinPath);

    //bcc -I..\INCLUDE -L..\LIB -eproga.exe RunTime.cpp %1

    //sParams = sFileBase + ".asm," + sFileBase + ".obj," + sFileBase + ".lst";
    sParams = "-IINCLUDE -LLIB -e" + sFilePath +"\\"+ sFileBase + ".exe " + "RunTime.cpp " + sFilePath +"\\"+ sFileBase + ".asm";

 //   g_pOutput->Printf("\r\n\r\nАссемблирование...");
	if ( 32 >= (int)::ShellExecute(NULL, "open", "bcc.exe", sParams, NULL, SW_SHOW) )
    {
        CString mes;
        mes.Format(_T("Can't compile file %s"), GetFileNameAsm().GetBuffer(0));
        AfxMessageBox(mes);
    }


//    g_pOutput->Printf("\r\nАссемблирование...");
//	if ( 32 >= (int)::ShellExecute(NULL, "open", sBinPath+"tasm.exe", sParams, NULL, SW_SHOW) )
//    {
//        CString mes;
//        mes.Format(_T("Can't compile file %s"), GetFileNameAsm().GetBuffer(0));
//        AfxMessageBox(mes);
//    }
//
//    sParams = sFileBase + ".obj";
//
//    g_pOutput->Printf("\r\nКомпоновка...");    
//	if ( 32 >= (int)::ShellExecute(NULL, "open", sBinPath+"tlink.exe", sParams, NULL, SW_SHOW) )
//    {
//        CString mes;
//        mes.Format(_T("Can't compile file %s"), GetFileNameAsm().GetBuffer(0));
//        AfxMessageBox(mes);
//    }

    SetCurrentDirectory(sOldPath);
}
//-----------------------------------------------------------------------------
Соседние файлы в папке Курсовая работа2