@@ -892,6 +892,18 @@ static const Statement *parseCaseStatement(Scope *scope, const std::vector<Token
892892 error (2086 , tokens[i], " WHEN condition must be constant" );
893893 }
894894 const CaseStatement::WhenCondition *cond = new CaseStatement::ComparisonWhenCondition (comparisonFromToken (op), when);
895+ for (auto clause: clauses) {
896+ for (auto c: clause.first ) {
897+ if (cond->overlaps (c)) {
898+ error (2106 , tokens[i], " overlapping case condition" );
899+ }
900+ }
901+ }
902+ for (auto c: conditions) {
903+ if (cond->overlaps (c)) {
904+ error (2107 , tokens[i], " overlapping case condition" );
905+ }
906+ }
895907 conditions.push_back (cond);
896908 break ;
897909 }
@@ -913,9 +925,33 @@ static const Statement *parseCaseStatement(Scope *scope, const std::vector<Token
913925 error (2090 , tokens[i], " WHEN condition must be constant" );
914926 }
915927 const CaseStatement::WhenCondition *cond = new CaseStatement::RangeWhenCondition (when, when2);
928+ for (auto clause: clauses) {
929+ for (auto c: clause.first ) {
930+ if (cond->overlaps (c)) {
931+ error (2108 , tokens[i], " overlapping case condition" );
932+ }
933+ }
934+ }
935+ for (auto c: conditions) {
936+ if (cond->overlaps (c)) {
937+ error (2109 , tokens[i], " overlapping case condition" );
938+ }
939+ }
916940 conditions.push_back (cond);
917941 } else {
918942 const CaseStatement::WhenCondition *cond = new CaseStatement::ComparisonWhenCondition (ComparisonExpression::EQ, when);
943+ for (auto clause: clauses) {
944+ for (auto c: clause.first ) {
945+ if (cond->overlaps (c)) {
946+ error (2110 , tokens[i], " overlapping case condition" );
947+ }
948+ }
949+ }
950+ for (auto c: conditions) {
951+ if (cond->overlaps (c)) {
952+ error (2111 , tokens[i], " overlapping case condition" );
953+ }
954+ }
919955 conditions.push_back (cond);
920956 }
921957 break ;
@@ -953,6 +989,115 @@ static const Statement *parseCaseStatement(Scope *scope, const std::vector<Token
953989 return new CaseStatement (expr, clauses);
954990}
955991
992+ namespace overlap {
993+
994+ static bool operator ==(const Number &x, const Number &y) { return number_is_equal (x, y); }
995+ static bool operator !=(const Number &x, const Number &y) { return number_is_not_equal (x, y); }
996+ static bool operator <(const Number &x, const Number &y) { return number_is_less (x, y); }
997+ static bool operator >(const Number &x, const Number &y) { return number_is_greater (x, y); }
998+ static bool operator <=(const Number &x, const Number &y) { return number_is_less_equal (x, y); }
999+ static bool operator >=(const Number &x, const Number &y) { return number_is_greater_equal (x, y); }
1000+
1001+ template <typename T> bool check (ComparisonExpression::Comparison comp1, const T &value1, ComparisonExpression::Comparison comp2, const T &value2)
1002+ {
1003+ switch (comp1) {
1004+ case ComparisonExpression::EQ:
1005+ switch (comp2) {
1006+ case ComparisonExpression::EQ:
1007+ return value1 == value2;
1008+ case ComparisonExpression::NE:
1009+ return value1 != value2;
1010+ case ComparisonExpression::LT:
1011+ return value1 < value2;
1012+ case ComparisonExpression::GT:
1013+ return value1 > value2;
1014+ case ComparisonExpression::LE:
1015+ return value1 <= value2;
1016+ case ComparisonExpression::GE:
1017+ return value1 >= value2;
1018+ }
1019+ break ;
1020+ case ComparisonExpression::NE:
1021+ return false ; // TODO
1022+ case ComparisonExpression::LT:
1023+ return false ; // TODO
1024+ case ComparisonExpression::GT:
1025+ return false ; // TODO
1026+ case ComparisonExpression::LE:
1027+ return false ; // TODO
1028+ case ComparisonExpression::GE:
1029+ return false ; // TODO
1030+ }
1031+ }
1032+
1033+ template <typename T> bool check (ComparisonExpression::Comparison comp1, const T &value1, const T &value2low, const T &value2high)
1034+ {
1035+ return false ; // TODO
1036+ }
1037+
1038+ template <typename T> bool check (const T &value1low, const T &value1high, const T &value2low, const T &value2high)
1039+ {
1040+ return false ; // TODO
1041+ }
1042+
1043+ } // namespace overlap
1044+
1045+ bool CaseStatement::ComparisonWhenCondition::overlaps (const WhenCondition *cond) const
1046+ {
1047+ const ComparisonWhenCondition *cwhen = dynamic_cast <const ComparisonWhenCondition *>(cond);
1048+ const RangeWhenCondition *rwhen = dynamic_cast <const RangeWhenCondition *>(cond);
1049+ if (cwhen != nullptr ) {
1050+ if (expr->type ->is_equivalent (TYPE_NUMBER)) {
1051+ return overlap::check (comp, expr->eval_number (), cwhen->comp , cwhen->expr ->eval_number ());
1052+ } else if (expr->type ->is_equivalent (TYPE_STRING)) {
1053+ return overlap::check (comp, expr->eval_string (), cwhen->comp , cwhen->expr ->eval_string ());
1054+ } else {
1055+ fprintf (stderr, " compiler internal error" );
1056+ abort ();
1057+ }
1058+ } else if (rwhen != nullptr ) {
1059+ if (expr->type ->is_equivalent (TYPE_NUMBER)) {
1060+ return overlap::check (comp, expr->eval_number (), rwhen->low_expr ->eval_number (), rwhen->high_expr ->eval_number ());
1061+ } else if (expr->type ->is_equivalent (TYPE_STRING)) {
1062+ return overlap::check (comp, expr->eval_string (), rwhen->low_expr ->eval_string (), rwhen->high_expr ->eval_string ());
1063+ } else {
1064+ fprintf (stderr, " compiler internal error" );
1065+ abort ();
1066+ }
1067+ } else {
1068+ fprintf (stderr, " compiler internal error" );
1069+ abort ();
1070+ }
1071+ }
1072+
1073+ bool CaseStatement::RangeWhenCondition::overlaps (const WhenCondition *cond) const
1074+ {
1075+ const ComparisonWhenCondition *cwhen = dynamic_cast <const ComparisonWhenCondition *>(cond);
1076+ const RangeWhenCondition *rwhen = dynamic_cast <const RangeWhenCondition *>(cond);
1077+ if (cwhen != nullptr ) {
1078+ if (low_expr->type ->is_equivalent (TYPE_NUMBER)) {
1079+ return overlap::check (cwhen->comp , cwhen->expr ->eval_number (), low_expr->eval_number (), high_expr->eval_number ());
1080+ } else if (low_expr->type ->is_equivalent (TYPE_STRING)) {
1081+ return overlap::check (cwhen->comp , cwhen->expr ->eval_string (), low_expr->eval_string (), high_expr->eval_string ());
1082+ } else {
1083+ fprintf (stderr, " compiler internal error" );
1084+ abort ();
1085+ }
1086+ } else if (rwhen != nullptr ) {
1087+ if (low_expr->type ->is_equivalent (TYPE_NUMBER)) {
1088+ return overlap::check (low_expr->eval_number (), high_expr->eval_number (), rwhen->low_expr ->eval_number (), rwhen->high_expr ->eval_number ());
1089+ } else if (low_expr->type ->is_equivalent (TYPE_STRING)) {
1090+ return overlap::check (low_expr->eval_string (), high_expr->eval_string (), rwhen->low_expr ->eval_string (), rwhen->high_expr ->eval_string ());
1091+ } else {
1092+ fprintf (stderr, " compiler internal error" );
1093+ abort ();
1094+ }
1095+ } else {
1096+ fprintf (stderr, " compiler internal error" );
1097+ abort ();
1098+ }
1099+ }
1100+
9561101static const Statement *parseImport (Scope *scope, const std::vector<Token> &tokens, std::vector<Token>::size_type &i)
9571102{
9581103 ++i;
0 commit comments