mirror of
https://github.com/zeek/zeek.git
synced 2025-10-08 17:48:21 +00:00
Implementing += operator for record types.
This is per #375. Record types can now get additional fields later via '+='. The added fields must however either be &optional or have a &default value. Example: type Foo: record { a: count; b: count &optional; }; redef record Foo += { c: count &default=42; d: count &optional; }; global f: Foo = [$a=21]; print f; Output: [a=21, b=<uninitialized>, c=42, d=<uninitialized>]
This commit is contained in:
parent
cdb20e61b7
commit
95069f0993
3 changed files with 44 additions and 2 deletions
20
src/Type.cc
20
src/Type.cc
|
@ -898,6 +898,26 @@ void RecordType::Describe(ODesc* d) const
|
|||
}
|
||||
}
|
||||
|
||||
const char* RecordType::AddFields(type_decl_list* others)
|
||||
{
|
||||
assert(types);
|
||||
|
||||
loop_over_list(*others, i)
|
||||
{
|
||||
TypeDecl* td = (*others)[i];
|
||||
|
||||
if ( ! td->FindAttr(ATTR_DEFAULT) && ! td->FindAttr(ATTR_OPTIONAL) )
|
||||
return "extension field must be &optional or have &default";
|
||||
|
||||
types->append(td);
|
||||
}
|
||||
|
||||
delete others;
|
||||
|
||||
num_fields = types->length();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RecordType::DescribeFields(ODesc* d) const
|
||||
{
|
||||
if ( d->IsReadable() )
|
||||
|
|
|
@ -409,6 +409,10 @@ public:
|
|||
|
||||
int NumFields() const { return num_fields; }
|
||||
|
||||
// Returns 0 if all is ok, otherwise a pointer to an error message. Takes
|
||||
// ownership of list.
|
||||
const char* AddFields(type_decl_list* types);
|
||||
|
||||
void Describe(ODesc* d) const;
|
||||
void DescribeFields(ODesc* d) const;
|
||||
|
||||
|
|
22
src/parse.y
22
src/parse.y
|
@ -799,8 +799,8 @@ decl:
|
|||
| TOK_REDEF global_id opt_type init_class opt_init opt_attr ';'
|
||||
{ add_global($2, $3, $4, $5, $6, VAR_REDEF); }
|
||||
|
||||
| TOK_REDEF TOK_ENUM global_id TOK_ADD_TO
|
||||
'{' enum_id_list opt_comma '}' ';'
|
||||
| TOK_REDEF TOK_ENUM global_id TOK_ADD_TO
|
||||
'{' enum_id_list opt_comma '}' ';'
|
||||
{
|
||||
if ( ! $3->Type() )
|
||||
$3->Error("unknown identifier");
|
||||
|
@ -815,6 +815,24 @@ decl:
|
|||
}
|
||||
}
|
||||
|
||||
| TOK_REDEF TOK_RECORD global_id TOK_ADD_TO
|
||||
'{' type_decl_list '}' ';'
|
||||
{
|
||||
if ( ! $3->Type() )
|
||||
$3->Error("unknown identifier");
|
||||
else
|
||||
{
|
||||
RecordType* add_to = $3->Type()->AsRecordType();
|
||||
if ( ! add_to )
|
||||
$3->Error("not a record type");
|
||||
else {
|
||||
const char* error = add_to->AddFields($6);
|
||||
if ( error )
|
||||
$3->Error(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
| TOK_TYPE global_id ':' refined_type opt_attr ';'
|
||||
{
|
||||
add_type($2, $4, $5, 0);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue