Delete operator for record fields.

"delete x$y" now resets record field "x" back to its original state if
it is either &optional or has a &default. "delete" may not be used
with non-optional/default fields.
This commit is contained in:
Robin Sommer 2011-04-22 18:40:14 -07:00
parent 964060c32f
commit 46b1fd9850
9 changed files with 70 additions and 18 deletions

View file

@ -3113,9 +3113,14 @@ Expr* FieldExpr::Simplify(SimplifyType simp_type)
return this;
}
int FieldExpr::CanDel() const
{
return td->FindAttr(ATTR_DEFAULT) || td->FindAttr(ATTR_OPTIONAL);
}
void FieldExpr::Assign(Frame* f, Val* v, Opcode opcode)
{
if ( IsError() || ! v )
if ( IsError() )
return;
if ( field < 0 )
@ -3130,6 +3135,11 @@ void FieldExpr::Assign(Frame* f, Val* v, Opcode opcode)
}
}
void FieldExpr::Delete(Frame* f)
{
Assign(f, 0, OP_ASSIGN_IDX);
}
Val* FieldExpr::Fold(Val* v) const
{
Val* result = v->AsRecordVal()->Lookup(field);

View file

@ -688,8 +688,11 @@ public:
int Field() const { return field; }
int CanDel() const;
Expr* Simplify(SimplifyType simp_type);
void Assign(Frame* f, Val* v, Opcode op = OP_ASSIGN);
void Delete(Frame* f);
Expr* MakeLvalue();

View file

@ -13,22 +13,22 @@ Jodel
file "test2" of string
/^?(abbcdefgh)$?/
{
6,
4,
5,
3,
6,
2
2,
3
}
{
[4, JKL] = 104,
[3, GHI] = 103,
[2, DEF] = 103,
[4, JKL] = 104
[2, DEF] = 103
}
{
[6767] = /^?(QWERTZ)$?/,
[12346] = /^?(12345)$?/,
[12345] = /^?(12345)$?/
[12345] = /^?(12345)$?/,
[6767] = /^?(QWERTZ)$?/
}
6667/tcp
[2, 20, 3, 4]
[a=zxzxzx, b=[a=pop, b=43, c=9.999], c=[a=IOIOI, b=201, c=612.2], d=6.6666]
[a=zxzxzx, b=[a=pop, b=43, c=9.999], c=[a=IOIOI, b=201, c=612.2], d=6.6666, e=<uninitialized>]

View file

@ -13,22 +13,22 @@ Jodel
file "test2" of string
/^?(abbcdefgh)$?/
{
6,
4,
5,
3,
6,
2
2,
3
}
{
[4, JKL] = 104,
[3, GHI] = 103,
[2, DEF] = 103,
[4, JKL] = 104
[2, DEF] = 103
}
{
[6767] = /^?(QWERTZ)$?/,
[12346] = /^?(12345)$?/,
[12345] = /^?(12345)$?/
[12345] = /^?(12345)$?/,
[6767] = /^?(QWERTZ)$?/
}
6667/tcp
[2, 20, 3, 4]
[a=zxzxzx, b=[a=pop, b=43, c=9.999], c=[a=IOIOI, b=201, c=612.2], d=6.6666]
[a=zxzxzx, b=[a=pop, b=43, c=9.999], c=[a=IOIOI, b=201, c=612.2], d=6.6666, e=<uninitialized>]

View file

@ -0,0 +1,4 @@
a: 20
20
a: not set
5

View file

@ -0,0 +1 @@
/da/home/robin/bro/master/testing/btest/.tmp/language.wrong-delete-field/wrong-delete-field.bro, line 11 (delete x$a): error, illegal delete statement

View file

@ -39,13 +39,14 @@ type type2: record {
b: type1;
c: type1;
d: double;
e: double &optional;
};
global foo17: type2 = [
$a = "yuyuyu",
$b = [$a="rec1", $b=100, $c=1.24],
$c = [$a="rec2", $b=200, $c=2.24],
$d = 7.77
$d = 7.77, $e=100.0
] &persistent &synchronized;
# Print variables.
@ -127,6 +128,7 @@ function modify()
++foo17$c$b;
foo17$c$c = 612.2;
foo17$d = 6.6666;
delete foo17$e;
foo2 = 1234567;
}

View file

@ -0,0 +1,21 @@
# @TEST-EXEC: bro %INPUT >output 2>&1
# @TEST-EXEC: btest-diff output
type X: record {
a: count &optional;
b: count &default=5;
};
function p(x: X)
{
print x?$a ? fmt("a: %d", x$a) : "a: not set";
print x$b;
}
global x: X = [$a=20, $b=20];
p(x);
delete x$a;
delete x$b;
p(x);

View file

@ -0,0 +1,11 @@
# @TEST-EXEC-FAIL: bro %INPUT >output 2>&1
# @TEST-EXEC: btest-diff output
type X: record {
a: count;
};
global x: X = [$a=20];
delete x$a;