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

📄 t_parse.c

📁 The source code of Doom legacy for windows
💻 C
📖 第 1 页 / 共 2 页
字号:
void parse_data(char *data, char *end){  char *token_alloc;      // allocated memory for tokens    killscript = false;     // dont kill the script straight away    // allocate space for the tokens  token_alloc = Z_Malloc(current_script->len + T_MAXTOKENS, PU_STATIC, 0);    prev_section = NULL;  // clear it    while(*rover)   // go through the script executing each statement    {      // past end of script?      if(rover > end)        break;            // reset the tokens before getting the next line      tokens[0] = token_alloc;            prev_section = current_section; // store from prev. statement            // get the line and tokens      get_tokens(rover);            if(killscript) break;            if(!num_tokens)        {          if(current_section)       // no tokens but a brace            {              // possible } at end of loop:              // refer to spec.c              spec_brace();            }                    continue;  // continue to next statement        }            if(script_debug) print_tokens();   // debug      run_statement();         // run the statement    }  Z_Free(token_alloc);}void run_statement(){  // decide what to do with it    // NB this stuff is a bit hardcoded:  //    it could be nicer really but i'm  //    aiming for speed    // if() and while() will be mistaken for functions  // during token processing  if(tokentype[0] == function)    {      if(!strcmp(tokens[0], "if"))        {          current_script->lastiftrue = spec_if() ? true: false;          return;        }      else if(!strcmp(tokens[0], "elseif"))        {          if(!prev_section || (prev_section->type != st_if && prev_section->type != st_elseif))          {            script_error("elseif without if!\n");            return;          }          current_script->lastiftrue = spec_elseif(current_script->lastiftrue) ? true : false;          return;        }      else if(!strcmp(tokens[0], "else"))        {          if(!prev_section || (prev_section->type != st_if && prev_section->type != st_elseif))          {            script_error("else without if!\n");            return;          }          spec_else(current_script->lastiftrue);          current_script->lastiftrue = true;          return;        }      else if(!strcmp(tokens[0], "while"))        {          spec_while();          return;        }      else if(!strcmp(tokens[0], "for"))        {          spec_for();          return;        }    }  else if(tokentype[0] == name)    {      // NB: goto is a function so is not here      // if a variable declaration, return now      if(spec_variable()) return;    }  // just a plain expression  evaluate_expression(0, num_tokens-1);}/***************** Evaluating Expressions ************************/        // find a token, ignoring things in brackets        int find_operator(int start, int stop, char *value){  int i;  int bracketlevel = 0;    for(i=start; i<=stop; i++)    {      // only interested in operators      if(tokentype[i] != operator) continue;            // use bracketlevel to check the number of brackets      // which we are inside      bracketlevel += tokens[i][0]=='(' ? 1 :        tokens[i][0]==')' ? -1 : 0;            // only check when we are not in brackets      if(!bracketlevel && !strcmp(value, tokens[i]))        return i;    }    return -1;}        // go through tokens the same as find_operator, but backwardsint find_operator_backwards(int start, int stop, char *value){  int i;  int bracketlevel = 0;    for(i=stop; i>=start; i--)      // check backwards    {      // operators only      if(tokentype[i] != operator) continue;            // use bracketlevel to check the number of brackets      // which we are inside            bracketlevel += tokens[i][0]=='(' ? -1 :        tokens[i][0]==')' ? 1 : 0;            // only check when we are not in brackets      // if we find what we want, return it      if(!bracketlevel && !strcmp(value, tokens[i]))        return i;    }    return -1;}// simple_evaluate is used once evalute_expression gets to the level// where it is evaluating just one token// converts number tokens into svalue_ts and returns// the same with string tokens// name tokens are considered to be variables and// attempts are made to find the value of that variable// command tokens are executed (does not return a svalue_t)extern svalue_t nullvar;static svalue_t simple_evaluate(int n){  svalue_t returnvar;  svariable_t *var;    switch(tokentype[n])    {    case string:      returnvar.type = svt_string;      returnvar.value.s = tokens[n];      return returnvar;    case number:      if(strchr(tokens[n], '.'))        {          returnvar.type = svt_fixed;          returnvar.value.f = atof(tokens[n]) * FRACUNIT;        }      else        {          returnvar.type = svt_int;          returnvar.value.i = atoi(tokens[n]);        }      return returnvar;    case name:      var = find_variable(tokens[n]);      if(!var)        {          script_error("unknown variable '%s'\n", tokens[n]);          return nullvar;        }      else        return getvariablevalue(var);    default: return nullvar;    }}// pointless_brackets checks to see if there are brackets surrounding// an expression. eg. "(2+4)" is the same as just "2+4"//// because of the recursive nature of evaluate_expression, this function is// neccesary as evaluating expressions such as "2*(2+4)" will inevitably// lead to evaluating "(2+4)"static void pointless_brackets(int *start, int *stop){  int bracket_level, i;    // check that the start and end are brackets    while(tokens[*start][0] == '(' && tokens[*stop][0] == ')')    {            bracket_level = 0;            // confirm there are pointless brackets..      // if they are, bracket_level will only get to 0      // at the last token      // check up to <*stop rather than <=*stop to ignore      // the last token            for(i = *start; i<*stop; i++)        {          if(tokentype[i] != operator) continue; // ops only          bracket_level += (tokens[i][0] == '(');          bracket_level -= (tokens[i][0] == ')');          if(bracket_level == 0) return; // stop if braces stop before end        }            // move both brackets in            *start = *start + 1;      *stop = *stop - 1;    }}// evaluate_expresion is the basic function used to evaluate// a FraggleScript expression.// start and stop denote the tokens which are to be evaluated.//// works by recursion: it finds operators in the expression// (checking for each in turn), then splits the expression into// 2 parts, left and right of the operator found.// The handler function for that particular operator is then// called, which in turn calls evaluate_expression again to// evaluate each side. When it reaches the level of being asked// to evaluate just 1 token, it calls simple_evaluatesvalue_t evaluate_expression(int start, int stop){  int i, n;  if(killscript) return nullvar;  // killing the script    // possible pointless brackets  if(tokentype[start] == operator && tokentype[stop] == operator)    pointless_brackets(&start, &stop);    if(start == stop)       // only 1 thing to evaluate    {      return simple_evaluate(start);    }    // go through each operator in order of precedence    for(i=0; i<num_operators; i++)    {      // check backwards for the token. it has to be      // done backwards for left-to-right reading: eg so      // 5-3-2 is (5-3)-2 not 5-(3-2)      if( -1 != (n = (operators[i].direction==forward ?                find_operator_backwards : find_operator)                 (start, stop, operators[i].string)) )        {          // CONS_Printf("operator %s, %i-%i-%i\n", operators[count].string, start, n, stop);          // call the operator function and evaluate this chunk of tokens          return operators[i].handler(start, n, stop);        }    }    if(tokentype[start] == function)    return evaluate_function(start, stop);    // error ?  {            char tempstr[1024]="";        for(i=start; i<=stop; i++)      sprintf(tempstr,"%s %s", tempstr, tokens[i]);    script_error("couldnt evaluate expression: %s\n",tempstr);    return nullvar;  }  }void script_error(char *s, ...){  va_list args;  char tempstr[2048];    va_start(args, s);    if(killscript) return;  //already killing script    if(current_script->scriptnum == -1)    CONS_Printf("global");  else    CONS_Printf("%i", current_script->scriptnum);    // find the line number    if(rover >= current_script->data &&     rover <= current_script->data+current_script->len)    {      int linenum = 1;      char *temp;      for(temp = current_script->data; temp<linestart; temp++)        if(*temp == '\n') linenum++;    // count EOLs      CONS_Printf(", %i", linenum);    }    // print the error  vsprintf(tempstr, s, args);  CONS_Printf(": %s", tempstr);    // make a noise  S_StartSound(NULL, sfx_pldeth);    killscript = true;}//// sf: string value of an svalue_t//char *stringvalue(svalue_t v){  static char buffer[256];  switch(v.type)   {      case svt_string:        return v.value.s;      case svt_mobj:        return "map object";      case svt_fixed:        {          double val = ((double)v.value.f / FRACUNIT);          sprintf(buffer, "%g", val);          return buffer;        }      case svt_int:      default:        sprintf(buffer, "%li", v.value.i);        return buffer;    }}//---------------------------------------------------------------------------//// $Log: t_parse.c,v $// Revision 1.4  2001/05/03 21:22:25  hurdler// remove some warnings//// Revision 1.3  2000/11/04 16:23:44  bpereira// no message//// Revision 1.2  2000/11/03 11:48:40  hurdler// Fix compiling problem under win32 with 3D-Floors and FragglScript (to verify!)//// Revision 1.1  2000/11/02 17:57:28  stroggonmeth// FraggleScript files...//// Revision 1.1.1.1  2000/04/30 19:12:08  fraggle// initial import//////---------------------------------------------------------------------------

⌨️ 快捷键说明

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