mirror of
https://github.com/zeek/zeek.git
synced 2025-10-10 10:38:20 +00:00
Allow named set constructors. Addresses #983.
This commit is contained in:
parent
a0ad87b4c2
commit
b256642f27
7 changed files with 86 additions and 5 deletions
53
src/Expr.cc
53
src/Expr.cc
|
@ -3537,16 +3537,30 @@ bool TableConstructorExpr::DoUnserialize(UnserialInfo* info)
|
||||||
}
|
}
|
||||||
|
|
||||||
SetConstructorExpr::SetConstructorExpr(ListExpr* constructor_list,
|
SetConstructorExpr::SetConstructorExpr(ListExpr* constructor_list,
|
||||||
attr_list* arg_attrs)
|
attr_list* arg_attrs, BroType* arg_type)
|
||||||
: UnaryExpr(EXPR_SET_CONSTRUCTOR, constructor_list)
|
: UnaryExpr(EXPR_SET_CONSTRUCTOR, constructor_list)
|
||||||
{
|
{
|
||||||
if ( IsError() )
|
if ( IsError() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if ( arg_type )
|
||||||
|
{
|
||||||
|
if ( ! arg_type->IsSet() )
|
||||||
|
{
|
||||||
|
Error("bad set constructor type", arg_type);
|
||||||
|
SetError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetType(arg_type->Ref());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if ( constructor_list->Exprs().length() == 0 )
|
if ( constructor_list->Exprs().length() == 0 )
|
||||||
SetType(new ::SetType(new TypeList(base_type(TYPE_ANY)), 0));
|
SetType(new ::SetType(new TypeList(base_type(TYPE_ANY)), 0));
|
||||||
else
|
else
|
||||||
SetType(init_type(constructor_list));
|
SetType(init_type(constructor_list));
|
||||||
|
}
|
||||||
|
|
||||||
if ( ! type )
|
if ( ! type )
|
||||||
SetError();
|
SetError();
|
||||||
|
@ -3555,6 +3569,43 @@ SetConstructorExpr::SetConstructorExpr(ListExpr* constructor_list,
|
||||||
SetError("values in set(...) constructor do not specify a set");
|
SetError("values in set(...) constructor do not specify a set");
|
||||||
|
|
||||||
attrs = arg_attrs ? new Attributes(arg_attrs, type, false) : 0;
|
attrs = arg_attrs ? new Attributes(arg_attrs, type, false) : 0;
|
||||||
|
|
||||||
|
type_list* indices = type->AsTableType()->Indices()->Types();
|
||||||
|
expr_list& cle = constructor_list->Exprs();
|
||||||
|
|
||||||
|
loop_over_list(cle, i)
|
||||||
|
{
|
||||||
|
Expr* ce = cle[i];
|
||||||
|
|
||||||
|
if ( ce->Tag() == EXPR_LIST )
|
||||||
|
{
|
||||||
|
// check promote each expression in composite index
|
||||||
|
expr_list& el = ce->AsListExpr()->Exprs();
|
||||||
|
|
||||||
|
if ( el.length() != indices->length() )
|
||||||
|
{
|
||||||
|
ExprError("inconsistent index type length in set constructor");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
loop_over_list(el, j)
|
||||||
|
{
|
||||||
|
Expr* e = el[j];
|
||||||
|
|
||||||
|
if ( ! check_and_promote_expr(e, (*indices)[j]) )
|
||||||
|
{
|
||||||
|
ExprError("inconsistent index type in set constructor");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ( indices->length() == 1 )
|
||||||
|
{
|
||||||
|
if ( ! check_and_promote_expr(ce, (*indices)[0]) )
|
||||||
|
ExprError("inconsistent index type in set constructor");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Val* SetConstructorExpr::Eval(Frame* f) const
|
Val* SetConstructorExpr::Eval(Frame* f) const
|
||||||
|
|
|
@ -782,7 +782,8 @@ protected:
|
||||||
|
|
||||||
class SetConstructorExpr : public UnaryExpr {
|
class SetConstructorExpr : public UnaryExpr {
|
||||||
public:
|
public:
|
||||||
SetConstructorExpr(ListExpr* constructor_list, attr_list* attrs);
|
SetConstructorExpr(ListExpr* constructor_list, attr_list* attrs,
|
||||||
|
BroType* arg_type = 0);
|
||||||
~SetConstructorExpr() { Unref(attrs); }
|
~SetConstructorExpr() { Unref(attrs); }
|
||||||
|
|
||||||
Attributes* Attrs() { return attrs; }
|
Attributes* Attrs() { return attrs; }
|
||||||
|
|
|
@ -546,6 +546,15 @@ expr:
|
||||||
$$ = new RecordConstructorExpr($4, ctor_type);
|
$$ = new RecordConstructorExpr($4, ctor_type);
|
||||||
break;
|
break;
|
||||||
case TYPE_TABLE:
|
case TYPE_TABLE:
|
||||||
|
if ( ctor_type->IsTable() )
|
||||||
|
{
|
||||||
|
$1->Error("constructor type not implemented");
|
||||||
|
YYERROR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
$$ = new SetConstructorExpr($4, 0, ctor_type);
|
||||||
|
|
||||||
|
break;
|
||||||
case TYPE_VECTOR:
|
case TYPE_VECTOR:
|
||||||
default:
|
default:
|
||||||
$1->Error("constructor type not implemented");
|
$1->Error("constructor type not implemented");
|
||||||
|
|
9
testing/btest/Baseline/language.named-set-ctors/out
Normal file
9
testing/btest/Baseline/language.named-set-ctors/out
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
1,
|
||||||
|
5,
|
||||||
|
3
|
||||||
|
}
|
||||||
|
{
|
||||||
|
[test, 1] ,
|
||||||
|
[cool, 2]
|
||||||
|
}
|
11
testing/btest/language/named-set-ctors.bro
Normal file
11
testing/btest/language/named-set-ctors.bro
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# @TEST-EXEC: bro -b %INPUT >out
|
||||||
|
# @TEST-EXEC: btest-diff out
|
||||||
|
|
||||||
|
type FooSet: set[count];
|
||||||
|
type FooSetComp: set[string, count];
|
||||||
|
|
||||||
|
global myset: FooSet = FooSet(1, 5, 3);
|
||||||
|
global mysetcomp: FooSetComp = FooSetComp(["test", 1], ["cool", 2]);
|
||||||
|
|
||||||
|
print myset;
|
||||||
|
print mysetcomp;
|
Loading…
Add table
Add a link
Reference in a new issue