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

📄 basic.c

📁 用C语言写的YABasic解释器
💻 C
📖 第 1 页 / 共 3 页
字号:
					break;
			}
			break;
		case evKeyDown:
			switch(pEvent->x)
			{
				case cmInputExplain:
					exec_input();
					limit_pos = Strlen(pOutBuf);
					if (InputError)
						ApExit(Lastcurrent_mode);
					return 0;
				case cmVkEnter:
					if (InputError)
					{
						ApExit(Lastcurrent_mode);
						return 0;
					}
					else 
						SaveInputData();
					if (InputError) 
					{
						ApExit(Lastcurrent_mode);
						return 0;
					}
					if (InputFlag)
					{
						ev.type = evKeyDown;
						ev.x =cmInputExplain;
						ev.y = 0;
						ev.infoPtr = 0;
						MsgPost(&ev);
					}
					else
					{
						if (!InputError)
						{
							ApExit(RUNMODE);
							return 0;
						}
					}
					break;
				case cmVkUp:
				case cmVkDown:
				case cmVkPageUp:
				case cmVkPageDown:
				case cmVkHome:
					return 0;
				case cmVkDel:					
					GuiEditGetCursorMem(hEditWnd,&cur_pos);
					if (pEvent->y == cmVkShift) 
					{
						if (cur_pos<limit_pos) pEvent->type = evNothing;
					}
					else
					{
						if (cur_pos<=limit_pos) pEvent->type = evNothing;
					}
					break;
				case cmVkLeft:					
					GuiEditGetCursorMem(hEditWnd,&cur_pos);
					if (cur_pos<=limit_pos) pEvent->type = evNothing;
					break;
				default :					
					GuiEditGetCursorMem(hEditWnd,&cur_pos);
					if (cur_pos <= 1) pEvent->type = evNothing;
					break;
			}
			break;
		case evQuit:
			if (pEvent->infoPtr==cmExitHotKey) return 0;
			FreeOpMem();
			FreeAllocMem();
			ApExit(Lastcurrent_mode);
			return 0;         				        		
		default :
			break;        					                 
	}
	if(pEvent->type != evNothing) GuiScrnEditHandleEvent(handle,pEvent);	
	return 0;
}


void wpush(while_stack_str *i)
{
       wstack[wtos].exploc = i->exploc;
       wstack[wtos].endloc = i->endloc;
       wtos++;
}

void exec_while()         /* while 表达式 -- 循环语句*/
{
       /*表达式返回值为数值类型或布尔类型*/
       while_stack_str i; 
       char *x, wn, en;
       wn = 1;
       en = 0;
       i.exploc = prog; 
       i.endloc = (char *)Null;
       x = GetAllocBuf();
       get_exp(x);
       if (*x==BOOL_TYPE&&*(x+1)!='1'||*x==REAL_TYPE&&atof(x+1)==0||*x==INTEGER_TYPE&&atoi(x+1)==0) 
       {
	   for(;;)
	   {
	       while ((tok!=WEND)&&(tok!=FINISHED)&&(tok!=WHILE)) get_token(2);
	       switch (tok) 
	       {
		   case WEND  : en++; break;
		   case WHILE : wn++; break;
        	   default    : break;
	       }
	       if (wn==en) break;  /*找到与while对称的wend位置,退出循环*/                          
	       if (tok==FINISHED&&wn!=en) serror(7);          /***While-Wend语句出现语法错误***/
	       get_token(2);
	   }
       } 
       else 
       {
       	   if (*x==STRING_TYPE) serror(7);
	   wpush(&i);
       }  
}

void wend()        /*while循环结束语句*/
{	
         while_stack_str i; 
         char *x;
         
         wpop(&i);
         if (i.endloc==(char *)Null) i.endloc = prog;
         prog = i.exploc;
         x = GetAllocBuf();
         get_exp(x);
         if (*x==BOOL_TYPE&&*(x+1)!='1'||*x==REAL_TYPE&&atof(x+1)==0||*x==INTEGER_TYPE&&atoi(x+1)==0)
                  prog = i.endloc;
         else 
                  wpush(&i);     
}

void gosub()   /*过程跳转指令: gosub 标号*/
{
	 char *loc, *p;
	 	 
	 while (*prog==0x20||*prog==0x09) prog++;
	 if (*prog==0x0d||*prog==':'||*prog==0) serror(8);
	 p = token;
	 while (*prog!=0x20&&*prog!=0&&*prog!=0x0d&&*prog!=':'&&*prog!=0x09)
	 {
	 	 if (*prog<0x30||*prog>0x39) serror(8);
	 	 *p++ = *prog++;
	 }
	 *p = 0;
	 IsEndOfLine();
	 if ((loc = find_label(token))==(char*)Null) serror(8); /***GoSub语句出现错误,对应标号没有定义***/
	 gpush(prog);
	 prog = loc;
	 
}

void exec_on()
{     
        char *value;
        int i,j;
        j = 0;    
        value = GetAllocBuf();
        get_exp(value);
        if (*(value + 1)=='-'||*value!=INTEGER_TYPE&&*value!=REAL_TYPE) serror(13);
        if (*(value + 1)=='+') i = atoi(value + 2) - 1;
        else i = atoi(value + 1) - 1;
        get_token(0);
        if (tok!=GOTO) serror(13);                                /***On语句出现语法错误***/
        value = prog;                        /*对GOTO 后面的语句进行语法判断*/
        while (*value == 0x20) value++;
        if (*value < 0x30 || *value > 0x39) serror(13);
        for(;*value!=0x0D&&*value!=':'&&*value!=0;)
        {
               while (*value >= 0x30 && *value <= 0x39) value++;
               if (*value != 0x0D && *value != ':' && *value != 0 && *value != ',' && *value != 0x20 ) serror(13);
               while (*value == 0x20) value++;
               if (*value != 0x0D && *value != ':' && *value != 0 && *value != ',') serror(13);
               if (*value == ',') 
               {
               	       while (*(++value) == 0x20);
               	       if (*value < 0x30 || *value > 0x39) serror(13);
               }
        }        
        while ( i != j && *prog != 0x0D && *prog != ':' && *prog != 0 )
        {
        	if (*prog++ == ',') j++;
        }
        if (i==j) exec_goto();
}

void exec_graph()
{
	exec_cls();
	current_mode = RUNMODE;
	nBasicRet = 2;
	GTflag = 1;
	IsEndOfLine();
}

void exec_gotextmode()
{
        exec_cls();	
	GTflag = 0;	
	IsEndOfLine();
}

FAR void serror(Int8 error)
{		
	char *e, *p;	
	int  AbsErrAddr;
	
	AbsErrAddr = error + BaseErrorAddr;
	FreeOpMem();
	FreeAllocMem();
	GTflag = 0; 		
	if (InputFlag == 1) InputError = 1;
	if (error!=52) 
               GuiMsgBox(hBasicWnd, ofStyle4|ofResource, AbsErrAddr, IDS_MAIN_BASIC , MT_OK_X);
	MsgSend2(hBasicWnd,evKeyDown,cmVkEnter,0,0);
	*pOutBuf = 0;
	longjmp(e_buf,1);
}

void _BasicExplain()
{
	char *p_save, flet, tok_save, *temp;
	
	if(setjmp(e_buf)) return;
	if (sl_flag) scan_labels();
	flet = 0;
	do{
		p_save = prog;
		tok_save = tok;
		token_type = get_token(0);
		if (token_type==OPERATION2&&tok!=PRINT) serror(0);
		if (*token == 0) serror(0);
		if (flet&&token_type!=VARIABLE) serror(15);         /***Let语句出现语法错误***/		
		if (tok == EOL) continue;
		if (token_type == VARIABLE) 
		{
			if (flet) flet = 0;
			prog = p_save;
			assignment();  
		} else {			
			switch(tok){
				case SPC  : serror(0);break;
				case LET  : flet = 1;break;
				case PRINT: exec_print();break;
				case GOTO:  exec_goto();break;
				case IF:    exec_if();break;
				case ELSE:  exec_else();break;
				case FOR:   exec_for();break;
				case NEXT:  next();break;
				case WHILE: exec_while();break;
				case WEND:  wend();break;
				case READ:  exec_read();break;
				case DATA:  find_eol();break;
				case RESTORE: cur_buf = data_buf ;break;
				case INPUT:
				            if (!GTflag)
				            {
				            	current_mode = RUNINPUTMODE;
				            	return;
				            } else {
				                exec_GraphModeInput();
				                break;
				            }
				case DIM  : dim();break;
				case GOSUB: gosub();break;
				case RETURN: prog = gpop();break;
				case DEF   :exec_def();break;
				case GRAPH :
				             if (GTflag==0) exec_graph();				                   
				             break;
				case LINE  :exec_line(); break;				
				case INKEY :exec_inkey();break;
				case DRAW  :exec_draw(); break;
				case BOX   :exec_box();  break;
				case OPEN  :exec_open(); break;
				case CLOSE :exec_close(); break;
				case PUT   :exec_put(); break;
				case GET   :exec_get(); break;
/*				case RSET  :exec_rset(); break;
				case LSET  :exec_lset(); break;
				case COPY  :exec_copy(); break;      */
				case CIRCLE:exec_circle(); break;
				case ELLIPSE:exec_ellipse();break;                        
				case LOCATE: 
				             if (GTflag==1) exec_locate(); 
				             else find_eol();				             
				             break;
			        case CLS   : 
			                     /*
			                     if (GTflag==1) exec_cls();
			                     else find_eol(); */
			                     exec_cls();
			                     break;
/*				case PLAY  : exec_play(); break;              */
				case BEEP  : _PrjBeep(); break;
				case SWAP  : exec_swap(); break;
				case REM   : while ( *prog != 0x0D && *prog != 0 ) prog++; break;
				case GOTEXTMODE :
/*				                   if (GTflag==1)  */
				                   exec_gotextmode();						                   
				                   break;
				case ON    : exec_on(); break;
				case END   : 
				             if (ftos) serror(16);           
				             if (wtos) serror(17);				             
				             FreeAllocMem(); 
				             return;
				default    :tok=0; break;
			}         
		}
	}while(tok != FINISHED);	
	return;
}

FAR void InitialVariable() 
{
	explain_over_flag = 0;
	GTflag = 0;
	InputFlag = 0; 
	sl_flag = 1;
	Memset(pOutBuf,0,200);
	InputError = 0;
	notdoelse = 0;
	seed = 0;
	Variables = (bitnode *)Null;
	data_buf = (bitnode *)Null;
	cur_buf = (bitnode *)Null;
	pf = (pfnode *)Null;
	fl = (fsnode *)Null;
	dl = (Do_List *)Null;
	TmpList = (Tmp_List*)Null;
	label_table = (label_str *)Null;
	pCurBuf = 0;
	prog = pInBuf;
	ftos = 0;
	gtos = 0;
	wtos = 0;
	bPosX = 0;
	bPosY = 0;
	Memset(TmpOut,0,200);
}

FAR UInt8 _BasicGetpInBuf()            /*返回为 1: 成功; 返回为 0 : 文件长度大于BUFFERPROGRAM, 太长; 返回为 2 : 读错误; 返回为 3: 文件打开失败*/
{
	FileHandle fin;
	UInt32 c;
	if (current_mode == LISTMODE) 
	{
             Strcpy(pBasicFileName,pInBuf+(UInt16)CurLine*(UInt16)10);
             Strcat(pBasicFileName,".bsc");
        }
        fin = FileOpen(_Far(pBasicFileName),FILEMODE_READONLY);
	if (fin)
	{             
		c = FileLength(fin);
                if (c > BUFFERPROGRAM) 
                {  
                       FileClose(fin);
                       return 0;         /*返回为0: 文件太长*/
                }
                Memset(pInBuf,0,BUFFERPROGRAM);
		if (FileRead(fin,_Far(pInBuf),FileLength(fin)) != FileLength(fin))
		{
			FileClose(fin);
			return 2;
		}
	} 
	else  		        
	        return 3;	/*返回为3: 文件打开失败*/
	FileClose(fin);
	return 1;       /*返回为1: 成功获得内容*/
}

FAR void _BasicFileDelete()
{	
	if (current_mode==LISTMODE) {
		Memset(pBasicFileName,0,20);
		Strcpy(pBasicFileName,pInBuf + (UInt16)CurLine * (UInt16)10);
                Strcat(pBasicFileName,".bsc");
	}
	GuiStatusBoxStart(hBasicWnd, ofStyle4, _Far("正在删除..."));
	if (!FileDelete(_Far(pBasicFileName)))
	{
		GuiStatusBoxEnd(hBasicWnd);
		PrjShowFileOperateError();
	}
	else
	        GuiStatusBoxEnd(hBasicWnd);
	Memset(pBasicFileName,0,20);
}

FAR UInt8 _BasicFileSave(FarPtr s)  /***返回1则文件保存成功,返回0则文件保存失败,返回2则文件名重复要重新输入***/
{
	FileHandle fout;
	StructFileFind  bffblk;
	Boolean done;
	UInt16 nMsgRet;

	done = FileFindFirst(&bffblk,_Far(s));
	if (done)
	{
		nMsgRet = GuiMsgBox(hBasicWnd,ofStyle4,_Far("文件名重复,要覆盖吗?"),_Far("Basic编程"),MT_YESNO);
		if (nMsgRet == cmMsgBoxNo) return 2;    /**返回2则要重新输入文件名**/
		else FileDelete(s);
	}
	fout = FileOpen(s,FILEMODE_READWRITE);
	if (fout)
	{
		GuiStatusBoxStart(hBasicWnd, ofStyle4, _Far("正在保存..."));
		if (FileWrite(fout,_Far(pInBuf),Strlen(pInBuf)) == Strlen(pInBuf))
		{						
			FileClose(fout);
			GuiStatusBoxEnd(hBasicWnd);			
			return 1;
		}
		else 
		{
			FileClose(fout);			
			GuiStatusBoxEnd(hBasicWnd);
			PrjShowFileOperateError();
			return 0;
		}
	}
	else
	        GuiMsgBox(hBasicWnd,ofStyle4,_Far("文件打开出错"),_Far("Basic编程"),MT_NONE);
	return 0; 
}

void BasicApInitialize(char *bAllBuf)
{

	Memset(bAllBuf,0,BUFFERPROGRAM + 3000);       /*2100 - > 2500*/
	HomeKeyDownFlag = 0;
	pInBuf = bAllBuf;
	pOutBuf = pInBuf + BUFFERPROGRAM;
	TmpOut = pOutBuf + 200;
        token = TmpOut + 200;
        TmpBuf = token + 180;
        pBasicFileName = TmpBuf + 2400;
        current_mode = LISTMODE;   /***nBasicRet: 1.输入窗口状态, 2.输出窗口状态, 3. 关闭输出窗口标志***/
        GTflag = 0;        
          /**GTflag=0设置为初始文本模式,ResetFlag=0程序开始标识***/        
        CurLine = 0;      
        pCurBuf = 0;
        InputError = 0;        
}

⌨️ 快捷键说明

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