implemented enum parsing
This commit is contained in:
parent
c34bea6fff
commit
5902ec8dbc
4 changed files with 113 additions and 2 deletions
8
lc.c
8
lc.c
|
|
@ -150,6 +150,14 @@ void print_ast(ast_node *node, int depth) {
|
||||||
m = m->next;
|
m = m->next;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case NODE_ENUM:
|
||||||
|
printf("Enum: %.*s\n", (int)node->expr.enm.name_len, node->expr.enm.name);
|
||||||
|
variant *v = node->expr.enm.variants;
|
||||||
|
while (v) {
|
||||||
|
printf("\t%.*s\n", (int)v->name_len, v->name);
|
||||||
|
v = v->next;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case NODE_IF:
|
case NODE_IF:
|
||||||
printf("If:\n");
|
printf("If:\n");
|
||||||
print_ast(node->expr.whle.condition, depth + 1);
|
print_ast(node->expr.whle.condition, depth + 1);
|
||||||
|
|
|
||||||
89
parser.c
89
parser.c
|
|
@ -727,6 +727,91 @@ static member *parse_member(parser *p)
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static variant *parse_variant(parser *p)
|
||||||
|
{
|
||||||
|
if (!match_peek(p, TOKEN_IDENTIFIER)) {
|
||||||
|
error(p, "expected identifier.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
variant *v = arena_alloc(p->allocator, sizeof(variant));
|
||||||
|
v->name = peek(p)->lexeme;
|
||||||
|
v->name_len = peek(p)->lexeme_len;
|
||||||
|
advance(p);
|
||||||
|
|
||||||
|
if (match(p, TOKEN_EQ)) {
|
||||||
|
v->value = parse_factor(p);
|
||||||
|
if (!v->value) {
|
||||||
|
error(p, "expected integer.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v->value->type != NODE_INTEGER) {
|
||||||
|
error(p, "expected integer.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ast_node *parse_enum(parser *p)
|
||||||
|
{
|
||||||
|
ast_node *enm = arena_alloc(p->allocator, sizeof(ast_node));
|
||||||
|
enm->type = NODE_ENUM;
|
||||||
|
if (match_peek(p, TOKEN_IDENTIFIER)) {
|
||||||
|
/* Named enum */
|
||||||
|
enm->expr.enm.name = peek(p)->lexeme;
|
||||||
|
enm->expr.enm.name_len = peek(p)->lexeme_len;
|
||||||
|
advance(p);
|
||||||
|
} else if (!match_peek(p, TOKEN_LCURLY)) {
|
||||||
|
error(p, "expected identifier or `{`.");
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
enm->expr.enm.name = NULL;
|
||||||
|
enm->expr.enm.name_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!match(p, TOKEN_LCURLY)) {
|
||||||
|
error(p, "expected `{`.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
variant *prev = parse_variant(p);
|
||||||
|
variant *head = prev;
|
||||||
|
enm->expr.enm.variants = head;
|
||||||
|
if (!prev) {
|
||||||
|
error(p, "invalid enum definition. Enums should contain at least 1 variant.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!match(p, TOKEN_COMMA)) {
|
||||||
|
if (!match(p, TOKEN_RCURLY)) {
|
||||||
|
error(p, "expected `,`.");
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
return enm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (!match(p, TOKEN_RCURLY)) {
|
||||||
|
variant *current = parse_variant(p);
|
||||||
|
if (!current) {
|
||||||
|
error(p, "expected variant definition.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
prev->next = current;
|
||||||
|
if (!match(p, TOKEN_COMMA)) {
|
||||||
|
if (!match_peek(p, TOKEN_RCURLY)) {
|
||||||
|
error(p, "expected `,`.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
prev = current;
|
||||||
|
}
|
||||||
|
|
||||||
|
return enm;
|
||||||
|
}
|
||||||
|
|
||||||
static ast_node *parse_struct(parser *p)
|
static ast_node *parse_struct(parser *p)
|
||||||
{
|
{
|
||||||
ast_node *structure = arena_alloc(p->allocator, sizeof(ast_node));
|
ast_node *structure = arena_alloc(p->allocator, sizeof(ast_node));
|
||||||
|
|
@ -917,6 +1002,10 @@ static ast_node *parse_statement(parser *p)
|
||||||
{
|
{
|
||||||
return parse_struct(p);
|
return parse_struct(p);
|
||||||
}
|
}
|
||||||
|
else if (match(p, TOKEN_ENUM))
|
||||||
|
{
|
||||||
|
return parse_enum(p);
|
||||||
|
}
|
||||||
else if (match(p, TOKEN_UNION))
|
else if (match(p, TOKEN_UNION))
|
||||||
{
|
{
|
||||||
ast_node *u = parse_struct(p);
|
ast_node *u = parse_struct(p);
|
||||||
|
|
|
||||||
12
parser.h
12
parser.h
|
|
@ -64,6 +64,13 @@ typedef struct {
|
||||||
member *params;
|
member *params;
|
||||||
} function;
|
} function;
|
||||||
|
|
||||||
|
typedef struct _variant {
|
||||||
|
struct _ast_node *value;
|
||||||
|
char *name;
|
||||||
|
usize name_len;
|
||||||
|
struct _variant *next;
|
||||||
|
} variant;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NODE_IDENTIFIER,
|
NODE_IDENTIFIER,
|
||||||
NODE_INTEGER,
|
NODE_INTEGER,
|
||||||
|
|
@ -184,6 +191,11 @@ typedef struct _ast_node {
|
||||||
char *name;
|
char *name;
|
||||||
usize name_len;
|
usize name_len;
|
||||||
} structure;
|
} structure;
|
||||||
|
struct {
|
||||||
|
variant *variants;
|
||||||
|
char *name;
|
||||||
|
usize name_len;
|
||||||
|
} enm; // enum
|
||||||
} expr;
|
} expr;
|
||||||
} ast_node;
|
} ast_node;
|
||||||
|
|
||||||
|
|
|
||||||
6
test.c
6
test.c
|
|
@ -1,3 +1,5 @@
|
||||||
if a == x {
|
enum {
|
||||||
printf("hello");
|
a = 3,
|
||||||
|
b,
|
||||||
|
c
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue