⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 editdlg.cpp

📁 一个简易的CPU模拟程序
💻 CPP
字号:
// EditDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "SimpleCPU.h"
#include "EditDlg.h"
#include ".\editdlg.h"

CString SampleStr=
"LOD 20\nADD 10\nSTA $8\nDIV $9\nJMP $6\nMUL 3\nNOP\nHALT\nDB 0\nDB  3";
OpCode opercode[]={
				{"ADD",ADD,true},
				{"SUB",SUB,true},
				{"MUL",MUL,true},
				{"DIV",DIV,true},
				{"HALT",HALT,false},
				{"JMP",JMP,true},
				{"STA",STA,true},
				{"LOD",LOD,true},
				{"NOP",NOP,false},
				{"DB",DB,true}
};
// CEditDlg 对话框
#define ERRORSTR(word,discrib) ("\""+word+"\"  :  "+discrib)

IMPLEMENT_DYNAMIC(CEditDlg, CDialog)
CEditDlg::CEditDlg(vector<Instruction> &InsList)
	: CDialog(CEditDlg::IDD, NULL)
{
	Empty=false;
	Success=false;
	InstructList=InsList;
}

CEditDlg::~CEditDlg()
{
}

void CEditDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_RICHEDIT21, CodeEdit);
	DDX_Control(pDX, IDC_LIST1, ErrorList);
}


BEGIN_MESSAGE_MAP(CEditDlg, CDialog)
	ON_BN_CLICKED(IDC_CHECK, OnBnClickedCheck)
	ON_NOTIFY(NM_DBLCLK, IDC_LIST1, OnNMDblclkList1)
	ON_BN_CLICKED(IDC_LOADSAM, OnBnClickedLoadsam)
	ON_BN_CLICKED(IDOK, OnBnClickedOk)
END_MESSAGE_MAP()


// CEditDlg 消息处理程序

BOOL CEditDlg::OnInitDialog()
{
	CDialog::OnInitDialog();
	ErrorList.SetExtendedStyle(LVS_EX_GRIDLINES|LVS_EX_FULLROWSELECT);
	LV_COLUMN lv;
	lv.mask=LVCF_TEXT|LVCF_FMT|LVCF_WIDTH;
	lv.fmt=LVCFMT_LEFT;
	lv.pszText="行数";
	lv.cx=50;
	ErrorList.InsertColumn(0,&lv);
	lv.cx=300;
	lv.pszText="错误信息";
	ErrorList.InsertColumn(1,&lv);

	CHARFORMAT cf;
	cf.dwMask=CFM_FACE|CFM_SIZE;
	lstrcpyn(cf.szFaceName,_T("Courier New"),32);
	cf.yHeight=200;
	CodeEdit.SetDefaultCharFormat(cf);
	CString source;
	for(int i=0;i<InstructList.size();i++)
	{
		source+=InstructList[i].instruct;
		source+="\n";
	}
	CodeEdit.SetWindowText(source);
	return TRUE;  // return TRUE unless you set the focus to a control
	// 异常: OCX 属性页应返回 FALSE
}

void CEditDlg::OnOK()
{
}

void CEditDlg::CheckCode(void)
{
	InstructList.clear();
	ErrorList.DeleteAllItems();
	int LineCount=CodeEdit.GetLineCount();
	bool flag=true;
	for(int i=0;i<LineCount;i++)
	{
		if(!Analysis(i))
		{
			flag=false;
			InsertList(i);
		}
		if(!Empty&&flag)
		{
			InstructList.push_back(instruct);
		}
	}
	if(flag)
		Success=CheckMemory();
	if(Success)
	{
		ErrorStr="检测成功";
		InsertList(0);
	}
}

void CEditDlg::OnBnClickedCheck()
{
	UpdateData();
	CheckCode();
}

OpCode * CEditDlg::FindOper(CString& oper)
{
	for(int i=0;i<sizeof(opercode)/sizeof(opercode[0]);i++)
	{
		if(opercode[i].oper==oper)
			return &opercode[i];
	}
	return 0;
}

BOOL CEditDlg::PreTranslateMessage(MSG* pMsg)
{
	if(GetFocus()==(CWnd*)&CodeEdit)
	{
		if(pMsg->message==WM_KEYDOWN&&pMsg->wParam==VK_TAB)
			pMsg->wParam=VK_SPACE;
	}
	return CDialog::PreTranslateMessage(pMsg);
}

void CEditDlg::InsertList(int LineNum)
{
	CString num;
	num.Format("%d",LineNum);
	int i=ErrorList.InsertItem(ErrorList.GetItemCount(),num);
	ErrorList.SetItemText(i,1,ErrorStr);
}

void CEditDlg::OnNMDblclkList1(NMHDR *pNMHDR, LRESULT *pResult)
{
	POSITION pos=ErrorList.GetFirstSelectedItemPosition();
	int index=ErrorList.GetNextSelectedItem(pos);
	CString num=ErrorList.GetItemText(index,0);
	int LineNum=atoi(num);
	CodeEdit.SetFocus();
	int vil=CodeEdit.GetFirstVisibleLine();
	CodeEdit.LineScroll(LineNum-vil-4,1);
	int p=CodeEdit.LineIndex(LineNum);
	CodeEdit.SetSel(p,p);
	ShowCaret ();
	*pResult = 0;
}

bool CEditDlg::IsData(char *str)
{
	if(*str=='$'||*str=='-')str++;
	while(*str!=0)
	{
		if(*str>'9'||*str<'0')
			return false;
		str++;
	}
	return true;
}
void CEditDlg::OnBnClickedLoadsam()
{
	CodeEdit.SetWindowText(SampleStr);
}

bool CEditDlg::Analysis(int Index)
{
	CString str[3];
	CString code;
	TCHAR src[50];

	Empty=false;
	int curpos=0;
	int part=0;
	CodeEdit.GetLine(Index,src,50);
	code=src;
	code=code.MakeUpper();
	code.Remove(13);

	str[part]=code.Tokenize(" ",curpos);
	while(str[part]!=""&&part<3)
	{
		part++;
		str[part]=code.Tokenize(" ",curpos);
	}
	if(part<=0) 
	{
		Empty=true;
		return true;
	}
	if(part>=3)
	{
		ErrorStr=ERRORSTR(str[3],"意外的行结尾");
		return false;
	}
	OpCode *opcode=FindOper(str[0]);
	if(!opcode) 
	{
		ErrorStr=ERRORSTR(str[0],"未定义的操作符");
		return false;
	}
	instruct.oper=opcode->indicate;
	instruct.instruct=code;
	instruct.addr=false;
	if(opcode->data)
	{
		if(part==1)
		{
			ErrorStr=ERRORSTR(str[0],"需要一个操作数");
			return false;
		}
		char *pstr=(char *)(PCSTR)str[1];
		if(str[1][0]=='$')
		{
			pstr++;
			instruct.addr=true;
		}
		if(IsData((char*)(PCSTR)str[1]))instruct.data=atoi(pstr);
		else 
		{
			ErrorStr=ERRORSTR(str[1],"不是操作数");
			return false;
		}
	}
	else if(part==2)
	{
		ErrorStr=ERRORSTR(str[0],"不能带操作数");
		return false;
	}
	return true;
}
bool CEditDlg::CheckMemory(void)
{
	bool Lineflag;
	bool Codeflag=true;
	int Max=InstructList.size();
	for(int i=0;i<Max;i++)
	{
		Lineflag=true;
		Instruction ins=InstructList[i];
		if(ins.oper==JMP)
		{
			if(ins.data>=Max)
			{
				ErrorStr=ERRORSTR(ins.instruct,"跳转到未定义地址单元");
				Lineflag=false;
			}
			else if(InstructList[ins.data].oper==DB)
			{
				ErrorStr=ERRORSTR(ins.instruct,"不能跳转到数据地址单元");
				Lineflag=false;
			}
		}
		else if(ins.addr)
		{
			if(ins.data>=Max)
			{
				ErrorStr=ERRORSTR(ins.instruct,"访问未定义地址单元");
				Lineflag=false;
			}
			else if(InstructList[ins.data].oper!=DB)
			{
				ErrorStr=ERRORSTR(ins.instruct,"不能访问指令地址单元");
				Lineflag=false;
			}
		}
		if(!Lineflag)
		{
			InsertList(i);
			Codeflag=false;
		}
	}
	return Codeflag;
}

void CEditDlg::OnBnClickedOk()
{
	OnBnClickedCheck();
	if(Success)
		CDialog::OnOK();
	else
		AfxMessageBox("代码有误,不能导入");
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -