void display(Object *root) { if (root == NULL) { return; } switch (root->type) { case OBJ_TYPE_FIXNUM: { printf("%zd", root->fixnum); } break; case OBJ_TYPE_BOOL: { if (root->boolean) { printf("true"); } else { printf("false"); } } break; case OBJ_TYPE_NIL: { printf("()"); } break; case OBJ_TYPE_STRING: { printf("\"%.*s\"", (int)root->string_n, root->string); } break; case OBJ_TYPE_SYMBOL: { printf(":%.*s", (int)root->symbol_n, root->symbol); } break; case OBJ_TYPE_PAIR: { printf("("); display_pair(root); printf(")"); } break; default: { printf("TYPE NOT IMPLEMENTED FOR DISPLAY."); } break; } } Object * eval(Object *root) { if (root == NULL) { return NULL; } switch (root->type) { case OBJ_TYPE_FIXNUM: case OBJ_TYPE_BOOL: case OBJ_TYPE_NIL: case OBJ_TYPE_STRING: case OBJ_TYPE_SYMBOL: { return root; } break; case OBJ_TYPE_PAIR: { if (root->car->type == OBJ_TYPE_SYMBOL) { Object *value = find_environment_symbol(root->car); if (value == NULL) { printf("error: symbol not found: `"); display(root->car); printf("`\n"); return NULL; } if (value->type == OBJ_TYPE_PROCEDURE) { return value->proc(root->cdr); } } } break; default: { printf("error: can't eval type %d.\n", root->type); } break; } return NULL; } Object * proc_add(Object *args) { ssize_t tot = 0; while (args->type == OBJ_TYPE_PAIR) { Object *car = eval(args->car); if (car->type != OBJ_TYPE_FIXNUM) { fprintf(stderr, "addition not supported for type %d\n", car->type); return NULL; } tot += car->fixnum; args = args->cdr; } return make_fixnum(tot); } Object * proc_sub(Object *args) { if (args->type != OBJ_TYPE_PAIR) { fprintf(stderr, "substraction not supported for type %d\n", args->type); return NULL; } // Extract first parameter. Object *car = eval(args->car); args = args->cdr; ssize_t tot = car->fixnum; while (args->type == OBJ_TYPE_PAIR) { Object *car = eval(args->car); if (car->type != OBJ_TYPE_FIXNUM) { fprintf(stderr, "substraction not supported for type %d\n", car->type); return NULL; } tot -= car->fixnum; args = args->cdr; } return make_fixnum(tot); } Object * proc_mul(Object *args) { ssize_t tot = 1; while (args->type == OBJ_TYPE_PAIR) { Object *car = eval(args->car); if (car->type != OBJ_TYPE_FIXNUM) { fprintf(stderr, "multiply not supported for type %d\n", car->type); return NULL; } tot *= car->fixnum; args = args->cdr; } return make_fixnum(tot); } Object * proc_div(Object *args) { if (args->type != OBJ_TYPE_PAIR) { fprintf(stderr, "substraction not supported for type %d\n", args->type); return NULL; } // Extract first parameter. Object *car = eval(args->car); args = args->cdr; ssize_t tot = car->fixnum; while (args->type == OBJ_TYPE_PAIR) { Object *car = eval(args->car); if (car->type != OBJ_TYPE_FIXNUM) { fprintf(stderr, "div not supported for type %d\n", car->type); return NULL; } tot /= car->fixnum; args = args->cdr; } return make_fixnum(tot); }