sem.c (5387B)
1 #include <assert.h> 2 #include <stdio.h> 3 #include <string.h> 4 5 #include "sem.h" 6 #include "parser.h" 7 #include "utils.h" 8 9 #define CALLOC_SZ 16 10 #define BASE_DEPTH 1 11 12 static int next_id = 100; 13 14 Scope 15 scope_init(Node* node) 16 { 17 Scope s = (Scope) { .parent = NULL, 18 .symbols = (Symbol**)calloc(CALLOC_SZ, sizeof(Symbol*)), 19 .children = (Scope**)calloc(CALLOC_SZ, sizeof(Scope*)), 20 .cap = CALLOC_SZ, 21 .len = 0, 22 .ch_cap = CALLOC_SZ, 23 .ch_len = 0, 24 .depth = BASE_DEPTH, 25 .owner = node, 26 .id = next_id++ }; 27 28 if (s.symbols == NULL) panic("scope_init: could not alloc"); 29 if (s.children == NULL) panic("scope_init: could not alloc"); 30 return s; 31 } 32 33 static Scope* 34 new_scope_from_scope(Scope* parent_scope, Node* node) 35 { 36 // new scope 37 Scope* scope = (Scope*)calloc(1, sizeof(Scope)); 38 if (scope == NULL) panic("new_scope_from_scope: could not alloc"); 39 40 scope->id = next_id++; 41 scope->owner = node; 42 node->scope = scope; 43 44 // init symbols list 45 scope->symbols = (Symbol**)calloc(CALLOC_SZ, sizeof(Symbol*)); 46 if (scope->symbols == NULL) panic("new_scope_from_scope: symbols: could not alloc"); 47 scope->cap = CALLOC_SZ; 48 scope->len = 0; 49 50 scope->children = (Scope**)calloc(CALLOC_SZ, sizeof(Scope*)); 51 if (scope->children == NULL) panic("new_scope_from_scope: children: could not alloc"); 52 scope->ch_cap = CALLOC_SZ; 53 scope->ch_len = 0; 54 55 // init parent and depth 56 if (parent_scope != NULL) { 57 scope->parent = parent_scope; 58 scope->depth = parent_scope->depth + 1; 59 assert(parent_scope->children != NULL); 60 if (parent_scope->ch_len == parent_scope->ch_cap) { 61 parent_scope->ch_cap *= 2; 62 parent_scope->children = (Scope**)realloc(parent_scope->children, parent_scope->ch_cap * sizeof(Scope*)); 63 assert(parent_scope->children != NULL && "realloc failed"); 64 } 65 parent_scope->children[parent_scope->ch_len++] = scope; 66 } else { 67 scope->parent = NULL; 68 scope->depth = BASE_DEPTH; 69 } 70 71 return scope; 72 } 73 74 static void 75 add_to_scope(Scope* scope, Symbol* sym) 76 { 77 if (scope->len >= scope->cap) { 78 scope->cap *= 2; 79 scope->symbols = (Symbol**)realloc(scope->symbols, scope->cap * sizeof(Symbol*)); 80 } 81 scope->symbols[scope->len++] = sym; 82 } 83 84 static void 85 scope_var(Scope* scope, Ast* ast, Node* node) 86 { 87 const char* var_name = span_str(ast->src, node->data.var_decl.name, (char[IDENTSZ]) { 0 }); 88 const char* type_name = span_str(ast->src, node->data.var_decl.type->data.ident.name, (char[IDENTSZ]) { 0 }); 89 90 Symbol* sym = (Symbol*)calloc(1, sizeof(Symbol)); 91 if (sym == NULL) panic("scope_var: symbol: could not alloc"); 92 93 TypeInfo* type = (TypeInfo*)calloc(1, sizeof(TypeInfo)); 94 if (type == NULL) panic("scope_var: type: could not alloc"); 95 96 if (strcmp(type_name, "float") == 0) { 97 type->type = SYMTYPE_FLOAT; 98 } else if (strcmp(type_name, "int") == 0) { 99 type->type = SYMTYPE_INT; 100 } else if (strcmp(type_name, "string") == 0) { 101 type->type = SYMTYPE_STRING; 102 } else if (strcmp(type_name, "uint") == 0) { 103 type->type = SYMTYPE_UINT; 104 } else { 105 if (type_name[0] >= 'A' && type_name[0] <= 'Z') { 106 type->type = SYMTYPE_USER; 107 } else { 108 panic("sem: not yet defined type '%s' for variable '%s'", type_name, var_name); 109 } 110 } 111 112 sym->name = node->data.var_decl.name; 113 sym->decl = node->data.var_decl.init; 114 sym->type = type; 115 printf("scope_var: adding to scope %s (%s)\n", var_name, type_name); 116 add_to_scope(scope, sym); 117 } 118 119 static void 120 scope_func(Scope* parent_scope, Ast* ast, Node* node) 121 { 122 Scope* scope = new_scope_from_scope(parent_scope, node); 123 node->scope = scope; 124 125 for (size_t i = 0; i < node->data.block.len; i++) { 126 Node* stmt = node->data.block.stmts[i]; 127 stmt->scope = scope; 128 switch (stmt->type) { 129 case NODE_VAR_DECL: { 130 scope_var(scope, ast, stmt); 131 break; 132 } 133 default: 134 continue; 135 } 136 } 137 } 138 139 void 140 scope_program(Scope* scope, Ast* ast) 141 { 142 for (size_t i = 0; i < ast->node->data.program.len; i++) { 143 Node* node = ast->node->data.program.decl[i]; 144 node->scope = scope; 145 switch (node->type) { 146 case NODE_VAR_DECL: 147 scope_var(scope, ast, node); 148 break; 149 case NODE_FUNCTION_DECL: 150 scope_func(/*parent_scope*/ scope, ast, node->data.function_decl.body); 151 break; 152 default: 153 printf("unknown definition at TODO\n"); 154 } 155 } 156 } 157 158 void 159 scope_print(Scope* scope, Ast* ast) 160 { 161 if (scope == NULL || scope->symbols == NULL) return; 162 163 for (size_t i = 0; i < scope->len; i++) { 164 Symbol* sym = scope->symbols[i]; 165 const char* name = span_str(ast->src, sym->name, (char[IDENTSZ]) { 0 }); 166 int parent = -1; 167 if (scope->parent != NULL) parent = scope->parent->id; 168 bool has_owner_node = false; 169 if (scope->owner != NULL) has_owner_node = true; 170 printf("[depth %d] [id %d] Symbol name `%s` \t of type %s (parent %d, owner %s)\n", 171 scope->depth, 172 scope->id, 173 name, 174 type_kind_str(sym->type->type), 175 parent, 176 has_owner_node ? "yes" : "no"); 177 } 178 179 if (scope->ch_len == 0) return; 180 181 for (size_t j = 0; j < scope->ch_len; j++) { 182 Scope* child_scope = scope->children[j]; 183 scope_print(child_scope, ast); 184 } 185 } 186 187 const char* 188 type_kind_str(SymbolType t) 189 { 190 static const char* type_strings[] = { 191 [SYMTYPE_VOID] = "TYPE_VOID", 192 [SYMTYPE_INT] = "TYPE_INT", 193 [SYMTYPE_UINT] = "TYPE_UINT", 194 [SYMTYPE_FLOAT] = "TYPE_FLOAT", 195 [SYMTYPE_STRING] = "TYPE_STRING", 196 [SYMTYPE_USER] = "TYPE_USER", 197 [SYMTYPE_FUNC] = "TYPE_FUNC", 198 [SYMTYPE_TODO] = "TYPE_TODO", 199 }; 200 201 return (t >= SYMTYPE_VOID && t <= SYMTYPE_TODO) ? type_strings[t] : "UNKNOWN_TYPE_KIND"; 202 }