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

📄 symbol.c

📁 YBasic编程语言的移植和开发 YBasic编程语言的移植和开发 YBasic编程语言的移植和开发
💻 C
📖 第 1 页 / 共 3 页
字号:
    p=push();  p->value= *(double *)cmd->pointer;  p->type=stNUMBER;}void pushdblsym(struct command *cmd) {  /* push double symbol onto stack */  struct stackentry *p;    p=push();  if (!cmd->name) error(WARNING,"invalid pushdblsym");  if (!cmd->symbol) cmd->symbol=&(get_sym(cmd->name,syNUMBER,amADD_GLOBAL)->value);  p->value=*(double *)cmd->symbol;  p->type=stNUMBER;}void popdblsym(struct command *cmd)  /* pop double from stack */{  double d;    d=pop(stNUMBER)->value;  if (!cmd->symbol) cmd->symbol=&(get_sym(cmd->name,syNUMBER,amADD_GLOBAL)->value);  *(double *)(cmd->symbol)=d;}void create_makelocal(char *name,int type) /* create command 'cMAKELOCAL' */{  struct command *cmd;  cmd=add_command(cMAKELOCAL,name);  cmd->args=type;}void makelocal(struct command *cmd) /* makes symbol local */{  if (get_sym(cmd->name,cmd->args,amSEARCH_VERY_LOCAL)) {    sprintf(string,"local variable '%s' already defined within this subroutine",strip(cmd->name));    error(ERROR,string);    return;  }  get_sym(cmd->name,cmd->args,amADD_LOCAL);}void create_numparam(void) /* create command 'cNUMPARAM' */{  struct command *cmd;  /* dotifying numparams at compiletime (as opposed to runtime) is essential,      because the function name is not known at runtime */  cmd=add_command(cNUMPARAM,dotify("numparams",FALSE));}void numparam(struct command *cmd) /* count number of function parameters */{  struct symbol *sym;  sym=get_sym(cmd->name,syNUMBER,amADD_LOCAL);  sym->value=abs(count_args(FALSE));}void create_makestatic(char *name,int type) /* create command 'cMAKESTATIC' */{  struct command *cmd;  cmd=add_command(cMAKESTATIC,name);  cmd->args=type;}void makestatic(struct command *cmd) /* makes symbol static */{  struct symbol *l,*g;  char *at=NULL;    /* mask function name */  if ((at=strchr(cmd->name,'@'))!=NULL) *at='\0';  if (get_sym(cmd->name,cmd->args,amSEARCH_VERY_LOCAL)) {    sprintf(string,"static variable '%s' already defined within this subroutine",strip(cmd->name));    error(ERROR,string);    return;  }  /* create global variable with unique name */  if (at) *at='@';  g=get_sym(cmd->name,cmd->args,amADD_GLOBAL);  if (at) *at='\0';  /* create local variable */  l=get_sym(cmd->name,cmd->args,amADD_LOCAL);  if (at) *at='@';  /* link those two together */  link_symbols(l,g);}void create_arraylink(char *name,int type) /* create command 'cARRAYLINK' */{  struct command *cmd;  cmd=add_command(cARRAYLINK,name);  cmd->pointer=current_function;  cmd->args=type;}void arraylink(struct command *cmd) /* link a local symbol to a global array */{  struct symbol *l,*g;  struct array *ar;    if (get_sym(cmd->name,cmd->args,amSEARCH_VERY_LOCAL)) {    sprintf(string,"'%s()' already defined within this subroutine",strip(cmd->name));    error(ERROR,string);    return;  }  /* get globally defined array */  g=get_sym(pop(cmd->args)->pointer,syARRAY,amSEARCH_PRE);  /* create local array */  l=get_sym(cmd->name,syARRAY,amADD_LOCAL);  if (!l) return;  if (!g || !g->pointer) { /* no global array supplied, create one */    error(DEBUG,"creating dummy array");    ar=create_array((cmd->args==stNUMBERARRAYREF)?'d':'s',0);    l->pointer=ar;    if (infolevel>=DEBUG) {      sprintf(string,"creating 0-dimensional dummy array '%s()'",cmd->name);      error(DEBUG,string);    }  } else {    /* link those two together */    link_symbols(l,g);  }}void create_pusharrayref(char *name,int type) /* create command 'cPUSHARRAYREF' */{  struct command *cmd;  cmd=add_command(cPUSHARRAYREF,name);  cmd->args=type;}void pusharrayref(struct command *cmd) /* push an array reference onto stack */{  struct stackentry *s;  s=push();  s->type=cmd->args;  s->pointer=my_strdup(cmd->name);}void create_require(int type) /* create command 'cREQUIRE' */{  struct command *cmd;    cmd=add_command(cREQUIRE,NULL);  cmd->args=type;}void require(struct command *cmd) /* check, that item on stack has right type */{  char *expected,*supplied;  struct stackentry *s;  if (stackhead->prev->type==cmd->args) return; /* okay, they match */        if (stackhead->prev->type==stFREE) { /* no argument supplied, create it */    s=push();    if (cmd->args==stSTRING) {      s->type=stSTRING;      s->pointer=my_strdup("");      return;    } else if (cmd->args==stNUMBER) {      s->type=stNUMBER;      s->value=0.0;      return;    } else {      /* create array */      s->type=cmd->args;      s->pointer=NULL;      return;    }  }      s=stackhead->prev;  if (s->type==stSTRING)     supplied="string";  else if (s->type==stNUMBER)     supplied="number";  else if (s->type==stSTRINGARRAYREF)    supplied="string array";  else if (s->type==stNUMBERARRAYREF)    supplied="numeric array";  else if (s->type==stFREE)     supplied="nothing";  else     supplied="something strange";  if (cmd->args==stSTRING)     expected="string";  else if (cmd->args==stNUMBER)     expected="number";  else if (cmd->args==stSTRINGARRAYREF)    expected="string array";  else if (cmd->args==stNUMBERARRAYREF)    expected="numeric array";  else if (cmd->args==stFREE)    expected="nothing";  else    expected="something strange";  sprintf(string,"invalid subroutine call: %s expected, %s supplied",expected,supplied);  error(ERROR,string);}void create_dblbin(char c) /* create command for binary double operation */{  switch(c) {  case '+':add_command(cDBLADD,NULL);break;  case '-':add_command(cDBLMIN,NULL);break;  case '*':add_command(cDBLMUL,NULL);break;  case '/':add_command(cDBLDIV,NULL);break;  case '^':add_command(cDBLPOW,NULL);break;  }  /* no specific information needed */}void dblbin(struct command *cmd) /* compute with two numbers from stack */{  struct stackentry *d;  double a,b,c;    b=pop(stNUMBER)->value;  a=pop(stNUMBER)->value;  d=push();  switch(cmd->type) {  case(cDBLADD):c=a+b; break;  case(cDBLMIN):c=a-b; break;  case(cDBLMUL):c=a*b; break;  case(cDBLDIV):     if (fabs(b)<DBL_MIN) {      sprintf(string,"Division by zero, set to %g",DBL_MAX);      error(NOTE,string);      c=DBL_MAX;}    else      c=a/b;    break;  case(cDBLPOW):    if ((a==0 && b<=0) || (a<0 && b!=(int)b)) {      error(ERROR,"result is not a real number");      return;    } else {      c=pow(a,b);    }    break;  }  d->value=c;  d->type=stNUMBER;}void negate() /* negates top of stack */{  stackhead->prev->value=-stackhead->prev->value;}void pushstrptr(struct command *cmd)  /* push string-pointer onto stack */{  struct stackentry *p;    p=push();  if (!cmd->symbol) cmd->symbol=&(get_sym(cmd->name,sySTRING,amADD_GLOBAL)->pointer);  p->pointer=*(char **)cmd->symbol;  if (!p->pointer) p->pointer=my_strdup("");  p->type=stSTRING;}void pushstrsym(struct command *cmd)  /* push string-symbol onto stack */{  struct stackentry *p;    p=push();  if (!cmd->symbol) cmd->symbol=&(get_sym(cmd->name,sySTRING,amADD_GLOBAL)->pointer);  p->pointer=my_strdup(*(char **)cmd->symbol);  p->type=stSTRING;}void popstrsym(struct command *cmd) /* pop string from stack */{  if (!cmd->name) return;  if (!cmd->symbol) cmd->symbol= &(get_sym(cmd->name,sySTRING,amADD_GLOBAL)->pointer);  if (*(char **)cmd->symbol!=NULL) my_free(*(char **)cmd->symbol);  *(char **)cmd->symbol=my_strdup(pop(stSTRING)->pointer);}void create_pushstr(char *s) /* creates command pushstr */{  struct command *cmd;    cmd=add_command(cPUSHSTR,NULL);  cmd->pointer=my_strdup(s); /* store string */}void pushstr(struct command *cmd) {  /* push string onto stack */  struct stackentry *p;    p=push();  p->pointer=my_strdup((char *)cmd->pointer);  p->type=stSTRING;}void duplicate(void) /* duplicate topmost element of stack */{  struct stackentry *s;  double actual;    actual=stackhead->prev->value;  s=push();  s->type=stNUMBER;  s->value=actual;}void create_goto(char *label) /* creates command goto */{  struct command *cmd;    cmd=add_command(cGOTO,NULL);  /* specific info */  cmd->pointer=my_strdup(label);}void create_gosub(char *label) /* creates command gosub */{  struct command *cmd;    cmd=add_command(cGOSUB,NULL);  /* specific info */  cmd->pointer=my_strdup(label);}void create_call(char *label) /* creates command function call */{  struct command *cmd;    cmd=add_command(cCALL,NULL);  /* specific info */  cmd->pointer=my_strdup(label);}static void link_label(struct command *cmd) /* link label into list of labels */{  if (!labelroot)     labelroot=cmd;  else    labelhead->nextassoc=cmd;  labelhead=cmd;}struct command *search_label(char *name,int type) /* search label */{  struct command *curr;  char *at=NULL;  curr=labelroot;  if (type&smGLOBAL) {    at=strchr(name,'@');    if (at) *at='\0';  }  while(curr) {    if ((type&smSUB) && curr->type==cUSER_FUNCTION && !strcmp(curr->pointer,name)) {      if (at) *at='@';      return curr;    }    if ((type&smLINK) && curr->type==cSUBLINK && !strcmp(curr->pointer,name)) {      if (at) *at='@';      return curr->next;    }    if ((type&smLABEL) && curr->type==cLABEL && !strcmp(curr->pointer,name)) {      if (at) *at='@';      return curr;    }    curr=curr->nextassoc;  }  return NULL;}void jump(struct command *cmd) /* jump to specific Label; used as goto, gosub or function call */{  struct command *label;  struct stackentry *ret;  int type;  char *dot;    type=cmd->type;  if (type==cGOSUB || type==cQGOSUB || type==cCALL || type==cQCALL) {    /* leave return address for return */    ret=push();    ret->pointer=current;    if (type==cGOSUB || type==cQGOSUB) {      ret->type=stRETADD;    } else {      ret->type=stRETADDCALL;      reshufflestack(ret);    }  }  if (type==cQGOSUB || type==cQGOTO || type==cQCALL) {    current=(struct command *)cmd->jump; /* use remembered address */    return;  }  label=search_label(cmd->pointer,smSUB|smLINK|smLABEL);  if (!label && type==cCALL && (dot=strchr(cmd->pointer,'.'))) {    strcpy(string,"main");    strcat(string,dot);    label=search_label(string,smLINK);  }  if (label) {      /* found right label */    current=label; /* jump to new location */    /* use the address instead of the name next time */    cmd->jump=label;    switch(cmd->type) {    case cGOTO: cmd->type=cQGOTO; break;    case cGOSUB: cmd->type=cQGOSUB; break;    case cCALL: cmd->type=cQCALL; break;    }  } else {    /* label not found */    sprintf(string,"can't find %s '%s'",(type==cCALL)?"subroutine":"label",strip((char *)cmd->pointer));    if (strchr(cmd->pointer,'@')) strcat(string," (not in this sub)");    error(ERROR,string);  }  /* check, if goto enters or leaves a switch_statement */  if (cmd->type==cQGOTO) {    if (label->switch_id && !cmd->switch_id)       error(ERROR,"cannot jump into switch-statement");    else if (!label->switch_id && cmd->switch_id)       error(ERROR,"cannot jump out of switch-statement");    else if (label->switch_id!=cmd->switch_id)      error(ERROR,"cannot jump between switch statements");  }}void reshufflestack(struct stackentry *ret) /* reorganize stack for function call */{  struct stackentry *a,*b,*c;  struct stackentry *top,*bot;  struct stackentry *ttop,*bbot;  int args;  /* this is a function call; revert stack and shuffle return address to bottom */  /* push address below parameters */  args=0;  top=a=ret->prev;  while(a->type!=stFREE) {    a=a->prev;    args++;  }  bot=a->next;  b=a->prev;  /* remove ret */  ret->prev->next=ret->next;  ret->next->prev=ret->prev;  /* squeeze ret between a and b */  ret->next=a;  a->prev=ret;  b->next=ret;  ret->prev=b;  /* revert stack between top and bot */  if (args>1) {    a=bot;    b=a->next;    bbot=bot->prev;    ttop=top->next;    for(;args>1;args--) {      a->prev=b;      c=b->next;      b->next=a;      a=b;      b=c;    }    bot->next=ttop;    bot->next->prev=bot;    top->prev=bbot;    top->prev->next=top;  }}void myreturn(struct command *cmd) /* return from gosub of function call */{  struct stackentry *address;  address=pop(stANY);  if (cmd->type==cRET_FROM_FUN) {    if (address->type!=stRETADDCALL) {      error(ERROR,"RETURN from a subroutine without CALL");      return;    }  } else {    if (address->type!=stRETADD) {      error(ERROR,"RETURN without GOSUB");      return;    }  }  current=(struct command *)address->pointer;  return;}void create_label(char *label,int type) /* creates command label */{  struct command *cmd;    /* check, if label is duplicate */  if (search_label(label,smSUB|smLINK|smLABEL)) {    sprintf(string,"duplicate %s '%s'",(type==cLABEL)?"label":"subroutine",strip(label));    error(ERROR,string);    return;  }    cmd=add_command(type,NULL);  /* store label */  cmd->pointer=my_strdup(label);  link_label(cmd);}void create_sublink(char *label) /* create link to subroutine */{  char global[200];  char *dot;  struct command *cmd;  if (!inlib) return;  dot=strchr(label,'.');  strcpy(global,"main");  strcat(global,dot);    /* check, if label is duplicate */  if (search_label(global,smSUB|smLINK|smLABEL)) {    sprintf(string,"duplicate subroutine '%s'",strip(global));    error(ERROR,string);    return;  }  cmd=add_command(cSUBLINK,NULL);  /* store label */  cmd->pointer=my_strdup(global);  link_label(cmd);}void decide() /*  skips next command, if not 0 on stack */{  if (pop(stNUMBER)->value!=0) current=current->next; /* skip one command */}

⌨️ 快捷键说明

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