mirror of
https://github.com/zeek/zeek.git
synced 2025-10-14 04:28:20 +00:00
Fix table(), set(), vector() constructors in table initializer lists.
Also adds type checking of yield values to table() constructor and fixes the type checking of yield values in vector() constructor. Addresses #5.
This commit is contained in:
parent
e2fdf16e0c
commit
a0590b2140
4 changed files with 150 additions and 6 deletions
38
src/Expr.cc
38
src/Expr.cc
|
@ -2663,7 +2663,7 @@ void AssignExpr::EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f) const
|
||||||
TableVal* tv = aggr->AsTableVal();
|
TableVal* tv = aggr->AsTableVal();
|
||||||
|
|
||||||
Val* index = op1->Eval(f);
|
Val* index = op1->Eval(f);
|
||||||
Val* v = op2->Eval(f);
|
Val* v = check_and_promote(op2->Eval(f), t->YieldType(), 1);
|
||||||
if ( ! index || ! v )
|
if ( ! index || ! v )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -3386,7 +3386,14 @@ Val* TableConstructorExpr::InitVal(const BroType* t, Val* aggr) const
|
||||||
if ( IsError() )
|
if ( IsError() )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return op->InitVal(t, aggr);
|
TableType* tt = Type()->AsTableType();
|
||||||
|
TableVal* tval = aggr ? aggr->AsTableVal() : new TableVal(tt, attrs);
|
||||||
|
const expr_list& exprs = op->AsListExpr()->Exprs();
|
||||||
|
|
||||||
|
loop_over_list(exprs, i)
|
||||||
|
exprs[i]->EvalIntoAggregate(t, tval, 0);
|
||||||
|
|
||||||
|
return tval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TableConstructorExpr::ExprDescribe(ODesc* d) const
|
void TableConstructorExpr::ExprDescribe(ODesc* d) const
|
||||||
|
@ -3456,7 +3463,26 @@ Val* SetConstructorExpr::InitVal(const BroType* t, Val* aggr) const
|
||||||
if ( IsError() )
|
if ( IsError() )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return op->InitVal(t, aggr);
|
const BroType* index_type = t->AsTableType()->Indices();
|
||||||
|
TableType* tt = Type()->AsTableType();
|
||||||
|
TableVal* tval = aggr ? aggr->AsTableVal() : new TableVal(tt, attrs);
|
||||||
|
const expr_list& exprs = op->AsListExpr()->Exprs();
|
||||||
|
|
||||||
|
loop_over_list(exprs, i)
|
||||||
|
{
|
||||||
|
Expr* e = exprs[i];
|
||||||
|
Val* element = check_and_promote(e->Eval(0), index_type, 1);
|
||||||
|
|
||||||
|
if ( ! element || ! tval->Assign(element, 0) )
|
||||||
|
{
|
||||||
|
Error(fmt("initialization type mismatch in set"), e);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Unref(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetConstructorExpr::ExprDescribe(ODesc* d) const
|
void SetConstructorExpr::ExprDescribe(ODesc* d) const
|
||||||
|
@ -3536,14 +3562,14 @@ Val* VectorConstructorExpr::InitVal(const BroType* t, Val* aggr) const
|
||||||
if ( IsError() )
|
if ( IsError() )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
VectorVal* vec = aggr->AsVectorVal();
|
VectorType* vt = Type()->AsVectorType();
|
||||||
const BroType* vt = vec->Type()->AsVectorType()->YieldType();
|
VectorVal* vec = aggr ? aggr->AsVectorVal() : new VectorVal(vt);
|
||||||
const expr_list& exprs = op->AsListExpr()->Exprs();
|
const expr_list& exprs = op->AsListExpr()->Exprs();
|
||||||
|
|
||||||
loop_over_list(exprs, i)
|
loop_over_list(exprs, i)
|
||||||
{
|
{
|
||||||
Expr* e = exprs[i];
|
Expr* e = exprs[i];
|
||||||
Val* v = check_and_promote(e->Eval(0), vt, 1);
|
Val* v = check_and_promote(e->Eval(0), t->YieldType(), 1);
|
||||||
|
|
||||||
if ( ! v || ! vec->Assign(i, v, e) )
|
if ( ! v || ! vec->Assign(i, v, e) )
|
||||||
{
|
{
|
||||||
|
|
|
@ -3117,6 +3117,8 @@ void VectorVal::ValDescribe(ODesc* d) const
|
||||||
|
|
||||||
Val* check_and_promote(Val* v, const BroType* t, int is_init)
|
Val* check_and_promote(Val* v, const BroType* t, int is_init)
|
||||||
{
|
{
|
||||||
|
if ( ! v ) return 0;
|
||||||
|
|
||||||
BroType* vt = v->Type();
|
BroType* vt = v->Type();
|
||||||
|
|
||||||
vt = flatten_type(vt);
|
vt = flatten_type(vt);
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
table of set
|
||||||
|
{
|
||||||
|
[13] = {
|
||||||
|
[bar, 2] ,
|
||||||
|
[foo, 1]
|
||||||
|
},
|
||||||
|
[5] = {
|
||||||
|
[bah, 3] ,
|
||||||
|
[baz, 4]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table of vector
|
||||||
|
{
|
||||||
|
[13] = [1, 2],
|
||||||
|
[5] = [3, 4]
|
||||||
|
}
|
||||||
|
|
||||||
|
table of table
|
||||||
|
{
|
||||||
|
[13] = {
|
||||||
|
[bar, 2] = 2,
|
||||||
|
[foo, 1] = 1
|
||||||
|
},
|
||||||
|
[5] = {
|
||||||
|
[bah, 3] = 3,
|
||||||
|
[baz, 4] = 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
T
|
||||||
|
T
|
||||||
|
T
|
||||||
|
T
|
||||||
|
T
|
||||||
|
T
|
||||||
|
T
|
||||||
|
T
|
||||||
|
T
|
||||||
|
T
|
||||||
|
T
|
||||||
|
T
|
74
testing/btest/language/table-init-container-ctors.bro
Normal file
74
testing/btest/language/table-init-container-ctors.bro
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
# @TEST-EXEC: bro -b %INPUT >output
|
||||||
|
# @TEST-EXEC: btest-diff output
|
||||||
|
|
||||||
|
# The various container constructor expressions should work in table
|
||||||
|
# initialization lists.
|
||||||
|
|
||||||
|
type set_yield: set[string, count];
|
||||||
|
type vector_yield: vector of count;
|
||||||
|
type table_yield: table[string, count] of count;
|
||||||
|
|
||||||
|
global lone_set_ctor: set_yield = set(["foo", 1], ["bar", 2]);
|
||||||
|
global lone_vector_ctor: vector_yield = vector(1, 2);
|
||||||
|
global lone_table_ctor: table_yield = table(["foo", 1] = 1, ["bar", 2] = 2);
|
||||||
|
|
||||||
|
global table_of_set: table[count] of set_yield = {
|
||||||
|
[13] = lone_set_ctor,
|
||||||
|
[5] = set(["bah", 3], ["baz", 4]),
|
||||||
|
};
|
||||||
|
|
||||||
|
global table_of_vector: table[count] of vector_yield = {
|
||||||
|
[13] = lone_vector_ctor,
|
||||||
|
[5] = vector(3, 4),
|
||||||
|
};
|
||||||
|
|
||||||
|
global table_of_table: table[count] of table_yield = {
|
||||||
|
[13] = lone_table_ctor,
|
||||||
|
[5] = table(["bah", 3] = 3, ["baz", 4] = 4),
|
||||||
|
};
|
||||||
|
|
||||||
|
# Just copying the inline ctors used in the table initializer lists here
|
||||||
|
# for later comparisons.
|
||||||
|
global inline_set_ctor: set_yield = set(["bah", 3], ["baz", 4]);
|
||||||
|
global inline_vector_ctor: vector_yield = vector(3, 4);
|
||||||
|
global inline_table_ctor: table_yield = table(["bah", 3] = 3, ["baz", 4] = 4);
|
||||||
|
|
||||||
|
function compare_set_yield(a: set_yield, b: set_yield)
|
||||||
|
{
|
||||||
|
local s: string;
|
||||||
|
local c: count;
|
||||||
|
for ( [s, c] in a )
|
||||||
|
print [s, c] in b;
|
||||||
|
}
|
||||||
|
|
||||||
|
function compare_vector_yield(a: vector_yield, b: vector_yield)
|
||||||
|
{
|
||||||
|
local c: count;
|
||||||
|
for ( c in a )
|
||||||
|
print a[c] == b[c];
|
||||||
|
}
|
||||||
|
|
||||||
|
function compare_table_yield(a: table_yield, b: table_yield)
|
||||||
|
{
|
||||||
|
local s: string;
|
||||||
|
local c: count;
|
||||||
|
for ( [s, c] in a )
|
||||||
|
print [s, c] in b && a[s, c] == b[s, c];
|
||||||
|
}
|
||||||
|
|
||||||
|
print "table of set";
|
||||||
|
print table_of_set;
|
||||||
|
print "";
|
||||||
|
print "table of vector";
|
||||||
|
print table_of_vector;
|
||||||
|
print "";
|
||||||
|
print "table of table";
|
||||||
|
print table_of_table;
|
||||||
|
print "";
|
||||||
|
|
||||||
|
compare_set_yield(table_of_set[13], lone_set_ctor);
|
||||||
|
compare_set_yield(table_of_set[5], inline_set_ctor);
|
||||||
|
compare_vector_yield(table_of_vector[13], lone_vector_ctor);
|
||||||
|
compare_vector_yield(table_of_vector[5], inline_vector_ctor);
|
||||||
|
compare_table_yield(table_of_table[13], lone_table_ctor);
|
||||||
|
compare_table_yield(table_of_table[5], inline_table_ctor);
|
Loading…
Add table
Add a link
Reference in a new issue