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;
  }
}