support for indexing "table[pattern] of T" with strings to get multi-matches

This commit is contained in:
Vern Paxson 2023-11-01 11:23:48 +01:00 committed by Arne Welzel
parent a5a79d3f3a
commit 699549eb45
8 changed files with 228 additions and 2 deletions

View file

@ -2382,6 +2382,18 @@ IndexExpr::IndexExpr(ExprPtr arg_op1, ListExprPtr arg_op2, bool arg_is_slice, bo
if ( IsError() )
return;
if ( op1->GetType()->Tag() == TYPE_TABLE ) { // Check for a table[pattern] being indexed by a string
auto table_type = op1->GetType()->AsTableType();
auto& it = table_type->GetIndexTypes();
auto& rhs_type = op2->GetType()->AsTypeList()->GetTypes();
if ( it.size() == 1 && it[0]->Tag() == TYPE_PATTERN && table_type->Yield() && rhs_type.size() == 1 &&
rhs_type[0]->Tag() == TYPE_STRING ) {
is_pattern_table = true;
SetType(make_intrusive<VectorType>(op1->GetType()->Yield()));
return;
}
}
int match_type = op1->GetType()->MatchesIndex(op2->AsListExpr());
if ( match_type == DOES_NOT_MATCH_INDEX ) {
@ -2532,7 +2544,12 @@ ValPtr IndexExpr::Fold(Val* v1, Val* v2) const {
return index_slice(vect, lv);
} break;
case TYPE_TABLE: v = v1->AsTableVal()->FindOrDefault({NewRef{}, v2}); break;
case TYPE_TABLE:
if ( is_pattern_table )
return v1->AsTableVal()->LookupPattern(v2->AsListVal()->Idx(0)->AsStringVal());
v = v1->AsTableVal()->FindOrDefault({NewRef{}, v2});
break;
case TYPE_STRING: return index_string(v1->AsString(), v2->AsListVal());