#include "parser.h" #include "assert.h" #include "printf.h" #include "malloc.h" struct token peek(struct token_reader * reader) { if (reader->have_token) { return reader->token; } else { reader->token = lexer_next_token(&reader->lexer_state); reader->have_token = true; return reader->token; } } struct token consume(struct token_reader * reader) { struct token token = peek(reader); reader->have_token = false; return token; } bool match_type(struct token_reader * reader, enum token_type token_type) { struct token token = peek(reader); if (token.type == token_type) { consume(reader); return true; } else { return false; } } struct token expect_type(struct token_reader * reader, enum token_type token_type) { struct token token = consume(reader); if (!(token.type == token_type)) { printf("token.type=%d token_type=%d\n", token.type, token_type); fail(token.type == token_type); } return token; } struct expression * parse_expression(struct token_reader * reader) { struct expression * expr = malloct(struct expression); struct token token = expect_type(reader, TOKEN_CONSTANT); expr->constant = token; return expr; } struct statement_return * parse_statement_return(struct token_reader * reader) { struct expression * expr = parse_expression(reader); struct statement_return * stmt = malloct(struct statement_return); stmt->expression = expr; return stmt; } struct statement_if_else * parse_statement_if_else(struct token_reader * reader) { struct statement_if_else * stmt = malloct(struct statement_if_else); expect_type(reader, TOKEN_LPAREN); struct expression * expr = parse_expression(reader); expect_type(reader, TOKEN_RPAREN); struct statement * statement_if = parse_statement(reader); struct statement * statement_else = match_type(reader, TOKEN_ELSE) ? parse_statement(reader) : nullptr; stmt->expression = expr; stmt->statement_if = statement_if; stmt->statement_else = statement_else; return stmt; } struct statement * parse_statement(struct token_reader * reader) { struct statement * stmt = malloct(struct statement); if (match_type(reader, TOKEN_IF)) { stmt->type = STATEMENT_IF_ELSE; stmt->statement_if_else = parse_statement_if_else(reader); } else if (match_type(reader, TOKEN_RETURN)) { stmt->type = STATEMENT_RETURN; stmt->statement_return = parse_statement_return(reader); } else { printf("token_type=%d\n", peek(reader).type); fail("expected statement"); } return stmt; }