broken! preliminary work on sema

This commit is contained in:
Lorenzo Torres 2025-12-04 14:42:44 +01:00
parent 006015c607
commit d130124d53
7 changed files with 1983 additions and 10 deletions

View file

@ -3,7 +3,7 @@
include config.mk
SRC = lc.c utils.c lexer.c parser.c
SRC = lc.c utils.c lexer.c parser.c sema.c
HDR = config.def.h utils.h lexer.h parser.h sema.h
OBJ = ${SRC:.c=.o}

View file

@ -1,5 +1,10 @@
import std;
struct {
u32 a,
u32 b,
};
i32 main(usize argc, [*u8] argv)
{
print("Hello world!\n");

2
lc.c
View file

@ -3,6 +3,7 @@
#include "utils.h"
#include "lexer.h"
#include "parser.h"
#include "sema.h"
void print_indent(int depth) {
for (int i = 0; i < depth; i++) printf(" ");
@ -234,6 +235,7 @@ int main(void)
lexer *l = lexer_init(src, size, &a);
parser *p = parser_init(l, &a);
print_ast(p->ast, 0);
sema *s = sema_init(p, &a);
arena_deinit(a);

View file

@ -3,6 +3,7 @@
#include "lexer.h"
#include "utils.h"
#include <stdbool.h>
struct _ast_node;

63
sema.c Normal file
View file

@ -0,0 +1,63 @@
#define STB_DS_IMPLEMENTATION
#include "sema.h"
#include <string.h>
static struct { char *key; type *value; } *types;
static char *intern_string(sema *s, char *str, usize len)
{
char *ptr = arena_alloc(s->allocator, len + 1);
memcpy(ptr, str, len);
ptr[len] = '\0';
return ptr;
}
static type *analyze_type(sema *s, ast_node *node)
{
if (node->type == NODE_STRUCT || node->type == NODE_UNION) {
type *t = arena_alloc(s->allocator, sizeof(type));
t->tag = node->type == NODE_STRUCT ? TYPE_STRUCT : TYPE_UNION;
t->data.structure.name = node->expr.structure.name;
t->data.structure.name_len = node->expr.structure.name_len;
t->data.structure.members = node->expr.structure.members;
shput(types, intern_string(s, t->data.structure.name, t->data.structure.name_len), t);
return t;
}
if (node->type == NODE_ENUM) {
type *t = arena_alloc(s->allocator, sizeof(type));
t->tag = TYPE_ENUM;
t->data.enm.name = node->expr.enm.name;
t->data.enm.name_len = node->expr.enm.name_len;
t->data.enm.variants = node->expr.enm.variants;
shput(types, intern_string(s, t->data.enm.name, t->data.enm.name_len), t);
return t;
}
return NULL;
}
static void analyze_unit(sema *s, ast_node *node)
{
ast_node *current = node;
while (current && current->type == NODE_UNIT) {
if (analyze_type(s, current)) goto end;
end:
current = current->expr.unit_node.next;
}
}
sema *sema_init(parser *p, arena *a)
{
sema *s = arena_alloc(a, sizeof(sema));
s->allocator = a;
types = NULL;
s->ast = p->ast;
analyze_unit(s, s->ast);
return s;
}

25
sema.h
View file

@ -1,6 +1,10 @@
#ifndef SEMA_H
#define SEMA_H
#include "parser.h"
#include "stb_ds.h"
#include "utils.h"
typedef enum {
TYPE_VOID,
TYPE_PTR,
@ -15,6 +19,7 @@ typedef enum {
TYPE_STRUCT,
TYPE_UNION,
TYPE_ENUM,
TYPE_GENERIC,
} type_tag;
typedef struct _type {
@ -26,29 +31,31 @@ typedef struct _type {
bool is_const;
bool is_volatile;
u16 alignment;
struct _type child;
struct _type *child;
} ptr;
struct {
usize len;
struct _type child;
struct _type *child;
} array;
struct {
struct_layout layout;
char *name;
usize name_len;
usize alignment;
member *members;
function_decl *decls;
} structure;
struct {
struct_layout layout;
char *name;
usize name_len;
usize alignment;
member *members;
function_decl *decls;
} enum;
variant *variants;
} enm;
} data;
} type;
typedef struct {
arena *allocator;
ast_node *ast;
} sema;
sema *sema_init(parser *p, arena *a);
#endif

1895
stb_ds.h Normal file

File diff suppressed because it is too large Load diff