aboutsummaryrefslogtreecommitdiffstats
path: root/src/semantic.c
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2022-04-19 10:41:32 -0300
committerBad Diode <bd@badd10de.dev>2022-04-19 10:41:32 -0300
commitc69929cc501203829082b810bafe75a22947e00c (patch)
tree46dceba9e657a424626ab97f510b49d3b2b889cf /src/semantic.c
parent7cf1451ab52586ed9c4eeae1b1ec3b4ebaa83393 (diff)
downloadbdl-c69929cc501203829082b810bafe75a22947e00c.tar.gz
bdl-c69929cc501203829082b810bafe75a22947e00c.zip
Add viz for symbol tables
Diffstat (limited to 'src/semantic.c')
-rw-r--r--src/semantic.c44
1 files changed, 24 insertions, 20 deletions
diff --git a/src/semantic.c b/src/semantic.c
index 06958b9..6c9f290 100644
--- a/src/semantic.c
+++ b/src/semantic.c
@@ -1,6 +1,7 @@
1#include "hashtable.h" 1#include "hashtable.h"
2 2
3typedef struct Scope { 3typedef struct Scope {
4 size_t id;
4 struct Scope *parent; 5 struct Scope *parent;
5 HashTable *symbols; 6 HashTable *symbols;
6 HashTable *types; 7 HashTable *types;
@@ -8,8 +9,7 @@ typedef struct Scope {
8 9
9typedef struct ParseTree { 10typedef struct ParseTree {
10 Root *roots; 11 Root *roots;
11 Scope *global_scope; 12 Scope **scopes;
12 Scope *current_scope;
13} ParseTree; 13} ParseTree;
14 14
15typedef struct Type { 15typedef struct Type {
@@ -70,6 +70,7 @@ typedef struct Symbol {
70 }; 70 };
71} Symbol; 71} Symbol;
72 72
73static size_t scope_gen_id = 0;
73 74
74Symbol * 75Symbol *
75alloc_symval(Node *name, SymbolType type) { 76alloc_symval(Node *name, SymbolType type) {
@@ -110,6 +111,7 @@ bool type_eq(void *a, void *b) {
110Scope * 111Scope *
111alloc_scope(Scope *parent) { 112alloc_scope(Scope *parent) {
112 Scope *scope = malloc(sizeof(Scope)); 113 Scope *scope = malloc(sizeof(Scope));
114 scope->id = scope_gen_id++;
113 scope->parent = parent; 115 scope->parent = parent;
114 scope->symbols = ht_init(sym_hash, sym_eq); 116 scope->symbols = ht_init(sym_hash, sym_eq);
115 scope->types = ht_init(type_hash, type_eq); 117 scope->types = ht_init(type_hash, type_eq);
@@ -216,7 +218,7 @@ find_symbol(Scope *scope, Node *node) {
216} 218}
217 219
218bool 220bool
219resolve_type(Scope *scope, Node *node) { 221resolve_type(ParseTree *ast, Scope *scope, Node *node) {
220 if (node->expr_type != NULL) { 222 if (node->expr_type != NULL) {
221 return true; 223 return true;
222 } 224 }
@@ -224,7 +226,7 @@ resolve_type(Scope *scope, Node *node) {
224 case NODE_BUILTIN: { 226 case NODE_BUILTIN: {
225 for (size_t i = 0; i < array_size(node->builtin.args); ++i) { 227 for (size_t i = 0; i < array_size(node->builtin.args); ++i) {
226 Node *arg = node->builtin.args[i]; 228 Node *arg = node->builtin.args[i];
227 if (!resolve_type(scope, arg)) { 229 if (!resolve_type(ast, scope, arg)) {
228 return false; 230 return false;
229 } 231 }
230 } 232 }
@@ -311,6 +313,7 @@ resolve_type(Scope *scope, Node *node) {
311 case NODE_FUN: { 313 case NODE_FUN: {
312 // Fill up new scope with parameters 314 // Fill up new scope with parameters
313 scope = alloc_scope(scope); 315 scope = alloc_scope(scope);
316 array_push(ast->scopes, scope);
314 317
315 // Parameters. 318 // Parameters.
316 for (size_t i = 0; i < array_size(node->fun.param_names); ++i) { 319 for (size_t i = 0; i < array_size(node->fun.param_names); ++i) {
@@ -328,14 +331,14 @@ resolve_type(Scope *scope, Node *node) {
328 if (body->type == NODE_BLOCK) { 331 if (body->type == NODE_BLOCK) {
329 for (size_t i = 0; i < array_size(body->block.expr); ++i) { 332 for (size_t i = 0; i < array_size(body->block.expr); ++i) {
330 Node *expr = body->block.expr[i]; 333 Node *expr = body->block.expr[i];
331 if (!resolve_type(scope, expr)) { 334 if (!resolve_type(ast, scope, expr)) {
332 return false; 335 return false;
333 } 336 }
334 } 337 }
335 Node *last_expr = body->block.expr[array_size(body->block.expr) - 1]; 338 Node *last_expr = body->block.expr[array_size(body->block.expr) - 1];
336 node->expr_type = last_expr->expr_type; 339 node->expr_type = last_expr->expr_type;
337 } else { 340 } else {
338 if (!resolve_type(scope, body)) { 341 if (!resolve_type(ast, scope, body)) {
339 return false; 342 return false;
340 } 343 }
341 } 344 }
@@ -350,9 +353,10 @@ resolve_type(Scope *scope, Node *node) {
350 } break; 353 } break;
351 case NODE_BLOCK: { 354 case NODE_BLOCK: {
352 scope = alloc_scope(scope); 355 scope = alloc_scope(scope);
356 array_push(ast->scopes, scope);
353 for (size_t i = 0; i < array_size(node->block.expr); ++i) { 357 for (size_t i = 0; i < array_size(node->block.expr); ++i) {
354 Node *expr = node->block.expr[i]; 358 Node *expr = node->block.expr[i];
355 if (!resolve_type(scope, expr)) { 359 if (!resolve_type(ast, scope, expr)) {
356 return false; 360 return false;
357 } 361 }
358 } 362 }
@@ -360,16 +364,16 @@ resolve_type(Scope *scope, Node *node) {
360 node->expr_type = last_expr->expr_type; 364 node->expr_type = last_expr->expr_type;
361 } break; 365 } break;
362 case NODE_IF: { 366 case NODE_IF: {
363 if (!resolve_type(scope, node->ifexpr.cond)) { 367 if (!resolve_type(ast, scope, node->ifexpr.cond)) {
364 return false; 368 return false;
365 } 369 }
366 if (!resolve_type(scope, node->ifexpr.expr_true)) { 370 if (!resolve_type(ast, scope, node->ifexpr.expr_true)) {
367 return false; 371 return false;
368 } 372 }
369 Type *type_true = node->ifexpr.expr_true->expr_type; 373 Type *type_true = node->ifexpr.expr_true->expr_type;
370 node->expr_type = type_true; 374 node->expr_type = type_true;
371 if (node->ifexpr.expr_false != NULL) { 375 if (node->ifexpr.expr_false != NULL) {
372 if (!resolve_type(scope, node->ifexpr.expr_false)) { 376 if (!resolve_type(ast, scope, node->ifexpr.expr_false)) {
373 return false; 377 return false;
374 } 378 }
375 } 379 }
@@ -396,10 +400,10 @@ resolve_type(Scope *scope, Node *node) {
396 } break; 400 } break;
397 case NODE_SET: { 401 case NODE_SET: {
398 node->expr_type = &default_types[TYPE_VOID]; 402 node->expr_type = &default_types[TYPE_VOID];
399 if (!resolve_type(scope, node->set.symbol)) { 403 if (!resolve_type(ast, scope, node->set.symbol)) {
400 return false; 404 return false;
401 } 405 }
402 if (!resolve_type(scope, node->set.value)) { 406 if (!resolve_type(ast, scope, node->set.value)) {
403 return false; 407 return false;
404 } 408 }
405 Node *symbol = node->set.symbol; 409 Node *symbol = node->set.symbol;
@@ -426,7 +430,7 @@ resolve_type(Scope *scope, Node *node) {
426 430
427 node->expr_type = &default_types[TYPE_VOID]; 431 node->expr_type = &default_types[TYPE_VOID];
428 // TODO: type inference from right side when not annotated? 432 // TODO: type inference from right side when not annotated?
429 if (!resolve_type(scope, node->def.value)) { 433 if (!resolve_type(ast, scope, node->def.value)) {
430 return false; 434 return false;
431 } 435 }
432 Node *symbol = node->def.symbol; 436 Node *symbol = node->def.symbol;
@@ -455,7 +459,7 @@ resolve_type(Scope *scope, Node *node) {
455 } break; 459 } break;
456 case NODE_FUNCALL: { 460 case NODE_FUNCALL: {
457 Symbol *val = find_symbol(scope, node->funcall.name); 461 Symbol *val = find_symbol(scope, node->funcall.name);
458 if (!resolve_type(scope, node->funcall.name)) { 462 if (!resolve_type(ast, scope, node->funcall.name)) {
459 return false; 463 return false;
460 } 464 }
461 if (val->type != SYMBOL_FUN) { 465 if (val->type != SYMBOL_FUN) {
@@ -470,7 +474,7 @@ resolve_type(Scope *scope, Node *node) {
470 node->expr_type = node->funcall.name->expr_type; 474 node->expr_type = node->funcall.name->expr_type;
471 for (size_t i = 0; i < array_size(node->funcall.args); ++i) { 475 for (size_t i = 0; i < array_size(node->funcall.args); ++i) {
472 Node *arg = node->funcall.args[i]; 476 Node *arg = node->funcall.args[i];
473 if (!resolve_type(scope, arg)) { 477 if (!resolve_type(ast, scope, arg)) {
474 return false; 478 return false;
475 } 479 }
476 Node *expected = val->fun.param_types[i]; 480 Node *expected = val->fun.param_types[i];
@@ -490,18 +494,18 @@ ParseTree *
490semantic_analysis(Root *roots) { 494semantic_analysis(Root *roots) {
491 ParseTree *parse_tree = malloc(sizeof(ParseTree)); 495 ParseTree *parse_tree = malloc(sizeof(ParseTree));
492 parse_tree->roots = roots; 496 parse_tree->roots = roots;
493 parse_tree->global_scope = alloc_scope(NULL); 497 array_init(parse_tree->scopes, 0);
494 parse_tree->current_scope = parse_tree->global_scope; 498 Scope *scope = alloc_scope(NULL);
499 array_push(parse_tree->scopes, scope);
495 500
496 // Fill global scope with default types. 501 // Fill global scope with default types.
497 HashTable *types = parse_tree->global_scope->types; 502 HashTable *types = scope->types;
498 for (size_t i = 0; i < sizeof(default_types)/sizeof(Type); ++i) { 503 for (size_t i = 0; i < sizeof(default_types)/sizeof(Type); ++i) {
499 Type *type = &default_types[i]; 504 Type *type = &default_types[i];
500 ht_insert(types, &type->name, type); 505 ht_insert(types, &type->name, type);
501 } 506 }
502 507
503 // Fill up global function symbols. 508 // Fill up global function symbols.
504 Scope *scope = parse_tree->global_scope;
505 for (size_t i = 0; i < array_size(parse_tree->roots); ++i) { 509 for (size_t i = 0; i < array_size(parse_tree->roots); ++i) {
506 Node *root = parse_tree->roots[i]; 510 Node *root = parse_tree->roots[i];
507 if (root->type == NODE_FUN) { 511 if (root->type == NODE_FUN) {
@@ -518,7 +522,7 @@ semantic_analysis(Root *roots) {
518 for (size_t i = 0; i < array_size(parse_tree->roots); ++i) { 522 for (size_t i = 0; i < array_size(parse_tree->roots); ++i) {
519 // Fill up symbol tables in proper scope and resolve type of expression 523 // Fill up symbol tables in proper scope and resolve type of expression
520 // for all elements. 524 // for all elements.
521 if (!resolve_type(scope, parse_tree->roots[i])) { 525 if (!resolve_type(parse_tree, scope, parse_tree->roots[i])) {
522 return NULL; 526 return NULL;
523 } 527 }
524 } 528 }