sem.c (7119B)
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_at(node, "scope_init: could not alloc"); 29 if (s.children == NULL) panic_at(node, "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_at(node, "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_at(node, "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_at(node, "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_at(node, "scope_var: symbol: could not alloc"); 92 93 TypeInfo* type = (TypeInfo*)calloc(1, sizeof(TypeInfo)); 94 if (type == NULL) panic_at(node, "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, "uint") == 0) { 101 type->type = SYMTYPE_UINT; 102 103 } else if (strcmp(type_name, "str") == 0) { 104 type->type = SYMTYPE_STR; 105 } else if (strcmp(type_name, "chr") == 0) { 106 type->type = SYMTYPE_CHR; 107 } else if (strcmp(type_name, "bool") == 0) { 108 type->type = SYMTYPE_BOOL; 109 110 } else if (strcmp(type_name, "struct") == 0) { 111 type->type = SYMTYPE_STRUCT; 112 113 } else if (strcmp(type_name, "i8") == 0) { 114 type->type = SYMTYPE_I8; 115 } else if (strcmp(type_name, "i16") == 0) { 116 type->type = SYMTYPE_I16; 117 } else if (strcmp(type_name, "i32") == 0) { 118 type->type = SYMTYPE_I32; 119 } else if (strcmp(type_name, "i64") == 0) { 120 type->type = SYMTYPE_I64; 121 } else if (strcmp(type_name, "i128") == 0) { 122 type->type = SYMTYPE_I128; 123 124 } else if (strcmp(type_name, "u8") == 0) { 125 type->type = SYMTYPE_U8; 126 } else if (strcmp(type_name, "u16") == 0) { 127 type->type = SYMTYPE_U16; 128 } else if (strcmp(type_name, "u32") == 0) { 129 type->type = SYMTYPE_U32; 130 } else if (strcmp(type_name, "u64") == 0) { 131 type->type = SYMTYPE_U64; 132 } else if (strcmp(type_name, "u128") == 0) { 133 type->type = SYMTYPE_U128; 134 135 } else if (strcmp(type_name, "f32") == 0) { 136 type->type = SYMTYPE_F32; 137 } else if (strcmp(type_name, "f64") == 0) { 138 type->type = SYMTYPE_F64; 139 } else if (strcmp(type_name, "f128") == 0) { 140 type->type = SYMTYPE_F128; 141 142 } else { 143 if (type_name[0] >= 'A' && type_name[0] <= 'Z') { 144 type->type = SYMTYPE_USER; 145 } else { 146 panic_at(node, "sem: not yet defined type '%s' for variable '%s'", type_name, var_name); 147 } 148 } 149 150 sym->name = node->data.var_decl.name; 151 sym->decl = node->data.var_decl.init; 152 sym->type = type; 153 printf("scope_var: adding to scope %s (%s)\n", var_name, type_name); 154 add_to_scope(scope, sym); 155 } 156 157 static void 158 scope_func(Scope* parent_scope, Ast* ast, Node* node) 159 { 160 Scope* scope = new_scope_from_scope(parent_scope, node); 161 node->scope = scope; 162 163 for (size_t i = 0; i < node->data.block.len; i++) { 164 Node* stmt = node->data.block.stmts[i]; 165 stmt->scope = scope; 166 switch (stmt->type) { 167 case NODE_VAR_DECL: { 168 scope_var(scope, ast, stmt); 169 break; 170 } 171 default: 172 continue; 173 } 174 } 175 } 176 177 void 178 scope_program(Scope* scope, Ast* ast) 179 { 180 for (size_t i = 0; i < ast->node->data.program.len; i++) { 181 Node* node = ast->node->data.program.decl[i]; 182 node->scope = scope; 183 switch (node->type) { 184 case NODE_VAR_DECL: 185 scope_var(scope, ast, node); 186 break; 187 case NODE_FUNCTION_DECL: 188 scope_func(/*parent_scope*/ scope, ast, node->data.function_decl.body); 189 break; 190 default: 191 printf("unknown definition at TODO\n"); 192 } 193 } 194 } 195 196 void 197 scope_print(Scope* scope, Ast* ast) 198 { 199 if (scope == NULL || scope->symbols == NULL) return; 200 201 for (size_t i = 0; i < scope->len; i++) { 202 Symbol* sym = scope->symbols[i]; 203 const char* name = span_str(ast->src, sym->name, (char[IDENTSZ]) { 0 }); 204 int parent = -1; 205 if (scope->parent != NULL) parent = scope->parent->id; 206 bool has_owner_node = false; 207 if (scope->owner != NULL) has_owner_node = true; 208 printf("[depth %d] [id %d] Symbol name `%s` \t of type %s (parent %d, owner %s)\n", 209 scope->depth, 210 scope->id, 211 name, 212 type_kind_str(sym->type->type), 213 parent, 214 has_owner_node ? "yes" : "no"); 215 } 216 217 if (scope->ch_len == 0) return; 218 219 for (size_t j = 0; j < scope->ch_len; j++) { 220 Scope* child_scope = scope->children[j]; 221 scope_print(child_scope, ast); 222 } 223 } 224 225 const char* 226 type_kind_str(SymbolType t) 227 { 228 static const char* type_strings[] = { 229 [SYMTYPE_VOID] = "TYPE_VOID", 230 [SYMTYPE_INT] = "TYPE_INT", 231 232 [SYMTYPE_I8] = "TYPE_I8", 233 [SYMTYPE_I16] = "TYPE_I16", 234 [SYMTYPE_I32] = "TYPE_I32", 235 [SYMTYPE_I64] = "TYPE_I64", 236 [SYMTYPE_I128] = "TYPE_I128", 237 [SYMTYPE_UINT] = "TYPE_UINT", 238 239 [SYMTYPE_U8] = "TYPE_U8", 240 [SYMTYPE_U16] = "TYPE_U16", 241 [SYMTYPE_U32] = "TYPE_U32", 242 [SYMTYPE_U64] = "TYPE_U64", 243 [SYMTYPE_U128] = "TYPE_U128", 244 245 [SYMTYPE_F32] = "TYPE_F32", 246 [SYMTYPE_F64] = "TYPE_F64", 247 [SYMTYPE_F128] = "TYPE_F128", 248 [SYMTYPE_FLOAT] = "TYPE_FLOAT", 249 250 [SYMTYPE_STR] = "TYPE_STR", 251 [SYMTYPE_CHR] = "TYPE_CHR", 252 [SYMTYPE_BOOL] = "TYPE_BOOL", 253 [SYMTYPE_STRUCT] = "TYPE_STRUCT", 254 [SYMTYPE_USER] = "TYPE_USER", 255 [SYMTYPE_FUNC] = "TYPE_FUNC", 256 [SYMTYPE_TODO] = "TYPE_TODO", 257 }; 258 259 return (t >= SYMTYPE_VOID && t <= SYMTYPE_TODO) ? type_strings[t] : "UNKNOWN_TYPE_KIND"; 260 }