?? impubasicview.cpp
字號:
// IMPUBasicView.cpp : implementation of the CIMPUBasicView class
//
#include "stdafx.h"
#include "IMPUBasic語言程序設計器.h"
#include "IMPUBasic語言程序設計器Doc.h"
#include "IMPUBasicView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CIMPUBasicView
IMPLEMENT_DYNCREATE(CIMPUBasicView, CEditView)
BEGIN_MESSAGE_MAP(CIMPUBasicView, CEditView)
//{{AFX_MSG_MAP(CIMPUBasicView)
ON_COMMAND(ID_PROGRAM_RUN, OnProgramRun)
ON_COMMAND(ID_RESULT_VIEW, OnResultView)
ON_COMMAND(ID_HELP_VIEW, OnHelpView)
ON_WM_MOUSEMOVE()
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CEditView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CEditView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CEditView::OnFilePrintPreview)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CIMPUBasicView construction/destruction
CIMPUBasicView::CIMPUBasicView()
{
// TODO: add construction code here
}
CIMPUBasicView::~CIMPUBasicView()
{
}
BOOL CIMPUBasicView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
BOOL bPreCreated = CEditView::PreCreateWindow(cs);
cs.style &= ~(ES_AUTOHSCROLL|WS_HSCROLL); // Enable word-wrapping
return bPreCreated;
}
/////////////////////////////////////////////////////////////////////////////
// CIMPUBasicView drawing
void CIMPUBasicView::OnDraw(CDC* pDC)
{
CIMPUBasicDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
}
/////////////////////////////////////////////////////////////////////////////
// CIMPUBasicView printing
BOOL CIMPUBasicView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default CEditView preparation
return CEditView::OnPreparePrinting(pInfo);
}
void CIMPUBasicView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
{
// Default CEditView begin printing.
CEditView::OnBeginPrinting(pDC, pInfo);
}
void CIMPUBasicView::OnEndPrinting(CDC* pDC, CPrintInfo* pInfo)
{
// Default CEditView end printing
CEditView::OnEndPrinting(pDC, pInfo);
}
/////////////////////////////////////////////////////////////////////////////
// CIMPUBasicView diagnostics
#ifdef _DEBUG
void CIMPUBasicView::AssertValid() const
{
CEditView::AssertValid();
}
void CIMPUBasicView::Dump(CDumpContext& dc) const
{
CEditView::Dump(dc);
}
CIMPUBasicDoc* CIMPUBasicView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CIMPUBasicDoc)));
return (CIMPUBasicDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CIMPUBasicView message handlers
void CIMPUBasicView::OnProgramRun()
{
val_Edit1 = "";
CFile file;
CFileDialog fdlg(TRUE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,_T("Basic Files(*.bas)|*.bas||"),NULL);
CString strFilePath,strFileName;
if(fdlg.DoModal()==IDOK)
{
strFilePath = fdlg.GetPathName();
strFileName = fdlg.GetFileName();
}
if(strFileName!="")
{
file.Open(strFilePath,CFile::modeReadWrite);
char str[PROG_SIZE];
DWORD m_nLen = file.GetLength();
file.Read(&str,m_nLen);
str[m_nLen+1]='\0';
prog=str;
scan_labels();
do
{
token_type=get_token();
if(token_type==VARIABLE)
{
putback();
assignment();
}
else
switch(tok){
case PRINT: print(); break;
case INPUT: input(); break;
case IF: exec_if(); break;
case ELSE: exec_else(); break;
case ENDIF: exec_endif();break;
case FOR: exec_for(); break;
case NEXT: next(); break;
case WHILE: exec_while();break;
case WEND: wend(); break;
case GOTO: exec_goto(); break;
case GOSUB: gosub(); break;
case RETURN:greturn(); break;
case REM: rem(); break;
case DO: exec_do(); break;
case LOOP: exec_loop(); break;
case EXITDO:exitdo(); break;
case SELECT:exec_select();break;
case CASE: exec_case(); break;
case ENDSELECT:endselect();break;
case STOP: exec_stop(); break;
case ON: exec_on(); break;
case END: ;
}
}while(tok!=END);//
// return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
val_Edit2 += "* * * * * * * * * 歡迎使用IMPUBasic語言程序設計器* * * * * * * * * * * * * * * * * * * * * * * * * \r\n";
val_Edit2 += val_Edit1;
}
else
{
val_Edit1= "文件名為空!!!";
}
CRunDlg *m_RunDlg;
m_RunDlg = new CRunDlg(val_Edit1);
m_RunDlg->Create();
}
void CIMPUBasicView::OnResultView()
{
// TODO: Add your command handler code here
CRunResultDlg *m_RunResultDlg;
m_RunResultDlg = new CRunResultDlg(val_Edit2);
m_RunResultDlg->Create();
}
void CIMPUBasicView::OnHelpView()
{
// TODO: Add your command handler code here
CHelpDlg *m_HelpDlg;
m_HelpDlg = new CHelpDlg;
m_HelpDlg->Create();
}
void CIMPUBasicView::Error(int error)//錯誤提示庫
{
CString e[19]={
"語法錯誤!",
"插入不匹配!",
"表達式不存在!",
"賦值錯誤!",
"變量名不存在!",
"標號表已滿!",
"標號不匹配!",
"標號沒定義!",
"不是THEN!",
"不是TO!",
"NEXT沒有FOR!",
"RETURN 沒有GOSUB!",
"while缺少wend!",
"else 沒有 if!",
"endif 沒有 if!",
"if或else沒有endif!",
"do缺少loop!",
"loop缺少do!",
"case缺少select!"
};
val_Edit1 += e[error];
val_Edit1 += "\r\n";
}
int CIMPUBasicView::isdelim(CString c)//判斷字符是否是運算符或數字字符
{
CString m_str1 = "0123456789+-*%/^(<>,\r=;).Mod";
int i=m_str1.Find(c);
if (i>0)
return 1;
else
return 0;
}
int CIMPUBasicView::isdelim1(CString c)//判斷字符是否是運算符
{
CString m_str1 = "=+-*%/^(,\r;)\"Mod";
int i=m_str1.Find(c);
if (i>=0)
return 1;
else
return 0;
}
int CIMPUBasicView::iswhite(CString c)//判斷字符是否是空格或制表符
{
if(c==' '||c=='\t')
return 1;
else
return 0;
}
int CIMPUBasicView::look_up(CString str)
{
CCommands table[31];
table[0].command="print";
table[0].tok= PRINT;
table[1].command="input";
table[1].tok= INPUT;
table[2].command="if";
table[2].tok= IF;
table[3].command="then";
table[3].tok= THEN;
table[4].command="goto";
table[4].tok= GOTO;
table[5].command="for";
table[5].tok= FOR;
table[6].command="next";
table[6].tok= NEXT;
table[7].command="to";
table[7].tok= TO;
table[8].command="gosub";
table[8].tok= GOSUB;
table[9].command="return";
table[9].tok= RETURN;
table[10].command="while";
table[10].tok= WHILE;
table[11].command="wend";
table[11].tok= WEND;
table[12].command="end";
table[12].tok= END;
table[13].command="null";
table[13].tok= END;
table[14].command="endif";
table[14].tok= ENDIF;
table[15].command="else";
table[15].tok= ELSE;
table[16].command="rem";
table[16].tok= REM;
table[17].command="do";
table[17].tok= DO;
table[18].command="loop";
table[18].tok= LOOP;
table[19].command="exitdo";
table[19].tok= EXITDO;
table[20].command="until";
table[20].tok= UNTIL;
table[21].command="select";
table[21].tok= SELECT;
table[22].command="case";
table[22].tok= CASE;
table[23].command="endselect";
table[23].tok= ENDSELECT;
table[24].command="step";
table[24].tok= STEP;
table[25].command="is";
table[25].tok= IS;
table[26].command="stop";
table[26].tok= STOP;
table[27].command="on";
table[27].tok= ON;
table[28].command="and";
table[28].tok= AND;
table[29].command="or";
table[29].tok= OR;
table[30].command="not";
table[30].tok= NOT;
int i,j=0;
str.MakeLower();
for(i=0;i<31;i++)
{
int n=table[i].command.CompareNoCase(str);
if(n==0)
{
j=table[i].tok;
break;
}
else
j=0;
}
return j;
}
int CIMPUBasicView::get_token()//語句分解函數
{
char *temp;
token_type=0;
tok=0;
temp=token;
while(*temp!='\0')//將token[80]清空
{
*temp='\0';
temp++;
}
temp=token;
if(*prog=='\0')//判斷文件是否結束,結束將tok賦結束標志
{
*token='\0';
tok=FINISHED;
token_type=DELIMITER;
return(token_type);
}
while(iswhite(CString(*prog)))//處理空白符
++prog;
if(*prog=='\r')//處理回車換行符
{
++prog;
++prog;
tok=EOL;
*token='\r';
token[1]='\n';
token[2]='\0';
token_type=DELIMITER;
return(token_type);
}
if(isdelim2(CString(*prog)))//處理算數運算符
{
*temp++=*prog++;
*temp='\0';
token_type=DELIMITER;
return(token_type);
}
if(isdelim3(CString(*prog)))//處理關系運算符
{
while(isdelim3(CString(*prog)))*temp++=*prog++;
*temp='\0';
token_type=DELIMITER;
return(token_type);
}
if(*prog=='"')//處理空符
{
prog++;
while(*prog!='"'&&*prog!='\r')
*temp++=*prog++;
if(*prog=='\r')
Error(1);
prog++;*temp='\0';
token_type=QUOTE;
return(token_type);
}
if(isdigit(*prog))
{
while(!isdelim1(CString(*prog))&&*prog!=' ')
*temp++=*prog++;
*temp = '\0';
token_type=NUMBER;
return(token_type);
}
if (isalpha(*prog))
{
while (isalpha(*prog))
*temp++=*prog++;
token_type=STRING;
}
*temp='\0';
if(token_type==STRING){
tok=look_up(CString(token));
if(!tok)token_type=VARIABLE;
else token_type=COMMAND;
}
return token_type;
}
int CIMPUBasicView::isdelim2(CString c)//判斷字符是否是運算符
{
CString m_str1 = "+-*%/^(,;)";
int i=m_str1.Find(c);
if (i>=0)
return 1;
else
return 0;
}
int CIMPUBasicView::isdelim3(CString c)//判斷字符是否是運算符
{
CString m_str1 = "=><";
int i=m_str1.Find(c);
if (i>=0)
return 1;
else
return 0;
}
void CIMPUBasicView::get_exp(int *result)//表達式運算函數
{
get_token();
if(!*token)
{
Error(2);
return;
}
level2(result);
putback();
}
void CIMPUBasicView::level2(int *result)//計算+、-
{
char op;
int hold;
level3(result);
while((op=*token)=='+'||op=='-')
{
get_token();
level3(&hold);
arith(op,result,&hold);
}
}
void CIMPUBasicView::level3(int *result)//計算*、/、%
{
char op;
int hold;
level4(result);
while((op=*token)=='*'||op=='/'||op=='%')
{
get_token();
level4(&hold);
arith(op,result,&hold);
}
}
void CIMPUBasicView::level4(int *result)//計算^
{
int hold;
level5(result);
while(*token=='^'){
get_token();
level4(&hold);
arith('^',result,&hold);
}
}
void CIMPUBasicView::level5(int *result)//計算自+、-
{
char op;
op=0;
if((token_type==DELIMITER)&&*token=='+'||*token=='-')
{
op=*token;
get_token();
}
level6(result);
if(op)
unary(op,result);
}
void CIMPUBasicView::level6(int *result)//計算(
{
if((*token=='(')&&(token_type==DELIMITER))
{
get_token();
level2(result);
if(*token!=')')
Error(1);
get_token();
}
else
primitive(result);
}
void CIMPUBasicView::primitive(int *result)//處理變量、數字
{
switch(token_type){
case VARIABLE:
*result=find_var(token);
get_token();
return;
case NUMBER:
*result=atoi(token);
get_token();
return;
default:
Error(0);
}
}
void CIMPUBasicView::arith(char o, int *r, int *h)//算術運算
{
int t,ex;
switch(o){
case '-':
*r=*r-*h;
break;
case '+':
*r=*r+*h;
break;
case'*':
*r=*r**h;
break;
case '/':
*r=(*r)/(*h);
break;
case '%':
t=(*r)/(*h);
*r=*r-(t*(*h));
break;
case '^':
ex=*r;
if(*h==0){
*r=1;
break;
}
for(t=*h-1;t>0;--t)*r=(*r)*ex;
break;
}
}
void CIMPUBasicView::unary(char o, int *r)//負號運算
{
if(o=='-')
*r=-(*r);
}
int CIMPUBasicView::find_var(char *s)//返回變量值
{
if(!isalpha(*s)){
Error(4);
return 0;
}
return variables[toupper(*token)-'A'];
}
void CIMPUBasicView::putback()//文件指針后退一個單位
{
char *t;
t=token;
for(;*t;t++)prog--;
}
int CIMPUBasicView::assignment()//賦值函數
{
int var,value;
get_token();
if(!isalpha(*token)){
Error(4);
return 0;
}
var=toupper(*token)-'A';
get_token();
if(*token!='='){
Error(3);
return 0;
}
get_exp(&value);
variables[var]=value;
return 0;
}
void CIMPUBasicView::print()//關鍵字print
{
char m_buf[80];
int answer;
int len=0;
char last_delim;
do{
get_token();
if(tok==EOL||tok==FINISHED)
break;
if(token_type==QUOTE)
{
val_Edit1 += CString(token);
len++;
get_token();
}
else{
putback();
get_exp(&answer);
len++;
int m=sprintf(m_buf,"%d",answer);
val_Edit1 += CString(m_buf);
get_token();
}
last_delim=*token;
if(*token==';')
{
if(len<8)
val_Edit1 += "\t";
else
{
val_Edit1 += "\r\n";
len=0;
}
}
else if(*token==',')
val_Edit1 += " ";
else if(tok!=EOL&&tok!=FINISHED&&token_type!=COMMAND)
{
Error(0);
}
}while(*token==';'||*token==',');
if(tok==EOL||tok==FINISHED||token_type==COMMAND)
{
if(last_delim!=';'&&last_delim!=',')
val_Edit1 += "\r\n";
}
else
{
Error(0);
}
if(token_type==COMMAND)
putback();
}
void CIMPUBasicView::exec_if()//關鍵字if
{
int x,y,cond=0;
get_exp(&x);
get_token();
CString str1,str2;
str1=CString(token);
get_exp(&y);
cond=get_rel(x,str1,y);
get_token();
if(tok!=THEN)
{
Error(8);
return;
}
else
{
get_token();
if(token_type==COMMAND||token_type==NUMBER||token_type==VARIABLE)
{
if(!cond)
{
CString str = "MFALSE";
ifpush(str);
findeolelse();
}
else
{
CString str = "MTRUE";
ifpush(str);
putback();
}
}
else
{
putback();
if(!cond)
{
CString str = "FALSE";
ifpush(str);
findendifelse();
}
else
{
CString str = "TRUE";
ifpush(str);
}
}
}
}
void CIMPUBasicView::find_eol()//文件指針移向行尾
{
while(*prog!='\n'&&*prog!='\0')
++prog;
if (*prog)
prog++;
}
void CIMPUBasicView::exec_for()//關鍵字for
{
struct for_stack *i = new for_stack;
int value;
get_token();
if(!isalpha(*token))
{
Error(4);
return;
}
i->var=toupper(*token)-'A';
get_token();
if(*token!='=')
{
Error(3);
return;
}
get_exp(&value);
variables[i->var]=value;
get_token();
if(tok!=TO)
Error(9);
get_exp(&i->target);
get_token();
if(token_type==COMMAND)
{
CString str = "step";
CString str1 = CString(str);
int m=str.CompareNoCase(str1);
if(m==0)
{
get_exp(&i->step);
i->loc=prog;
}
else
{
putback();
i->step=1;
i->loc=prog;
}
}
else
{
putback();
i->step=1;
i->loc=prog;
}
fpush(i);
}
void CIMPUBasicView::next()//關鍵字next
{
struct for_stack *i = new for_stack;
i=fpop();
variables[i->var]=variables[i->var]+i->step;
if(variables[i->var]>i->target)
return;
fpush(i);
prog=i->loc;
}
void CIMPUBasicView::fpush(struct for_stack *i)//for入棧
{
fstack1.AddTail(i);
}
struct for_stack * CIMPUBasicView::fpop()//for彈棧
{
if(fstack1.IsEmpty())
{
Error(10);
return NULL;
}
else
{
for_stack *q=(for_stack *)fstack1.RemoveTail();
return q;
}
}
void CIMPUBasicView::exec_goto()//關鍵字goto
{
int i;
get_token();
i=find_label(CString(token));
if(i<0)
Error(7);
else
prog=label_table[i].p;
}
void CIMPUBasicView::label_init()//標號表初始化
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -