|
CS456 - Systems Programming
| Displaying exercises/e8/files/run.c
#include "lang.h"
int64_t eval_expr(enode_t *e)
{
int64_t l, r;
// Don't "evaluate" the lval of an assignment.
if (e->left && e->op != T_ASSIGN) l = eval_expr(e->left);
if (e->right) r = eval_expr(e->right);
switch(e->op) {
case T_NUMBER: return e->value;
case T_IDENTIFIER: return e->var->value;
case T_PLUS: return l + r;
case T_MINUS: return l - r;
case T_MULT: return l * r;
case T_DIV: return l / r;
case T_MOD: return l % r;
case T_OR: return l || r;
case T_AND: return l && r;
case T_LT: return l < r;
case T_GT: return l > r;
case T_EQUAL: return l == r;
case T_ASSIGN:
e->left->var->value = r;
return r;
default:
return 0;
}
return 0;
}
void run(stnode_t *st, int *cont, int *brk)
{
stnode_t *n;
for(n = st; n != NULL; n=n->next) {
switch(n->type) {
case ST_EXPRESSION:
eval_expr(n->expr);
break;
case ST_PRINT:
printf("%ld\n", eval_expr(n->expr));
break;
case ST_CONTINUE:
(*cont)++;
return;
case ST_BREAK:
(*brk)++;
return;
case ST_WHILE:
*brk = *cont = 0;
while(eval_expr(n->w->expr)) {
run(n->w->body, cont, brk);
if (*brk) break;
if (*cont) { *cont = 0; continue; }
}
*brk = *cont = 0;
break;
case ST_IF:
if (eval_expr(n->i->expr)) {
run(n->i->body, cont, brk);
} else if (n->i->elsebody) {
run(n->i->elsebody, cont, brk);
}
break;
}
if (*brk || *cont) return;
}
}
|