compiler/parser.c

91 lines
2.5 KiB
C

#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;
}