Option<Term> singleTerm(TokenStream& tokens) { if (tokens->type == Token::LAMBDA) { return lambdaTerm(tokens); } else if (tokens->type == Token::OPEN_BRACKET) { tokens.advance(); Option<Term> t = term(tokens); if (tokens->type == Token::CLOSE_BRACKET) { tokens.advance(); return t; } else return errorTerm("expected closing bracket"); } else if (tokens->type == Token::IDENTIFIER) { string id = tokens->identifierValue; tokens.advance(); return Option<Term>(variableTerm(id)); } else if (tokens->type == Token::INTEGER) { int value = tokens->intValue; tokens.advance(); return Option<Term>(integerTerm(value)); } else if (tokens->type == Token::CLOSE_BRACKET) { return errorTerm("unexpected closing bracket"); } else if (!tokens.good()) { return errorTerm("expected a term"); } else return errorTerm("unknown token"); }
Option<Term> lambdaTerm(TokenStream& tokens) { assert(tokens->type == Token::LAMBDA); tokens.advance(); if (tokens->type == Token::IDENTIFIER) { string id = tokens->identifierValue; tokens.advance(); Option<Term> body = term(tokens); if (body.exists()) { return Option<Term>(lambdaTerm(id, *body)); } else return body; } else return errorTerm("expected identifier"); }