added pointer types resolution, type validity checks and void type

This commit is contained in:
Lorenzo Torres 2025-12-05 16:45:03 +01:00
parent 8f19852746
commit 3ca2c2f009
5 changed files with 51 additions and 14 deletions

View file

@ -1,14 +1,5 @@
struct a { struct b {
b hello,
u64 hi,
}
union b {
u32 ciao, u32 ciao,
u32 test, u32 test,
u32 test1, u32 test1,
} }
struct c {
u32 test,
}

View file

@ -856,6 +856,8 @@ static ast_node *parse_type(parser *p)
/* Array/slice type */ /* Array/slice type */
type = arena_alloc(p->allocator, sizeof(ast_node)); type = arena_alloc(p->allocator, sizeof(ast_node));
type->type = NODE_PTR_TYPE; type->type = NODE_PTR_TYPE;
if (match(p, TOKEN_CONST)) type->expr.ptr_type.flags |= PTR_CONST;
if (match(p, TOKEN_VOLATILE)) type->expr.ptr_type.flags |= PTR_VOLATILE;
type->expr.ptr_type.flags |= PTR_SLICE; type->expr.ptr_type.flags |= PTR_SLICE;
type->expr.ptr_type.type = parse_type(p); type->expr.ptr_type.type = parse_type(p);
if (!type->expr.ptr_type.type) { if (!type->expr.ptr_type.type) {
@ -869,6 +871,8 @@ static ast_node *parse_type(parser *p)
} else if (match(p, TOKEN_STAR)) { } else if (match(p, TOKEN_STAR)) {
type = arena_alloc(p->allocator, sizeof(ast_node)); type = arena_alloc(p->allocator, sizeof(ast_node));
type->type = NODE_PTR_TYPE; type->type = NODE_PTR_TYPE;
if (match(p, TOKEN_CONST)) type->expr.ptr_type.flags |= PTR_CONST;
if (match(p, TOKEN_VOLATILE)) type->expr.ptr_type.flags |= PTR_VOLATILE;
type->expr.ptr_type.flags |= PTR_RAW; type->expr.ptr_type.flags |= PTR_RAW;
type->expr.ptr_type.type = parse_type(p); type->expr.ptr_type.type = parse_type(p);
if (!type->expr.ptr_type.type) { if (!type->expr.ptr_type.type) {

View file

@ -110,6 +110,8 @@ typedef enum {
#define PTR_SLICE 0x0 #define PTR_SLICE 0x0
#define PTR_RAW 0x1 #define PTR_RAW 0x1
#define PTR_CONST 0x2
#define PTR_VOLATILE 0x4
#define LOOP_WHILE 0x1 #define LOOP_WHILE 0x1
#define LOOP_UNTIL 0x2 #define LOOP_UNTIL 0x2

31
sema.c
View file

@ -129,6 +129,24 @@ static type *get_type(sema *s, ast_node *n)
t = shget(type_reg, name); t = shget(type_reg, name);
free(name); free(name);
return t; return t;
case NODE_PTR_TYPE:
t = malloc(sizeof(type));
t->size = sizeof(usize);
t->alignment = sizeof(usize);
if (n->expr.ptr_type.flags & PTR_RAW) {
t->name = "ptr";
t->tag = TYPE_PTR;
t->data.ptr.child = get_type(s, n->expr.ptr_type.type);
t->data.ptr.is_const = (n->expr.ptr_type.flags & PTR_CONST) != 0;
t->data.ptr.is_volatile = (n->expr.ptr_type.flags & PTR_VOLATILE) != 0;
} else {
t->name = "slice";
t->tag = TYPE_SLICE;
t->data.slice.child = get_type(s, n->expr.ptr_type.type);
t->data.slice.is_const = (n->expr.ptr_type.flags & PTR_CONST) != 0;
t->data.slice.is_volatile = (n->expr.ptr_type.flags & PTR_VOLATILE) != 0;
}
return t;
default: default:
error(n, "expected type."); error(n, "expected type.");
return NULL; return NULL;
@ -145,6 +163,16 @@ static void register_struct(sema *s, char *name, type *t)
while (m) { while (m) {
m_type = get_type(s, m->type); m_type = get_type(s, m->type);
if (!m_type) {
error(m->type, "unknown type.");
return;
}
if (m_type->size == 0) {
error(m->type, "a struct member can't be of type `void`.");
return;
}
if (alignment < m_type->alignment) { if (alignment < m_type->alignment) {
alignment = m_type->alignment; alignment = m_type->alignment;
} }
@ -165,6 +193,8 @@ static void register_struct(sema *s, char *name, type *t)
} }
t->size = offset; t->size = offset;
printf("%ld\n", t->size);
} }
static void register_union(sema *s, char *name, type *t) static void register_union(sema *s, char *name, type *t)
@ -276,6 +306,7 @@ sema *sema_init(parser *p, arena *a)
types = NULL; types = NULL;
s->ast = p->ast; s->ast = p->ast;
register_type(s, "void", create_integer(s, "void", 0, false));
register_type(s, "u8", create_integer(s, "u8", 8, false)); register_type(s, "u8", create_integer(s, "u8", 8, false));
register_type(s, "u16", create_integer(s, "u16", 16, false)); register_type(s, "u16", create_integer(s, "u16", 16, false));
register_type(s, "u32", create_integer(s, "u32", 32, false)); register_type(s, "u32", create_integer(s, "u32", 32, false));

17
sema.h
View file

@ -9,13 +9,14 @@
typedef enum { typedef enum {
TYPE_VOID, TYPE_VOID,
TYPE_PTR, TYPE_PTR,
TYPE_SLICE,
TYPE_FLOAT, TYPE_FLOAT,
TYPE_INTEGER, TYPE_INTEGER,
TYPE_UINTEGER, TYPE_UINTEGER,
TYPE_STRUCT, TYPE_STRUCT,
TYPE_UNION, TYPE_UNION,
TYPE_ENUM, TYPE_ENUM, /* TODO */
TYPE_GENERIC, TYPE_GENERIC, /* TODO */
} type_tag; } type_tag;
typedef struct _type { typedef struct _type {
@ -33,8 +34,10 @@ typedef struct _type {
} ptr; } ptr;
struct { struct {
usize len; usize len;
bool is_const;
bool is_volatile;
struct _type *child; struct _type *child;
} array; } slice;
struct { struct {
char *name; char *name;
usize name_len; usize name_len;
@ -44,10 +47,16 @@ typedef struct _type {
char *name; char *name;
usize name_len; usize name_len;
variant *variants; variant *variants;
} enm; } enm; /* TODO */
} data; } data;
} type; } type;
typedef struct {
char *name;
type *type;
type *parameters
} prototype;
typedef struct { typedef struct {
arena *allocator; arena *allocator;
ast_node *ast; ast_node *ast;