aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2024-06-23 15:55:34 +0200
committerBad Diode <bd@badd10de.dev>2024-06-23 15:55:34 +0200
commitc6fd7856bfe5dd0567f672d0d1a70a3b698feaa4 (patch)
tree967afe5d560bbf8b9c64ab408cb66e66a6146bc7
parent35eaad923d3ef598d6f9ed6925fd65c6a311896b (diff)
downloadbdl-c6fd7856bfe5dd0567f672d0d1a70a3b698feaa4.tar.gz
bdl-c6fd7856bfe5dd0567f672d0d1a70a3b698feaa4.zip
Add more expressions to type inference method
-rw-r--r--src/main.c126
-rw-r--r--tests/semantics.bad4
2 files changed, 105 insertions, 25 deletions
diff --git a/src/main.c b/src/main.c
index 3614e56..077039a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -79,6 +79,8 @@ typedef struct Analyzer {
79 Str file_name; 79 Str file_name;
80 sz scope_gen; 80 sz scope_gen;
81 Scope **scopes; 81 Scope **scopes;
82 StrSet *numeric_types;
83 StrSet *integer_types;
82} Analyzer; 84} Analyzer;
83 85
84Scope * 86Scope *
@@ -195,7 +197,83 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
195 assert(a); 197 assert(a);
196 assert(scope); 198 assert(scope);
197 assert(node); 199 assert(node);
200 // NOTE: For now we are not going to do implicit numeric conversions.
198 switch (node->kind) { 201 switch (node->kind) {
202 case NODE_TRUE:
203 case NODE_FALSE: return cstr("bool");
204 case NODE_NOT:
205 case NODE_AND:
206 case NODE_OR: {
207 Type left = type_inference(a, node->left, scope);
208 if (!str_eq(left, cstr("bool"))) {
209 emit_semantic_error(a, node,
210 cstr("expected bool on logic expression"));
211 return (Type){0};
212 }
213 if (node->right) {
214 Type right = type_inference(a, node->right, scope);
215 if (!str_eq(right, cstr("bool"))) {
216 emit_semantic_error(
217 a, node, cstr("expected bool on logic expression"));
218 return (Type){0};
219 }
220 }
221 return cstr("bool");
222 } break;
223 case NODE_EQ:
224 case NODE_NEQ:
225 case NODE_LT:
226 case NODE_GT:
227 case NODE_LE:
228 case NODE_GE: {
229 Type left = type_inference(a, node->left, scope);
230 Type right = type_inference(a, node->right, scope);
231 if (!str_eq(left, right)) {
232 emit_semantic_error(
233 a, node, cstr("mismatched types on binary expression"));
234 return (Type){0};
235 }
236 return cstr("bool");
237 } break;
238 case NODE_BITNOT:
239 case NODE_BITAND:
240 case NODE_BITOR:
241 case NODE_BITLSHIFT:
242 case NODE_BITRSHIFT: {
243 Type left = type_inference(a, node->left, scope);
244 Type right = type_inference(a, node->right, scope);
245 if (!strset_lookup(&a->integer_types, left) ||
246 !strset_lookup(&a->integer_types, right)) {
247 emit_semantic_error(
248 a, node, cstr("non integer type on bit twiddling expr"));
249 return (Type){0};
250 }
251 if (!str_eq(left, right)) {
252 emit_semantic_error(
253 a, node, cstr("mismatched types on binary expression"));
254 return (Type){0};
255 }
256 } break;
257 case NODE_ADD:
258 case NODE_SUB:
259 case NODE_DIV:
260 case NODE_MUL:
261 case NODE_MOD: {
262 Type left = type_inference(a, node->left, scope);
263 Type right = type_inference(a, node->right, scope);
264 if (!strset_lookup(&a->numeric_types, left) ||
265 !strset_lookup(&a->numeric_types, right)) {
266 emit_semantic_error(
267 a, node, cstr("non numeric type on arithmetic expr"));
268 return (Type){0};
269 }
270 if (!str_eq(left, right)) {
271 emit_semantic_error(
272 a, node, cstr("mismatched types on binary expression"));
273 return (Type){0};
274 }
275 return left;
276 } break;
199 case NODE_NUM_UINT: return cstr("uint"); break; 277 case NODE_NUM_UINT: return cstr("uint"); break;
200 case NODE_NUM_INT: return cstr("int"); break; 278 case NODE_NUM_INT: return cstr("int"); break;
201 case NODE_NUM_FLOAT: return cstr("f64"); break; 279 case NODE_NUM_FLOAT: return cstr("f64"); break;
@@ -471,7 +549,7 @@ symbolic_analysis(Analyzer *a, Parser *parser) {
471 assert(parser); 549 assert(parser);
472 assert(scope); 550 assert(scope);
473 551
474 // Fill builtin functions. 552 // Fill builtin tables.
475 Str builtin_functions[] = { 553 Str builtin_functions[] = {
476 cstr("print"), 554 cstr("print"),
477 cstr("println"), 555 cstr("println"),
@@ -481,35 +559,33 @@ symbolic_analysis(Analyzer *a, Parser *parser) {
481 Symbol sym = (Symbol){.kind = SYM_BUILTIN, .name = symbol}; 559 Symbol sym = (Symbol){.kind = SYM_BUILTIN, .name = symbol};
482 symmap_insert(&scope->symbols, symbol, sym, a->storage); 560 symmap_insert(&scope->symbols, symbol, sym, a->storage);
483 } 561 }
484
485 // Fill builtin types.
486 Type builtin_types[] = { 562 Type builtin_types[] = {
487 cstr("u8"), cstr("s8"), cstr("u16"), cstr("s16"), cstr("u32"), 563 cstr("u8"), cstr("s8"), cstr("u16"), cstr("s16"),
488 cstr("s32"), cstr("u64"), cstr("s64"), cstr("f32"), cstr("f64"), 564 cstr("u32"), cstr("s32"), cstr("u64"), cstr("s64"),
489 cstr("ptr"), cstr("int"), cstr("uint"), cstr("str"), 565 cstr("f32"), cstr("f64"), cstr("ptr"), cstr("int"),
490 }; 566 cstr("uint"), cstr("str"), cstr("bool"), cstr("nil")};
491 for (sz i = 0; i < LEN(builtin_types); i++) { 567 for (sz i = 0; i < LEN(builtin_types); i++) {
492 Type type = builtin_types[i]; 568 Type type = builtin_types[i];
493 typemap_insert(&scope->types, type, type, a->storage); 569 typemap_insert(&scope->types, type, type, a->storage);
494 } 570 }
495 571 Type numeric_types[] = {
496 // Str valid_int_types[] = { 572 cstr("u8"), cstr("s8"), cstr("u16"), cstr("s16"), cstr("u32"),
497 // cstr("u8"), cstr("u16"), cstr("u32"), cstr("u64"), cstr("s8"), 573 cstr("s32"), cstr("u64"), cstr("s64"), cstr("f32"), cstr("f64"),
498 // cstr("s16"), cstr("s32"), cstr("s64"), cstr("int"), cstr("uint"), 574 cstr("ptr"), cstr("int"), cstr("uint"),
499 // }; 575 };
500 // for (sz i = 0; i < LEN(valid_int_types); i++) { 576 for (sz i = 0; i < LEN(numeric_types); i++) {
501 // Str type = valid_int_types[i]; 577 Type type = numeric_types[i];
502 // strset_insert(&a->valid_int_types, type, a->storage); 578 strset_insert(&a->numeric_types, type, a->storage);
503 // } 579 }
504 580 Type integer_types[] = {
505 // Str valid_float_types[] = { 581 cstr("u8"), cstr("s8"), cstr("u16"), cstr("s16"),
506 // cstr("f32"), 582 cstr("u32"), cstr("s32"), cstr("u64"), cstr("s64"),
507 // cstr("f64"), 583 cstr("ptr"), cstr("int"), cstr("uint"),
508 // }; 584 };
509 // for (sz i = 0; i < LEN(valid_float_types); i++) { 585 for (sz i = 0; i < LEN(integer_types); i++) {
510 // Str type = valid_float_types[i]; 586 Type type = integer_types[i];
511 // strset_insert(&a->valid_float_types, type, a->storage); 587 strset_insert(&a->integer_types, type, a->storage);
512 // } 588 }
513 589
514 // Find top level function declarations. 590 // Find top level function declarations.
515 for (sz i = 0; i < array_size(parser->nodes); i++) { 591 for (sz i = 0; i < array_size(parser->nodes); i++) {
diff --git a/tests/semantics.bad b/tests/semantics.bad
index e574a73..d1effe4 100644
--- a/tests/semantics.bad
+++ b/tests/semantics.bad
@@ -3,6 +3,10 @@
3let a:int = (1 + 2 * 2) / 2 3let a:int = (1 + 2 * 2) / 2
4let b = 1 4let b = 1
5let c = b 5let c = b
6let d = 1 + 2 * 4
7let e = 1 <= 2
8let booleans = !true && false || (1 <= 2)
9let bits = 0xff & 0b00001111
6 10
7; enum test { 11; enum test {
8; a = 1 12; a = 1