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> term(TokenStream& tokens) { Option<Term> current = singleTerm(tokens); if (current.exists()) { while (tokens.good() && tokens->type != Token::CLOSE_BRACKET) { Option<Term> next = singleTerm(tokens); if (next.exists()) { current = Option<Term>(applicationTerm(*current, *next)); } else return next; } return current; } else return current; }