📄 compiler.cpp
字号:
///////////////////////////////////////////////////////////////
// PL/0 Compiler Shell 0.14 (2003.12.30) [Source File]
// Author:Dwing
///////////////////////////////////////////////////////////////
#include"compiler.h" //For Shell
#include"stdio.h"
///////////////////////////////////////////////////////////////
HINSTANCE hinst; //Recent Instance
OPENFILENAME ofn; //For Open File Dialog
FILE *fp; //For Open File
zCompile *cp; //编译器对象指针
int asmnum=0; //目标代码数量
int errnum=0; //错误数量
char buf[65536]; //I/O Buffer
char bufERR[65536];
char str[512]; //File Name Buffer
char in[16];
char * p=in;
int digit;
//for syntex
zSyntax * s;
char text[65536]; //输入文法缓冲区
char out[65536]; //输出结果缓冲区
char str1[256],b[256]; //临时字串缓冲区
//for syntex end
#ifndef asm_
#define asm_
typedef struct //汇编指令格式
{
char opr; //指令操作码
char lvl; //级数
unsigned short adr; //地址码/操作数
}ASM;
#endif
enum{OP_LIT,OP_LOD,OP_STO,OP_CAL,OP_INT,OP_JMP,OP_JPC,OP_OPR};
enum{
OPR_RET,OPR_NEG,OPR_ADD,OPR_SUB,OPR_MUL,OPR_DIV,
OPR_ODD,OPR_NUL,OPR_EQL,OPR_NE ,OPR_LT ,OPR_LGE,
OPR_LG ,OPR_LTE,OPR_WRT,OPR_WRN,OPR_RED
};
///////////////////////////////////////////////////////////////
void _main() //Program Entry
{
//Get Instance Handle
hinst=GetModuleHandle(0);
//Main DialogBox
DialogBox(hinst,MAKEINTRESOURCE(IDD_MAINDLG),0,(DLGPROC)dlgproc);
}
///////////////////////////////////////////////////////////////
int getbase(int *s,int base,int lvl) //取基址
{
while(lvl--) base=s[base];
return base;
}
///////////////////////////////////////////////////////////////
//For MAIN DialogBox
BOOL CALLBACK dlgproc(HWND hdlg,UINT msg,WPARAM wparam,LPARAM lparam)
{
int i;int j;
int num;//for run
char b[4];//for run
ASM a[16384];//for run
switch(msg)
{
case WM_INITDIALOG:
buf[65535]=0; //结尾清0防止溢出
bufERR[65535]=0;
str[0]=0; //Clear str[]
//Set Window Text Font
SendDlgItemMessage(hdlg,IDC_INPUT,WM_SETFONT,(DWORD)GetStockObject(ANSI_FIXED_FONT),0);
SendDlgItemMessage(hdlg,IDC_ASM,WM_SETFONT,(DWORD)GetStockObject(SYSTEM_FIXED_FONT),0);
SendDlgItemMessage(hdlg,IDC_ERR,WM_SETFONT,(DWORD)GetStockObject(SYSTEM_FIXED_FONT),0);
//填充OPENFILENAME结构体
memset(&ofn,0,sizeof(OPENFILENAME)); //Clear it First
ofn.lStructSize=sizeof(OPENFILENAME);
ofn.hwndOwner=hdlg;
ofn.hInstance=hinst;
ofn.lpstrFilter="所有文件(*.*)\0*.*\0";
ofn.nMaxFile=511; //最大文件名缓冲区长度
ofn.lpstrFile=str; //使用临时字符串
ofn.Flags=OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST;
ofn.lpstrTitle="打开PL/0程序文件";
return 1;
case WM_COMMAND:
switch(LOWORD(wparam))
{
case ID_SYN:
DialogBox(hinst,MAKEINTRESOURCE(IDD_SYN),0,(DLGPROC)synproc);break;
case ID_COMPILE:
SetCursor(LoadCursor(0,IDC_WAIT)); //Please wait...
GetDlgItemText(hdlg,IDC_INPUT,buf,65535); //Get PL/0 Text
cp=new zCompile; //Let's begin to compile...
cp->compile(buf); //Do the most complex part
errnum=cp->geterr(bufERR); //Get Error Text
SetDlgItemText(hdlg,IDC_ERR,bufERR); //Display it
strcpy(bufERR,"运行结果为:\r\n");
asmnum=cp->getasm(buf); //Get ASM Text
SetDlgItemText(hdlg,IDC_ASM,buf); //Display it
delete cp; //The end of Compiling
SetCursor(LoadCursor(0,IDC_ARROW)); //Completed
break;
case ID_RUN://以下为模拟堆栈机执行代码
if(!asmnum)
MessageBox(hdlg,"请先编译后再运行!","错误",MB_ICONERROR);
else
if(errnum)
MessageBox(hdlg,"请先改正错误后再运行!","错误",MB_ICONERROR);
else
{
fp=fopen("temp.pl0","wb"); //Write to temp file
fprintf(fp,"%u\r\n",asmnum);
fwrite(buf,1,strlen(buf),fp);
fclose(fp);
//PL/0 Interpreter
fp=fopen("temp.pl0","rb");
if(!fp)
{
printf("PL/0 ASM Interpreter 0.1\n");
printf("Can't open \"temp.pl0\"!\n");
return 0;
}
fscanf(fp,"%u",&num);
for(i=0;i<num;i++)
{
fscanf(fp,"%*4u:%s%u%u",b,&a[i].lvl,&a[i].adr);
if(!strcmp(b,"LIT")) a[i].opr=OP_LIT;
if(!strcmp(b,"LOD")) a[i].opr=OP_LOD;
if(!strcmp(b,"STO")) a[i].opr=OP_STO;
if(!strcmp(b,"CAL")) a[i].opr=OP_CAL;
if(!strcmp(b,"INT")) a[i].opr=OP_INT;
if(!strcmp(b,"JMP")) a[i].opr=OP_JMP;
if(!strcmp(b,"JPC")) a[i].opr=OP_JPC;
if(!strcmp(b,"OPR")) a[i].opr=OP_OPR;
}
fclose(fp);
int s[16384]={0},bp=0,sp=3,ip=0;
do{
switch(a[ip].opr)
{
case OP_INT:sp+=a[ip].adr; break;
case OP_LIT:s[++sp]=a[ip].adr; break;
case OP_LOD:s[++sp]=s[getbase(s,bp,a[ip].lvl)+a[ip].adr];break;
case OP_STO:s[getbase(s,bp,a[ip].lvl)+a[ip].adr]=s[sp--];break;
case OP_JMP:ip=a[ip].adr-1; break;
case OP_JPC:if(!s[sp--]) ip=a[ip].adr-1; break;
case OP_CAL:
s[sp++]=getbase(s,bp,a[ip].lvl);//静态链
s[sp++]=bp; //动态链
s[sp++]=ip+1; //返回地址
bp=sp-3;
ip=a[ip].adr-1;
break;
case OP_OPR:
switch(a[ip].adr)
{
//过程返回
case OPR_RET:sp=bp; ip=s[bp+2]-1; bp=s[bp+1]; break;
//栈顶元素取负数
case OPR_NEG:s[sp]=-s[sp];break;
//次栈顶和栈顶相加,结果为栈顶
case OPR_ADD:sp--;s[sp]=s[sp]+s[sp+1];break;
//次栈顶和栈顶相减,结果为栈顶
case OPR_SUB:sp--;s[sp]=s[sp]-s[sp+1];break;
//次栈顶和栈顶相乘,结果为栈顶
case OPR_MUL:sp--;s[sp]=s[sp]*s[sp+1];break;
//次栈顶和栈顶相除,结果为栈顶
case OPR_DIV:sp--;s[sp]=s[sp]/s[sp+1];break;
//栈顶是否为奇数,结果入栈(0或1)
case OPR_ODD:s[sp]=s[sp]&1;break;
//次栈顶和栈顶是否相等,结果入栈(0或1)
case OPR_EQL:sp--;s[sp]=(s[sp]==s[sp+1]);break;
//次栈顶和栈顶是否不等,结果入栈(0或1)
case OPR_NE: sp--;s[sp]=(s[sp]!=s[sp+1]);break;
//次栈顶是否比栈顶小,结果入栈(0或1)
case OPR_LT: sp--;s[sp]=(s[sp]<s[sp+1]);break;
//是否次栈顶大于等于栈顶,结果入栈(0或1)
case OPR_LGE:sp--;s[sp]=(s[sp]>=s[sp+1]);break;
//是否次栈顶大于栈顶,结果入栈(0或1)
case OPR_LG: sp--;s[sp]=(s[sp]>s[sp+1]);break;
//是否次栈顶小于等于栈顶,结果入栈(0或1)
case OPR_LTE:sp--;s[sp]=(s[sp]<=s[sp+1]);break;
//打印栈顶元素
case OPR_WRT:j=strlen(bufERR);sprintf(bufERR+j,"%d ",s[sp--]);
SetDlgItemText(hdlg,IDC_ERR,bufERR);break;
//打印回车
case OPR_WRN: strcat(bufERR,"\r\n");
j=strlen(bufERR);sprintf(bufERR+j,"%d ",s[sp--]);
SetDlgItemText(hdlg,IDC_ERR,bufERR);break;
//从键盘读取数
case OPR_RED:DialogBox(hinst,MAKEINTRESOURCE(IDD_INPUT),0,(DLGPROC)inputproc);
int len=strlen(in);
if(len>6)
{
MessageBox(hdlg,"输入大于六位整数,请重新输入","错误!",MB_ICONERROR);
DialogBox(hinst,MAKEINTRESOURCE(IDD_INPUT),0,(DLGPROC)inputproc);
}
digit=0;
p=in;
if(*p=='-')//p是指向in的指针,处理输入为负数
{
p++;
while(*p)
{
if(ISNUMBER(*p))
{
digit=10*digit+(*p-'0');
p++;
}
else
{
MessageBox(hdlg,"输入有非数字,请重新输入","错误!",MB_ICONERROR);
DialogBox(hinst,MAKEINTRESOURCE(IDD_INPUT),0,(DLGPROC)inputproc);
}
}
digit=-digit;
}
else//处理输入为正整数
{
while(*p)
{
if(ISNUMBER(*p))
{
digit=10*digit+(*p-'0');
p++;
}
else
{
MessageBox(hdlg,"输入有非数字或未输入,请重新输入","错误!",MB_ICONERROR);
DialogBox(hinst,MAKEINTRESOURCE(IDD_INPUT),0,(DLGPROC)inputproc);
}
}
}
s[++sp]=digit;
break;
}
}
ip++; //得到下条指令
}while(ip);
printf("\nProgram terminated!\nPress ENTER to return...");
getchar();
return 0;
}
break;
case ID_OPEN:
if(!GetOpenFileName(&ofn)) break;
str[512]=0; //防止溢出
if(!(fp=fopen(ofn.lpstrFile,"rb")))
MessageBox(hdlg,str,"无法打开文件!",MB_ICONERROR);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -