mirror of
https://github.com/zeek/zeek.git
synced 2025-10-08 17:48:21 +00:00
Allow named table constructors. Addresses #983.
This commit is contained in:
parent
29740d3d6e
commit
bcf5c41786
5 changed files with 117 additions and 14 deletions
50
src/Expr.cc
50
src/Expr.cc
|
@ -3461,12 +3461,25 @@ bool RecordConstructorExpr::DoUnserialize(UnserialInfo* info)
|
||||||
}
|
}
|
||||||
|
|
||||||
TableConstructorExpr::TableConstructorExpr(ListExpr* constructor_list,
|
TableConstructorExpr::TableConstructorExpr(ListExpr* constructor_list,
|
||||||
attr_list* arg_attrs)
|
attr_list* arg_attrs, BroType* arg_type)
|
||||||
: UnaryExpr(EXPR_TABLE_CONSTRUCTOR, constructor_list)
|
: UnaryExpr(EXPR_TABLE_CONSTRUCTOR, constructor_list)
|
||||||
{
|
{
|
||||||
if ( IsError() )
|
if ( IsError() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if ( arg_type )
|
||||||
|
{
|
||||||
|
if ( ! arg_type->IsTable() )
|
||||||
|
{
|
||||||
|
Error("bad table 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 TableType(new TypeList(base_type(TYPE_ANY)), 0));
|
SetType(new TableType(new TypeList(base_type(TYPE_ANY)), 0));
|
||||||
else
|
else
|
||||||
|
@ -3480,8 +3493,43 @@ TableConstructorExpr::TableConstructorExpr(ListExpr* constructor_list,
|
||||||
type->AsTableType()->IsSet() )
|
type->AsTableType()->IsSet() )
|
||||||
SetError("values in table(...) constructor do not specify a table");
|
SetError("values in table(...) constructor do not specify a table");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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();
|
||||||
|
|
||||||
|
// check and promote all index expressions in ctor list
|
||||||
|
loop_over_list(cle, i)
|
||||||
|
{
|
||||||
|
if ( cle[i]->Tag() != EXPR_ASSIGN )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Expr* idx_expr = cle[i]->AsAssignExpr()->Op1();
|
||||||
|
|
||||||
|
if ( idx_expr->Tag() != EXPR_LIST )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
expr_list& idx_exprs = idx_expr->AsListExpr()->Exprs();
|
||||||
|
|
||||||
|
if ( idx_exprs.length() != indices->length() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
loop_over_list(idx_exprs, j)
|
||||||
|
{
|
||||||
|
Expr* idx = idx_exprs[j];
|
||||||
|
|
||||||
|
if ( check_and_promote_expr(idx, (*indices)[j]) )
|
||||||
|
{
|
||||||
|
if ( idx != idx_exprs[j] )
|
||||||
|
idx_exprs.replace(j, idx);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExprError("inconsistent types in table constructor");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Val* TableConstructorExpr::Eval(Frame* f) const
|
Val* TableConstructorExpr::Eval(Frame* f) const
|
||||||
|
|
15
src/Expr.h
15
src/Expr.h
|
@ -58,6 +58,7 @@ class Stmt;
|
||||||
class Frame;
|
class Frame;
|
||||||
class ListExpr;
|
class ListExpr;
|
||||||
class NameExpr;
|
class NameExpr;
|
||||||
|
class AssignExpr;
|
||||||
class CallExpr;
|
class CallExpr;
|
||||||
class EventExpr;
|
class EventExpr;
|
||||||
|
|
||||||
|
@ -177,6 +178,17 @@ public:
|
||||||
return (NameExpr*) this;
|
return (NameExpr*) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const AssignExpr* AsAssignExpr() const
|
||||||
|
{
|
||||||
|
CHECK_TAG(tag, EXPR_ASSIGN, "ExprVal::AsAssignExpr", expr_name)
|
||||||
|
return (const AssignExpr*) this;
|
||||||
|
}
|
||||||
|
AssignExpr* AsAssignExpr()
|
||||||
|
{
|
||||||
|
CHECK_TAG(tag, EXPR_ASSIGN, "ExprVal::AsAssignExpr", expr_name)
|
||||||
|
return (AssignExpr*) this;
|
||||||
|
}
|
||||||
|
|
||||||
void Describe(ODesc* d) const;
|
void Describe(ODesc* d) const;
|
||||||
|
|
||||||
bool Serialize(SerialInfo* info) const;
|
bool Serialize(SerialInfo* info) const;
|
||||||
|
@ -760,7 +772,8 @@ protected:
|
||||||
|
|
||||||
class TableConstructorExpr : public UnaryExpr {
|
class TableConstructorExpr : public UnaryExpr {
|
||||||
public:
|
public:
|
||||||
TableConstructorExpr(ListExpr* constructor_list, attr_list* attrs);
|
TableConstructorExpr(ListExpr* constructor_list, attr_list* attrs,
|
||||||
|
BroType* arg_type = 0);
|
||||||
~TableConstructorExpr() { Unref(attrs); }
|
~TableConstructorExpr() { Unref(attrs); }
|
||||||
|
|
||||||
Attributes* Attrs() { return attrs; }
|
Attributes* Attrs() { return attrs; }
|
||||||
|
|
|
@ -545,16 +545,15 @@ expr:
|
||||||
case TYPE_RECORD:
|
case TYPE_RECORD:
|
||||||
$$ = new RecordConstructorExpr($4, ctor_type);
|
$$ = new RecordConstructorExpr($4, ctor_type);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_TABLE:
|
case TYPE_TABLE:
|
||||||
if ( ctor_type->IsTable() )
|
if ( ctor_type->IsTable() )
|
||||||
{
|
$$ = new TableConstructorExpr($4, 0, ctor_type);
|
||||||
$1->Error("constructor type not implemented");
|
|
||||||
YYERROR;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
$$ = new SetConstructorExpr($4, 0, ctor_type);
|
$$ = new SetConstructorExpr($4, 0, ctor_type);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_VECTOR:
|
case TYPE_VECTOR:
|
||||||
default:
|
default:
|
||||||
$1->Error("constructor type not implemented");
|
$1->Error("constructor type not implemented");
|
||||||
|
|
19
testing/btest/Baseline/language.named-table-ctors/out
Normal file
19
testing/btest/Baseline/language.named-table-ctors/out
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
[1] = one,
|
||||||
|
[5] = five,
|
||||||
|
[3] = three
|
||||||
|
}
|
||||||
|
{
|
||||||
|
[[min=<uninitialized>, max=5]] = max5,
|
||||||
|
[[min=<uninitialized>, max=2]] = max2
|
||||||
|
}
|
||||||
|
{
|
||||||
|
[test, 1] = test1,
|
||||||
|
[cool, 2] = cool2
|
||||||
|
}
|
||||||
|
{
|
||||||
|
[two] = 2.0,
|
||||||
|
[one] = 1.0,
|
||||||
|
[three] = 3.0
|
||||||
|
}
|
||||||
|
0
|
24
testing/btest/language/named-table-ctors.bro
Normal file
24
testing/btest/language/named-table-ctors.bro
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# @TEST-EXEC: bro -b %INPUT >out
|
||||||
|
# @TEST-EXEC: btest-diff out
|
||||||
|
|
||||||
|
type MyRec: record {
|
||||||
|
min: count &optional;
|
||||||
|
max: count;
|
||||||
|
};
|
||||||
|
|
||||||
|
type FooTable: table[count] of string;
|
||||||
|
type FooTableRec: table[MyRec] of string;
|
||||||
|
type FooTableComp: table[string, count] of string;
|
||||||
|
type FooTableY: table[string] of double;
|
||||||
|
|
||||||
|
global mytable: FooTable = FooTable([1] = "one", [5] = "five", [3] = "three");
|
||||||
|
global mytablerec: FooTableRec = FooTableRec([[$max=5]] = "max5", [[$max=2]] = "max2");
|
||||||
|
global mytablecomp: FooTableComp = FooTableComp(["test", 1] = "test1", ["cool",
|
||||||
|
2] = "cool2");
|
||||||
|
global mytabley: FooTableY = FooTableY(["one"] = 1, ["two"] = 2, ["three"] = 3) &default=0;
|
||||||
|
|
||||||
|
print mytable;
|
||||||
|
print mytablerec;
|
||||||
|
print mytablecomp;
|
||||||
|
print mytabley;
|
||||||
|
print mytabley["test"];
|
Loading…
Add table
Add a link
Reference in a new issue