Misc. tweaks to vector slicing implementation

* Minor style/format changes

* Fix a signed/unsigned comparison compiler warning

* Use a non-fatal error for non-integral slice indices so we can
  report any further scripting errors instead of stopping the parse
  right there
This commit is contained in:
Jon Siwek 2019-06-18 17:25:32 -07:00
parent 502ad9abc3
commit 91835752b7
5 changed files with 18 additions and 10 deletions

6
NEWS
View file

@ -94,6 +94,12 @@ New Functionality
is available in the events: ``ssl_extension_pre_shared_key_client_hello`` is available in the events: ``ssl_extension_pre_shared_key_client_hello``
and ``ssl_extension_pre_shared_key_server_hello``. and ``ssl_extension_pre_shared_key_server_hello``.
- Add support for vector slicing operations. For example::
local v = vector(1, 2, 3, 4, 5);
v[2:4] = vector(6, 7, 8); # v is now [1, 2, 6, 7, 8, 5]
print v[:4]; # prints [1, 2, 6, 7]
Changed Functionality Changed Functionality
--------------------- ---------------------

View file

@ -3200,27 +3200,26 @@ void IndexExpr::Assign(Frame* f, Val* v, Opcode op)
switch ( v1->Type()->Tag() ) { switch ( v1->Type()->Tag() ) {
case TYPE_VECTOR: case TYPE_VECTOR:
{ {
const ListVal *lv = v2->AsListVal(); const ListVal* lv = v2->AsListVal();
VectorVal* v1_vect = v1->AsVectorVal(); VectorVal* v1_vect = v1->AsVectorVal();
if ( lv->Length() > 1 ) if ( lv->Length() > 1 )
{ {
int len = v1_vect->Size(); auto len = v1_vect->Size();
bro_int_t first = get_slice_index(lv->Index(0)->CoerceToInt(), len); bro_int_t first = get_slice_index(lv->Index(0)->CoerceToInt(), len);
bro_int_t last = get_slice_index(lv->Index(1)->CoerceToInt(), len); bro_int_t last = get_slice_index(lv->Index(1)->CoerceToInt(), len);
// Remove the elements from the vector within the slice // Remove the elements from the vector within the slice
for ( int idx = first; idx < last; idx++ ) for ( auto idx = first; idx < last; idx++ )
v1_vect->Remove(first); v1_vect->Remove(first);
// Insert the new elements starting at the first position // Insert the new elements starting at the first position
VectorVal* v_vect = v->AsVectorVal(); VectorVal* v_vect = v->AsVectorVal();
for ( int idx = 0; idx < v_vect->Size(); idx++, first++ )
{ for ( auto idx = 0u; idx < v_vect->Size(); idx++, first++ )
v1_vect->Insert(first, v_vect->Lookup(idx)->Ref()); v1_vect->Insert(first, v_vect->Lookup(idx)->Ref());
}
} }
else if ( !v1_vect->Assign(v2, v, op) ) else if ( ! v1_vect->Assign(v2, v, op) )
{ {
if ( v ) if ( v )
{ {

View file

@ -3417,6 +3417,7 @@ bool VectorVal::Insert(unsigned int index, Val* element)
} }
vector<Val*>::iterator it; vector<Val*>::iterator it;
if ( index < val.vector_val->size() ) if ( index < val.vector_val->size() )
it = std::next(val.vector_val->begin(), index); it = std::next(val.vector_val->begin(), index);
else else

View file

@ -1197,8 +1197,8 @@ public:
// Insert an element at a specific position into the underlying vector. // Insert an element at a specific position into the underlying vector.
bool Insert(unsigned int index, Val* element); bool Insert(unsigned int index, Val* element);
// Removes an element or a range of elements from a specific position. // Removes an element at a specific position.
bool Remove(unsigned int start_index); bool Remove(unsigned int index);
protected: protected:
friend class Val; friend class Val;

View file

@ -484,8 +484,10 @@ expr:
set_location(@1, @6); set_location(@1, @6);
Expr* low = $3 ? $3 : new ConstExpr(val_mgr->GetCount(0)); Expr* low = $3 ? $3 : new ConstExpr(val_mgr->GetCount(0));
Expr* high = $5 ? $5 : new SizeExpr($1); Expr* high = $5 ? $5 : new SizeExpr($1);
if ( ! IsIntegral(low->Type()->Tag()) || ! IsIntegral(high->Type()->Tag()) ) if ( ! IsIntegral(low->Type()->Tag()) || ! IsIntegral(high->Type()->Tag()) )
reporter->FatalError("slice notation must have integral values as indexes"); reporter->Error("slice notation must have integral values as indexes");
ListExpr* le = new ListExpr(low); ListExpr* le = new ListExpr(low);
le->Append(high); le->Append(high);
$$ = new IndexExpr($1, le, true); $$ = new IndexExpr($1, le, true);