@@ -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,116 @@ 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+ return false ;
1032+ }
1033+
1034+ template <typename T> bool check (ComparisonExpression::Comparison comp1, const T &value1, const T &value2low, const T &value2high)
1035+ {
1036+ return false ; // TODO
1037+ }
1038+
1039+ template <typename T> bool check (const T &value1low, const T &value1high, const T &value2low, const T &value2high)
1040+ {
1041+ return false ; // TODO
1042+ }
1043+
1044+ } // namespace overlap
1045+
1046+ bool CaseStatement::ComparisonWhenCondition::overlaps (const WhenCondition *cond) const
1047+ {
1048+ const ComparisonWhenCondition *cwhen = dynamic_cast <const ComparisonWhenCondition *>(cond);
1049+ const RangeWhenCondition *rwhen = dynamic_cast <const RangeWhenCondition *>(cond);
1050+ if (cwhen != nullptr ) {
1051+ if (expr->type ->is_equivalent (TYPE_NUMBER)) {
1052+ return overlap::check (comp, expr->eval_number (), cwhen->comp , cwhen->expr ->eval_number ());
1053+ } else if (expr->type ->is_equivalent (TYPE_STRING)) {
1054+ return overlap::check (comp, expr->eval_string (), cwhen->comp , cwhen->expr ->eval_string ());
1055+ } else {
1056+ fprintf (stderr, " compiler internal error" );
1057+ abort ();
1058+ }
1059+ } else if (rwhen != nullptr ) {
1060+ if (expr->type ->is_equivalent (TYPE_NUMBER)) {
1061+ return overlap::check (comp, expr->eval_number (), rwhen->low_expr ->eval_number (), rwhen->high_expr ->eval_number ());
1062+ } else if (expr->type ->is_equivalent (TYPE_STRING)) {
1063+ return overlap::check (comp, expr->eval_string (), rwhen->low_expr ->eval_string (), rwhen->high_expr ->eval_string ());
1064+ } else {
1065+ fprintf (stderr, " compiler internal error" );
1066+ abort ();
1067+ }
1068+ } else {
1069+ fprintf (stderr, " compiler internal error" );
1070+ abort ();
1071+ }
1072+ }
1073+
1074+ bool CaseStatement::RangeWhenCondition::overlaps (const WhenCondition *cond) const
1075+ {
1076+ const ComparisonWhenCondition *cwhen = dynamic_cast <const ComparisonWhenCondition *>(cond);
1077+ const RangeWhenCondition *rwhen = dynamic_cast <const RangeWhenCondition *>(cond);
1078+ if (cwhen != nullptr ) {
1079+ if (low_expr->type ->is_equivalent (TYPE_NUMBER)) {
1080+ return overlap::check (cwhen->comp , cwhen->expr ->eval_number (), low_expr->eval_number (), high_expr->eval_number ());
1081+ } else if (low_expr->type ->is_equivalent (TYPE_STRING)) {
1082+ return overlap::check (cwhen->comp , cwhen->expr ->eval_string (), low_expr->eval_string (), high_expr->eval_string ());
1083+ } else {
1084+ fprintf (stderr, " compiler internal error" );
1085+ abort ();
1086+ }
1087+ } else if (rwhen != nullptr ) {
1088+ if (low_expr->type ->is_equivalent (TYPE_NUMBER)) {
1089+ return overlap::check (low_expr->eval_number (), high_expr->eval_number (), rwhen->low_expr ->eval_number (), rwhen->high_expr ->eval_number ());
1090+ } else if (low_expr->type ->is_equivalent (TYPE_STRING)) {
1091+ return overlap::check (low_expr->eval_string (), high_expr->eval_string (), rwhen->low_expr ->eval_string (), rwhen->high_expr ->eval_string ());
1092+ } else {
1093+ fprintf (stderr, " compiler internal error" );
1094+ abort ();
1095+ }
1096+ } else {
1097+ fprintf (stderr, " compiler internal error" );
1098+ abort ();
1099+ }
1100+ }
1101+
9561102static const Statement *parseImport (Scope *scope, const std::vector<Token> &tokens, std::vector<Token>::size_type &i)
9571103{
9581104 ++i;
0 commit comments