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

📄 yabasic.c

📁 一个小巧的BASIC解释器的源代码很小可它的确做到了
💻 C
📖 第 1 页 / 共 5 页
字号:
    }
    break;
  }
}


void create_function(int type) /* create command 'function' */
     /* type can be sin,cos,mid$ ... */
{
  struct command *cmd;
	
  cmd=add_command(cFUNCTION);
  cmd->args=type;  
}


void function(struct command *current) /* performs a function */
{
  struct stackentry *stack,*a1,*a2,*a3;
  char *pointer;
  double value;
  time_t datetime;
  int type,result,len,start,i,max;
  char *str,*str2;
	
  type=current->args;
  if (type>fTWOARGS) a3=pop();
  if (type>fONEARGS) a2=pop();
  if (type>fZEROARGS) a1=pop();
	
  switch (type) {
  case fSIN:
    value=sin(a1->value);
    result=stNUMBER;
    break;
  case fASIN:
    value=asin(a1->value);
    type=stNUMBER;
    break;
  case fCOS:
    value=cos(a1->value);
    result=stNUMBER;
    break;
  case fACOS:
    value=acos(a1->value);
    result=stNUMBER;
    break;
  case fTAN:
    value=tan(a1->value);
    result=stNUMBER;
    break;
  case fATAN:
    value=atan(a1->value);
    result=stNUMBER;
    break;
  case fEXP:
    value=exp(a1->value);
    result=stNUMBER;
    break;
  case fLOG:
    value=log(a1->value);
    result=stNUMBER;
    break;
  case fXMAP:
    value=a1->value*xinc+xoff;
    result=stNUMBER;
    break;
  case fYMAP:
    value=a1->value*yinc+yoff;
    result=stNUMBER;
    break;
  case fLEN:
    value=(double) strlen(a1->pointer);
    result=stNUMBER;
    break;
  case fSTR:
    sprintf(string,"%g",a1->value);
    pointer=my_strdup(string);
    result=stSTRING;
    break;
  case fSTR2:
    result=stSTRING;
    if (!myformat(string,a1->value,a2->pointer)) {
      pointer=my_strdup("");
      sprintf(string,"'%s' is not a valid format",(char *)a2->pointer);
      error(ERROR,string);
      break;
    }
    pointer=my_strdup(string);
    break;
  case fSQRT:
    value=sqrt(a1->value);
    result=stNUMBER;
    break;
  case fSQR:
    value=exp(log(a1->value)/2);
    result=stNUMBER;
    break;
  case fINT:
    value=(int) a1->value;
    result=stNUMBER;
    break;
  case fFRAC:
    value=a1->value-(int)a1->value;
    result=stNUMBER;
    break;
  case fABS:
    value=fabs(a1->value);
    result=stNUMBER;
    break;
  case fSIG:
    if (a1->value<0) value=-1.;
    else if (a1->value>0) value=1.;
    else value=0.;
    result=stNUMBER;
    break;
  case fMOD:
    value=a1->value-a2->value*(int)(a1->value/a2->value);
    result=stNUMBER;
    break;
  case fRAN:
    value=a1->value*(float)rand()/RAND_MAX;
    result=stNUMBER;
    break;
  case fRAN2:
    value=(float)rand()/RAND_MAX;
    result=stNUMBER;
    break;
  case fMIN:
    if (a1->value>a2->value)
      value=a2->value;
    else
      value=a1->value;
    result=stNUMBER;
    break;
  case fMAX:
    if (a1->value>a2->value)
      value=a1->value;
    else
      value=a2->value;
    result=stNUMBER;
    break;
  case fVAL:
    i=sscanf((char *) a1->pointer,"%lf",&value);
    if (i!=1) value=0;
    result=stNUMBER;
    break;
  case fATAN2:
    value=atan2(a1->value,a2->value);
    result=stNUMBER;
    break;
  case fLEFT:
    str=a1->pointer;
    len=(int)a2->value;
    pointer=fromto(str,0,len-1);
    result=stSTRING;
    break;
  case fRIGHT:
    str=a1->pointer;
    max=strlen(str);
    len=(int)a2->value;
    pointer=fromto(str,max-len,max-1);
    result=stSTRING;
    break;
  case fMID:
    str=a1->pointer;
    start=(int)a2->value;
    len=(int)a3->value;
    pointer=fromto(str,start-1,start+len-2);
    result=stSTRING;
    break;
  case fINKEY:
    pointer=inkey(a1->value);
    result=stSTRING;
    break;
  case fCHR:
    pointer=my_malloc(2);
    i=(int)floor(a1->value);
    if (i>255 || i<0) {
      sprintf(string,"can磘 convert %g to character",a1->value);
      error(ERROR,string);
      return;
    }
    pointer[1]='\0';
    pointer[0]=(unsigned char)i;
    result=stSTRING;
    break;
  case fASC:
    value=((unsigned char *)a1->pointer)[0];
    result=stNUMBER;
    break;
  case fUPPER:
    str=a1->pointer;
    pointer=my_malloc(strlen(str)+1);
    i=-1;
    do {
      i++;
      pointer[i]=toupper((int)str[i]);
    } while(pointer[i]);
    result=stSTRING;
    break;
  case fLOWER:
    str=a1->pointer;
    pointer=my_malloc(strlen(str)+1);
    i=-1;
    do {
      i++;
      pointer[i]=tolower((int)str[i]);
    } while(pointer[i]);
    result=stSTRING;
    break;
  case fLTRIM:
    str=a1->pointer;
    while(isspace(*str)) str++;
    pointer=my_strdup(str);
    result=stSTRING;
    break;
  case fRTRIM:
    str=a1->pointer;
    i=strlen(str)-1;
    while(isspace(str[i]) && i>=0) i--;
    str[i+1]='\0';
    pointer=my_strdup(str);
    result=stSTRING;
    break;
  case fTRIM:
    str=a1->pointer;
    i=strlen(str)-1;
    while(isspace(str[i]) && i>=0) i--;
    str[i+1]='\0';
    while(isspace(*str)) str++;
    pointer=my_strdup(str);
    result=stSTRING;
    break;
  case fINSTR:
    str=a1->pointer;
    str2=a2->pointer;
    pointer=strstr(str,str2);
    if (pointer==NULL) 
      value=0;
    else
      value=pointer-str+1;
    result=stNUMBER;
    break;   
  case fDATE:
    pointer=my_malloc(100);
    time(&datetime);
    strftime(pointer,100,"%w-%m-%d-%Y-%a-%b",localtime(&datetime));
    result=stSTRING;
    break;
  case fTIME:
    pointer=my_malloc(100);
    time(&datetime);
    strftime(pointer,100,"%H-%M-%S",localtime(&datetime));
    sprintf(pointer+strlen(pointer),"-%d",
	    (int)difftime(time(NULL),compilation_start));
    result=stSTRING;
    break;
  case fSYSTEM:
    str=a1->pointer;
    pointer=do_system(str);
    result=stSTRING;
    break;
  case fSYSTEM2:
    str=a1->pointer;
    value=do_system2(str);
    result=stNUMBER;
    break;
  case fPEEK:
    str=a1->pointer;
    value=peek(str);
    result=stNUMBER;
    break;
  case fPEEK2:
    str=a1->pointer;
    pointer=peek2(str);
    result=stSTRING;
    break;
  default:
    error(ERROR,"function called but not implemented");
    return;
  }
  
  stack=push();
  /* copy result */
  stack->type=result;
  if (result==stSTRING)
    stack->pointer=pointer;
  else
    stack->value=value;
}

int myformat(char *dest,double num,char *format) /* format number according to string */
{
  int i1,i2; /* dummy */
  char c1; /* dummy */
  static char ctrl[6];
  char *found,*form;
  int pre,post,dot,len,i,digit;
  int ip,neg=FALSE;
  double fp,round;
  static char *digits="0123456789";
  
  form=format;
  if (*form=='%') { /* c-style format */
    strcpy(ctrl,"+- #0"); /* allowed control chars for c-format */
    form++;
    while((found=strchr(ctrl,*form))!=NULL) {
      *found='?';
      form++;
    } 
    if (sscanf(form,"%u.%u%c%n",&i1,&i2,&c1,&i)!=3 &&
	sscanf(form,"%u.%c%n",&i2,&c1,&i)!=2 &&
	sscanf(form,".%u%c%n",&i2,&c1,&i)!=2 &&
	sscanf(form,"%u%c%n",&i2,&c1,&i)!=2) return FALSE;
    if (!strchr("feEgG",c1) || form[i]) return FALSE;
    /* seems okay, let's print */
    sprintf(dest,format,num);
  } else { /* basic-style format */
    if (num<0) {
      neg=TRUE;
      num=-num;
    }
    for(pre=0;*format=='#';pre++) format++;
    dot=*format;
    if (*format) {
      if (*format!='.') return FALSE;
      format++;
    }
    for(post=0;*format=='#';post++) format++;
    if (dot) *(dest+pre)=dot;
    len=pre+post+(dot?1:0);
    dest[len]='\0';
    round=0.5;
    for(i=0;i<post;i++) round/=10.;
    num+=round;
    ip=(int)num;
    fp=num-ip;
    for(i=pre-1;i>=0;i--) {
      if (ip) {
	digit=ip%10;
	ip/=10;
	dest[i]=digits[digit];
      } else {
	break;
      }
    }
    if ((neg && i<0) || ip) {
      for(i=0;i<len;i++) dest[i]='*';
      return TRUE;
    }
    if (neg) dest[i--]='-';
    for(;i>=0;i--) dest[i]=' ';
    for(i=pre+1;i<len;i++) {
      fp*=10;
      digit=(int)fp;
      fp-=digit;
      dest[i]=digits[digit];
    }
    return TRUE;
  }
  return TRUE;
}

void create_dim(char *name,char type) /* create command 'dim' */
     /* type can be 's'=string or 'd'=double Array */
{ 
  struct command *cmd;
  struct symbol *s;
  struct array *ar;
  int dimcount;
	
  dimcount=(int)pop()->value;
  cmd=add_command(cDIM);
  s=get_sym(name,syARRAY,FALSE); /* search for array */
  if (s!=NULL) {
    sprintf(string,"array '%s' has been dimed already",name);
    error(ERROR,string);
    return;
  }
  s=get_sym(name,syARRAY,TRUE); /* create array */
  ar=my_malloc(sizeof(struct array));
  cmd->pointer=ar;
  s->pointer=ar;
  ar->type=type;
  ar->dimed=FALSE;
  ar->dimension=dimcount;
  if (dimcount>10) {
    error(ERROR,"Dimension larger than 10");
    return;
  }
}


void dim(struct command *cmd) /* get room for array */
{
  struct array *ar;
  struct stackentry *s;
  char *nul,**str;
  double *dbl;
  int total,size,i;
	
  ar=(struct array *)cmd->pointer;
  if (ar->dimed) {
    error(ERROR,"Array has been dimed already");
    return;
  }
  total=1; /* count total amount of memory */
  for(i=0;i<ar->dimension;i++) {
    s=pop();
    size=(int) s->value;
    if (size<=0) {
      error(ERROR,"One bound is less or equal zero");
      return;
    }
    size++; /* allow for zero-index-element */
    (ar->bounds)[i]=size;
    total*=size;
  }
  ar->total=total;
  if (ar->type=='s')         /* it is a string array */
    ar->pointer=my_malloc(total*sizeof(char *));
  else
    ar->pointer=my_malloc(total*sizeof(double));
  if (ar->pointer==NULL) {
    error(ERROR,"Could not get enough memory for dim");
    return;
  }
  /* initialize Array */
  if (ar->type=='s') { 
    str=ar->pointer;
    for(i=0;i<total;i++) {
      nul=my_malloc(sizeof(char));
      *nul='\0';
      *(str+i)=nul;}}
  else {
    dbl=ar->pointer;
    for(i=0;i<total;i++) *(dbl+i)=0.0;
  }
  ar->dimed=TRUE;
}


char *fromto(char *str,int from,int to) /* gives back portion of string */
     /* from and to can be in the range 1...strlen(str) */
{
  int len,i;
  char *part;
	
  len=strlen(str);
  if (from>to || to<0 || from>len-1) {
    /* give back empty string */
    part=my_malloc(1);
    part[0]='\0';
  }
  else {
    if (from<=0) from=0;
    if (to>=len) to=len-1;
    part=my_malloc(sizeof(char)*(to-from+2)); /* characters and '/0' */
    for(i=from;i<=to;i++) part[i-from]=str[i]; /* copy */
    part[i-from]='\0';
  }
  return part;
}


char *inkey(double tmout) /* gets char from keyboard, blocks and doesn磘 print */
{
  char keybuff[20];
  char *skey;
  int key; /* returned key */
  int ms; /* number of milliseconds to wait*/
#ifdef WINDOWS
  DWORD oflags; /* saves normal state of console input buffer */
  DWORD flags; /* new input mode for console input buffer */
  INPUT_RECORD inrec; /* for reading key-event */
  int ret,end,now,left,num;
#endif
  ms=(int)(tmout*1000);
  if (!curinized) {
#ifdef UNIX
    error(ERROR,"need to call 'clear screen' first");
    return my_strdup("");
#endif
  }
#ifdef UNIX
  noecho();
  cbreak();
  timeout(ms);
  do key=getch(); while(ms<0 && key==ERR);
  echo();
  nocbreak();
  skey=keybuff;
  switch(key) {
  case ERR: skey="";break;
  case KEY_UP: skey="up";break;
  case KEY_DOWN: skey="down";break;
  case KEY_LEFT: skey="left";break;
  case KEY_RIGHT: skey="right";break;
  case KEY_DC: skey="del";break;
  case KEY_IC: skey="ins";break;
  case KEY_IL: skey="ins";break;
  case KEY_CLEAR: skey="clear";break;
  case KEY_HOME: skey="home";break;
  case KEY_F0: skey="f0";break;
  case KEY_F(1): skey="f1";break;
  case KEY_F(2): skey="f2";break;
  case KEY_F(3): skey="f3";break;
  case KEY_F(4): skey="f4";break;
  case KEY_F(5): skey="f5";break;
  case KEY_F(6): skey="f6";break;
  case KEY_F(7): skey="f7";break;
  case KEY_F(8): skey="f8";break;
  case KEY_F(9): skey="f9";break;
  case KEY_F(10): skey="f10";break;
  case KEY_F(11): skey="f11";break;
  case KEY_F(12): skey="f12";break;
  case KEY_F(13): skey="f13";break;
  case KEY_F(14): skey="f14";break;
  case KEY_F(15): skey="f15";break;
  case KEY_F(16): skey="f16";break;
  case KEY_F(17): skey="f17";break;
  case KEY_F(18): skey="f18";break;
  case KEY_F(19): skey="f19";break;
  case KEY_F(20): skey="f20";break;
  case KEY_F(21): skey="f21";break;
  case KEY_F(22): skey="f22";break;
  case KEY_F(23): skey="f23";break;
  case KEY_F(24): skey="f24";break;
  case KEY_BACKSPACE: skey="backspace";break;
  case KEY_NPAGE: skey="scrndown";break;
  case KEY_PPAGE: skey="scrnup";break;
  case KEY_ENTER: skey="enter";break;
  default:
    if (isprint(key)) {
      keybuff[0]=key;
      keybuff[1]='\0';
    }
    else {
      switch(key) {
      case 0x1b:skey="esc";break;
      case 0x7f:skey="del";break;
      case 0xa:skey="enter";break;
      case 0x9:skey="tab";break;
      default:
	sprintf(keybuff,"key%x",key);
      }
    }

⌨️ 快捷键说明

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