📄 chsh.cpp
字号:
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 + -