diff options
author | Bad Diode <bd@badd10de.dev> | 2024-06-23 15:55:34 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2024-06-23 15:55:34 +0200 |
commit | c6fd7856bfe5dd0567f672d0d1a70a3b698feaa4 (patch) | |
tree | 967afe5d560bbf8b9c64ab408cb66e66a6146bc7 /src/main.c | |
parent | 35eaad923d3ef598d6f9ed6925fd65c6a311896b (diff) | |
download | bdl-c6fd7856bfe5dd0567f672d0d1a70a3b698feaa4.tar.gz bdl-c6fd7856bfe5dd0567f672d0d1a70a3b698feaa4.zip |
Add more expressions to type inference method
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 126 |
1 files changed, 101 insertions, 25 deletions
@@ -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 | ||
84 | Scope * | 86 | Scope * |
@@ -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++) { |