mirror of
https://github.com/zeek/zeek.git
synced 2025-10-05 08:08:19 +00:00
Implementing a VectorCoerceExpr.
Turns out we didn't have that yet. I don't remember who implemented vectors originally, but he does owe us all round at Jupiter ...
This commit is contained in:
parent
b3b5a73113
commit
5a6311d360
7 changed files with 115 additions and 6 deletions
70
src/Expr.cc
70
src/Expr.cc
|
@ -2497,12 +2497,7 @@ AssignExpr::AssignExpr(Expr* arg_op1, Expr* arg_op2, int arg_is_init,
|
|||
bool AssignExpr::TypeCheck()
|
||||
{
|
||||
TypeTag bt1 = op1->Type()->Tag();
|
||||
if ( IsVector(bt1) )
|
||||
bt1 = op1->Type()->AsVectorType()->YieldType()->Tag();
|
||||
|
||||
TypeTag bt2 = op2->Type()->Tag();
|
||||
if ( IsVector(bt2) )
|
||||
bt2 = op2->Type()->AsVectorType()->YieldType()->Tag();
|
||||
|
||||
if ( bt1 == TYPE_LIST && bt2 == TYPE_ANY )
|
||||
// This is ok because we cannot explicitly declare lists on
|
||||
|
@ -2531,6 +2526,13 @@ bool AssignExpr::TypeCheck()
|
|||
return true;
|
||||
}
|
||||
|
||||
if ( bt1 == TYPE_VECTOR && bt2 == bt1 &&
|
||||
op2->Type()->AsVectorType()->IsUnspecifiedVector() )
|
||||
{
|
||||
op2 = new VectorCoerceExpr(op2, op1->Type()->AsVectorType());
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( op1->Type()->Tag() == TYPE_RECORD &&
|
||||
op2->Type()->Tag() == TYPE_RECORD )
|
||||
{
|
||||
|
@ -3506,6 +3508,13 @@ VectorConstructorExpr::VectorConstructorExpr(ListExpr* constructor_list)
|
|||
if ( IsError() )
|
||||
return;
|
||||
|
||||
if ( constructor_list->Exprs().length() == 0 )
|
||||
{
|
||||
// vector().
|
||||
SetType(new ::VectorType(base_type(TYPE_ANY)));
|
||||
return;
|
||||
}
|
||||
|
||||
BroType* t = merge_type_list(constructor_list);
|
||||
if ( t )
|
||||
{
|
||||
|
@ -4122,6 +4131,50 @@ bool TableCoerceExpr::DoUnserialize(UnserialInfo* info)
|
|||
return true;
|
||||
}
|
||||
|
||||
VectorCoerceExpr::VectorCoerceExpr(Expr* op, VectorType* v)
|
||||
: UnaryExpr(EXPR_VECTOR_COERCE, op)
|
||||
{
|
||||
if ( IsError() )
|
||||
return;
|
||||
|
||||
SetType(v->Ref());
|
||||
|
||||
if ( Type()->Tag() != TYPE_VECTOR )
|
||||
ExprError("coercion to non-vector");
|
||||
|
||||
else if ( op->Type()->Tag() != TYPE_VECTOR )
|
||||
ExprError("coercion of non-vector to vector");
|
||||
}
|
||||
|
||||
|
||||
VectorCoerceExpr::~VectorCoerceExpr()
|
||||
{
|
||||
}
|
||||
|
||||
Val* VectorCoerceExpr::Fold(Val* v) const
|
||||
{
|
||||
VectorVal* vv = v->AsVectorVal();
|
||||
|
||||
if ( vv->Size() > 0 )
|
||||
Internal("coercion of non-empty vector");
|
||||
|
||||
return new VectorVal(Type()->Ref()->AsVectorType());
|
||||
}
|
||||
|
||||
IMPLEMENT_SERIAL(VectorCoerceExpr, SER_VECTOR_COERCE_EXPR);
|
||||
|
||||
bool VectorCoerceExpr::DoSerialize(SerialInfo* info) const
|
||||
{
|
||||
DO_SERIALIZE(SER_VECTOR_COERCE_EXPR, UnaryExpr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VectorCoerceExpr::DoUnserialize(UnserialInfo* info)
|
||||
{
|
||||
DO_UNSERIALIZE(UnaryExpr);
|
||||
return true;
|
||||
}
|
||||
|
||||
FlattenExpr::FlattenExpr(Expr* arg_op)
|
||||
: UnaryExpr(EXPR_FLATTEN, arg_op)
|
||||
{
|
||||
|
@ -5337,6 +5390,13 @@ int check_and_promote_expr(Expr*& e, BroType* t)
|
|||
return 1;
|
||||
}
|
||||
|
||||
if ( t->Tag() == TYPE_VECTOR && et->Tag() == TYPE_VECTOR &&
|
||||
et->AsVectorType()->IsUnspecifiedVector() )
|
||||
{
|
||||
e = new VectorCoerceExpr(e, t->AsVectorType());
|
||||
return 1;
|
||||
}
|
||||
|
||||
t->Error("type clash", e);
|
||||
return 0;
|
||||
}
|
||||
|
|
16
src/Expr.h
16
src/Expr.h
|
@ -40,7 +40,7 @@ typedef enum {
|
|||
EXPR_CALL,
|
||||
EXPR_EVENT,
|
||||
EXPR_SCHEDULE,
|
||||
EXPR_ARITH_COERCE, EXPR_RECORD_COERCE, EXPR_TABLE_COERCE,
|
||||
EXPR_ARITH_COERCE, EXPR_RECORD_COERCE, EXPR_TABLE_COERCE, EXPR_VECTOR_COERCE,
|
||||
EXPR_SIZE,
|
||||
EXPR_FLATTEN,
|
||||
#define NUM_EXPRS (int(EXPR_FLATTEN) + 1)
|
||||
|
@ -895,6 +895,20 @@ protected:
|
|||
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 {
|
||||
|
|
|
@ -146,6 +146,7 @@ SERIAL_EXPR(TABLE_CONSTRUCTOR_EXPR, 40)
|
|||
SERIAL_EXPR(SET_CONSTRUCTOR_EXPR, 41)
|
||||
SERIAL_EXPR(VECTOR_CONSTRUCTOR_EXPR, 42)
|
||||
SERIAL_EXPR(TABLE_COERCE_EXPR, 43)
|
||||
SERIAL_EXPR(VECTOR_COERCE_EXPR, 44)
|
||||
|
||||
#define SERIAL_STMT(name, val) SERIAL_CONST(name, val, STMT)
|
||||
SERIAL_STMT(STMT, 1)
|
||||
|
|
|
@ -1290,6 +1290,11 @@ int VectorType::MatchesIndex(ListExpr*& index) const
|
|||
MATCHES_INDEX_SCALAR : DOES_NOT_MATCH_INDEX;
|
||||
}
|
||||
|
||||
bool VectorType::IsUnspecifiedVector() const
|
||||
{
|
||||
return yield_type->Tag() == TYPE_ANY;
|
||||
}
|
||||
|
||||
IMPLEMENT_SERIAL(VectorType, SER_VECTOR_TYPE);
|
||||
|
||||
bool VectorType::DoSerialize(SerialInfo* info) const
|
||||
|
@ -1651,6 +1656,7 @@ BroType* merge_types(const BroType* t1, const BroType* t2)
|
|||
case TYPE_ADDR:
|
||||
case TYPE_NET:
|
||||
case TYPE_SUBNET:
|
||||
case TYPE_BOOL:
|
||||
case TYPE_ANY:
|
||||
case TYPE_ERROR:
|
||||
return base_type(tg1);
|
||||
|
|
|
@ -525,6 +525,10 @@ public:
|
|||
|
||||
int MatchesIndex(ListExpr*& index) const;
|
||||
|
||||
// Returns true if this table type is "unspecified", which is what one
|
||||
// gets using an empty "vector()" constructor.
|
||||
bool IsUnspecifiedVector() const;
|
||||
|
||||
protected:
|
||||
VectorType() { yield_type = 0; }
|
||||
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
[]
|
||||
[1, 2, 3]
|
||||
[T, F, T]
|
||||
[]
|
20
testing/btest/language/vector-coerce-expr.bro
Normal file
20
testing/btest/language/vector-coerce-expr.bro
Normal file
|
@ -0,0 +1,20 @@
|
|||
# @TEST-EXEC: bro %INPUT >output 2>&1
|
||||
# @TEST-EXEC: btest-diff output
|
||||
|
||||
type X: record {
|
||||
a: vector of bool &default=vector(T, F, T);
|
||||
b: vector of bool &default=vector();
|
||||
};
|
||||
|
||||
global x: X;
|
||||
|
||||
global a: vector of count;
|
||||
|
||||
a = vector();
|
||||
print a;
|
||||
|
||||
a = vector(1,2,3);
|
||||
print a;
|
||||
|
||||
print x$a;
|
||||
print x$b;
|
Loading…
Add table
Add a link
Reference in a new issue