126 lines
2.6 KiB
C
126 lines
2.6 KiB
C
#include <math.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stddef.h>
|
|
|
|
#include "prog1.h"
|
|
#include "main.h"
|
|
|
|
int maxargs(A_stm statement)
|
|
{
|
|
switch (statement->kind) {
|
|
case A_compoundStm: {
|
|
int a = maxargs(statement->u.compound.stm1);
|
|
int b = maxargs(statement->u.compound.stm2);
|
|
return a > b ? a : b;
|
|
break;
|
|
}
|
|
case A_assignStm: {
|
|
if (statement->u.assign.exp->kind == A_eseqExp) {
|
|
return maxargs(statement->u.assign.exp->u.eseq.stm);
|
|
}
|
|
}
|
|
case A_printStm: {
|
|
int sum = 1;
|
|
A_expList expList = statement->u.print.exps;
|
|
while (expList->kind == A_pairExpList) {
|
|
sum++;
|
|
expList = expList->u.pair.tail;
|
|
}
|
|
return sum;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
Table_ interpStm(A_stm stm, Table_ t)
|
|
{
|
|
if (stm->kind == A_compoundStm) {
|
|
t = interpStm(stm->u.compound.stm1, t);
|
|
t = interpStm(stm->u.compound.stm2, t);
|
|
} else if (stm->kind == A_assignStm) {
|
|
IntAndTable_ it = interpExp(stm->u.assign.exp, t);
|
|
t = Table(stm->u.assign.id, it->i, it->t);
|
|
} else {
|
|
A_expList expList = stm->u.print.exps;
|
|
while (expList->kind != A_lastExpList) {
|
|
t = interpExp(expList->u.pair.head, t)->t;
|
|
expList = expList->u.pair.tail;
|
|
}
|
|
t = interpExp(expList->u.last, t)->t;
|
|
}
|
|
|
|
return t;
|
|
}
|
|
|
|
IntAndTable_ interpExp(A_exp e, Table_ t)
|
|
{
|
|
if (e->kind == A_idExp) {
|
|
return IntAndTable(lookup(t, e->u.id), t);
|
|
} else if (e->kind == A_numExp) {
|
|
return IntAndTable(e->u.num, t);
|
|
} else if (e->kind == A_opExp) {
|
|
IntAndTable_ left = interpExp(e->u.op.left, t);
|
|
IntAndTable_ right = interpExp(e->u.op.right, t);
|
|
A_binop op = e->u.op.oper;
|
|
|
|
switch (op) {
|
|
case A_plus:
|
|
return IntAndTable(left->i + right->i, t);
|
|
case A_minus:
|
|
return IntAndTable(left->i - right->i, t);
|
|
case A_times:
|
|
return IntAndTable(left->i * right->i, t);
|
|
case A_div:
|
|
return IntAndTable(left->i / right->i, t);
|
|
}
|
|
} else {
|
|
t = interpStm(e->u.eseq.stm, t);
|
|
return interpExp(e->u.eseq.exp, t);
|
|
}
|
|
}
|
|
|
|
IntAndTable_ IntAndTable(int i, Table_ t)
|
|
{
|
|
IntAndTable_ it = checked_malloc(sizeof(*it));
|
|
it->i = i;
|
|
it->t = t;
|
|
return it;
|
|
}
|
|
|
|
Table_ Table(string id, int value, struct table *tail)
|
|
{
|
|
Table_ t = checked_malloc(sizeof(*t));
|
|
t->id = id;
|
|
t->value = value;
|
|
t->tail = tail;
|
|
return t;
|
|
}
|
|
|
|
int lookup(Table_ t, string key)
|
|
{
|
|
if (t == NULL) {
|
|
// HACK: should indicate a null value
|
|
return 0;
|
|
}
|
|
|
|
if (strcmp(t->id, key) == 0) {
|
|
return t->value;
|
|
}
|
|
|
|
return lookup(t->tail, key);
|
|
}
|
|
|
|
int main()
|
|
{
|
|
A_stm program = prog();
|
|
int result = maxargs(program);
|
|
printf("maxargs: %d\n", result);
|
|
|
|
Table_ t = interpStm(program, NULL);
|
|
|
|
printf("a: %d\n", lookup(t, "a"));
|
|
printf("b: %d\n", lookup(t, "b"));
|
|
}
|