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

📄 chsh.cpp

📁 一个类c++语言解释器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
      strcpy(p->var_name, token);
      get_token();
      i--;
    }
    else break;
  } while(*token == ',');

  if(*token != ')') throw InterpExc(PAREN_EXPECTED);
}

// Return from a function.
void func_ret()
{
  int value;

  value = 0;

  // Get return value, if any.
  eval_exp(value);

  ret_value = value;
}

// Assign a value to a variable.
void assign_var(char *vname, int value)
{
  // First, see if it's a local variable.
  if(!local_var_stack.empty())
    for(int i=local_var_stack.size()-1;
        i >= func_call_stack.top(); i--)
    {
      if(!strcmp(local_var_stack[i].var_name,
                 vname))
      {
        if(local_var_stack[i].v_type == CHAR)
          local_var_stack[i].value = (char) value;
        else if(local_var_stack[i].v_type == INT)
          local_var_stack[i].value = value;
        return;
      }
    }

  // Otherwise, try global vars.
  for(unsigned i=0; i < global_vars.size(); i++)
    if(!strcmp(global_vars[i].var_name, vname)) {
      if(global_vars[i].v_type == CHAR)
        global_vars[i].value = (char) value;
      else if(global_vars[i].v_type == INT)
        global_vars[i].value = value;
      return;
    }

  throw InterpExc(NOT_VAR); // variable not found
}

// Find the value of a variable.
int find_var(char *vname)
{
  // First, see if it's a local variable.
  if(!local_var_stack.empty())
    for(int i=local_var_stack.size()-1;
        i >= func_call_stack.top(); i--)
    {
      if(!strcmp(local_var_stack[i].var_name, vname))
        return local_var_stack[i].value;
    }

  // Otherwise, try global vars.
  for(unsigned i=0; i < global_vars.size(); i++)
    if(!strcmp(global_vars[i].var_name, vname))
      return global_vars[i].value;

  throw InterpExc(NOT_VAR); // variable not found
}

// Execute an if statement.
void exec_if()
{
  int cond;

  eval_exp(cond); // get if expression.

  if(cond) { // if true, process target of IF
    // Confirm start of block.
    if(*token != '{')
      throw InterpExc(BRACE_EXPECTED);

    interp();
  }
  else {
    // Otherwise skip around IF block and
    // process the ELSE, if present.

    find_eob(); // find start of next line
    get_token();

    if(tok != ELSE) {
      // Restore token if no ELSE is present.
      putback();
      return;
    }

    // Confirm start of block.
    get_token();
    if(*token != '{')
      throw InterpExc(BRACE_EXPECTED);
    putback();

    interp();
  }
}

// Execute a switch statement.
void exec_switch()
{
  int sval, cval;
  int brace;

  eval_exp(sval); // Get switch expression.

  // Check for start of block.
  if(*token != '{')
    throw InterpExc(BRACE_EXPECTED);

  // Record new scope.
  nest_scope_stack.push(local_var_stack.size());

  // Now, check case statements.
  for(;;) {
    brace = 1;
    // Find a case statement.
    do {
      get_token();
      if(*token == '{') brace++;
      else if(*token == '}') brace--;
    } while(tok != CASE && tok != END && brace);

    // If no matching case found, then skip.
    if(!brace) break;

    if(tok == END) throw InterpExc(SYNTAX);

    // Get value of the case statement.
    eval_exp(cval);

    // Read and discard the :
    get_token();

    if(*token != ':')
      throw InterpExc(COLON_EXPECTED);

    // If values match, then interpret.
    if(cval == sval) {
      brace = 1;
      do {
        interp();

        if(*token == '{') brace++;
        else if(*token == '}') brace--;
      } while(!breakfound && tok != END && brace);

      // Find end of switch statement.
      while(brace) {
        get_token();
        if(*token == '{') brace++;
        else if(*token == '}') brace--;
      }
      breakfound = false;

      break;
    }
  }
}

// Execute a while loop.
void exec_while()
{
  int cond;
  char *temp;

  putback(); // put back the while
  temp = prog; // save location of top of while loop

  get_token();
  eval_exp(cond); // check the conditional expression

  // Confirm start of block.
  if(*token != '{')
    throw InterpExc(BRACE_EXPECTED);

  if(cond)
    interp(); // if true, interpret
  else { // otherwise, skip to end of loop
    find_eob();
    return;
  }

  prog = temp; // loop back to top

  // Check for break in loop.
  if(breakfound) {
    // Find start of loop block.
    do {
      get_token();
    } while(*token != '{' && tok != END);

    putback();
    breakfound = false;
    find_eob(); // now, find end of loop
    return;
  }
}

// Execute a do loop.
void exec_do()
{
  int cond;
  char *temp;


  // Save location of top of do loop.
  putback(); // put back do
  temp = prog;

  get_token(); // get start of loop block

  // Confirm start of block.
  get_token();
  if(*token != '{')
    throw InterpExc(BRACE_EXPECTED);
  putback();

  interp(); // interpret loop

  // Check for break in loop.
  if(breakfound) {
    prog = temp;
    // Find start of loop block.
    do {
      get_token();
    } while(*token != '{' && tok != END);

    // Find end of while block.
    putback();
    find_eob();

    // Now, find end of while expression.
    do {
      get_token();
    } while(*token != ';' && tok != END);
    if(tok == END) throw InterpExc(SYNTAX);

    breakfound = false;
    return;
  }

  get_token();
  if(tok != WHILE) throw InterpExc(WHILE_EXPECTED);

  eval_exp(cond); // check the loop condition

  // If true loop; otherwise, continue on.
  if(cond) prog = temp;
}

// Execute a for loop.
void exec_for()
{
  int cond;
  char *temp, *temp2;
  int paren ;

  get_token(); // skip opening (
  eval_exp(cond); // initialization expression

  if(*token != ';') throw InterpExc(SEMI_EXPECTED);
  prog++; // get past the ;
  temp = prog;

  for(;;) {
    // Get the value of the conditional expression.
    eval_exp(cond);

    if(*token != ';') throw InterpExc(SEMI_EXPECTED);
    prog++; // get past the ;
    temp2 = prog;

    // Find start of for block.
    paren = 1;
    while(paren) {
      get_token();
      if(*token == '(') paren++;
      if(*token == ')') paren--;
    }

    // Confirm start of block.
    get_token();
    if(*token != '{')
      throw InterpExc(BRACE_EXPECTED);
    putback();

    // If condition is true, interpret
    if(cond)
      interp();
    else { // otherwise, skip to end of loop
      find_eob();
      return;
    }

    prog = temp2; // go to increment expression

    // Check for break in loop.
    if(breakfound) {
      // Find start of loop block.
      do {
        get_token();
      } while(*token != '{' && tok != END);

      putback();
      breakfound = false;
      find_eob(); // now, find end of loop
      return;
    }

    // Evaluate the increment expression.
    eval_exp(cond);

    prog = temp; // loop back to top
  }
}

// Execute a cout statement.
void exec_cout()
{
  int val;

  get_token();
  if(*token != LS) throw InterpExc(SYNTAX);

  do {
    get_token();

    if(token_type==STRING) {
      // Output a string.
      cout << token;
    }
    else if(token_type == NUMBER ||
            token_type == IDENTIFIER) {
      // Output a number.
      putback();
      eval_exp(val);
      cout << val;
    }
    else if(*token == '\'') {
      // Output a character constant.
      putback();
      eval_exp(val);
      cout << (char) val;
    }

    get_token();
  } while(*token == LS);

  if(*token != ';') throw InterpExc(SEMI_EXPECTED);
}

// Execute a cin statement.
void exec_cin()
{
  int val;
  char chval;
  token_ireps vtype;

  get_token();
  if(*token != RS) throw InterpExc(SYNTAX);

  do {
    get_token();
    if(token_type != IDENTIFIER)
      throw InterpExc(NOT_VAR);

      vtype = find_var_type(token);

      if(vtype == CHAR) {
        cin >> chval;
        assign_var(token, chval);
      }
      else if(vtype == INT) {
        cin >> val;
        assign_var(token, val);
      }

      get_token();
  } while(*token == RS);

  if(*token != ';') throw InterpExc(SEMI_EXPECTED);
}

// Find the end of a block.
void find_eob()
{
  int brace;

  get_token();
  if(*token != '{')
    throw InterpExc(BRACE_EXPECTED);

  brace = 1;

  do {
    get_token();
    if(*token == '{') brace++;
    else if(*token == '}') brace--;
  } while(brace && tok != END);

  if(tok==END) throw InterpExc(UNBAL_BRACES);
}

// Determine if an identifier is a variable. Return
// true if variable is found; false otherwise.
bool is_var(char *vname)
{
  // See if vname a local variable.
  if(!local_var_stack.empty())
    for(int i=local_var_stack.size()-1;
        i >= func_call_stack.top(); i--)
    {
      if(!strcmp(local_var_stack[i].var_name, vname))
        return true;
    }

  // See if vname is a global variable.
  for(unsigned i=0; i < global_vars.size(); i++)
    if(!strcmp(global_vars[i].var_name, vname))
      return true;

  return false;
}

// Return the type of variable.
token_ireps find_var_type(char *vname)
{
  // First, see if it's a local variable.
  if(!local_var_stack.empty())
    for(int i=local_var_stack.size()-1;
        i >= func_call_stack.top(); i--)
    {
      if(!strcmp(local_var_stack[i].var_name, vname))
        return local_var_stack[i].v_type;
    }

  // Otherwise, try global vars.
  for(unsigned i=0; i < global_vars.size(); i++)
    if(!strcmp(global_vars[i].var_name, vname))
        return local_var_stack[i].v_type;

  return UNDEFTOK;
}

⌨️ 快捷键说明

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