📄 executor.cpp
字号:
if(next_index != -1)
push(&stat_stak, next_index, NOT_YET_EVALUATED);
}
return;
}
void handle_goto(int stat_ndx)
{
long fpos;
FILE *fp;
char *token;
char *identifier;
int jump_index;
int i, max;
int origin, dest;
int blk_begin, blk_end;
struct BLOCK_REC *blocks;
//get the starting file position
fpos = get_start_position(*stat_tab, stat_ndx);
//open file and set pointer
fp = fopen(fname, "rt");
fseek(fp,fpos,SEEK_SET);
//consume goto
token = (char *)safe_alloc(TOKEN_SIZE,sizeof(char));
token = get_next_token(fp,token);
//read identifier
memset(token,'\0',strlen(token));
token = get_next_token(fp,token);
identifier = (char *)safe_alloc(strlen(token)+1,sizeof(char));
strcpy(identifier,token);
//get value of label identifier from symbol table
jump_index = get_symbol_offset_value(*sym_tab,
symbol_table_lookup(*sym_tab, identifier));
//push program scope onto block stack
max = count_statements(*stat_tab);
block_push(&blocks,0,max);
origin = get_top_index(stat_stak);
dest = jump_index;
//pop statement stack
pop(&stat_stak);
for(i=0;i<max;i++)
{
//adjust the current block stack
while(i < get_top_start(blocks) || i > get_top_end(blocks))
{
block_pop(&blocks);
}
//is this statement a while or an if?
if(get_statement_type(*stat_tab,i) == WHILE_TYPE ||
get_statement_type(*stat_tab,i) == IF_TYPE)
{
//find extent of statement block
blk_begin = get_jump_index(*stat_tab,i);
blk_end = get_next_index(*stat_tab,i) -1;
if(blk_end == -2)
blk_end = get_top_end(blocks);
//push current block onto block stack
block_push(&blocks, blk_begin, blk_end);
//compare origin and dest to current block
if((origin >= blk_begin && origin <= blk_end) &&
(dest < blk_begin || dest > blk_end))
{
//jumping out of this block from inside
//extract this from the statement stack
extract(&stat_stak,i);
}
if((origin < blk_begin || origin > blk_end) &&
(dest >= blk_begin && dest <= blk_end))
{
//jumping into this block from outside
//push this onto the statement stack
push(&stat_stak,i,ALREADY_EVALUATED);
}
}
}
//push label statement being "jumped to"
push(&stat_stak, jump_index, NOT_YET_EVALUATED);
//dump_structs("source.txt");
while(blocks == NULL)
block_pop(&blocks);
safe_free(token);
safe_free(identifier);
fclose(fp); //CTL
return;
}
int evaluate_expression(FILE *fp, long *ires, float *fres,
char **sres)
{
int val_type;
long ival;
float fval;
char *sval;
struct PEND_OP *curr;
struct PEND_OP *tmp;
val_type = evaluate_term(fp, &ival, &fval, &sval);
curr = evaluate_eprime(fp);
//No math operations with strings
if(val_type == SY_STRING_TYPE)
{
if(curr)
info_message("Strings not allowed in mathematical expression.\n");
*sres = (char *)safe_alloc(strlen(sval)+1,sizeof(char));
strcpy(*sres,sval);
safe_free(sval);
while(curr)
{
tmp = curr;
curr = curr->next;
safe_free(tmp);
}
return(val_type);
}
//process pending + - operations
while(curr)
{
if(val_type == SY_INT_TYPE)
{
if(curr->val_type == SY_INT_TYPE)
{ //int int
if(curr->op_type == ADD_OP)
ival = ival + curr->ival;
else
ival = ival - curr->ival;
}
else
{ //int float
if(curr->op_type == ADD_OP)
{
val_type = SY_FLOAT_TYPE;
fval = (float)(ival) + curr->fval;
}
else
{
val_type = SY_FLOAT_TYPE;
fval = (float)(ival) - curr->fval;
}
}
}
else
{
if(curr->val_type == SY_INT_TYPE)
{ //float int
if(curr->op_type == ADD_OP)
fval = fval + (float)(curr->ival);
else
fval = fval - (float)(curr->ival);
}
else
{ //float float
if(curr->op_type == ADD_OP)
fval = fval + curr->fval;
else
fval = fval - curr->fval;
}
}
tmp = curr;
curr = curr->next;
safe_free(tmp);
}
//return value
if(val_type == SY_INT_TYPE)
*ires = ival;
if(val_type == SY_FLOAT_TYPE)
*fres = fval;
return(val_type);
}
struct PEND_OP *evaluate_eprime(FILE *fp)
{
char *token;
long fpos;
int val_type;
long ival;
float fval;
char *sval;
struct PEND_OP *tail;
struct PEND_OP *curr;
fpos = ftell(fp);
token = (char *)safe_alloc(TOKEN_SIZE,sizeof(char));
token = get_next_token(fp,token);
if(strcmp(token,"+")==0)
{
val_type = evaluate_term(fp,&ival,&fval,&sval);
tail = evaluate_eprime(fp);
curr = (struct PEND_OP *)safe_alloc(1,sizeof(struct PEND_OP));
curr->next = tail;
curr->op_type = ADD_OP;
curr->val_type = val_type;
if(val_type == SY_FLOAT_TYPE)
curr->fval = fval;
if(val_type == SY_INT_TYPE)
curr->ival = ival;
safe_free(token);
return(curr);
}
if(strcmp(token,"-")==0)
{
val_type = evaluate_term(fp,&ival,&fval,&sval);
tail = evaluate_eprime(fp);
curr = (struct PEND_OP *)safe_alloc(1,sizeof(struct PEND_OP));
curr->next = tail;
curr->op_type = SUBTRACT_OP;
curr->val_type = val_type;
if(val_type == SY_FLOAT_TYPE)
curr->fval = fval;
if(val_type == SY_INT_TYPE)
curr->ival = ival;
safe_free(token);
return(curr);
}
//produce an empty eprime
fseek(fp,fpos,SEEK_SET);
safe_free(token);
return(NULL);
}
int evaluate_term(FILE *fp, long *ires, float *fres,
char **sres)
{
int val_type;
long ival;
float fval;
char *sval;
struct PEND_OP *curr;
struct PEND_OP *tmp;
val_type = evaluate_fneg(fp, &ival, &fval, &sval);
curr = evaluate_tprime(fp);
//No math operations with strings
if(val_type == SY_STRING_TYPE)
{
if(curr)
info_message("Strings not allowed in mathematical term.\n");
*sres = (char *)safe_alloc(strlen(sval)+1,sizeof(char));
strcpy(*sres,sval);
safe_free(sval);
while(curr)
{
tmp = curr;
curr = curr->next;
safe_free(tmp);
}
return(val_type);
}
//process pending * / operations
while(curr)
{
if(val_type == SY_INT_TYPE)
{
if(curr->val_type == SY_INT_TYPE)
{ //int int
if(curr->op_type == MULTIPLY_OP)
ival = ival * curr->ival;
else
ival = (int)(ival / curr->ival);
}
else
{ //int float
if(curr->op_type == MULTIPLY_OP)
{
val_type = SY_FLOAT_TYPE;
fval = (float)(ival) * curr->fval;
}
else
{
val_type = SY_FLOAT_TYPE;
fval = (float)(ival) / curr->fval;
}
}
}
else
{
if(curr->val_type == SY_INT_TYPE)
{ //float int
if(curr->op_type == MULTIPLY_OP)
fval = fval * (float)(curr->ival);
else
fval = fval / (float)(curr->ival);
}
else
{ //float float
if(curr->op_type == MULTIPLY_OP)
fval = fval * curr->fval;
else
fval = fval / curr->fval;
}
}
tmp = curr;
curr = curr->next;
safe_free(tmp);
}
//return value
if(val_type == SY_INT_TYPE)
*ires = ival;
if(val_type == SY_FLOAT_TYPE)
*fres = fval;
return(val_type);
}
struct PEND_OP *evaluate_tprime(FILE *fp)
{
char *token;
long fpos;
int val_type;
long ival;
float fval;
char *sval;
struct PEND_OP *tail;
struct PEND_OP *curr;
fpos = ftell(fp);
token = (char *)safe_alloc(TOKEN_SIZE,sizeof(char));
token = get_next_token(fp,token);
if(strcmp(token,"*")==0)
{
val_type = evaluate_fneg(fp, &ival, &fval, &sval);
tail = evaluate_tprime(fp);
curr = (struct PEND_OP *)safe_alloc(1,sizeof(struct PEND_OP));
curr->next = tail;
curr->op_type = MULTIPLY_OP;
curr->val_type = val_type;
if(val_type == SY_FLOAT_TYPE)
curr->fval = fval;
if(val_type == SY_INT_TYPE)
curr->ival = ival;
safe_free(token);
return(curr);
}
if(strcmp(token,"/")==0)
{
val_type = evaluate_fneg(fp, &ival, &fval, &sval);
tail = evaluate_tprime(fp);
curr = (struct PEND_OP *)safe_alloc(1,sizeof(struct PEND_OP));
curr->next = tail;
curr->op_type = DIVIDE_OP;
curr->val_type = val_type;
if(val_type == SY_FLOAT_TYPE)
{
if(fval == 0)
{
info_message("Division by zero - Results will be invalid.\n");
fval = 0.1;
}
curr->fval = fval;
}
if(val_type == SY_INT_TYPE)
{
if(ival == 0)
{
info_message("Division by zero - Results will be invalid.\n");
ival = 1;
}
curr->ival = ival;
}
safe_free(token);
return(curr);
}
//Produce an empty tprime
fseek(fp,fpos,SEEK_SET);
safe_free(token);
return(NULL);
}
int evaluate_fneg(FILE *fp, long *ires, float *fres,
char **sres)
{
char *token;
int val_type;
long ival;
float fval;
char *sval;
long fpos;
fpos = ftell(fp);
token = (char *)safe_alloc(TOKEN_SIZE,sizeof(char));
token = get_next_token(fp, token);
if(strcmp(token,"-")==0)
{
safe_free(token);
val_type = evaluate_factor(fp, &ival, &fval, &sval);
if(val_type == SY_INT_TYPE)
{
*ires = -ival;
return(val_type);
}
if(val_type == SY_FLOAT_TYPE)
{
*fres = -fval;
return(val_type);
}
info_message("Cannot negate a string value.\n");
*sres = (char *)safe_alloc(strlen(sval)+1,sizeof(char));
strcpy(*sres,sval);
safe_free(sval);
return(val_type);
}
else
{
fseek(fp,fpos,SEEK_SET);
safe_free(token);
val_type = evaluate_factor(fp, &ival, &fval, &sval);
if(val_type == SY_INT_TYPE)
{
*ires = ival;
return(val_type);
}
if(val_type == SY_FLOAT_TYPE)
{
*fres = fval;
return(val_type);
}
*sres = (char *)safe_alloc(strlen(sval)+1,sizeof(char));
strcpy(*sres,sval);
safe_free(sval);
return(val_type);
}
}
int evaluate_factor(FILE *fp, long *ires, float *fres,
char **sres)
{
char *token;
int val_type;
long ival;
float fval;
char *sval;
char c;
long numeric_val;
long fpos;
int i;
//read in a token
fpos = ftell(fp);
token = (char *)safe_alloc(TOKEN_SIZE,sizeof(char));
token = get_next_token(fp,token);
//if it is a '(' then evaluate an expression, consume ')'
// and then return the result
if(strcmp(token,"(")==0)
{
val_type = evaluate_expression(fp, &ival, &fval, &sval);
memset(token,'\0',strlen(token));
token = get_next_token(fp,token);
if(val_type == SY_STRING_TYPE)
{
*sres = (char *)safe_alloc(strlen(sval)+1,sizeof(char));
strcpy(*sres,sval);
safe_free(sval);
safe_free(token);
return(SY_STRING_TYPE);
}
if(val_type == SY_FLOAT_TYPE)
{
*fres = fval;
safe_free(token);
return(SY_FLOAT_TYPE);
}
if(val_type == SY_INT_TYPE)
{
*ires = ival;
safe_free(token);
return(SY_INT_TYPE);
}
}
//pushback input token
fseek(fp,fpos,SEEK_SET);
if(parse_fname(fp))
{
fseek(fp,fpos,SEEK_SET);
//Function wrapper will take care of moving fp
val_type = function_wrapper(fp, &ival, &fval, &sval);
if(val_type == SY_STRING_TYPE)
{
*sres = (char *)safe_alloc(strlen(sval)+1,sizeof(char));
strcpy(*sres,sval);
safe_free(sval);
}
if(val_type == SY_FLOAT_TYPE)
{
*fres = fval;
}
if(val_type == SY_INT_TYPE)
{
*ires = ival;
}
safe_free(token);
return(val_type);
}
//if it starts with a character, then look up an identifier and
// return the identifier's value
memset(token,'\0',strlen(token));
token = get_next_token(fp,token);
c = token[0];
if(isitalpha(c))
{
i = symbol_table_lookup(*sym_tab, token);
val_type = get_symbol_type(*sym_tab, i);
if(val_type == SY_STRING_TYPE)
{
sval = get_symbol_string_value(*sym_tab, i);
*sres = (char *)safe_alloc(strlen(sval)+1,sizeof(char));
strcpy(*sres,sval);
safe_free(token);
return(SY_STRING_TYPE);
}
if(val_type == SY_FLOAT_TYPE)
{
*fres = get_symbol_float_value(*sym_tab,i);
safe_free(token);
return(SY_FLOAT_TYPE);
}
if(val_type == SY_INT_TYPE)
{
*ires = get_symbol_int_value(*sym_tab,i);
safe_free(token);
return(SY_INT_TYPE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -