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

📄 yabasic.c

📁 一个小巧的BASIC解释器的源代码很小可它的确做到了
💻 C
📖 第 1 页 / 共 5 页
字号:
	   (!tileol && currch!=' ' &&
	    currch!='\t' && currch!='\0')) &&
	  currch!=EOF && numread<INBUFFLEN);
	
  /* put back last char */
  if (currch!=EOF && currch!='\0') backchar(currch);
  /* and remove it from buff */
  if (currch!=EOF) numread--;
  buffer[numread]='\0';
  if (currch=='\0' || currch==EOF) goto done;
	
  /* skip trailing whitespace */
  if (!tileol) {
    do {
      currch=onechar();
    } while(currch==' ' || currch=='\t');
    if (currch!=EOF && currch!='\0') backchar(currch);
  }
	
 done:
  if (cmd->tag=='s') { /* read string */
    s=push();
    s->type=stSTRING;
    s->pointer=my_strdup(buffer);}
  else { /* read double */
    s=push();
    s->type=stNUMBER;
    s->value=0.0;
    if (buffer[0] && (sscanf(buffer,"%lf",&d)==1)) s->value=d;
  }
}


void readline(void) /* read one line from current stream */
{  
#ifdef UNIX
  char *nl; /* position of newline */
  int x,y;
#endif
	
  memset(linebuffer,'\0',INBUFFLEN);
#ifdef UNIX
  if (curinized && cinstr==stdin) {
    getyx(stdscr,y,x);
#ifdef HAVE_GETNSTR
    getnstr(linebuffer,INBUFFLEN);
#else
    getstr(linebuffer);
#endif
    if ((nl=strchr(linebuffer,'\0'))) *nl='\n';
    if (y>=LINES-1) scrl(1);
    refresh();
  }
  else 
#endif
    {
      fgets(linebuffer,INBUFFLEN,cinstr);
    }
  currchar=linebuffer;
  prompted=FALSE;
}


int onechar() /* read one char from cinstr */
{
  int ch;
	
  if (cinstr==stdin) {
    if (!currchar || !*currchar) {
      readline();
    }
    currchar++;
    ch=*(currchar-1);
  }
  else
    ch=fgetc(cinstr);
	
  if (ch=='\n' || ch==EOF)
    return '\0';
  else
    return ch;
}


void backchar(int ch) /* put char back into stream */
{
  if (cinstr==stdin) {
    if (currchar>linebuffer) currchar--;
  }
  else {
    ungetc(ch,cinstr);
  }
}


void chkprompt() /* print an intermediate prompt if necessary */
{
  if (cinstr==stdin && (!currchar || !*currchar) && !prompted) onestring("?");
}


void create_onestring(char *str) /* create command 'onestring' */
{
  struct command *cmd;
	
  cmd=add_command(cONESTRING);
  cmd->pointer=my_strdup(str);
}


void onestring(char *string) /* write string to file */
{
#ifdef UNIX
  if (curinized && coutstr==stdout) {
    addstr(string);
    refresh();
  }
#else
  DWORD len,written;
	
  if (curinized && coutstr==stdout) {
    len=strlen(string);
    WriteConsole(ConsoleOutput,string,len,&written,NULL);
  }	
#endif
  else
    {
      fprintf(coutstr,"%s",string);
      fflush(coutstr);
    }
  prompted=TRUE;
}


void create_revert(int flag) /* create command 'reverse' */
{
  struct command *c;
	
  c=add_command(cREVERT);
  c->args=flag;
}


void revert(struct command *cmd) /* switch reverse-printing */
{
  static int reverse=FALSE;
	
  if (((cmd->args)?TRUE:FALSE)==reverse) return;
  if (cmd->args) {
    if (!curinized) {
      error(ERROR,"need to call 'clear screen' first");
      return;
    }
#ifdef UNIX
    attron(A_REVERSE);
#else
    SetConsoleTextAttribute(ConsoleOutput,BACKGROUND_RED | 
			    BACKGROUND_GREEN | BACKGROUND_BLUE);
#endif
    reverse=TRUE;
  }
  else {
#ifdef UNIX
    attroff(A_REVERSE);
#else
    SetConsoleTextAttribute(ConsoleOutput,FOREGROUND_RED | 
			    FOREGROUND_GREEN | FOREGROUND_BLUE);
#endif
    reverse=FALSE;
  }
}


void create_restore(char *label) /* create command 'restore' */
{
  struct command *c;
	
  c=add_command(cRESTORE);
  c->pointer=my_strdup(label);
}


void restore(struct command *cmd) /* reset data pointer to given label */
{
  struct command *curr;
	
  if (cmd->type==cRESTORE) { /* first time; got to search the label */
    if (*((char *)cmd->pointer)=='\0') {
      cmd->pointer=cmdroot;
      cmd->type=cQRESTORE;
      goto found; /* restore to first command */
    }
    curr=cmdroot;
    while(curr!=cmdhead) {   /* go through all commands */
      if (curr->type==cLABEL && !strcmp(curr->pointer,cmd->pointer)) {
				/* found right Label ! */
				/* use the address instead of the name next time ! */
	cmd->pointer=curr;
	cmd->type=cQRESTORE;
	goto found;
      }
      curr=curr->next;
    }
    /* did not found label */
    sprintf(string,"couldn't found label '%s'",(char *)cmd->pointer);
    error(ERROR,string);
    return;
  }
 found:
  datapointer=cmd->pointer;
  return;
}


void create_dbldata(double value)  /* create command dbldata */
{
  struct command *c;
	
  c=add_command(cDATA);
  c->pointer=my_malloc(sizeof(double));
  *((double *)c->pointer)=value;
  c->tag='d'; /* double value */
}


void create_strdata(char *value)  /* create command strdata */
{
  struct command *c;
	
  c=add_command(cDATA);
  c->pointer=my_strdup(value);
  c->tag='s'; /* string value */
}


void create_readdata(char type) /* create command readdata */
{
  struct command *cmd;
	
  cmd=add_command(cREADDATA);
  cmd->tag=type;
}


void readdata(struct command *cmd) /* read data items */
{
  struct stackentry *read;
  char type;
	
  type=cmd->tag;
  while(datapointer->type!=cDATA) {
    if (datapointer==cmdhead) {
      error(ERROR,"Run out of data items");
      return;
    }
    datapointer=datapointer->next;
  }
  if (type!=datapointer->tag) {
    error(ERROR,"Type of READ and DATA don't match");
    return;
  }
  read=push();
  if (type=='d') { /* read a double value */
    read->type=stNUMBER;
    read->value= *((double *)datapointer->pointer);}
  else {
    read->type=stSTRING;
    read->pointer=my_strdup(datapointer->pointer);
  }
  datapointer=datapointer->next; /* next item */
}


void create_dblrelop(char c) /* create command dblrelop */ 
{
  int type;
	
  switch(c) {
  case '=': type=cEQ;break;
  case '!': type=cNE;break;
  case '<': type=cLT;break;
  case '{': type=cLE;break;
  case '>': type=cGT;break;
  case '}': type=cGE;break;
  }
  add_command(type);
}


void dblrelop(struct command *type)  /* compare topmost double-values */
{
  double a,b,c;
  struct stackentry *result;
	
  b=pop()->value;
  a=pop()->value;
  switch(current->type) {
  case cEQ:c=(a==b);break;
  case cNE:c=(a!=b);break;
  case cLE:c=(a<=b);break;
  case cLT:c=(a<b);break;
  case cGE:c=(a>=b);break;
  case cGT:c=(a>b);break;
  }
  result=push();
  result->value=c;
  result->type=stNUMBER;
}    


void create_strrelop(char c) /* create command strrelop */ 
{
  int type;
	
  switch(c) {
  case '=': type=cSTREQ;break;
  case '!': type=cSTRNE;break;
  case '<': type=cSTRLT;break;
  case '{': type=cSTRLE;break;
  case '>': type=cSTRGT;break;
  case '}': type=cSTRGE;break;
  }
  add_command(type);
}


void strrelop(struct command *type)  /* compare topmost string-values */
{
  char *a,*b;
  double c;
  struct stackentry *result;
	
  b=pop()->pointer;
  a=pop()->pointer;
  switch(current->type) {
  case cSTREQ:c=(strcmp(a,b)==0);break;
  case cSTRNE:c=(strcmp(a,b)!=0);break;
  case cSTRLT:c=(strcmp(a,b)<0);break;
  case cSTRLE:c=(strcmp(a,b)<=0);break;
  case cSTRGT:c=(strcmp(a,b)>0);break;
  case cSTRGE:c=(strcmp(a,b)>=0);break;
  }
  result=push();
  result->value=c;
  result->type=stNUMBER;
}    


void create_boole(char c) /* create command boole */ 
{
  int type;
	
  switch(c) {
  case '|': type=cOR;break;
  case '&': type=cAND;break;
  case '!': type=cNOT;break;
  }
  add_command(type);
}


void boole(struct command *type)  /* perform and/or/not */
{
  int a,b,c;
  struct stackentry *result;
	
  a=(int)pop()->value;
  if (current->type==cNOT) 
    c=!a;
  else {
    b=(int)pop()->value;
    if (current->type==cAND)
      c=a&&b;
    else
      c=a||b;
  }
  result=push();
  result->value=c;
  result->type=stNUMBER;
}    


void decide() /*  skips next command, if not 0 on stack */
{
  struct stackentry *a;
	
  a=pop();
  if (a->value!=0) current=current->next; /* skip one command */
}


void create_doarray(char *symbol,int command) /* creates array-commands */ 
{
  struct command *cmd;
  struct symbol *a;
  struct array *ar;
  int dimcount;
	
  a=get_sym(symbol,syARRAY,FALSE);
  if (a==NULL) {
    sprintf(string,"array '%s' has not been dimed",symbol);
    error(ERROR,string);
    return;
  }
	
  dimcount=(int)pop()->value;
  ar=a->pointer;
  if (dimcount!=ar->dimension) {
    sprintf(string,"improper array dimension %d for '%s'",dimcount,symbol);
    error(ERROR,string);
    return;
  }
	
  cmd=add_command(cDOARRAY);
	
  switch(command) {
  case CALLARRAY:
    cmd->args=CALLARRAY;
    break;
  case ASSIGNARRAY:
    cmd->args=ASSIGNARRAY;
    break;
  case CALLSTRINGARRAY:
    cmd->args=CALLSTRINGARRAY;
    break;
  case ASSIGNSTRINGARRAY:
    cmd->args=ASSIGNSTRINGARRAY;
    break;
  case GETSTRINGPOINTER:
    cmd->args=GETSTRINGPOINTER;
    break;
  }
	
  cmd->pointer=ar;
  cmd->args=command;
	
  return;
}


void doarray(struct command *current) /* call an array */
{
  struct array *ar;
  struct stackentry *stack;
  void *p;
  char **str;
  double *dbl;
  int i,j,bnd,index,call;
	
  call=(current->args==CALLARRAY || 
	current->args==CALLSTRINGARRAY ||
	current->args==GETSTRINGPOINTER);
  if (!call) stack=pop();
	
  ar=(struct array *)current->pointer;
  index=0;
  for(i=0;i<ar->dimension;i++) {
    bnd=(ar->bounds[i]);
    index*=bnd;
    j=(int)pop()->value;
    if (j<0 || j>=bnd) {
      sprintf(string,"index %d (=%d) out of range",ar->dimension-i,j);
      error(ERROR,string);
      return;
    }
    index+=j;
  }
	
  if (call) stack=push();
	
  p=ar->pointer;
  switch(current->args) {
  case CALLARRAY:
    dbl=(double *)p+index;
    stack->value= *dbl;
    stack->type=stNUMBER;
    break;
  case ASSIGNARRAY:
    dbl=(double *)p+index;
    *dbl=stack->value;
    break;
  case CALLSTRINGARRAY:
    str=((char **)p+index);
    stack->pointer=my_strdup(*str);
    stack->type=stSTRING;
    break;
  case ASSIGNSTRINGARRAY:
    str=((char **)p+index);
    if (*str!=NULL) free(*str);
    *str=my_strdup(stack->pointer);
    break;
  case GETSTRINGPOINTER:
    str=((char **)p+index);
    stack->pointer=*str;
    stack->type=stSTRING;
    break;
  }
}


void create_changestring(int type) /* create command 'changestring' */
{
  struct command *cmd;
	
  cmd=add_command(cCHANGESTRING);
  cmd->args=type;
}


void changestring(struct command *current) /* changes a string */
{
  int type,a2,a3;
  char *newpart;
  char *oldstring;
  int i,len;
  struct stackentry *a1;
	
  type=current->args;
  newpart=pop()->pointer;
  if (type>fTWOARGS) a3=(int)pop()->value;
  if (type>fONEARGS) a2=(int)pop()->value;
  a1=pop();
  oldstring=a1->pointer; 
  a1->pointer=NULL; /* this prevents push from freeing the memory */
	
  switch(type) {
  case fMID:
    for(i=1;i<a2+a3;i++) {
      if (!oldstring[i-1]) break;
      if (i>=a2) {
	if (!newpart[i-a2]) break;
	oldstring[i-1]=newpart[i-a2];
      }
    }
    break;
  case fLEFT:
    for(i=1;i<=a2;i++) {
      if (!oldstring[i-1] || !newpart[i-1]) break;
      oldstring[i-1]=newpart[i-1];
    }
    break;
  case fRIGHT:
    len=strlen(oldstring);
    for(i=1;i<=len;i++) {
      if (i>len-a2) {
	if (!newpart[i-1-len+a2]) break;
	oldstring[i-1]=newpart[i-1-len+a2];
      }

⌨️ 快捷键说明

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