📄 editdlg.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 + -