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:
Jon Siwek 2012-11-28 14:19:48 -06:00
parent e2fdf16e0c
commit a0590b2140
4 changed files with 150 additions and 6 deletions

View file

@ -2663,7 +2663,7 @@ void AssignExpr::EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f) const
TableVal* tv = aggr->AsTableVal();
Val* index = op1->Eval(f);
Val* v = op2->Eval(f);
Val* v = check_and_promote(op2->Eval(f), t->YieldType(), 1);
if ( ! index || ! v )
return;
@ -3386,7 +3386,14 @@ Val* TableConstructorExpr::InitVal(const BroType* t, Val* aggr) const
if ( IsError() )
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
@ -3456,7 +3463,26 @@ Val* SetConstructorExpr::InitVal(const BroType* t, Val* aggr) const
if ( IsError() )
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
@ -3536,14 +3562,14 @@ Val* VectorConstructorExpr::InitVal(const BroType* t, Val* aggr) const
if ( IsError() )
return 0;
VectorVal* vec = aggr->AsVectorVal();
const BroType* vt = vec->Type()->AsVectorType()->YieldType();
VectorType* vt = Type()->AsVectorType();
VectorVal* vec = aggr ? aggr->AsVectorVal() : new VectorVal(vt);
const expr_list& exprs = op->AsListExpr()->Exprs();
loop_over_list(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) )
{

View file

@ -3117,6 +3117,8 @@ void VectorVal::ValDescribe(ODesc* d) const
Val* check_and_promote(Val* v, const BroType* t, int is_init)
{
if ( ! v ) return 0;
BroType* vt = v->Type();
vt = flatten_type(vt);

View file

@ -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

View 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);