📄 yabasic.c
字号:
}
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 + -