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