mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
stmt: Support iterating over vector values
I ran into wanting to iterate over just the values of a vector and wondering whether that could just work. This adds support for the following, where v will be value of vec[i]. local vec = vector("zero", "one", "two"); for ( i, v in vec ) print i, v;
This commit is contained in:
parent
0f8e675a49
commit
f334df3b79
4 changed files with 66 additions and 16 deletions
8
NEWS
8
NEWS
|
@ -96,6 +96,14 @@ New Functionality
|
|||
``disable_analyzer()`` at a later point when it finds the condition due
|
||||
to which it vetoed fulfilled (which may be never).
|
||||
|
||||
- Add support for iterating over indices and values of a vector using the
|
||||
same syntax as used for iterating over key-value pairs of tables, where
|
||||
``value`` will be set to ``vec[idx]``.
|
||||
|
||||
local vec = vector("zero", "one", "two");
|
||||
for ( idx, value in vec )
|
||||
print idx, value;
|
||||
|
||||
Changed Functionality
|
||||
---------------------
|
||||
|
||||
|
|
31
src/Stmt.cc
31
src/Stmt.cc
|
@ -1290,24 +1290,30 @@ ForStmt::ForStmt(IDPList* arg_loop_vars, ExprPtr loop_expr, IDPtr val_var)
|
|||
{
|
||||
value_var = std::move(val_var);
|
||||
|
||||
if ( e->GetType()->IsTable() )
|
||||
{
|
||||
const auto& yield_type = e->GetType()->AsTableType()->Yield();
|
||||
auto t = e->GetType();
|
||||
zeek::TypePtr yield_type;
|
||||
|
||||
// Verify value_vars type if its already been defined
|
||||
if ( t->IsTable() )
|
||||
yield_type = t->AsTableType()->Yield();
|
||||
|
||||
else if ( t->Tag() == TYPE_VECTOR )
|
||||
yield_type = t->AsVectorType()->Yield();
|
||||
|
||||
else
|
||||
{
|
||||
e->Error("key value for loops only support iteration over tables or vectors");
|
||||
return;
|
||||
}
|
||||
|
||||
// Verify value_vars type if it's already been defined
|
||||
if ( value_var->GetType() )
|
||||
{
|
||||
if ( ! same_type(value_var->GetType(), yield_type) )
|
||||
value_var->GetType()->Error("type clash in iteration", yield_type.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
add_local(value_var, yield_type, INIT_NONE, nullptr, nullptr, VAR_REGULAR);
|
||||
}
|
||||
}
|
||||
else
|
||||
e->Error("key value for loops only support iteration over tables");
|
||||
}
|
||||
|
||||
ForStmt::~ForStmt()
|
||||
{
|
||||
|
@ -1358,8 +1364,11 @@ ValPtr ForStmt::DoExec(Frame* f, Val* v, StmtFlowType& flow)
|
|||
if ( ! raw_vv[i] )
|
||||
continue;
|
||||
|
||||
// Set the loop variable to the current index, and make
|
||||
// another pass over the loop body.
|
||||
// Set the loop variable to the current index, the value variable
|
||||
// to the current value, and make another pass over the loop body.
|
||||
if ( value_var )
|
||||
f->SetElement(value_var, vv->ValAt(i));
|
||||
|
||||
f->SetElement((*loop_vars)[0], val_mgr->Count(i));
|
||||
flow = FLOW_NEXT;
|
||||
ret = body->Exec(f, flow);
|
||||
|
|
13
testing/btest/Baseline/language.vector-for-value/out
Normal file
13
testing/btest/Baseline/language.vector-for-value/out
Normal file
|
@ -0,0 +1,13 @@
|
|||
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||
0, zero
|
||||
1, one
|
||||
2, two
|
||||
4, four
|
||||
0, zero
|
||||
1, one
|
||||
2, two
|
||||
4, four
|
||||
zero
|
||||
one
|
||||
two
|
||||
four
|
20
testing/btest/language/vector-for-value.zeek
Normal file
20
testing/btest/language/vector-for-value.zeek
Normal file
|
@ -0,0 +1,20 @@
|
|||
# @TEST-EXEC: zeek -b %INPUT >out
|
||||
# @TEST-EXEC: btest-diff out
|
||||
|
||||
local vec: vector of string = { "zero", "one", "two" };
|
||||
vec[4] = "four";
|
||||
|
||||
for ( i, v in vec )
|
||||
{
|
||||
print i, v;
|
||||
}
|
||||
|
||||
for ( [i], v in vec )
|
||||
{
|
||||
print i, v;
|
||||
}
|
||||
|
||||
for ( _, v in vec )
|
||||
{
|
||||
print v;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue