#include #include using namespace std; struct reader { string value; bool used; reader() { used = false; } string read_string() { string r; if (used) { used = false; r = value; } else cin >> r; return r; } string sneak_peek() { string r; if (! used) cin >> value; r = value; used = true; return r; } void clear() { used = false; } }; struct Sexpr { char kind; // 'L' = list link, 'A' = atom string atom; Sexpr * head, * tail; Sexpr(string a) { kind = 'A'; atom = a; } Sexpr(Sexpr * h, Sexpr * t) { kind = 'L'; head = h; tail = t; } void print() { if (this == NULL) { cout << "( )"; return; } if (kind == 'A') { cout << atom; return; } cout << "( "; Sexpr * ptr = this; while (ptr != NULL) { ptr->head->print(); cout << " "; ptr = ptr->tail; } cout << ")"; } }; /* int main() { Sexpr * F = new Sexpr("3"); Sexpr * E = new Sexpr(F, NULL); Sexpr * D = new Sexpr("2"); Sexpr * C = new Sexpr(D, E); Sexpr * B = new Sexpr("1"); Sexpr * A = new Sexpr(B, C); A->print(); } */ Sexpr * read_rest_sexpr(reader & R); Sexpr * read_sexpr(reader & R) { string a = R.read_string(); if (a == "(") return read_rest_sexpr(R); if (a == ")") { cout << "ERROR unexpected )\n"; a = "???"; } return new Sexpr(a); } Sexpr * read_rest_sexpr(reader & R) // read an Sexpression that begins with a (, // but the ( has already been read { string a = R.sneak_peek(); if (a == ")") { R.read_string(); return NULL; } Sexpr * h = read_sexpr(R); Sexpr * t = read_rest_sexpr(R); return new Sexpr(h, t); } int str_to_int(string s) { int r = 0, n = s.length(); for (int i = 0; i < n; i += 1) r = r * 10 + s[i] - '0'; return r; } string int_to_str(int n) { string r = ""; if (n > 9) r = r + int_to_str(n / 10); return r + (char)('0' + n % 10); } Sexpr * add(Sexpr * A, Sexpr * B) { return new Sexpr(int_to_str(str_to_int(A->atom) + str_to_int(B->atom))); } Sexpr * mul(Sexpr * A, Sexpr * B) { return new Sexpr(int_to_str(str_to_int(A->atom) * str_to_int(B->atom))); } Sexpr * eval(Sexpr * E) { if (E == NULL) return NULL; if (E->kind == 'A') return E; Sexpr * h = E->head; if (h->kind != 'A') { cout << "ERROR " << h->atom << " is not sn operation\n"; return NULL; } if (h->atom == "quote") return E->tail->head; if (h->atom == "+") { Sexpr * ptr = E->tail; Sexpr * sum = new Sexpr("0"); while (ptr != NULL) { sum = add(sum, eval(ptr->head)); ptr = ptr->tail; } return sum; } if (h->atom == "*") { Sexpr * ptr = E->tail; Sexpr * sum = new Sexpr("1"); while (ptr != NULL) { sum = mul(sum, eval(ptr->head)); ptr = ptr->tail; } return sum; } cout << "can't handle operator " << h->atom << " yet\n"; return NULL; } int main() { reader R; while (true) { R.clear(); cout << "> "; Sexpr * x = read_sexpr(R); eval(x)->print(); cout << "\n\n"; } }