Allow local table variables to be initialized with {} list expressions.

This commit is contained in:
Jon Siwek 2012-01-04 16:44:25 -06:00
parent f8ec98625d
commit aae60a6d76
5 changed files with 50 additions and 6 deletions

View file

@ -2435,7 +2435,7 @@ bool RefExpr::DoUnserialize(UnserialInfo* info)
} }
AssignExpr::AssignExpr(Expr* arg_op1, Expr* arg_op2, int arg_is_init, AssignExpr::AssignExpr(Expr* arg_op1, Expr* arg_op2, int arg_is_init,
Val* arg_val) Val* arg_val, attr_list* arg_attrs)
: BinaryExpr(EXPR_ASSIGN, : BinaryExpr(EXPR_ASSIGN,
arg_is_init ? arg_op1 : arg_op1->MakeLvalue(), arg_op2) arg_is_init ? arg_op1 : arg_op1->MakeLvalue(), arg_op2)
{ {
@ -2455,14 +2455,14 @@ AssignExpr::AssignExpr(Expr* arg_op1, Expr* arg_op2, int arg_is_init,
// We discard the status from TypeCheck since it has already // We discard the status from TypeCheck since it has already
// generated error messages. // generated error messages.
(void) TypeCheck(); (void) TypeCheck(arg_attrs);
val = arg_val ? arg_val->Ref() : 0; val = arg_val ? arg_val->Ref() : 0;
SetLocationInfo(arg_op1->GetLocationInfo(), arg_op2->GetLocationInfo()); SetLocationInfo(arg_op1->GetLocationInfo(), arg_op2->GetLocationInfo());
} }
bool AssignExpr::TypeCheck() bool AssignExpr::TypeCheck(attr_list* attrs)
{ {
TypeTag bt1 = op1->Type()->Tag(); TypeTag bt1 = op1->Type()->Tag();
TypeTag bt2 = op2->Type()->Tag(); TypeTag bt2 = op2->Type()->Tag();
@ -2494,6 +2494,19 @@ bool AssignExpr::TypeCheck()
return true; return true;
} }
if ( bt1 == TYPE_TABLE && op2->Tag() == EXPR_LIST )
{
attr_list* attr_copy = 0;
if ( attrs )
{
attr_copy = new attr_list;
loop_over_list(*attrs, i)
attr_copy->append((*attrs)[i]);
}
op2 = new TableConstructorExpr(op2->AsListExpr(), attr_copy);
return true;
}
if ( bt1 == TYPE_VECTOR && bt2 == bt1 && if ( bt1 == TYPE_VECTOR && bt2 == bt1 &&
op2->Type()->AsVectorType()->IsUnspecifiedVector() ) op2->Type()->AsVectorType()->IsUnspecifiedVector() )
{ {

View file

@ -623,7 +623,7 @@ class AssignExpr : public BinaryExpr {
public: public:
// If val is given, evaluating this expression will always yield the val // If val is given, evaluating this expression will always yield the val
// yet still perform the assignment. Used for triggers. // yet still perform the assignment. Used for triggers.
AssignExpr(Expr* op1, Expr* op2, int is_init, Val* val = 0); AssignExpr(Expr* op1, Expr* op2, int is_init, Val* val = 0, attr_list* attrs = 0);
virtual ~AssignExpr() { Unref(val); } virtual ~AssignExpr() { Unref(val); }
Expr* Simplify(SimplifyType simp_type); Expr* Simplify(SimplifyType simp_type);
@ -638,7 +638,7 @@ protected:
friend class Expr; friend class Expr;
AssignExpr() { } AssignExpr() { }
bool TypeCheck(); bool TypeCheck(attr_list* attrs = 0);
bool TypeCheckArithmetics(TypeTag bt1, TypeTag bt2); bool TypeCheckArithmetics(TypeTag bt1, TypeTag bt2);
DECLARE_SERIAL(AssignExpr); DECLARE_SERIAL(AssignExpr);

View file

@ -202,7 +202,8 @@ Stmt* add_local(ID* id, BroType* t, init_class c, Expr* init,
Ref(id); Ref(id);
Stmt* stmt = Stmt* stmt =
new ExprStmt(new AssignExpr(new NameExpr(id), init, 0)); new ExprStmt(new AssignExpr(new NameExpr(id), init, 0, 0,
id->Attrs() ? id->Attrs()->Attrs() : 0 ));
stmt->SetLocationInfo(init->GetLocationInfo()); stmt->SetLocationInfo(init->GetLocationInfo());
return stmt; return stmt;

View file

@ -0,0 +1,10 @@
{
[2] = two,
[1] = one
}
global table default
{
[4] = four,
[3] = three
}
local table default

View file

@ -0,0 +1,20 @@
# @TEST-EXEC: bro %INPUT >output
# @TEST-EXEC: btest-diff output
global global_table: table[count] of string = {
[1] = "one",
[2] = "two"
} &default = "global table default";
event bro_init()
{
local local_table: table[count] of string = {
[3] = "three",
[4] = "four"
} &default = "local table default";
print global_table;
print global_table[0];
print local_table;
print local_table[0];
}