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

📄 basic5.c

📁 用C语言写的YABasic解释器
💻 C
字号:
#include "os.h"
#include "ptype.h"

FAR Boolean GetValidNumber(char *p, int n);
FAR UInt8 IsInteger(char *value_ptr);

FAR char get_token(char tflag);
FAR void get_exp(char *result);
FAR char *GetAllocBuf();
FAR int iswhite(char c);
FAR int atoi(char *x);
FAR void adjust_poutbuf(char *ad_ptr);
FAR void serror(Int8 error);
FAR void IsArray();
FAR int isdigit(char c);
FAR void IsEndOfLine();
FAR void exec_open();
FAR void exec_close();
FAR void get_next();
FAR char look_up(char *s);
FAR void exec_goto();
FAR char *find_label(char *s);
FAR void fpop(for_stack_str *i);
FAR void wpop(while_stack_str *i);
FAR void FreeAllocMem();
FAR void exec_gvbasicif();
FAR void putback();
FAR int gcvt(double i, char flag, char *result);
FAR double atof(char *x);
FAR void exec_mid();
extern Int8  *prog, *TmpOut, tok, token_type, *token, *pOutBuf, *TmpBuf;
extern UInt8           *hBasicWnd;
extern UInt8           bPosX,bPosY;
extern UInt8           GTflag;
extern fsnode          *fl;

extern bitnode 		 *Variables;
extern pfnode 		 *pf;     
extern Int8              *pInBuf;
extern Int8              pCurBuf;
extern data_str 	 *data_buf, *cur_buf;
extern for_stack_str 	 fstack[FOR_NEST];
extern while_stack_str 	 wstack[WHILE_WEND];
extern label_str 	 *label_table;
extern char 		 notdoelse;
extern char 		 *gstack[SUB_NEST];
extern int 		 ftos,wtos,gtos;
extern UInt8             nBasicRet;
extern Tmp_List          *TmpList;
extern Int8              InputError, InputFlag;
extern Int8              SetCursorLastFlag, sl_flag;
extern UInt8             GVBasicIf_flag;

FAR void exec_gvbasicif()
{
	char *x;
	x = GetAllocBuf();
	get_exp(x);
	get_token(0);
	if (tok!=THEN) serror(35);  /***if语句出现语法错误***/
	if (*x == BOOL_TYPE && *(x+1) == '1' || *x!=BOOL_TYPE && *(x+1) != '0' && *(x+1) != 0  )
	{		
		notdoelse++;
	}
	else
	{
	        if (x = Strstr(prog," else ")) prog = x + 5 ;
	        else 
	        {
	        	GVBasicIf_flag = 0;
	        	x = Strstr(prog," ELSE ");
	        	prog = x + 5;
	        }
	}      	
}


FAR void exec_open()
{
        char *filename, filemode, *p, *filename_tmp;
        int filenum, i, reclen;
        fsnode *fnode,*q;
        StructFileFind bffblk;
        Boolean done;
     
        i = 0; 
        reclen = 32;
        filename_tmp = GetAllocBuf();
        get_exp(filename_tmp);
        if (*filename_tmp!=STRING_TYPE) serror(44);         /***Open语句出现语法错误***/
        get_next();
        if (Stricmp(token,"for")!=0) serror(44);
        get_next();
     
        if (Stricmp("input",token)==0) filemode = 1;
        else if (Stricmp("output",token)==0) filemode = 2;
        else if (Stricmp("append",token)==0) filemode = 3;
        else if (Stricmp("random",token)==0) filemode = 4;
     
        get_next();
        if (Stricmp(token,"as")!=0) serror(44);
        get_next();
        if (*token!='#') serror(44);
        p = token + 1;
        while (*p!=0) {
	   if  (!isdigit(*p)) serror(44);
	   p++;
        }
        filenum = atoi(token+1);
        i = 1;
        while (*(prog - i) == 0x20) i--;        
        if ( *(prog - i) != 0x0D && *(prog - i) != ':') serror(44);
        i = 0;
/*****        
        get_next();
        if ((*token != 0)&&(look_up(token)>20)) {
	     if (Stricmp(token,"len")!=0||*prog++!='=') serror(44);
	     get_next();
	     p = token;
	     while (*p!=0) {
	          if (!isdigit(*p)) serror(44);
	          p++;
	     }
	     reclen = atoi(token);
        }
*****/
        if ((fnode=(fsnode *)MemAlloc(sizeof(fsnode)))==(fsnode*)Null) serror(1);     /***内存不足***/
        if ((filename = (char *)MemAlloc(Strlen(filename_tmp)+1))==(char*)Null) {        
     	      MemFree((UInt8*)fnode);
     	      serror(1);
        } else {
     	      Strcpy(filename,filename_tmp);
     	      *(filename+Strlen(filename))=0;
        }     
        fnode->filename = filename;
        fnode->filenum = filenum;
        fnode->filemode = filemode;
        fnode->next = (fsnode*)Null;
        if (fl == (fsnode *)Null) fl = fnode;
        else {
	      q = fl;
	      while (q->next) q = q->next;
	      q->next = fnode;
        }
        switch (filemode) {
	    case 1 : 
	             fnode->handle = FileOpen(_Far(filename+1),FILEMODE_READONLY);
		     if (!fnode->handle) serror(45);   /***文件打开错误***/
		     else FileSeek(fnode->handle,0,FILESEEK_BEGIN);
		     break;
	    case 2 : 
	             done = FileFindFirst(&bffblk,_Far(filename+1));
	             if (done) 
	             {
	             	  if (!Strchr(filename + 1,'.')) serror(45);
	                  if (!FileDelete(_Far(filename+1)))
	                  {
	                  	PrjShowFileOperateError();
	                  	serror(52);
	                  }
	             }
	             fnode->handle = FileOpen(_Far(filename+1),FILEMODE_READWRITE);
		     if (!fnode->handle) serror(45);
		     break;
	    case 3 : 
	             fnode->handle = FileOpen(_Far(filename+1),FILEMODE_READWRITE);
	             if (!fnode->handle) serror(45);
	             FileSeek(fnode->handle, 0, FILESEEK_END);
		     break;
	    case 4 : 
	             fnode->handle = FileOpen(_Far(filename+1), FILEMODE_READWRITE);
		     fnode->reclen = reclen;
		     if (!fnode->handle) serror(45);
		     break;
	    default: 
	             serror(44);
        }	
}

FAR void exec_close()
{
       char *p; 
       int filenum;
       fsnode *q, *qb;
       q = fl;
       get_next();
       if (*token!='#') serror(46);         /***Close语句出现语法错误***/
       p = token+1;
       while (*p!=0) {
	   if (!isdigit(*p)) serror(46);
	   p++;
       }
       filenum = atoi(token+1);
       qb = q;
       while (q) {
	    if (q->filenum!=filenum) {
	       qb = q;
	       q = q->next;
	       continue;
	    }
	    break;
       }
       if (q == (fsnode *)Null) serror(46);
       FileClose(q->handle);
       if (qb == q)  
     	       fl = q->next;	            
       else
	       qb->next = q->next;
       MemFree(q->filename); 
       MemFree((Int8*)q);
}


FAR void exec_print()
{		
	UInt8   *hEditWin;
	char    *p, last_delim, *answer, *PrintBuf, *dot_pos, *temp_buf;
	int     len , i, j;
	double  f;
	
/*	temp_buf = GetAllocBuf(); */
        temp_buf = TmpBuf + 18 * 120;
        Memset(temp_buf, 0, 120);
	len = 0;
	answer = GetAllocBuf();
	PrintBuf = TmpOut;
	do{
		p = prog;
		if (*prog==0x20||*prog==0x09) prog++;
		if (*prog==0||*prog==0x0D||*prog==':') tok = EOL;
	/*	get_token(0);   用此句会造成循环分配的内存产生覆盖,在输出数组里套数组时 ,用上面二句代替这句  */
	/*	if (token_type == OPERATION2) serror(3); */
		if(tok==EOL||tok==FINISHED)
		{
			while (*prog == 0x20) prog++;
                        if (Strstr(prog,"spc")==prog||Strstr(prog,"SPC")==prog)
                        {
                        	i = 1;
                        	while (*(prog - i) == 0x20) i++;
                        	if (*(prog - i) != ':') serror(3);
                        	prog += 3;
				get_exp(answer);
				i = Strlen(temp_buf);
				if ((j = atoi(answer+1))>20||j <= 0) serror(51);
				Memset(temp_buf+i,32,j);
				*(temp_buf+i+atoi(answer+1)) = 0;
		        } else
			        break;
		}
		prog = p;
		token_type = COMMAND;
		get_exp(answer);
		if (*answer == 0 && (*prog == ',' || *prog == ';')) serror(0);		
		if (!Strcmp(answer+1,"????????????????")) serror(1);
		if (*answer == STRING_TYPE&&*(answer + 1) == 0xff&&*(answer + 2)==0) *(answer + 1) = 0;		
		get_token(0);
		if (*answer==REAL_TYPE||*answer==INTEGER_TYPE)
		{			
			if (!GetValidNumber(answer + 1, 14)) serror(1);
		}
		IsInteger(answer);		
		if (Strlen(answer+1)+Strlen(temp_buf) > 120) serror(1);
		Strcat(temp_buf,answer+1);		
		len += Strlen(answer+1);

		last_delim = *token;
		while (*prog == 0x20) prog++;
                if (Strstr(prog,"spc")==prog||Strstr(prog,"SPC")==prog) 
                {
                	i = 1;
                	while (*(prog - i) == 0x20) i++;
                	if (*(prog - i) != ':') serror(3);
                	prog += 3;
		        get_exp(answer);
			i = Strlen(temp_buf);
			if ((j = atoi(answer+1))>20 || j <= 0) serror(51);
			Memset(temp_buf+i,32,j);
			*(temp_buf+i+atoi(answer+1))=0;
			get_token(0);
		}
		else		
			while (*(prog-1)==0x20) prog--;		
		if(*token==',') 
		{
			len = Strlen(temp_buf);
			*(temp_buf+len) = 0x0D;
			*(temp_buf+len+1) = 0;
		} 
		else if (*token==';');
		else if (tok!=EOL&&tok!=FINISHED&&token_type!=COMMAND)
			serror(3);           /***打印语句出现错误***/
	}while(*token ==';'||*token ==',');
	if(tok==EOL || tok == FINISHED) 
	{
		if(last_delim != ';' && last_delim != ',') 
		{
                           len = Strlen(temp_buf);
                           *(temp_buf+len) = 0x0D;        
                           *(temp_buf+len+1) = 0;        
                }                           
	} else if (token_type == COMMAND) putback();		
	else
		serror(3);		      /***打印语句出现错误***/
	hEditWin = GuiScrnEditGetEdit(hBasicWnd);
	adjust_poutbuf(PrintBuf);
	i = 0;	
	if (!GTflag)
	{
		if (Strlen(PrintBuf) + Strlen(temp_buf) > 200) serror(1);
                Strcat(PrintBuf,temp_buf);
                adjust_poutbuf(PrintBuf);
	        GuiEditSetText(hEditWin,(UInt8*)PrintBuf);
	        return;
	}
	j = bPosX/8;
	while (*temp_buf!=0)
	{
  	     if (*temp_buf!=0x0d&&i<20 - j)
	     {
		 if ((UInt8)*temp_buf>0x80)
		 {
		     if  (i + 2 < 21 - j)	
		     {
		      	  *(answer + i++) = *temp_buf++;
		          *(answer + i++) = *temp_buf++;			               
		     }
		     else 
		     {
		      	  *(answer + i) = 0;
		          i = 20;
		          j = 0;
		     }
		 }
		 else				 
		     *(answer + i++) = *temp_buf++;			        		  		 
	     }
	     else
	     {				
		 *(answer + i) = 0;
		 i = 0;
		 j = 0;
		 GraphDrawText((MDC *)hEditWin,bPosX,bPosY,0,0,_Far(answer));
		 bPosX = 0;
		 bPosY += 16; 
		 if (*temp_buf==0x0d) temp_buf++;
	     }
	}
	if (i) GraphDrawText((MDC *)hEditWin,bPosX,bPosY,0,0,_Far(answer));
	if (bPosX!=0||bPosY!=0)
	{
		bPosX = 0;
		bPosY = 0;		
	}	
	return;
}

FAR void IsEndOfLine()
{
	while (*prog==0x20||*prog==0x09) prog++;
	if (*prog!=0x0d&&*prog!=':') serror(0);
}


FAR void exec_goto()/*执行GOTO语句*/
{
	char *loc, *p;
	int for_num, next_num, while_num, wend_num, k;
	for_stack_str i;
	while_stack_str j;
	p = prog;
	while (*p!=0x0D&&*p!=':'&&*p!=0) 
	{
		if (Strchr("!^*()&%$#@-+;\/[]{}",*p)||*p=='"') serror(6);
		else p++;
	}
	get_token(0);
	p = token;
	while (*p!=0) 
	{
		if (!isdigit(*p)) serror(6);
		else p++;
	}
	if ((loc = find_label(token))==(char*)Null) serror(6); /***GoTo语句出现错误,对应标号没有定义***/	        
	if (loc>prog) p = loc;
	else 
	{
	     p = prog; 
	     prog = loc;
	}	
	get_next();
	for_num = 0;
	next_num = 0;
	while_num = 0;
	wend_num = 0;
	while ( prog < p) 
	{
		if (!Stricmp(token,"for")) for_num++;
		else if (!Stricmp(token,"while")) while_num++;
		else if (!Stricmp(token,"next")) next_num++;
		else if (!Stricmp(token,"wend")) wend_num++;			
		get_next();
	}
	for_num -= next_num;
	while_num -= wend_num;
	if (for_num<0) for_num = -for_num;
	if (while_num<0) while_num = -while_num;
	for (k=0; k<for_num; k++) 
	          fpop(&i);
	for (k=0; k<while_num; k++)
	          wpop(&j);
	prog = loc;
}

FAR void FreeAllocMem()
{
	bitnode *p,*q;
	pfnode *r,*s;
	data_str *u,*v;
	fsnode *m,*n;
	label_str *i,*j;
		
        while (Variables!=(bitnode *)Null) {
        	p = Variables;
	        q = p;
	        while (p->lch!=(bitnode*)Null||p->rch!=(bitnode*)Null) {
		       if (p->lch!=(bitnode*)Null) { 
			     q = p;
			     p = p->lch;
		       }
		       else {
			     q = p;
			     p = p->rch;					
		       }
	        }
	        if (p==q) { 
	        	MemFree((Int8*)Variables->var_addr);
	        	MemFree((Int8*)Variables->value_addr);
	        	MemFree((Int8*)Variables);
	        	break;
	        }
	        if (q->lch==p) q->lch = (bitnode*)Null;
	        else if (q->rch==p) q->rch = (bitnode*)Null;	        
	        MemFree((Int8*)p->var_addr);
	        MemFree((Int8*)p->value_addr);
	        MemFree((Int8*)p);	        	        
        }
        
        while (pf!=(pfnode*)Null) { 
        	r = pf; 
        	s = r;       	
        	while (r->next!=(pfnode*)Null) {
        		s = r;
        		r = r->next;
        	}        	 
        	if (r!=s) s->next = (pfnode*)Null;
        	else pf = (pfnode*)Null;
        	MemFree(r->var);
        	MemFree(r->exp);
        	MemFree((Int8 *)r);
        }
        
        while (data_buf!=(data_str*)Null) {
        	u = data_buf; 
        	v = u;
        	while (u->next!=(data_str*)Null) {
        		v = u;
        		u = u->next;
        	}
        	if (u!=v) v->next = (data_str*)Null;
        	else  data_buf = (data_str*)Null;
        	MemFree(u->value_addr);
        	MemFree((Int8 *)u);
        }
        
        while (fl!=(fsnode *)Null) {
        	m = fl; 
        	n = m;
        	while (m->next!=(fsnode*)Null) {
        		n = m;
        		m = m->next;
        	}
        	if (m!=n) n->next = (fsnode*)Null;
        	else fl = (fsnode*)Null;
        	MemFree(m->filename);
        	MemFree((Int8*)m);
        }
        
        while (label_table!=(label_str*)Null) 
        {
        	i = label_table;
        	j = i;
        	while (i->next!=(label_str*)Null) 
        	{
        		j = i;
        		i = i->next;
        	}
        	if (i!=j) j->next=(label_str*)Null;
        	else  label_table = (label_str*)Null;
        	MemFree((Int8*)i);
        }
}

⌨️ 快捷键说明

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