2023-05-04 06:20:48 -04: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) {
|
2023-05-04 07:05:20 -04:00
|
|
|
case TOKEN_ROUND_OPEN:
|
|
|
|
case TOKEN_SQUARE_OPEN:
|
|
|
|
case TOKEN_CURLY_OPEN:
|
|
|
|
return parens();
|
2023-05-04 07:22:11 -04:00
|
|
|
case TOKEN_IDENT:
|
2023-05-04 06:20:48 -04:00
|
|
|
{
|
2023-05-04 06:29:22 -04:00
|
|
|
struct Object *const object = Object_new_symbol(tokens_top()->val);
|
2023-05-04 06:20:48 -04: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()
|
|
|
|
{
|
2023-05-04 07:05:20 -04:00
|
|
|
assert(tokens_top());
|
|
|
|
struct Object *object = NULL;
|
|
|
|
|
|
|
|
if (tokens_top()->type == TOKEN_ROUND_OPEN) {
|
|
|
|
expect(TOKEN_ROUND_OPEN);
|
|
|
|
object = parens_part();
|
|
|
|
expect(TOKEN_ROUND_CLOSE);
|
|
|
|
} else if (tokens_top()->type == TOKEN_SQUARE_OPEN) {
|
|
|
|
expect(TOKEN_SQUARE_OPEN);
|
|
|
|
object = parens_part();
|
|
|
|
expect(TOKEN_SQUARE_CLOSE);
|
|
|
|
} else {
|
|
|
|
expect(TOKEN_CURLY_OPEN);
|
|
|
|
object = parens_part();
|
|
|
|
expect(TOKEN_CURLY_CLOSE);
|
|
|
|
}
|
|
|
|
|
2023-05-04 06:20:48 -04:00
|
|
|
return object;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct Object *parens_part()
|
|
|
|
{
|
|
|
|
assert(tokens_top());
|
2023-05-04 07:05:20 -04:00
|
|
|
if (tokens_top()->type == TOKEN_ROUND_CLOSE ||
|
|
|
|
tokens_top()->type == TOKEN_SQUARE_CLOSE ||
|
|
|
|
tokens_top()->type == TOKEN_CURLY_CLOSE)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
2023-05-04 06:20:48 -04:00
|
|
|
|
|
|
|
struct Object *const a = expr();
|
|
|
|
assert(tokens_top());
|
|
|
|
|
|
|
|
struct Object *b = NULL;
|
2023-05-04 07:05:20 -04:00
|
|
|
if (tokens_top()->type != TOKEN_ROUND_CLOSE &&
|
|
|
|
tokens_top()->type != TOKEN_SQUARE_CLOSE &&
|
|
|
|
tokens_top()->type != TOKEN_CURLY_CLOSE)
|
|
|
|
{
|
2023-05-04 06:20:48 -04:00
|
|
|
b = parens_part();
|
|
|
|
}
|
|
|
|
|
|
|
|
struct Object *object = Object_new_pair(a, b);
|
|
|
|
return object;
|
|
|
|
}
|