static struct term *_lambda_parse(struct lexer *lex, enum term_parse_res *res) { struct term *body = NULL; struct term *ret = NULL; if(lex->type != TOK_SYM) { *res = PARSE_EXPECTED_SYM; goto done; } else { char var[VAR_LEN]; strncpy(var, lex->sym, VAR_LEN); lexer_advance(lex); if(lex->type != TOK_DOT) { *res = PARSE_EXPECTED_DOT; goto done; } lexer_advance(lex); body = _term_parse(lex, res); if(! body) { goto done; } ret = make_lambda(var, body); } done: destroy_term(body); return ret; }
static struct term *_term_parse(struct lexer *lex, enum term_parse_res *res) { struct term *ret = NULL; switch(lex->type) { case TOK_NONE: *res = PARSE_EXPECTED_TERM; break; case TOK_LPAREN: lexer_advance(lex); ret = _lparen_parse(lex, res); break; case TOK_RPAREN: *res = PARSE_UNEXPECTED_RPAREN; break; case TOK_LAMBDA: lexer_advance(lex); ret = _lambda_parse(lex, res); break; case TOK_DOT: *res = PARSE_UNEXPECTED_DOT; break; case TOK_SYM: ret = make_var(lex->sym); lexer_advance(lex); break; } return ret; }
static struct term *_lparen_parse(struct lexer *lex, enum term_parse_res *res) { struct term *term1 = NULL; struct term *term2 = NULL; struct term *ret = NULL; term1 = _term_parse(lex, res); if(! term1) { goto done; } if(lex->type != TOK_RPAREN) { term2 = _term_parse(lex, res); if(! term2) { goto done; } if(lex->type != TOK_RPAREN) { *res = PARSE_EXPECTED_RPAREN; goto done; } lexer_advance(lex); ret = make_appl(term1, term2); } else { lexer_advance(lex); ret = term1; term1 = NULL; } done: destroy_term(term1); destroy_term(term2); return ret; }
struct term *term_parse(FILE *instream, enum term_parse_res *res) { struct lexer lex = { .stream = instream, .type = TOK_NONE }; *res = PARSE_OK; lexer_advance(&lex); return _term_parse(&lex, res); }
token_t * lexer_peek(lexer_t *l) { if (!l) return NULL; list_node_t *n = l->curtok; token_t *t = lexer_advance(l); l->curtok = n; return t; }