functions for indexing slices and strings

This commit is contained in:
Vern Paxson 2021-03-18 10:02:22 -07:00
parent 8f2637decb
commit b792feccab
2 changed files with 63 additions and 48 deletions

View file

@ -2936,24 +2936,7 @@ ValPtr IndexExpr::Fold(Val* v1, Val* v2) const
if ( lv->Length() == 1 ) if ( lv->Length() == 1 )
v = vect->ValAt(lv->Idx(0)->CoerceToUnsigned()); v = vect->ValAt(lv->Idx(0)->CoerceToUnsigned());
else else
{ return index_slice(vect, lv);
size_t len = vect->Size();
auto result = make_intrusive<VectorVal>(vect->GetType<VectorType>());
bro_int_t first = get_slice_index(lv->Idx(0)->CoerceToInt(), len);
bro_int_t last = get_slice_index(lv->Idx(1)->CoerceToInt(), len);
bro_int_t sub_length = last - first;
if ( sub_length >= 0 )
{
result->Resize(sub_length);
for ( bro_int_t idx = first; idx < last; idx++ )
result->Assign(idx - first, vect->ValAt(idx));
}
return result;
}
} }
break; break;
@ -2962,9 +2945,22 @@ ValPtr IndexExpr::Fold(Val* v1, Val* v2) const
break; break;
case TYPE_STRING: case TYPE_STRING:
return index_string(v1->AsString(), v2->AsListVal());
default:
RuntimeError("type cannot be indexed");
break;
}
if ( v )
return v;
RuntimeError("no such index");
return nullptr;
}
StringValPtr index_string(const String* s, const ListVal* lv)
{ {
const ListVal* lv = v2->AsListVal();
const String* s = v1->AsString();
int len = s->Len(); int len = s->Len();
String* substring = nullptr; String* substring = nullptr;
@ -2993,16 +2989,31 @@ ValPtr IndexExpr::Fold(Val* v1, Val* v2) const
return make_intrusive<StringVal>(substring ? substring : new String("")); return make_intrusive<StringVal>(substring ? substring : new String(""));
} }
default: VectorValPtr index_slice(VectorVal* vect, const ListVal* lv)
RuntimeError("type cannot be indexed"); {
break; auto first = lv->Idx(0)->CoerceToInt();
auto last = lv->Idx(1)->CoerceToInt();
return index_slice(vect, first, last);
} }
if ( v ) VectorValPtr index_slice(VectorVal* vect, int _first, int _last)
return v; {
size_t len = vect->Size();
auto result = make_intrusive<VectorVal>(vect->GetType<VectorType>());
RuntimeError("no such index"); bro_int_t first = get_slice_index(_first, len);
return nullptr; bro_int_t last = get_slice_index(_last, len);
bro_int_t sub_length = last - first;
if ( sub_length >= 0 )
{
result->Resize(sub_length);
for ( bro_int_t idx = first; idx < last; idx++ )
result->Assign(idx - first, vect->ValAt(idx));
}
return result;
} }
void IndexExpr::Assign(Frame* f, ValPtr v) void IndexExpr::Assign(Frame* f, ValPtr v)

View file

@ -941,6 +941,10 @@ protected:
bool is_slice; bool is_slice;
}; };
extern VectorValPtr index_slice(VectorVal* vect, const ListVal* lv);
extern VectorValPtr index_slice(VectorVal* vect, int first, int last);
extern StringValPtr index_string(const String* s, const ListVal* lv);
class IndexExprWhen final : public IndexExpr { class IndexExprWhen final : public IndexExpr {
public: public:
static inline std::vector<ValPtr> results = {}; static inline std::vector<ValPtr> results = {};