aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2022-04-09 08:22:31 -0300
committerBad Diode <bd@badd10de.dev>2022-04-09 08:22:31 -0300
commitab3e064c6f90ec94daad99b5a4c56e0abbcc79bb (patch)
tree597b3d8a3d10ea5914bb86d6c3774bde1b333eeb /src
parent233dd92768a54060df9096558aa58c1f598cce7d (diff)
downloadbdl-ab3e064c6f90ec94daad99b5a4c56e0abbcc79bb.tar.gz
bdl-ab3e064c6f90ec94daad99b5a4c56e0abbcc79bb.zip
Add more type rules and numeric type coercion
Diffstat (limited to 'src')
-rw-r--r--src/errors.c2
-rw-r--r--src/errors.h2
-rw-r--r--src/parser.c183
3 files changed, 167 insertions, 20 deletions
diff --git a/src/errors.c b/src/errors.c
index b987b34..3974281 100644
--- a/src/errors.c
+++ b/src/errors.c
@@ -22,6 +22,8 @@ static const char* error_msgs[] = {
22 [ERR_WRONG_RET_TYPE] = "error: return type don't match type signature", 22 [ERR_WRONG_RET_TYPE] = "error: return type don't match type signature",
23 [ERR_WRONG_COND_TYPE] = "error: conditional expression is not boolean", 23 [ERR_WRONG_COND_TYPE] = "error: conditional expression is not boolean",
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",
26 [ERR_WRONG_TYPE_BOOL] = "error: non bool argument types",
25}; 27};
26 28
27static Error current_error = {.value = ERR_OK}; 29static Error current_error = {.value = ERR_OK};
diff --git a/src/errors.h b/src/errors.h
index a84305b..3c85307 100644
--- a/src/errors.h
+++ b/src/errors.h
@@ -30,6 +30,8 @@ typedef enum ErrorValue {
30 ERR_WRONG_RET_TYPE, 30 ERR_WRONG_RET_TYPE,
31 ERR_WRONG_COND_TYPE, 31 ERR_WRONG_COND_TYPE,
32 ERR_WRONG_TYPE_T_F, 32 ERR_WRONG_TYPE_T_F,
33 ERR_WRONG_TYPE_NUM,
34 ERR_WRONG_TYPE_BOOL,
33 ERR_OK, 35 ERR_OK,
34} ErrorValue; 36} ErrorValue;
35 37
diff --git a/src/parser.c b/src/parser.c
index ddcee56..252ceaa 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -684,6 +684,107 @@ symbol_check(Parser *parser, Node *node) {
684 return true; 684 return true;
685} 685}
686 686
687Type *
688coerce_numeric_types(Type *a, Type *b) {
689 if (a == &default_types[TYPE_U8]) {
690 if (b == &default_types[TYPE_U16] ||
691 b == &default_types[TYPE_U32] ||
692 b == &default_types[TYPE_U64] ||
693 b == &default_types[TYPE_S8] ||
694 b == &default_types[TYPE_S16] ||
695 b == &default_types[TYPE_S32] ||
696 b == &default_types[TYPE_S64] ||
697 b == &default_types[TYPE_F32] ||
698 b == &default_types[TYPE_F64]) {
699 return b;
700 }
701 } else if (a == &default_types[TYPE_U16]) {
702 if (b == &default_types[TYPE_U32] ||
703 b == &default_types[TYPE_S16] ||
704 b == &default_types[TYPE_S32] ||
705 b == &default_types[TYPE_S64] ||
706 b == &default_types[TYPE_U64] ||
707 b == &default_types[TYPE_F32] ||
708 b == &default_types[TYPE_F64]) {
709 return b;
710 }
711 if (b == &default_types[TYPE_S8]) {
712 return &default_types[TYPE_S16];
713 }
714 } else if (a == &default_types[TYPE_U32]) {
715 if (b == &default_types[TYPE_U64] ||
716 b == &default_types[TYPE_S32] ||
717 b == &default_types[TYPE_S64] ||
718 b == &default_types[TYPE_F32] ||
719 b == &default_types[TYPE_F64]) {
720 return b;
721 }
722 if (b == &default_types[TYPE_S8] ||
723 b == &default_types[TYPE_S16]) {
724 return &default_types[TYPE_S32];
725 }
726 } else if (a == &default_types[TYPE_U64]) {
727 if (b == &default_types[TYPE_S64] ||
728 b == &default_types[TYPE_F32] ||
729 b == &default_types[TYPE_F64]) {
730 return b;
731 }
732 if (b == &default_types[TYPE_S8] ||
733 b == &default_types[TYPE_S16] ||
734 b == &default_types[TYPE_S32]) {
735 return &default_types[TYPE_S64];
736 }
737 } else if (a == &default_types[TYPE_S8]) {
738 if (b == &default_types[TYPE_S16] ||
739 b == &default_types[TYPE_S32] ||
740 b == &default_types[TYPE_S64] ||
741 b == &default_types[TYPE_F32] ||
742 b == &default_types[TYPE_F64]) {
743 return b;
744 }
745 } else if (a == &default_types[TYPE_S16]) {
746 if (b == &default_types[TYPE_S32] ||
747 b == &default_types[TYPE_S64] ||
748 b == &default_types[TYPE_F32] ||
749 b == &default_types[TYPE_F64]) {
750 return b;
751 }
752 } else if (a == &default_types[TYPE_S32]) {
753 if (b == &default_types[TYPE_S64] ||
754 b == &default_types[TYPE_F32] ||
755 b == &default_types[TYPE_F64]) {
756 return b;
757 }
758 } else if (a == &default_types[TYPE_S64]) {
759 if (b == &default_types[TYPE_F32] ||
760 b == &default_types[TYPE_F64]) {
761 return b;
762 }
763 } else if (a == &default_types[TYPE_F32]) {
764 if (b == &default_types[TYPE_F64]) {
765 return b;
766 }
767 }
768 return a;
769}
770
771bool
772type_is_numeric(Type *t) {
773 if (t == &default_types[TYPE_U8] ||
774 t == &default_types[TYPE_U16] ||
775 t == &default_types[TYPE_U32] ||
776 t == &default_types[TYPE_U64] ||
777 t == &default_types[TYPE_S8] ||
778 t == &default_types[TYPE_S16] ||
779 t == &default_types[TYPE_S32] ||
780 t == &default_types[TYPE_S64] ||
781 t == &default_types[TYPE_F32] ||
782 t == &default_types[TYPE_F64]) {
783 return true;
784 }
785 return false;
786}
787
687bool 788bool
688resolve_type(Parser *parser, Node *node) { 789resolve_type(Parser *parser, Node *node) {
689 if (node->expr_type != NULL) { 790 if (node->expr_type != NULL) {
@@ -696,6 +797,10 @@ resolve_type(Parser *parser, Node *node) {
696 } 797 }
697 switch (node->type) { 798 switch (node->type) {
698 case NODE_BUILTIN: { 799 case NODE_BUILTIN: {
800 for (size_t i = 0; i < array_size(node->builtin.args); ++i) {
801 Node *arg = node->builtin.args[i];
802 resolve_type(parser, arg);
803 }
699 switch (node->builtin.type) { 804 switch (node->builtin.type) {
700 // Numbers. 805 // Numbers.
701 case TOKEN_ADD: 806 case TOKEN_ADD:
@@ -703,35 +808,67 @@ resolve_type(Parser *parser, Node *node) {
703 case TOKEN_MUL: 808 case TOKEN_MUL:
704 case TOKEN_DIV: 809 case TOKEN_DIV:
705 case TOKEN_MOD: { 810 case TOKEN_MOD: {
706 // TODO: Properly resolve this 811 Type *type = NULL;
707 node->expr_type = &default_types[TYPE_U64]; 812 for (size_t i = 0; i < array_size(node->builtin.args); ++i) {
813 Node *arg = node->builtin.args[i];
814
815 // Check that all arguments are nums.
816 if (!type_is_numeric(arg->expr_type)) {
817 push_error(ERR_TYPE_PARSER, ERR_WRONG_TYPE_NUM,
818 arg->line, arg->col);
819 return false;
820 }
821
822 if (type == NULL) {
823 type = arg->expr_type;
824 } else if (type != arg->expr_type) {
825 type = coerce_numeric_types(type, arg->expr_type);
826 }
827 }
828 node->expr_type = type;
708 } break; 829 } break;
709 // Bools. 830 // Bools.
710 case TOKEN_NOT: 831 case TOKEN_NOT:
711 case TOKEN_AND: 832 case TOKEN_AND:
712 case TOKEN_OR: 833 case TOKEN_OR: {
834 // Check that all arguments are boolean.
835 for (size_t i = 0; i < array_size(node->builtin.args); ++i) {
836 Node *arg = node->builtin.args[i];
837 if (arg->expr_type != &default_types[TYPE_BOOL]) {
838 push_error(ERR_TYPE_PARSER, ERR_WRONG_TYPE_BOOL,
839 arg->line, arg->col);
840 return false;
841 }
842 }
843 node->expr_type = &default_types[TYPE_BOOL];
844 } break;
713 case TOKEN_EQ: 845 case TOKEN_EQ:
714 case TOKEN_LT: 846 case TOKEN_LT:
715 case TOKEN_GT: 847 case TOKEN_GT:
716 case TOKEN_LE: 848 case TOKEN_LE:
717 case TOKEN_GE: { 849 case TOKEN_GE: {
850 // Check that all arguments are nums.
851 for (size_t i = 0; i < array_size(node->builtin.args); ++i) {
852 Node *arg = node->builtin.args[i];
853 if (!type_is_numeric(arg->expr_type)) {
854 push_error(ERR_TYPE_PARSER, ERR_WRONG_TYPE_NUM,
855 arg->line, arg->col);
856 return false;
857 }
858 }
718 node->expr_type = &default_types[TYPE_BOOL]; 859 node->expr_type = &default_types[TYPE_BOOL];
719 } break; 860 } break;
720 default: break; 861 default: break;
721 } 862 }
722 for (size_t i = 0; i < array_size(node->builtin.args); ++i) {
723 Node *arg = node->builtin.args[i];
724 resolve_type(parser, arg);
725 }
726 } break; 863 } break;
727 case NODE_SYMBOL: { 864 case NODE_SYMBOL: {
728 node->expr_type = find_symbol(parser, node); 865 node->expr_type = find_symbol(parser, node);
729 } break; 866 } break;
730 case NODE_FUN: { 867 case NODE_FUN: {
731 resolve_type(parser, node->fun.body); 868 resolve_type(parser, node->fun.body);
869 // Check that the type of body matches the return type.
732 StringView *type_body = &node->fun.body->expr_type->name; 870 StringView *type_body = &node->fun.body->expr_type->name;
733 StringView *return_type = &node->fun.return_type->string; 871 StringView *return_type = &node->fun.return_type->string;
734 // Check that the type of body matches the return type.
735 if (!sv_equal(type_body, return_type)) { 872 if (!sv_equal(type_body, return_type)) {
736 push_error(ERR_TYPE_PARSER, ERR_WRONG_RET_TYPE, node->line, node->col); 873 push_error(ERR_TYPE_PARSER, ERR_WRONG_RET_TYPE, node->line, node->col);
737 return false; 874 return false;
@@ -747,22 +884,32 @@ resolve_type(Parser *parser, Node *node) {
747 } break; 884 } break;
748 case NODE_IF: { 885 case NODE_IF: {
749 resolve_type(parser, node->ifexpr.cond); 886 resolve_type(parser, node->ifexpr.cond);
887 resolve_type(parser, node->ifexpr.expr_true);
888 Type *type_true = node->ifexpr.expr_true->expr_type;
889 node->expr_type = type_true;
890 if (node->ifexpr.expr_false != NULL) {
891 resolve_type(parser, node->ifexpr.expr_false);
892 }
893
750 // Check ifexpr.cond is a bool. 894 // Check ifexpr.cond is a bool.
751 if (!sv_equal(&node->ifexpr.cond->expr_type->name, &default_types[TYPE_BOOL].name)) { 895 Type *type_cond = node->ifexpr.cond->expr_type;
752 push_error(ERR_TYPE_PARSER, ERR_WRONG_COND_TYPE, node->line, node->col); 896 if (!sv_equal(&type_cond->name, &default_types[TYPE_BOOL].name)) {
897 push_error(ERR_TYPE_PARSER, ERR_WRONG_COND_TYPE,
898 node->line, node->col);
753 return false; 899 return false;
754 } 900 }
755 901
756 resolve_type(parser, node->ifexpr.expr_true); 902 // Check if types of expr_true and expr_false match
757 if (node->ifexpr.expr_false != NULL) { 903 if (node->ifexpr.expr_false != NULL) {
758 resolve_type(parser, node->ifexpr.expr_false); 904 Type *type_false = node->ifexpr.expr_false->expr_type;
759 // Check if types of expr_true and expr_false match 905 if (type_is_numeric(type_true) && type_is_numeric(type_false)) {
760 if (!sv_equal(&node->ifexpr.expr_true->expr_type->name, &node->ifexpr.expr_false->expr_type->name)) { 906 node->expr_type = coerce_numeric_types(type_true, type_false);
761 push_error(ERR_TYPE_PARSER, ERR_WRONG_TYPE_T_F, node->line, node->col); 907 } else if (!sv_equal(&type_true->name, &type_false->name)) {
908 push_error(ERR_TYPE_PARSER, ERR_WRONG_TYPE_T_F,
909 node->line, node->col);
762 return false; 910 return false;
763 } 911 }
764 } 912 }
765 node->expr_type = node->ifexpr.expr_true->expr_type;
766 } break; 913 } break;
767 case NODE_SET: { 914 case NODE_SET: {
768 node->expr_type = &default_types[TYPE_VOID]; 915 node->expr_type = &default_types[TYPE_VOID];
@@ -773,10 +920,6 @@ resolve_type(Parser *parser, Node *node) {
773 resolve_type(parser, node->def.value); 920 resolve_type(parser, node->def.value);
774 } break; 921 } break;
775 case NODE_NUMBER: { 922 case NODE_NUMBER: {
776 // TODO: Is this the best way of doing it? We probably need a more
777 // sophisticated way of approaching this. For example:
778 // `(if (< 1 2) 1 -2)` will currently fail with this approach, since
779 // 1:u64 and -2:s64
780 if (node->number.fractional != 0) { 923 if (node->number.fractional != 0) {
781 node->expr_type = &default_types[TYPE_F64]; 924 node->expr_type = &default_types[TYPE_F64];
782 } else if (node->number.negative) { 925 } else if (node->number.negative) {