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; return this;
} }
int FieldExpr::CanDel() const
{
return td->FindAttr(ATTR_DEFAULT) || td->FindAttr(ATTR_OPTIONAL);
}
void FieldExpr::Assign(Frame* f, Val* v, Opcode opcode) void FieldExpr::Assign(Frame* f, Val* v, Opcode opcode)
{ {
if ( IsError() || ! v ) if ( IsError() )
return; return;
if ( field < 0 ) 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* FieldExpr::Fold(Val* v) const
{ {
Val* result = v->AsRecordVal()->Lookup(field); Val* result = v->AsRecordVal()->Lookup(field);

View file

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

View file

@ -13,22 +13,22 @@ Jodel
file "test2" of string file "test2" of string
/^?(abbcdefgh)$?/ /^?(abbcdefgh)$?/
{ {
6,
4, 4,
5, 5,
3, 2,
6, 3
2
} }
{ {
[4, JKL] = 104,
[3, GHI] = 103, [3, GHI] = 103,
[2, DEF] = 103, [2, DEF] = 103
[4, JKL] = 104
} }
{ {
[6767] = /^?(QWERTZ)$?/,
[12346] = /^?(12345)$?/, [12346] = /^?(12345)$?/,
[12345] = /^?(12345)$?/ [12345] = /^?(12345)$?/,
[6767] = /^?(QWERTZ)$?/
} }
6667/tcp 6667/tcp
[2, 20, 3, 4] [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 file "test2" of string
/^?(abbcdefgh)$?/ /^?(abbcdefgh)$?/
{ {
6,
4, 4,
5, 5,
3, 2,
6, 3
2
} }
{ {
[4, JKL] = 104,
[3, GHI] = 103, [3, GHI] = 103,
[2, DEF] = 103, [2, DEF] = 103
[4, JKL] = 104
} }
{ {
[6767] = /^?(QWERTZ)$?/,
[12346] = /^?(12345)$?/, [12346] = /^?(12345)$?/,
[12345] = /^?(12345)$?/ [12345] = /^?(12345)$?/,
[6767] = /^?(QWERTZ)$?/
} }
6667/tcp 6667/tcp
[2, 20, 3, 4] [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; b: type1;
c: type1; c: type1;
d: double; d: double;
e: double &optional;
}; };
global foo17: type2 = [ global foo17: type2 = [
$a = "yuyuyu", $a = "yuyuyu",
$b = [$a="rec1", $b=100, $c=1.24], $b = [$a="rec1", $b=100, $c=1.24],
$c = [$a="rec2", $b=200, $c=2.24], $c = [$a="rec2", $b=200, $c=2.24],
$d = 7.77 $d = 7.77, $e=100.0
] &persistent &synchronized; ] &persistent &synchronized;
# Print variables. # Print variables.
@ -127,6 +128,7 @@ function modify()
++foo17$c$b; ++foo17$c$b;
foo17$c$c = 612.2; foo17$c$c = 612.2;
foo17$d = 6.6666; foo17$d = 6.6666;
delete foo17$e;
foo2 = 1234567; 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;