implemented structure parsing
This commit is contained in:
parent
d0d750f059
commit
664affc6d3
4 changed files with 119 additions and 4 deletions
8
lc.c
8
lc.c
|
|
@ -134,6 +134,14 @@ void print_ast(ast_node *node, int depth) {
|
||||||
current = current->expr.unit_node.next;
|
current = current->expr.unit_node.next;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case NODE_STRUCT:
|
||||||
|
printf("Struct: %.*s\n", (int)node->expr.structure.name_len, node->expr.structure.name);
|
||||||
|
member *m = node->expr.structure.members;
|
||||||
|
while (m) {
|
||||||
|
print_ast(m->type, depth + 1);
|
||||||
|
m = m->next;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case NODE_IF:
|
case NODE_IF:
|
||||||
printf("IfStmt (Fields missing in struct)\n");
|
printf("IfStmt (Fields missing in struct)\n");
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
97
parser.c
97
parser.c
|
|
@ -676,6 +676,99 @@ static ast_node *parse_while(parser *p)
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ast_node *parse_struct(parser *p);
|
||||||
|
static member *parse_member(parser *p)
|
||||||
|
{
|
||||||
|
ast_node *type = NULL;
|
||||||
|
|
||||||
|
if (match(p, TOKEN_STRUCT)) {
|
||||||
|
type = parse_struct(p);
|
||||||
|
}
|
||||||
|
if (!type) {
|
||||||
|
type = parse_factor(p);
|
||||||
|
if (!type) {
|
||||||
|
error(p, "expected struct definition or identifier.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (type->type != NODE_IDENTIFIER) {
|
||||||
|
error(p, "expected struct definition or identifier.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!match_peek(p, TOKEN_IDENTIFIER)) {
|
||||||
|
error(p, "expected identifier.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
member *m = arena_alloc(p->allocator, sizeof(member));
|
||||||
|
m->type = type;
|
||||||
|
m->name = peek(p)->lexeme;
|
||||||
|
m->name_len = peek(p)->lexeme_len;
|
||||||
|
advance(p);
|
||||||
|
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ast_node *parse_struct(parser *p)
|
||||||
|
{
|
||||||
|
ast_node *structure = arena_alloc(p->allocator, sizeof(ast_node));
|
||||||
|
structure->type = NODE_STRUCT;
|
||||||
|
if (match_peek(p, TOKEN_IDENTIFIER)) {
|
||||||
|
/* Named structure */
|
||||||
|
structure->expr.structure.name = peek(p)->lexeme;
|
||||||
|
structure->expr.structure.name_len = peek(p)->lexeme_len;
|
||||||
|
advance(p);
|
||||||
|
} else if (!match_peek(p, TOKEN_LCURLY)) {
|
||||||
|
error(p, "expected identifier or `{`.");
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
structure->expr.structure.name = NULL;
|
||||||
|
structure->expr.structure.name_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!match(p, TOKEN_LCURLY)) {
|
||||||
|
error(p, "expected `{`.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
member *prev = parse_member(p);
|
||||||
|
member *head = prev;
|
||||||
|
structure->expr.structure.members = head;
|
||||||
|
if (!prev) {
|
||||||
|
error(p, "invalid struct definition. Structs should contain at least 1 member.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!match(p, TOKEN_COMMA)) {
|
||||||
|
if (!match(p, TOKEN_RCURLY)) {
|
||||||
|
error(p, "expected `,`.");
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
return structure;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (!match(p, TOKEN_RCURLY)) {
|
||||||
|
member *current = parse_member(p);
|
||||||
|
if (!current) {
|
||||||
|
error(p, "expected member 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 structure;
|
||||||
|
}
|
||||||
|
|
||||||
static ast_node *parse_statement(parser *p)
|
static ast_node *parse_statement(parser *p)
|
||||||
{
|
{
|
||||||
if (match(p, TOKEN_BREAK))
|
if (match(p, TOKEN_BREAK))
|
||||||
|
|
@ -802,6 +895,10 @@ static ast_node *parse_statement(parser *p)
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
else if (match(p, TOKEN_STRUCT))
|
||||||
|
{
|
||||||
|
return parse_struct(p);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ast_node *expr = parse_expression(p);
|
ast_node *expr = parse_expression(p);
|
||||||
|
|
|
||||||
13
parser.h
13
parser.h
|
|
@ -4,6 +4,8 @@
|
||||||
#include "lexer.h"
|
#include "lexer.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
struct _ast_node;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
OP_PLUS, // +
|
OP_PLUS, // +
|
||||||
OP_MINUS, // -
|
OP_MINUS, // -
|
||||||
|
|
@ -49,11 +51,11 @@ typedef enum {
|
||||||
LAYOUT_EXTERN
|
LAYOUT_EXTERN
|
||||||
} struct_layout;
|
} struct_layout;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct _member {
|
||||||
char *type_name;
|
struct _ast_node *type;
|
||||||
usize type_len;
|
|
||||||
char *name;
|
char *name;
|
||||||
usize name_len;
|
usize name_len;
|
||||||
|
struct _member *next;
|
||||||
} member;
|
} member;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
@ -177,6 +179,11 @@ typedef struct _ast_node {
|
||||||
char *type;
|
char *type;
|
||||||
usize type_len;
|
usize type_len;
|
||||||
} var_decl;
|
} var_decl;
|
||||||
|
struct {
|
||||||
|
member *members;
|
||||||
|
char *name;
|
||||||
|
usize name_len;
|
||||||
|
} structure;
|
||||||
} expr;
|
} expr;
|
||||||
} ast_node;
|
} ast_node;
|
||||||
|
|
||||||
|
|
|
||||||
5
test.c
5
test.c
|
|
@ -1 +1,4 @@
|
||||||
u32 a = 3;
|
struct {
|
||||||
|
struct { u32 x, u32 y } a,
|
||||||
|
u32 b,
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue