5.4. Samples for SFL
The simplifier
AST simplify(AST t)
{
switch(t->kind) {
case ID_NK:
return symbolTableLookup(t->fields.strval);
case INTCONST_NK:
case CHARCONST_NK:
case BOOLCONST_NK:
case CONS_NK:
case FUNCTION_NK:
return t;
case COLON_NK:
return consNode(simplify(t->fields.subtrees.s1),
simplify(t->fields.subtrees.s2));
case OP_NK:
return performOp(t->extra,
simplify(t->fields.subtrees.s1),
simplify(t->fields.subtrees.s2));
case APPLY_NK:
{AST A, B, SA, SB, R;
A = t->fields.subtrees.s1;
B = t->fields.subtrees.s2;
SA = simplify(A);
SB = simplify(B);
if(SA->kind != FUNCTION_NK) {
abort(applyNode(SA, SB));
}
R = performApply(SA->fields.subtrees.s1, SB);
return simplify(R);
}
…
}
}
The interpreter
void runInterpreter(void)
{
AST M, R;
M = symbolTableLookup("main");
R = simplify(M);
if(isAction(R)) {
performAction(R);
}
else {
printAST(R);
}
}
Performing actions
AST performAction(AST R)
{
AST S = simplify(R);
switch(S->kind) {
case READ_NK:
{int what = S->extra;
if(what == READ_INT_FK) {
return readInt();
}
else if(what == READ_CHAR_FK) {
return readChar();
}
else
abortAction(S);
}
}
case ACTION_FUN_NK:
{int what = S->extra;
if(what == PRODUCE_FK) {
return S->fields.subtrees.s1;
}
else if(what == PRINT_FK) {
return print(S->fields.subtrees.s1);
}
else if(what == PRINT_LIST_FK) {
return printList(S->fields.subtrees.s1);
}
else {
abortAction(S);
}
}
case TILDE_GT_NK:
{AST A, B, X;
A = S->fields.subtrees.s1;
B = S->fields.subtrees.s2;
X = performAction(A);
return performAction(applyNode(B, X));
}
…
default:
abortAction(S);
return NULL;
}
}
AST readInt(void)
{
int n, x;
n = scanf("%d", &x);
if(n == 1) {
return numberNode(x);
}
else {
abort("Cannot read an integer");
return NULL;
}
}