merge syms and resolve

This commit is contained in:
sfja 2026-10-02 03:48:45 +02:00
parent ac95ee12b9
commit 1558467b41
8 changed files with 142 additions and 87 deletions

View File

@ -1,5 +1,5 @@
larpcc: main.c lex.c preproc.c collection.c parse.c syms.c ast_print.c resolve.c
larpcc: main.c lex.c preproc.c collection.c parse.c ast_print.c resolve.c
gcc $^ -o $@ -std=c23 -pedantic -Wall -Wextra -g -fsanitize=address -Werror=switch

6
main.c
View File

@ -78,7 +78,9 @@ int main(int argc, char* argv[])
Parser* parser = parser_new(&tokstream, &ast_arena);
Resolver* resolver = resolver_new();
Arena sym_arena;
arena_init(&sym_arena, 4096);
Resolver* resolver = resolver_new(&sym_arena);
AstStmt* stmt;
while (!parser_done(parser)) {
@ -95,7 +97,7 @@ int main(int argc, char* argv[])
preproc_free(preproc);
arena_deinit(&tok_arena);
arena_deinit(&ast_arena);
arena_deinit(&sym_arena);
}
}

View File

@ -1,7 +1,7 @@
#include "parse.h"
#include "ast.h"
#include "collection.h"
#include "syms.h"
#include "resolve.h"
#include <assert.h>
#include <stddef.h>
#include <stdio.h>

View File

@ -3,7 +3,6 @@
#include "ast.h"
#include "collection.h"
#include "syms.h"
#include <stddef.h>
char* read_textfile(const char* filename);

113
resolve.c
View File

@ -1,18 +1,75 @@
#include "resolve.h"
#include "ast.h"
#include "syms.h"
#include "collection.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
struct Syms {
ARRAY_FIELD(Hashmap, maps);
};
Syms* syms_new()
{
Syms* s = malloc(sizeof(Syms));
*s = (Syms) {
ARRAY_FIELD_INIT(maps),
};
ARRAY_FIELD_PUSH(s, maps, &(Hashmap) { });
hashmap_init(&s->maps[0], sizeof(Sym*));
return s;
}
void syms_free(Syms* s)
{
free(s->maps);
free(s);
}
void syms_push_scope(Syms* s)
{
ARRAY_FIELD_PUSH(s, maps, &(Hashmap) { });
hashmap_init(&s->maps[s->maps_size - 1], sizeof(Sym*));
}
void syms_pop_scope(Syms* s)
{
assert(s->maps_size > 0);
hashmap_deinit(&s->maps[s->maps_size - 1]);
s->maps_size -= 1;
}
void syms_define(Syms* s, const char* ident, Sym* sym)
{
Hashmap* m = &s->maps[s->maps_size - 1];
hashmap_set(m, ident, &sym);
}
Sym* syms_get(Syms* s, const char* ident)
{
Hashmap* m = &s->maps[s->maps_size - 1];
Sym** res = hashmap_get(m, ident);
return res ? *res : nullptr;
}
typedef enum : unsigned int {
ResolverFlags_InTypedef,
} ResolverFlags;
struct Resolver {
Syms* ord_syms;
Syms* tag_syms;
Syms* label_syms;
bool in_typedef;
Arena* arena;
AstStmt* current_decl_stmt;
ResolverFlags flags;
};
Resolver* resolver_new()
Resolver* resolver_new(Arena* arena)
{
Resolver* r = malloc(sizeof(Resolver));
*r = (Resolver) {
@ -20,7 +77,10 @@ Resolver* resolver_new()
.tag_syms = syms_new(),
.label_syms = syms_new(),
.in_typedef = false,
.arena = arena,
.current_decl_stmt = nullptr,
.flags = 0,
};
return r;
}
@ -46,16 +106,39 @@ static AstVisitorResult visit_stmt_block(AstVisitor* v, AstStmtBlock* node)
static AstVisitorResult visit_stmt(AstVisitor* v, AstStmt* node)
{
Resolver* r = v->op;
if (node->ty == AstStmt_Decl) {
r->current_decl_stmt = node;
ast_stmt_visit_body(v, node);
return AstVisitor_Break;
}
return AstVisitor_Continue;
}
static AstVisitorResult visit_decl(AstVisitor* v, AstDecl* node)
{
Resolver* r = v->op;
if (node->spec & AstSpec_Typedef) {
r->flags |= ResolverFlags_InTypedef;
ast_decl_visit_body(v, node);
r->flags &= ~ResolverFlags_InTypedef;
return AstVisitor_Break;
}
return AstVisitor_Continue;
}
static AstVisitorResult visit_declar(AstVisitor* v, AstDeclar* node)
{
Resolver* r = v->op;
if (node->ty == AstDeclar_Function) {
syms_push_scope(r->ord_syms);
@ -65,11 +148,31 @@ static AstVisitorResult visit_declar(AstVisitor* v, AstDeclar* node)
return AstVisitor_Break;
}
if (node->ty == AstDeclar_Ident) { }
if (node->ty == AstDeclar_Ident) {
assert(r->current_decl_stmt);
Sym* sym = arena_alloc(r->arena, sizeof(Sym));
*sym = (Sym) {
.ty = Sym_Declarator,
.declarator = {
.stmt = r->current_decl_stmt,
.declar = node,
},
};
syms_define(r->ord_syms, node->ident, sym);
return AstVisitor_Break;
}
return AstVisitor_Continue;
}
static AstVisitorResult visit_expr(AstVisitor* v, AstExpr* node)
{
Resolver* r = v->op;
if (node->ty == AstExpr_Ident) { }
return AstVisitor_Continue;
}
void resolver_resolve_top_stmt(Resolver* r, AstStmt* stmt)

View File

@ -2,10 +2,37 @@
#define RES_H
#include "ast.h"
#include "collection.h"
typedef enum {
Sym_Typedef,
Sym_Declarator,
} SymTy;
typedef struct {
SymTy ty;
union {
struct {
AstStmt* stmt;
AstDeclar* declar;
} declarator;
};
} Sym;
typedef struct Syms Syms;
Syms* syms_new();
void syms_free(Syms* s);
void syms_push_scope(Syms* s);
void syms_pop_scope(Syms* s);
void syms_define(Syms* s, const char* ident, Sym* sym);
Sym* syms_get(Syms* s, const char* ident);
typedef struct Resolver Resolver;
Resolver* resolver_new();
Resolver* resolver_new(Arena* arena);
void resolver_free(Resolver* r);
void resolver_resolve_top_stmt(Resolver* r, AstStmt* stmt);

53
syms.c
View File

@ -1,53 +0,0 @@
#include "syms.h"
#include "collection.h"
#include <assert.h>
#include <stdlib.h>
struct Syms {
ARRAY_FIELD(Hashmap, maps);
};
Syms* syms_new()
{
Syms* s = malloc(sizeof(Syms));
*s = (Syms) {
ARRAY_FIELD_INIT(maps),
};
ARRAY_FIELD_PUSH(s, maps, &(Hashmap) { });
hashmap_init(&s->maps[0], sizeof(Sym*));
return s;
}
void syms_free(Syms* s)
{
free(s->maps);
free(s);
}
void syms_push_scope(Syms* s)
{
ARRAY_FIELD_PUSH(s, maps, &(Hashmap) { });
hashmap_init(&s->maps[s->maps_size - 1], sizeof(Sym*));
}
void syms_pop_scope(Syms* s)
{
assert(s->maps_size > 0);
hashmap_deinit(&s->maps[s->maps_size - 1]);
s->maps_size -= 1;
}
void syms_define(Syms* s, const char* ident, Sym* sym)
{
Hashmap* m = &s->maps[s->maps_size - 1];
hashmap_set(m, ident, &sym);
}
Sym* syms_get(Syms* s, const char* ident)
{
Hashmap* m = &s->maps[s->maps_size - 1];
Sym** res = hashmap_get(m, ident);
return res ? *res : nullptr;
}

23
syms.h
View File

@ -1,23 +0,0 @@
#ifndef SYMS_H
#define SYMS_H
typedef enum {
Sym_Typedef,
} SymTy;
typedef struct {
SymTy ty;
} Sym;
typedef struct Syms Syms;
Syms* syms_new();
void syms_free(Syms* s);
void syms_push_scope(Syms* s);
void syms_pop_scope(Syms* s);
void syms_define(Syms* s, const char* ident, Sym* sym);
Sym* syms_get(Syms* s, const char* ident);
#endif