aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2022-04-18 15:51:53 -0300
committerBad Diode <bd@badd10de.dev>2022-04-18 15:51:53 -0300
commitdcd3192e50d7b4ea333ecf57a7e8b325af145547 (patch)
treef07b4adabcd9220be7846694a9e1cbfcbac7edfc /src
parent891ea6836072a1201083669a8a212b03af0c2d5c (diff)
downloadbdl-dcd3192e50d7b4ea333ecf57a7e8b325af145547.tar.gz
bdl-dcd3192e50d7b4ea333ecf57a7e8b325af145547.zip
Add a more rich symbol table value and typecheck funcall args
Diffstat (limited to 'src')
-rw-r--r--src/errors.c2
-rw-r--r--src/errors.h2
-rw-r--r--src/parser.c127
3 files changed, 100 insertions, 31 deletions
diff --git a/src/errors.c b/src/errors.c
index e2dee00..6a69064 100644
--- a/src/errors.c
+++ b/src/errors.c
@@ -24,6 +24,8 @@ static const char* error_msgs[] = {
24 [ERR_WRONG_TYPE_T_F] = "error: unmatched types between true and false expression", 24 [ERR_WRONG_TYPE_T_F] = "error: unmatched types between true and false expression",
25 [ERR_WRONG_TYPE_NUM] = "error: non numeric argument types", 25 [ERR_WRONG_TYPE_NUM] = "error: non numeric argument types",
26 [ERR_WRONG_TYPE_BOOL] = "error: non bool argument types", 26 [ERR_WRONG_TYPE_BOOL] = "error: non bool argument types",
27 [ERR_WRONG_TYPE_FUN] = "error: not a function",
28 [ERR_BAD_ARGS] = "error: arguments don't match expected types",
27 [ERR_TYPE_MISMATCH] = "error: type mismatch", 29 [ERR_TYPE_MISMATCH] = "error: type mismatch",
28}; 30};
29 31
diff --git a/src/errors.h b/src/errors.h
index a814549..f2737d0 100644
--- a/src/errors.h
+++ b/src/errors.h
@@ -32,7 +32,9 @@ typedef enum ErrorValue {
32 ERR_WRONG_TYPE_T_F, 32 ERR_WRONG_TYPE_T_F,
33 ERR_WRONG_TYPE_NUM, 33 ERR_WRONG_TYPE_NUM,
34 ERR_WRONG_TYPE_BOOL, 34 ERR_WRONG_TYPE_BOOL,
35 ERR_WRONG_TYPE_FUN,
35 ERR_TYPE_MISMATCH, 36 ERR_TYPE_MISMATCH,
37 ERR_BAD_ARGS,
36 ERR_OK, 38 ERR_OK,
37} ErrorValue; 39} ErrorValue;
38 40
diff --git a/src/parser.c b/src/parser.c
index 10d82d1..0cf70d7 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -33,6 +33,27 @@ static Type default_types[] = {
33 [TYPE_F64] = {STRING("f64"), 8}, 33 [TYPE_F64] = {STRING("f64"), 8},
34}; 34};
35 35
36typedef enum SymbolType {
37 SYMBOL_VAR,
38 SYMBOL_FUN,
39} SymbolType;
40
41typedef struct SymbolValue {
42 Node *name;
43 SymbolType type;
44
45 union {
46 struct {
47 Node *type;
48 } var;
49
50 struct {
51 Node **param_types;
52 Node *return_type;
53 } fun;
54 };
55} SymbolValue;
56
36Token 57Token
37next_token(Parser *parser) { 58next_token(Parser *parser) {
38 return parser->tokens[parser->current_token++]; 59 return parser->tokens[parser->current_token++];
@@ -542,6 +563,14 @@ alloc_parsetree(void) {
542 return parse_tree; 563 return parse_tree;
543} 564}
544 565
566SymbolValue *
567alloc_symval(Node *name, SymbolType type) {
568 SymbolValue *val = malloc(sizeof(SymbolValue));
569 val->name = name;
570 val->type = type;
571 return val;
572}
573
545bool 574bool
546parse_roots(Parser *parser) { 575parse_roots(Parser *parser) {
547 while (has_next(parser)) { 576 while (has_next(parser)) {
@@ -573,36 +602,22 @@ find_type(Scope *scope, Node *type) {
573 return NULL; 602 return NULL;
574} 603}
575 604
576Type * 605bool
577find_symbol(Scope *scope, Node *node) { 606insert_symbol(Scope *scope, Node *symbol, SymbolValue *val) {
578 while (scope != NULL) { 607 // Check if symbol already exists.
579 Type *type = ht_lookup(scope->symbols, node);
580 if (type != NULL) {
581 return type;
582 }
583 scope = scope->parent;
584 }
585 push_error(ERR_TYPE_PARSER, ERR_UNKNOWN_SYMBOL, node->line, node->col);
586 return NULL;
587}
588
589Type *
590insert_symbol(Scope *scope, Node *symbol, Node *type) {
591 HashTable *symbols = scope->symbols; 608 HashTable *symbols = scope->symbols;
592 if (ht_lookup(symbols, symbol) != NULL) { 609 if (ht_lookup(symbols, symbol) != NULL) {
593 push_error(ERR_TYPE_PARSER, ERR_SYMBOL_REDEF, symbol->line, symbol->col); 610 push_error(ERR_TYPE_PARSER, ERR_SYMBOL_REDEF, symbol->line, symbol->col);
594 return NULL; 611 return false;
595 }
596 Type *t = find_type(scope, type);
597 if (t == NULL) {
598 return NULL;
599 } 612 }
600 ht_insert(symbols, symbol, t); 613 ht_insert(symbols, symbol, val);
601 return t; 614 return true;
602} 615}
603 616
604Type * 617Type *
605coerce_numeric_types(Type *a, Type *b) { 618coerce_numeric_types(Type *a, Type *b) {
619 // TODO: Decide what to do with mixed numeric types. What are the promotion
620 // rules, etc.
606 if (a == &default_types[TYPE_U8]) { 621 if (a == &default_types[TYPE_U8]) {
607 if (b == &default_types[TYPE_U16] || 622 if (b == &default_types[TYPE_U16] ||
608 b == &default_types[TYPE_U32] || 623 b == &default_types[TYPE_U32] ||
@@ -658,6 +673,19 @@ type_is_numeric(Type *t) {
658 return false; 673 return false;
659} 674}
660 675
676SymbolValue *
677find_symbol(Scope *scope, Node *node) {
678 while (scope != NULL) {
679 SymbolValue *val = ht_lookup(scope->symbols, node);
680 if (val != NULL) {
681 return val;
682 }
683 scope = scope->parent;
684 }
685 push_error(ERR_TYPE_PARSER, ERR_UNKNOWN_SYMBOL, node->line, node->col);
686 return NULL;
687}
688
661bool 689bool
662resolve_type(Scope *scope, Node *node) { 690resolve_type(Scope *scope, Node *node) {
663 if (node->expr_type != NULL) { 691 if (node->expr_type != NULL) {
@@ -732,7 +760,20 @@ resolve_type(Scope *scope, Node *node) {
732 } 760 }
733 } break; 761 } break;
734 case NODE_SYMBOL: { 762 case NODE_SYMBOL: {
735 Type *type = find_symbol(scope, node); 763 SymbolValue *val = find_symbol(scope, node);
764 if (val == NULL) {
765 return false;
766 }
767
768 Type *type = NULL;
769 switch (val->type) {
770 case SYMBOL_VAR: {
771 type = find_type(scope, val->var.type);
772 } break;
773 case SYMBOL_FUN: {
774 type = find_type(scope, val->fun.return_type);
775 } break;
776 }
736 if (type == NULL) { 777 if (type == NULL) {
737 return false; 778 return false;
738 } 779 }
@@ -746,7 +787,9 @@ resolve_type(Scope *scope, Node *node) {
746 for (size_t i = 0; i < array_size(node->fun.param_names); ++i) { 787 for (size_t i = 0; i < array_size(node->fun.param_names); ++i) {
747 Node *param = node->fun.param_names[i]; 788 Node *param = node->fun.param_names[i];
748 Node *type = node->fun.param_types[i]; 789 Node *type = node->fun.param_types[i];
749 if (insert_symbol(scope, param, type) == NULL) { 790 SymbolValue *var = alloc_symval(param, SYMBOL_VAR);
791 var->var.type = type;
792 if (!insert_symbol(scope, param, var)) {
750 return false; 793 return false;
751 } 794 }
752 } 795 }
@@ -840,7 +883,14 @@ resolve_type(Scope *scope, Node *node) {
840 } 883 }
841 } break; 884 } break;
842 case NODE_DEF: { 885 case NODE_DEF: {
843 Type *type = insert_symbol(scope, node->def.symbol, node->def.type); 886 // Prepare value for symbol table.
887 SymbolValue *var = alloc_symval(node->def.symbol, SYMBOL_VAR);
888 var->var.type = node->def.type;
889 if (!insert_symbol(scope, node->def.symbol, var)) {
890 return false;
891 }
892
893 Type *type = find_type(scope, node->def.type);
844 if (type == NULL) { 894 if (type == NULL) {
845 return false; 895 return false;
846 } 896 }
@@ -862,7 +912,7 @@ resolve_type(Scope *scope, Node *node) {
862 case NODE_NUMBER: { 912 case NODE_NUMBER: {
863 // TODO: Numbers are f64/s64 unless explicitely annotated. Annotated 913 // TODO: Numbers are f64/s64 unless explicitely annotated. Annotated
864 // numbers must fit in the given range (e.g. no negative constants 914 // numbers must fit in the given range (e.g. no negative constants
865 // inside a U64, no numbers bigger than 255 in a u8, etc.). 915 // inside a u64, no numbers bigger than 255 in a u8, etc.).
866 if (node->number.fractional != 0) { 916 if (node->number.fractional != 0) {
867 node->expr_type = &default_types[TYPE_F64]; 917 node->expr_type = &default_types[TYPE_F64];
868 } else { 918 } else {
@@ -876,16 +926,31 @@ resolve_type(Scope *scope, Node *node) {
876 node->expr_type = &default_types[TYPE_STR]; 926 node->expr_type = &default_types[TYPE_STR];
877 } break; 927 } break;
878 case NODE_FUNCALL: { 928 case NODE_FUNCALL: {
879 // TODO: Check that arguments type check with expectations. 929 SymbolValue *val = find_symbol(scope, node->funcall.name);
880 if (!resolve_type(scope, node->funcall.name)) { 930 if (!resolve_type(scope, node->funcall.name)) {
881 return false; 931 return false;
882 } 932 }
933 if (val->type != SYMBOL_FUN) {
934 push_error(ERR_TYPE_PARSER, ERR_WRONG_TYPE_FUN,
935 node->funcall.name->line, node->funcall.name->col);
936 return false;
937 }
938 if (array_size(node->funcall.args) != array_size(val->fun.param_types)) {
939 push_error(ERR_TYPE_PARSER, ERR_BAD_ARGS, node->line, node->col);
940 return false;
941 }
883 node->expr_type = node->funcall.name->expr_type; 942 node->expr_type = node->funcall.name->expr_type;
884 for (size_t i = 0; i < array_size(node->funcall.args); ++i) { 943 for (size_t i = 0; i < array_size(node->funcall.args); ++i) {
885 Node *arg = node->funcall.args[i]; 944 Node *arg = node->funcall.args[i];
886 if (!resolve_type(scope, arg)) { 945 if (!resolve_type(scope, arg)) {
887 return false; 946 return false;
888 } 947 }
948 Node *expected = val->fun.param_types[i];
949 if (!sv_equal(&arg->expr_type->name, &expected->string)) {
950 push_error(ERR_TYPE_PARSER, ERR_TYPE_MISMATCH,
951 arg->line, arg->col);
952 return false;
953 }
889 } 954 }
890 } break; 955 } break;
891 default: break; 956 default: break;
@@ -901,10 +966,10 @@ semantic_analysis(Parser *parser) {
901 Node *root = parser->parse_tree->roots[i]; 966 Node *root = parser->parse_tree->roots[i];
902 if (root->type == NODE_FUN) { 967 if (root->type == NODE_FUN) {
903 Node *name = root->fun.name; 968 Node *name = root->fun.name;
904 // TODO: make sure we store information in the symbol table that 969 SymbolValue *fun = alloc_symval(root->fun.name, SYMBOL_FUN);
905 // this is actually a function, not just a variable with 970 fun->fun.param_types = root->fun.param_types;
906 // return_type. 971 fun->fun.return_type = root->fun.return_type;
907 if (insert_symbol(scope, name, root->fun.return_type) == NULL) { 972 if (!insert_symbol(scope, name, fun)) {
908 return false; 973 return false;
909 } 974 }
910 } 975 }