#include "runtime.h" box_t cons(box_t car, box_t cdr) { cons_t* kons = alloc(); kons->car = car; kons->cdr = cdr; box_t box; box.type = CONS; box.cons = kons; return box; } void chomp_ws() { char c = getchar(); for(;;) { if (c == ' ' || c == '\t' || c == '\n' || c == '\r') { c = getchar(); } else { ungetchar(c); break; } } } box_t read_integer() { char buf[256]; size_t i = 0; char next = getchar(); while(isdigit(next)) { buf[i] = next; next = getchar(); i++; } ungetchar(next); buf[i] = 0; box_t res; res.type = INTEGER; res.integer = atoi(buf); chomp_ws(); return res; } box_t read_symbol() { char buf[256]; size_t i = 0; char next = getchar(); while (isalpha(next)) { // Totally insufficent but we'll look into it later buf[i] = next; next = getchar(); i++; } ungetchar(next); buf[i] = 0; box_t res; char *str = strndup(buf, i); res.type = SYMBOL; res.symbol = str; chomp_ws(); // Clean up whitespace afterwards return res; } box_t read_list() { char c = getchar(); box_t val; if (c == ')') { chomp_ws(); val.type = CONS; val.cons = the_empty_list; return val; } else { ungetchar(c); box_t car = read(); box_t cdr = read_list(); return cons(car, cdr); } } box_t read() { chomp_ws(); char next = getchar(); if (next == '(') { chomp_ws(); return read_list(); } else if (isdigit(next)) { ungetchar(next); return read_integer(); } else if (isalpha(next) || ispunct(next)) { ungetchar(next); return read_symbol(); } else if (next == EOF) { box_t bye; bye.type = BYE; return bye; } else { fprintf(stderr, "Bad input"); exit(1); } } void scm_print_cons(box_t exp) { printf("("); while(exp.type = CONS && exp.cons != the_empty_list) { scm_print(exp.cons->car); if (exp.cons->cdr.cons != the_empty_list) { printf(" "); } exp = exp.cons->cdr; } if (exp.cons == the_empty_list) { printf(")"); } else { printf(". "); scm_print(exp); printf(")"); } } void scm_print(box_t exp) { switch (exp.type) { case INTEGER: printf("%d", exp.integer); break; case SYMBOL: printf("%s", exp.symbol); break; case CONS: scm_print_cons(exp); break; } } box_t eval(box_t exp) { return exp; }