zeek/src/Expr.h
Jon Siwek e0fb9eb2b2 Add new function flavor called a "hook".
This new flavor of function behaves like a "synchronous event".
See documentation for more details on usage.
2012-11-15 13:45:13 -06:00

1116 lines
24 KiB
C++

// See the file "COPYING" in the main distribution directory for copyright.
#ifndef expr_h
#define expr_h
// BRO expressions.
#include "BroList.h"
#include "ID.h"
#include "Timer.h"
#include "Val.h"
#include "Debug.h"
#include "EventHandler.h"
#include "TraverseTypes.h"
typedef enum {
EXPR_ANY = -1,
EXPR_NAME, EXPR_CONST,
EXPR_CLONE,
EXPR_INCR, EXPR_DECR, EXPR_NOT, EXPR_POSITIVE, EXPR_NEGATE,
EXPR_ADD, EXPR_SUB, EXPR_ADD_TO, EXPR_REMOVE_FROM,
EXPR_TIMES, EXPR_DIVIDE, EXPR_MOD,
EXPR_AND, EXPR_OR,
EXPR_LT, EXPR_LE, EXPR_EQ, EXPR_NE, EXPR_GE, EXPR_GT,
EXPR_COND,
EXPR_REF,
EXPR_ASSIGN,
EXPR_MATCH,
EXPR_INDEX,
EXPR_FIELD, EXPR_HAS_FIELD,
EXPR_RECORD_CONSTRUCTOR,
EXPR_TABLE_CONSTRUCTOR,
EXPR_SET_CONSTRUCTOR,
EXPR_VECTOR_CONSTRUCTOR,
EXPR_FIELD_ASSIGN,
EXPR_IN,
EXPR_LIST,
EXPR_CALL,
EXPR_EVENT,
EXPR_SCHEDULE,
EXPR_ARITH_COERCE,
EXPR_RECORD_COERCE,
EXPR_TABLE_COERCE,
EXPR_VECTOR_COERCE,
EXPR_SIZE,
EXPR_FLATTEN,
#define NUM_EXPRS (int(EXPR_FLATTEN) + 1)
} BroExprTag;
typedef enum {
SIMPLIFY_GENERAL, // regular simplification
SIMPLIFY_LHS, // simplify as the LHS of an assignment
} SimplifyType;
extern const char* expr_name(BroExprTag t);
class Stmt;
class Frame;
class ListExpr;
class CallExpr;
class EventExpr;
class Expr : public BroObj {
public:
BroType* Type() const { return type; }
BroExprTag Tag() const { return tag; }
virtual ~Expr();
Expr* Ref() { ::Ref(this); return this; }
// Returns a fully simplified version of the expression (this
// may be the same expression, or a newly created one). simp_type
// gives the context of the simplification.
virtual Expr* Simplify(SimplifyType simp_type) = 0;
// Evaluates the expression and returns a corresponding Val*,
// or nil if the expression's value isn't fixed.
virtual Val* Eval(Frame* f) const = 0;
// Same, but the context is that we are adding an element
// into the given aggregate of the given type. Note that
// return type is void since it's updating an existing
// value, rather than creating a new one.
virtual void EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f)
const;
// Assign to the given value, if appropriate.
virtual void Assign(Frame* f, Val* v, Opcode op = OP_ASSIGN);
// Returns the type corresponding to this expression interpreted
// as an initialization. The type should be Unref()'d when done
// using it. Returns nil if the initialization is illegal.
virtual BroType* InitType() const;
// Returns true if this expression, interpreted as an initialization,
// constitutes a record element, false otherwise. If the TypeDecl*
// is non-nil and the expression is a record element, fills in the
// TypeDecl with a description of the element.
virtual int IsRecordElement(TypeDecl* td) const;
// Returns a value corresponding to this expression interpreted
// as an initialization, or nil if the expression is inconsistent
// with the given type. If "aggr" is non-nil, then this expression
// is an element of the given aggregate, and it is added to it
// accordingly.
virtual Val* InitVal(const BroType* t, Val* aggr) const;
// True if the expression has no side effects, false otherwise.
virtual int IsPure() const;
// True if the expression is a constant, false otherwise.
int IsConst() const { return tag == EXPR_CONST; }
// True if the expression is in error (to alleviate error propagation).
int IsError() const { return type && type->Tag() == TYPE_ERROR; }
// Mark expression as in error.
void SetError() { SetType(error_type()); }
void SetError(const char* msg);
// Returns the expression's constant value, or complains
// if it's not a constant.
inline Val* ExprVal() const;
// True if the expression is a constant zero, false otherwise.
int IsZero() const
{
return IsConst() && ExprVal()->IsZero();
}
// True if the expression is a constant one, false otherwise.
int IsOne() const
{
return IsConst() && ExprVal()->IsOne();
}
// True if the expression supports the "add" or "delete" operations,
// false otherwise.
virtual int CanAdd() const;
virtual int CanDel() const;
virtual void Add(Frame* f); // perform add operation
virtual void Delete(Frame* f); // perform delete operation
// Return the expression converted to L-value form. If expr
// cannot be used as an L-value, reports an error and returns
// the current value of expr (this is the default method).
virtual Expr* MakeLvalue();
// Marks the expression as one requiring (or at least appearing
// with) parentheses. Used for pretty-printing.
void MarkParen() { paren = 1; }
int IsParen() const { return paren; }
const ListExpr* AsListExpr() const
{
CHECK_TAG(tag, EXPR_LIST, "ExprVal::AsListExpr", expr_name)
return (const ListExpr*) this;
}
ListExpr* AsListExpr()
{
CHECK_TAG(tag, EXPR_LIST, "ExprVal::AsListExpr", expr_name)
return (ListExpr*) this;
}
void Describe(ODesc* d) const;
bool Serialize(SerialInfo* info) const;
static Expr* Unserialize(UnserialInfo* info, BroExprTag want = EXPR_ANY);
virtual TraversalCode Traverse(TraversalCallback* cb) const = 0;
protected:
Expr() { type = 0; }
Expr(BroExprTag arg_tag);
virtual void ExprDescribe(ODesc* d) const = 0;
void AddTag(ODesc* d) const;
// Puts the expression in canonical form.
virtual void Canonicize();
void SetType(BroType* t);
// Reports the given error and sets the expression's type to
// TYPE_ERROR.
void ExprError(const char msg[]);
DECLARE_ABSTRACT_SERIAL(Expr);
BroExprTag tag;
BroType* type;
int paren;
};
class NameExpr : public Expr {
public:
NameExpr(ID* id);
~NameExpr();
ID* Id() const { return id; }
Expr* Simplify(SimplifyType simp_type);
Val* Eval(Frame* f) const;
void Assign(Frame* f, Val* v, Opcode op = OP_ASSIGN);
Expr* MakeLvalue();
int IsPure() const;
TraversalCode Traverse(TraversalCallback* cb) const;
protected:
friend class Expr;
NameExpr() { id = 0; }
void ExprDescribe(ODesc* d) const;
DECLARE_SERIAL(NameExpr);
ID* id;
};
class ConstExpr : public Expr {
public:
ConstExpr(Val* val);
~ConstExpr();
Val* Value() const { return val; }
Expr* Simplify(SimplifyType simp_type);
Val* Eval(Frame* f) const;
TraversalCode Traverse(TraversalCallback* cb) const;
protected:
friend class Expr;
ConstExpr() { val = 0; }
void ExprDescribe(ODesc* d) const;
DECLARE_SERIAL(ConstExpr);
Val* val;
};
class UnaryExpr : public Expr {
public:
Expr* Op() const { return op; }
// Simplifies the operand and calls DoSimplify().
virtual Expr* Simplify(SimplifyType simp_type);
// UnaryExpr::Eval correctly handles vector types. Any child
// class that overrides Eval() should be modified to handle
// vectors correctly as necessary.
Val* Eval(Frame* f) const;
int IsPure() const;
TraversalCode Traverse(TraversalCallback* cb) const;
protected:
friend class Expr;
UnaryExpr() { op = 0; }
UnaryExpr(BroExprTag arg_tag, Expr* arg_op);
virtual ~UnaryExpr();
void ExprDescribe(ODesc* d) const;
// Can be overridden by subclasses that want to take advantage
// of UnaryExpr's Simplify() method.
virtual Expr* DoSimplify();
// Returns the expression folded using the given constant.
virtual Val* Fold(Val* v) const;
DECLARE_SERIAL(UnaryExpr);
Expr* op;
};
class BinaryExpr : public Expr {
public:
Expr* Op1() const { return op1; }
Expr* Op2() const { return op2; }
// Simplifies both operands, folds them if constant,
// otherwise calls DoSimplify().
virtual Expr* Simplify(SimplifyType simp_type);
int IsPure() const;
// BinaryExpr::Eval correctly handles vector types. Any child
// class that overrides Eval() should be modified to handle
// vectors correctly as necessary.
Val* Eval(Frame* f) const;
TraversalCode Traverse(TraversalCallback* cb) const;
protected:
friend class Expr;
BinaryExpr() { op1 = op2 = 0; }
BinaryExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2)
: Expr(arg_tag)
{
if ( ! (arg_op1 && arg_op2) )
return;
op1 = arg_op1;
op2 = arg_op2;
if ( op1->IsError() || op2->IsError() )
SetError();
}
virtual ~BinaryExpr();
// Can be overridden by subclasses that want to take advantage
// of BinaryExpr's Simplify() method.
virtual Expr* DoSimplify();
// Returns the expression folded using the given constants.
virtual Val* Fold(Val* v1, Val* v2) const;
// Same for when the constants are strings.
virtual Val* StringFold(Val* v1, Val* v2) const;
// Same for when the constants are addresses or subnets.
virtual Val* AddrFold(Val* v1, Val* v2) const;
virtual Val* SubNetFold(Val* v1, Val* v2) const;
int BothConst() const { return op1->IsConst() && op2->IsConst(); }
// Simplify both operands and canonicize.
void SimplifyOps();
// Exchange op1 and op2.
void SwapOps();
// Promote the operands to the given type tag, if necessary.
void PromoteOps(TypeTag t);
// Promote the expression to the given type tag (i.e., promote
// operands and also set expression's type).
void PromoteType(TypeTag t, bool is_vector);
void ExprDescribe(ODesc* d) const;
DECLARE_SERIAL(BinaryExpr);
Expr* op1;
Expr* op2;
};
class CloneExpr : public UnaryExpr {
public:
CloneExpr(Expr* op);
Val* Eval(Frame* f) const;
protected:
friend class Expr;
CloneExpr() { }
Val* Fold(Val* v) const;
DECLARE_SERIAL(CloneExpr);
};
class IncrExpr : public UnaryExpr {
public:
IncrExpr(BroExprTag tag, Expr* op);
Val* Eval(Frame* f) const;
Val* DoSingleEval(Frame* f, Val* v) const;
int IsPure() const;
protected:
friend class Expr;
IncrExpr() { }
DECLARE_SERIAL(IncrExpr);
};
class NotExpr : public UnaryExpr {
public:
NotExpr(Expr* op);
protected:
friend class Expr;
NotExpr() { }
Expr* DoSimplify();
Val* Fold(Val* v) const;
DECLARE_SERIAL(NotExpr);
};
class PosExpr : public UnaryExpr {
public:
PosExpr(Expr* op);
protected:
friend class Expr;
PosExpr() { }
Expr* DoSimplify();
Val* Fold(Val* v) const;
DECLARE_SERIAL(PosExpr);
};
class NegExpr : public UnaryExpr {
public:
NegExpr(Expr* op);
protected:
friend class Expr;
NegExpr() { }
Expr* DoSimplify();
Val* Fold(Val* v) const;
DECLARE_SERIAL(NegExpr);
};
class SizeExpr : public UnaryExpr {
public:
SizeExpr(Expr* op);
Val* Eval(Frame* f) const;
protected:
friend class Expr;
SizeExpr() { }
Val* Fold(Val* v) const;
DECLARE_SERIAL(SizeExpr);
};
class AddExpr : public BinaryExpr {
public:
AddExpr(Expr* op1, Expr* op2);
void Canonicize();
protected:
friend class Expr;
AddExpr() { }
Expr* DoSimplify();
DECLARE_SERIAL(AddExpr);
};
class AddToExpr : public BinaryExpr {
public:
AddToExpr(Expr* op1, Expr* op2);
Val* Eval(Frame* f) const;
protected:
friend class Expr;
AddToExpr() { }
DECLARE_SERIAL(AddToExpr);
};
class RemoveFromExpr : public BinaryExpr {
public:
RemoveFromExpr(Expr* op1, Expr* op2);
Val* Eval(Frame* f) const;
protected:
friend class Expr;
RemoveFromExpr() { }
DECLARE_SERIAL(RemoveFromExpr);
};
class SubExpr : public BinaryExpr {
public:
SubExpr(Expr* op1, Expr* op2);
protected:
friend class Expr;
SubExpr() { }
Expr* DoSimplify();
DECLARE_SERIAL(SubExpr);
};
class TimesExpr : public BinaryExpr {
public:
TimesExpr(Expr* op1, Expr* op2);
void Canonicize();
protected:
friend class Expr;
TimesExpr() { }
Expr* DoSimplify();
DECLARE_SERIAL(TimesExpr);
};
class DivideExpr : public BinaryExpr {
public:
DivideExpr(Expr* op1, Expr* op2);
protected:
friend class Expr;
DivideExpr() { }
Val* AddrFold(Val* v1, Val* v2) const;
Expr* DoSimplify();
DECLARE_SERIAL(DivideExpr);
};
class ModExpr : public BinaryExpr {
public:
ModExpr(Expr* op1, Expr* op2);
protected:
friend class Expr;
ModExpr() { }
Expr* DoSimplify();
DECLARE_SERIAL(ModExpr);
};
class BoolExpr : public BinaryExpr {
public:
BoolExpr(BroExprTag tag, Expr* op1, Expr* op2);
Val* Eval(Frame* f) const;
Val* DoSingleEval(Frame* f, Val* v1, Expr* op2) const;
protected:
friend class Expr;
BoolExpr() { }
Expr* DoSimplify();
DECLARE_SERIAL(BoolExpr);
};
class EqExpr : public BinaryExpr {
public:
EqExpr(BroExprTag tag, Expr* op1, Expr* op2);
void Canonicize();
protected:
friend class Expr;
EqExpr() { }
Expr* DoSimplify();
Val* Fold(Val* v1, Val* v2) const;
DECLARE_SERIAL(EqExpr);
};
class RelExpr : public BinaryExpr {
public:
RelExpr(BroExprTag tag, Expr* op1, Expr* op2);
void Canonicize();
protected:
friend class Expr;
RelExpr() { }
Expr* DoSimplify();
DECLARE_SERIAL(RelExpr);
};
class CondExpr : public Expr {
public:
CondExpr(Expr* op1, Expr* op2, Expr* op3);
~CondExpr();
Expr* Simplify(SimplifyType simp_type);
Val* Eval(Frame* f) const;
int IsPure() const;
TraversalCode Traverse(TraversalCallback* cb) const;
protected:
friend class Expr;
CondExpr() { op1 = op2 = op3 = 0; }
void ExprDescribe(ODesc* d) const;
DECLARE_SERIAL(CondExpr);
Expr* op1;
Expr* op2;
Expr* op3;
};
class RefExpr : public UnaryExpr {
public:
RefExpr(Expr* op);
void Assign(Frame* f, Val* v, Opcode op = OP_ASSIGN);
Expr* MakeLvalue();
protected:
friend class Expr;
RefExpr() { }
DECLARE_SERIAL(RefExpr);
};
class AssignExpr : public BinaryExpr {
public:
// If val is given, evaluating this expression will always yield the val
// yet still perform the assignment. Used for triggers.
AssignExpr(Expr* op1, Expr* op2, int is_init, Val* val = 0, attr_list* attrs = 0);
virtual ~AssignExpr() { Unref(val); }
Expr* Simplify(SimplifyType simp_type);
Val* Eval(Frame* f) const;
void EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f) const;
BroType* InitType() const;
int IsRecordElement(TypeDecl* td) const;
Val* InitVal(const BroType* t, Val* aggr) const;
int IsPure() const;
protected:
friend class Expr;
AssignExpr() { }
bool TypeCheck(attr_list* attrs = 0);
bool TypeCheckArithmetics(TypeTag bt1, TypeTag bt2);
DECLARE_SERIAL(AssignExpr);
int is_init;
Val* val; // optional
};
class IndexExpr : public BinaryExpr {
public:
IndexExpr(Expr* op1, ListExpr* op2);
int CanAdd() const;
int CanDel() const;
void Add(Frame* f);
void Delete(Frame* f);
Expr* Simplify(SimplifyType simp_type);
void Assign(Frame* f, Val* v, Opcode op = OP_ASSIGN);
Expr* MakeLvalue();
// Need to override Eval since it can take a vector arg but does
// not necessarily return a vector.
Val* Eval(Frame* f) const;
TraversalCode Traverse(TraversalCallback* cb) const;
protected:
friend class Expr;
IndexExpr() { }
Val* Fold(Val* v1, Val* v2) const;
void ExprDescribe(ODesc* d) const;
DECLARE_SERIAL(IndexExpr);
};
class FieldExpr : public UnaryExpr {
public:
FieldExpr(Expr* op, const char* field_name);
~FieldExpr();
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();
protected:
friend class Expr;
FieldExpr() { field_name = 0; td = 0; }
Val* Fold(Val* v) const;
void ExprDescribe(ODesc* d) const;
DECLARE_SERIAL(FieldExpr);
const char* field_name;
const TypeDecl* td;
int field; // -1 = attributes
};
// "rec?$fieldname" is true if the value of $fieldname in rec is not nil.
// "rec?$$attrname" is true if the attribute attrname is not nil.
class HasFieldExpr : public UnaryExpr {
public:
HasFieldExpr(Expr* op, const char* field_name);
~HasFieldExpr();
protected:
friend class Expr;
HasFieldExpr() { field_name = 0; }
Val* Fold(Val* v) const;
void ExprDescribe(ODesc* d) const;
DECLARE_SERIAL(HasFieldExpr);
bool is_attr;
const char* field_name;
int field;
};
class RecordConstructorExpr : public UnaryExpr {
public:
RecordConstructorExpr(ListExpr* constructor_list);
protected:
friend class Expr;
RecordConstructorExpr() { }
Val* InitVal(const BroType* t, Val* aggr) const;
Val* Fold(Val* v) const;
void ExprDescribe(ODesc* d) const;
DECLARE_SERIAL(RecordConstructorExpr);
};
class TableConstructorExpr : public UnaryExpr {
public:
TableConstructorExpr(ListExpr* constructor_list, attr_list* attrs);
~TableConstructorExpr() { Unref(attrs); }
Val* Eval(Frame* f) const;
protected:
friend class Expr;
TableConstructorExpr() { }
Val* InitVal(const BroType* t, Val* aggr) const;
void ExprDescribe(ODesc* d) const;
DECLARE_SERIAL(TableConstructorExpr);
Attributes* attrs;
};
class SetConstructorExpr : public UnaryExpr {
public:
SetConstructorExpr(ListExpr* constructor_list, attr_list* attrs);
~SetConstructorExpr() { Unref(attrs); }
Val* Eval(Frame* f) const;
protected:
friend class Expr;
SetConstructorExpr() { }
Val* InitVal(const BroType* t, Val* aggr) const;
void ExprDescribe(ODesc* d) const;
DECLARE_SERIAL(SetConstructorExpr);
Attributes* attrs;
};
class VectorConstructorExpr : public UnaryExpr {
public:
VectorConstructorExpr(ListExpr* constructor_list);
Val* Eval(Frame* f) const;
protected:
friend class Expr;
VectorConstructorExpr() { }
Val* InitVal(const BroType* t, Val* aggr) const;
void ExprDescribe(ODesc* d) const;
DECLARE_SERIAL(VectorConstructorExpr);
};
class FieldAssignExpr : public UnaryExpr {
public:
FieldAssignExpr(const char* field_name, Expr* value);
const char* FieldName() const { return field_name.c_str(); }
void EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f) const;
int IsRecordElement(TypeDecl* td) const;
protected:
friend class Expr;
FieldAssignExpr() { }
void ExprDescribe(ODesc* d) const;
DECLARE_SERIAL(FieldAssignExpr);
string field_name;
};
class ArithCoerceExpr : public UnaryExpr {
public:
ArithCoerceExpr(Expr* op, TypeTag t);
protected:
friend class Expr;
ArithCoerceExpr() { }
Expr* DoSimplify();
Val* FoldSingleVal(Val* v, InternalTypeTag t) const;
Val* Fold(Val* v) const;
DECLARE_SERIAL(ArithCoerceExpr);
};
class RecordCoerceExpr : public UnaryExpr {
public:
RecordCoerceExpr(Expr* op, RecordType* r);
~RecordCoerceExpr();
protected:
friend class Expr;
RecordCoerceExpr() { map = 0; }
Val* Fold(Val* v) const;
DECLARE_SERIAL(RecordCoerceExpr);
// For each super-record slot, gives subrecord slot with which to
// fill it.
int* map;
int map_size; // equivalent to Type()->AsRecordType()->NumFields()
};
class TableCoerceExpr : public UnaryExpr {
public:
TableCoerceExpr(Expr* op, TableType* r);
~TableCoerceExpr();
protected:
friend class Expr;
TableCoerceExpr() { }
Val* Fold(Val* v) const;
DECLARE_SERIAL(TableCoerceExpr);
};
class VectorCoerceExpr : public UnaryExpr {
public:
VectorCoerceExpr(Expr* op, VectorType* v);
~VectorCoerceExpr();
protected:
friend class Expr;
VectorCoerceExpr() { }
Val* Fold(Val* v) const;
DECLARE_SERIAL(VectorCoerceExpr);
};
// An internal operator for flattening array indices that are records
// into a list of individual values.
class FlattenExpr : public UnaryExpr {
public:
FlattenExpr(Expr* op);
protected:
friend class Expr;
FlattenExpr() { }
Val* Fold(Val* v) const;
DECLARE_SERIAL(FlattenExpr);
int num_fields;
};
class EventHandler;
class ScheduleTimer : public Timer {
public:
ScheduleTimer(EventHandlerPtr event, val_list* args, double t,
TimerMgr* tmgr);
~ScheduleTimer();
void Dispatch(double t, int is_expire);
protected:
EventHandlerPtr event;
val_list* args;
TimerMgr* tmgr;
};
class ScheduleExpr : public Expr {
public:
ScheduleExpr(Expr* when, EventExpr* event);
~ScheduleExpr();
int IsPure() const;
Expr* Simplify(SimplifyType simp_type);
Val* Eval(Frame* f) const;
Expr* When() const { return when; }
EventExpr* Event() const { return event; }
TraversalCode Traverse(TraversalCallback* cb) const;
protected:
friend class Expr;
ScheduleExpr() { when = 0; event = 0; }
void ExprDescribe(ODesc* d) const;
DECLARE_SERIAL(ScheduleExpr);
Expr* when;
EventExpr* event;
};
class InExpr : public BinaryExpr {
public:
InExpr(Expr* op1, Expr* op2);
protected:
friend class Expr;
InExpr() { }
Val* Fold(Val* v1, Val* v2) const;
DECLARE_SERIAL(InExpr);
};
class CallExpr : public Expr {
public:
CallExpr(Expr* func, ListExpr* args, bool in_hook = false);
~CallExpr();
Expr* Func() const { return func; }
ListExpr* Args() const { return args; }
int IsPure() const;
Expr* Simplify(SimplifyType simp_type);
Val* Eval(Frame* f) const;
TraversalCode Traverse(TraversalCallback* cb) const;
protected:
friend class Expr;
CallExpr() { func = 0; args = 0; }
void ExprDescribe(ODesc* d) const;
DECLARE_SERIAL(CallExpr);
Expr* func;
ListExpr* args;
};
class EventExpr : public Expr {
public:
EventExpr(const char* name, ListExpr* args);
~EventExpr();
const char* Name() const { return name.c_str(); }
ListExpr* Args() const { return args; }
EventHandlerPtr Handler() const { return handler; }
Expr* Simplify(SimplifyType simp_type);
Val* Eval(Frame* f) const;
TraversalCode Traverse(TraversalCallback* cb) const;
protected:
friend class Expr;
EventExpr() { args = 0; }
void ExprDescribe(ODesc* d) const;
DECLARE_SERIAL(EventExpr);
string name;
EventHandlerPtr handler;
ListExpr* args;
};
class ListExpr : public Expr {
public:
ListExpr();
ListExpr(Expr* e);
~ListExpr();
void Append(Expr* e);
const expr_list& Exprs() const { return exprs; }
expr_list& Exprs() { return exprs; }
// True if the entire list represents pure values.
int IsPure() const;
// True if the entire list represents constant values.
int AllConst() const;
Expr* Simplify(SimplifyType simp_type);
Val* Eval(Frame* f) const;
BroType* InitType() const;
Val* InitVal(const BroType* t, Val* aggr) const;
Expr* MakeLvalue();
void Assign(Frame* f, Val* v, Opcode op = OP_ASSIGN);
TraversalCode Traverse(TraversalCallback* cb) const;
protected:
Val* AddSetInit(const BroType* t, Val* aggr) const;
void ExprDescribe(ODesc* d) const;
DECLARE_SERIAL(ListExpr);
expr_list exprs;
};
class RecordAssignExpr : public ListExpr {
public:
RecordAssignExpr(Expr* record, Expr* init_list, int is_init);
Val* Eval(Frame* f) const { return ListExpr::Eval(f); }
protected:
friend class Expr;
RecordAssignExpr() { }
DECLARE_SERIAL(RecordAssignExpr);
};
inline Val* Expr::ExprVal() const
{
if ( ! IsConst() )
BadTag("ExprVal::Val", expr_name(tag), expr_name(EXPR_CONST));
return ((ConstExpr*) this)->Value();
}
// Decides whether to return an AssignExpr or a RecordAssignExpr.
Expr* get_assign_expr(Expr* op1, Expr* op2, int is_init);
// Type-check the given expression(s) against the given type(s). Complain
// if the expression cannot match the given type, returning 0. If it can
// match, promote it as necessary (modifying the ref parameter accordingly)
// and return 1.
//
// The second and third forms are for promoting a list of
// expressions (which is updated in place) to either match a list of
// types or a single type.
//
// Note, the type is not "const" because it can be ref'd.
extern int check_and_promote_expr(Expr*& e, BroType* t);
extern int check_and_promote_exprs(ListExpr*& elements, TypeList* types);
extern int check_and_promote_exprs_to_type(ListExpr*& elements, BroType* type);
// Returns a fully simplified form of the expression. Note that passed
// expression and its subexpressions may be modified, Unref()'d, etc.
Expr* simplify_expr(Expr* e, SimplifyType simp_type);
// Returns a simplified ListExpr - guaranteed to still be a ListExpr,
// even if it only contains one expr.
ListExpr* simplify_expr_list(ListExpr* l, SimplifyType simp_type);
// Returns a ListExpr simplified down to a list a values, or a nil
// pointer if they couldn't all be reduced.
val_list* eval_list(Frame* f, const ListExpr* l);
// Returns true if two expressions are identical.
extern int same_expr(const Expr* e1, const Expr* e2);
// Returns true if e1 is "greater" than e2 - here "greater" is just
// a heuristic, used with commutative operators to put them into
// a canonical form.
extern int expr_greater(const Expr* e1, const Expr* e2);
// Return constants of the given type.
Expr* make_zero(BroType* t);
Expr* make_one(BroType* t);
// True if the given Val* has a vector type
inline bool is_vector(Expr* e) { return e->Type()->Tag() == TYPE_VECTOR; }
#endif