diff --git a/examples/hello_world.l b/examples/hello_world.l index fb33b31..317b29e 100644 --- a/examples/hello_world.l +++ b/examples/hello_world.l @@ -1,14 +1,5 @@ -struct a { - b hello, - u64 hi, -} - -union b { +struct b { u32 ciao, u32 test, u32 test1, } - -struct c { - u32 test, -} diff --git a/parser.c b/parser.c index 854c7af..8c50839 100644 --- a/parser.c +++ b/parser.c @@ -856,6 +856,8 @@ static ast_node *parse_type(parser *p) /* Array/slice type */ type = arena_alloc(p->allocator, sizeof(ast_node)); 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.type = parse_type(p); if (!type->expr.ptr_type.type) { @@ -869,6 +871,8 @@ static ast_node *parse_type(parser *p) } else if (match(p, TOKEN_STAR)) { type = arena_alloc(p->allocator, sizeof(ast_node)); 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.type = parse_type(p); if (!type->expr.ptr_type.type) { diff --git a/parser.h b/parser.h index 6cb0a82..40f9a9c 100644 --- a/parser.h +++ b/parser.h @@ -110,6 +110,8 @@ typedef enum { #define PTR_SLICE 0x0 #define PTR_RAW 0x1 +#define PTR_CONST 0x2 +#define PTR_VOLATILE 0x4 #define LOOP_WHILE 0x1 #define LOOP_UNTIL 0x2 diff --git a/sema.c b/sema.c index c913e8a..128ecfa 100644 --- a/sema.c +++ b/sema.c @@ -129,6 +129,24 @@ static type *get_type(sema *s, ast_node *n) t = shget(type_reg, name); free(name); 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: error(n, "expected type."); return NULL; @@ -145,6 +163,16 @@ static void register_struct(sema *s, char *name, type *t) while (m) { 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) { alignment = m_type->alignment; } @@ -165,6 +193,8 @@ static void register_struct(sema *s, char *name, type *t) } t->size = offset; + + printf("%ld\n", t->size); } static void register_union(sema *s, char *name, type *t) @@ -276,6 +306,7 @@ sema *sema_init(parser *p, arena *a) types = NULL; 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, "u16", create_integer(s, "u16", 16, false)); register_type(s, "u32", create_integer(s, "u32", 32, false)); diff --git a/sema.h b/sema.h index 60fa3ef..6b4ce46 100644 --- a/sema.h +++ b/sema.h @@ -9,13 +9,14 @@ typedef enum { TYPE_VOID, TYPE_PTR, + TYPE_SLICE, TYPE_FLOAT, TYPE_INTEGER, TYPE_UINTEGER, TYPE_STRUCT, TYPE_UNION, - TYPE_ENUM, - TYPE_GENERIC, + TYPE_ENUM, /* TODO */ + TYPE_GENERIC, /* TODO */ } type_tag; typedef struct _type { @@ -33,8 +34,10 @@ typedef struct _type { } ptr; struct { usize len; + bool is_const; + bool is_volatile; struct _type *child; - } array; + } slice; struct { char *name; usize name_len; @@ -44,10 +47,16 @@ typedef struct _type { char *name; usize name_len; variant *variants; - } enm; + } enm; /* TODO */ } data; } type; +typedef struct { + char *name; + type *type; + type *parameters +} prototype; + typedef struct { arena *allocator; ast_node *ast;