1
0
Fork 0
lesson-lisp/parser.c

76 lines
1.4 KiB
C
Raw Normal View History

2023-05-04 10:20:48 +00:00
#include "parser.h"
#include "enums.h"
#include "object.h"
#include "tokens.h"
#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
static void expect(enum TokenType token_type);
static struct Object *expr();
static struct Object *parens();
static struct Object *parens_part();
void expect(const enum TokenType token_type)
{
assert(tokens_expect(token_type));
}
struct Object *parse()
{
return expr();
}
struct Object *expr()
{
assert(tokens_top());
switch (tokens_top()->type) {
case TOKEN_OPEN: return parens();
2023-05-04 10:29:22 +00:00
case TOKEN_SYMBOL:
2023-05-04 10:20:48 +00:00
{
2023-05-04 10:29:22 +00:00
struct Object *const object = Object_new_symbol(tokens_top()->val);
2023-05-04 10:20:48 +00:00
tokens_pop();
return object;
}
case TOKEN_NUM:
{
struct Object *const object =
Object_new_number(atoll(tokens_top()->val));
tokens_pop();
return object;
}
default:
abort();
return NULL;
}
}
struct Object *parens()
{
expect(STATE_OPEN);
struct Object *const object = parens_part();
expect(STATE_CLOSE);
return object;
}
struct Object *parens_part()
{
assert(tokens_top());
if (tokens_top()->type == TOKEN_CLOSE) return NULL;
struct Object *const a = expr();
assert(tokens_top());
struct Object *b = NULL;
if (tokens_top()->type != TOKEN_CLOSE) {
b = parens_part();
}
struct Object *object = Object_new_pair(a, b);
return object;
}