Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

AssignExpr Class Reference

#include <Expr.h>

Inheritance diagram for AssignExpr:

Inheritance graph
[legend]
Collaboration diagram for AssignExpr:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 AssignExpr (Expr *op1, Expr *op2, int is_init)
ExprSimplify (SimplifyType simp_type)
ValEval (Frame *f) const
BroTypeInitType () const
int IsRecordElement (TypeDecl *td) const
ValInitVal (const BroType *t, Val *aggr) const
int IsPure () const

Protected Member Functions

 AssignExpr ()
 DECLARE_SERIAL (AssignExpr)

Protected Attributes

int is_init

Friends

class Expr

Constructor & Destructor Documentation

AssignExpr::AssignExpr Expr op1,
Expr op2,
int  is_init
 

Definition at line 2218 of file Expr.cc.

References BroType::AsRecordType(), BroType::AsVectorType(), EXPR_ASSIGN, Expr::ExprError(), BroObj::GetLocationInfo(), is_init, IsArithmetic, Expr::IsError(), IsVector, Expr::IsZero(), BinaryExpr::PromoteOps(), BroType::Ref(), same_type(), BroObj::SetLocationInfo(), Expr::SetType(), BroType::Tag(), Expr::Type(), TYPE_ANY, TYPE_DOUBLE, TYPE_ENUM, TYPE_INT, TYPE_LIST, TYPE_RECORD, TYPE_TIME, TypeTag, BroObj::Warn(), and VectorType::YieldType().

02219 : BinaryExpr(EXPR_ASSIGN, arg_is_init ? arg_op1 : arg_op1->MakeLvalue(), arg_op2)
02220         {
02221         is_init = arg_is_init;
02222 
02223         if ( IsError() )
02224                 return;
02225 
02226         SetType(op1->Type()->Ref());
02227 
02228         if ( is_init )
02229                 {
02230                 SetLocationInfo(arg_op1->GetLocationInfo(),
02231                                 arg_op2->GetLocationInfo());
02232                 return;
02233                 }
02234 
02235         TypeTag bt1 = op1->Type()->Tag();
02236         if ( IsVector(bt1) )
02237                 bt1 = op1->Type()->AsVectorType()->YieldType()->Tag();
02238 
02239         TypeTag bt2 = op2->Type()->Tag();
02240         if ( IsVector(bt2) )
02241                 bt2 = op2->Type()->AsVectorType()->YieldType()->Tag();
02242 
02243         if ( ((bt1 == TYPE_ENUM) ^ (bt2 == TYPE_ENUM)) )
02244                 ExprError("can't convert to/from enumerated type");
02245 
02246         else if ( IsArithmetic(bt1) )
02247                 {
02248                 if ( ! IsArithmetic(bt2) )
02249                         ExprError("assignment of non-arithmetic value to arithmetic");
02250                 else if ( bt1 == TYPE_DOUBLE )
02251                         PromoteOps(TYPE_DOUBLE);
02252                 else
02253                         {
02254                         if ( bt2 == TYPE_DOUBLE )
02255                                 {
02256                                 Warn("dangerous assignment of double to integral");
02257                                 op2 = new ArithCoerceExpr(op2, bt1);
02258                                 bt2 = op2->Type()->Tag();
02259                                 }
02260 
02261                         if ( bt1 == TYPE_INT )
02262                                 PromoteOps(TYPE_INT);
02263                         else
02264                                 {
02265                                 if ( bt2 == TYPE_INT )
02266                                         {
02267                                         Warn("dangerous assignment of integer to count");
02268                                         op2 = new ArithCoerceExpr(op2, bt1);
02269                                         bt2 = op2->Type()->Tag();
02270                                         }
02271 
02272                                 // Assignment of count to counter or vice
02273                                 // versa is allowed, and requires no
02274                                 // coercion.
02275                                 }
02276                         }
02277                 }
02278 
02279         else if ( bt1 == TYPE_TIME && IsArithmetic(bt2) && op2->IsZero() )
02280                 { // Allow assignments to zero as a special case.
02281                 op2 = new ArithCoerceExpr(op2, bt1);
02282                 bt2 = op2->Type()->Tag();
02283                 }
02284 
02285         else if ( bt1 == TYPE_LIST && bt2 == TYPE_ANY )
02286                 {
02287                 // This is ok because we cannot explicitly declare lists on
02288                 // the script level.
02289                 }
02290 
02291         else if ( ! same_type(op1->Type(), op2->Type()) )
02292                 {
02293                 if ( op1->Type()->Tag() == TYPE_RECORD &&
02294                      op2->Type()->Tag() == TYPE_RECORD )
02295                         op2 = new RecordCoerceExpr(op2, op1->Type()->AsRecordType());
02296                 else
02297                         ExprError("type clash in assignment");
02298                 }
02299 
02300         SetLocationInfo(arg_op1->GetLocationInfo(), arg_op2->GetLocationInfo());
02301         }

AssignExpr::AssignExpr  )  [inline, protected]
 

Definition at line 589 of file Expr.h.

00589 { }


Member Function Documentation

AssignExpr::DECLARE_SERIAL AssignExpr   )  [protected]
 

Val * AssignExpr::Eval Frame f  )  const [virtual]
 

Reimplemented from BinaryExpr.

Definition at line 2310 of file Expr.cc.

References Expr::Assign(), BroObj::Error(), Expr::Eval(), is_init, and Val::Ref().

02311         {
02312         if ( is_init )
02313                 {
02314                 Error("illegal assignment in initialization");
02315                 return 0;
02316                 }
02317 
02318         Val* v = op2->Eval(f);
02319 
02320         if ( v )
02321                 {
02322                 op1->Assign(f, v);
02323                 //### op1->SetAttribs();
02324                 return v->Ref();
02325                 }
02326         else
02327                 return 0;
02328         }

BroType * AssignExpr::InitType  )  const [virtual]
 

Reimplemented from Expr.

Definition at line 2330 of file Expr.cc.

References BroType::AsTypeList(), BroObj::Error(), EXPR_LIST, BroObj::Internal(), BroType::Ref(), BroType::Tag(), Expr::Tag(), Expr::Type(), and TYPE_LIST.

02331         {
02332         if ( op1->Tag() != EXPR_LIST )
02333                 {
02334                 Error("bad initializer");
02335                 return 0;
02336                 }
02337 
02338         BroType* tl = op1->Type();
02339         if ( tl->Tag() != TYPE_LIST )
02340                 Internal("inconsistent list expr in AssignExpr::InitType");
02341 
02342         return new TableType(tl->Ref()->AsTypeList(), op2->Type()->Ref());
02343         }

Val * AssignExpr::InitVal const BroType t,
Val aggr
const [virtual]
 

Reimplemented from Expr.

Definition at line 2345 of file Expr.cc.

References BroType::AsRecordType(), RecordVal::Assign(), BroType::AsTableType(), BroObj::Error(), TableVal::ExpandAndInit(), EXPR_LIST, RecordType::FieldOffset(), RecordType::FieldType(), TypeDecl::id, IndexType::Indices(), Expr::InitVal(), BroObj::Internal(), Expr::IsError(), IsRecordElement(), Expr::Tag(), BroType::Tag(), Val::Type(), TYPE_RECORD, TYPE_TABLE, BroObj::Unref, and BroType::YieldType().

02346         {
02347         if ( ! aggr )
02348                 {
02349                 Error("assignment in initialization");
02350                 return 0;
02351                 }
02352 
02353         if ( IsError() )
02354                 return 0;
02355 
02356         TypeDecl td(0, 0);
02357         if ( IsRecordElement(&td) )
02358                 {
02359                 if ( t->Tag() != TYPE_RECORD )
02360                         {
02361                         Error("not a record initializer", t);
02362                         return 0;
02363                         }
02364                 const RecordType* rt = t->AsRecordType();
02365                 int field = rt->FieldOffset(td.id);
02366 
02367                 if ( field < 0 )
02368                         {
02369                         Error("no such field");
02370                         return 0;
02371                         }
02372 
02373                 if ( aggr->Type()->Tag() != TYPE_RECORD )
02374                         Internal("bad aggregate in AssignExpr::InitVal");
02375                 RecordVal* aggr_r = aggr->AsRecordVal();
02376 
02377                 Val* v = op2->InitVal(rt->FieldType(td.id), 0);
02378                 if ( ! v )
02379                         return 0;
02380 
02381                 aggr_r->Assign(field, v);
02382                 return v;
02383                 }
02384 
02385         else if ( op1->Tag() == EXPR_LIST )
02386                 {
02387                 if ( t->Tag() != TYPE_TABLE )
02388                         {
02389                         Error("not a table initialization", t);
02390                         return 0;
02391                         }
02392 
02393                 if ( aggr->Type()->Tag() != TYPE_TABLE )
02394                         Internal("bad aggregate in AssignExpr::InitVal");
02395 
02396                 TableVal* tv = aggr->AsTableVal();
02397                 const TableType* tt = tv->Type()->AsTableType();
02398                 const BroType* yt = tv->Type()->YieldType();
02399                 Val* index = op1->InitVal(tt->Indices(), 0);
02400                 Val* v = op2->InitVal(yt, 0);
02401                 if ( ! index || ! v )
02402                         return 0;
02403 
02404                 if ( ! tv->ExpandAndInit(index, v) )
02405                         {
02406                         Unref(index);
02407                         Unref(tv);
02408                         return 0;
02409                         }
02410 
02411                 Unref(index);
02412                 return tv;
02413                 }
02414 
02415         else
02416                 {
02417                 Error("illegal initializer");
02418                 return 0;
02419                 }
02420         }

int AssignExpr::IsPure  )  const [virtual]
 

Reimplemented from BinaryExpr.

Definition at line 2439 of file Expr.cc.

02440         {
02441         return 0;
02442         }

int AssignExpr::IsRecordElement TypeDecl td  )  const [virtual]
 

Reimplemented from Expr.

Definition at line 2422 of file Expr.cc.

References copy_string(), EXPR_NAME, NameExpr::Id(), TypeDecl::id, ID::Name(), BroType::Ref(), Expr::Tag(), Expr::Type(), and TypeDecl::type.

Referenced by InitVal().

02423         {
02424         if ( op1->Tag() == EXPR_NAME )
02425                 {
02426                 if ( td )
02427                         {
02428                         const NameExpr* n = (const NameExpr*) op1;
02429                         td->type = op2->Type()->Ref();
02430                         td->id = copy_string(n->Id()->Name());
02431                         }
02432 
02433                 return 1;
02434                 }
02435         else
02436                 return 0;
02437         }

Expr * AssignExpr::Simplify SimplifyType  simp_type  )  [virtual]
 

Reimplemented from BinaryExpr.

Definition at line 2303 of file Expr.cc.

References simplify_expr(), SIMPLIFY_GENERAL, and SIMPLIFY_LHS.

02304         {
02305         op1 = simplify_expr(op1, SIMPLIFY_LHS);
02306         op2 = simplify_expr(op2, SIMPLIFY_GENERAL);
02307         return this;
02308         }


Friends And Related Function Documentation

friend class Expr [friend]
 

Reimplemented from BinaryExpr.

Definition at line 588 of file Expr.h.


Member Data Documentation

int AssignExpr::is_init [protected]
 

Definition at line 593 of file Expr.h.

Referenced by AssignExpr(), and Eval().


The documentation for this class was generated from the following files:
Generated on Wed Sep 14 03:07:41 2005 for bro_docs by doxygen 1.3.5