diff --git a/src/Expr.cc b/src/Expr.cc index ca980e5acc..556c153643 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -3717,31 +3717,50 @@ bool SetConstructorExpr::DoUnserialize(UnserialInfo* info) return true; } -VectorConstructorExpr::VectorConstructorExpr(ListExpr* constructor_list) +VectorConstructorExpr::VectorConstructorExpr(ListExpr* constructor_list, + BroType* arg_type) : UnaryExpr(EXPR_VECTOR_CONSTRUCTOR, constructor_list) { if ( IsError() ) return; - if ( constructor_list->Exprs().length() == 0 ) + if ( arg_type ) { - // vector(). - SetType(new ::VectorType(base_type(TYPE_ANY))); - return; - } + if ( arg_type->Tag() != TYPE_VECTOR ) + { + Error("bad vector constructor type", arg_type); + SetError(); + return; + } - BroType* t = merge_type_list(constructor_list); - if ( t ) - { - SetType(new VectorType(t->Ref())); - - if ( ! check_and_promote_exprs_to_type(constructor_list, t) ) - ExprError("inconsistent types in vector constructor"); - - Unref(t); + SetType(arg_type->Ref()); } else - SetError(); + { + if ( constructor_list->Exprs().length() == 0 ) + { + // vector(). + SetType(new ::VectorType(base_type(TYPE_ANY))); + return; + } + + BroType* t = merge_type_list(constructor_list); + + if ( t ) + { + SetType(new VectorType(t->Ref())); + Unref(t); + } + else + { + SetError(); + return; + } + } + + if ( ! check_and_promote_exprs_to_type(constructor_list, + type->AsVectorType()->YieldType()) ) + ExprError("inconsistent types in vector constructor"); } Val* VectorConstructorExpr::Eval(Frame* f) const diff --git a/src/Expr.h b/src/Expr.h index ff97c52178..2dca42ef09 100644 --- a/src/Expr.h +++ b/src/Expr.h @@ -818,7 +818,7 @@ protected: class VectorConstructorExpr : public UnaryExpr { public: - VectorConstructorExpr(ListExpr* constructor_list); + VectorConstructorExpr(ListExpr* constructor_list, BroType* arg_type = 0); Val* Eval(Frame* f) const; diff --git a/src/parse.y b/src/parse.y index 74588408fa..2b86057f3c 100644 --- a/src/parse.y +++ b/src/parse.y @@ -555,6 +555,9 @@ expr: break; case TYPE_VECTOR: + $$ = new VectorConstructorExpr($4, ctor_type); + break; + default: $1->Error("constructor type not implemented"); YYERROR; diff --git a/testing/btest/Baseline/language.named-vector-ctors/out b/testing/btest/Baseline/language.named-vector-ctors/out new file mode 100644 index 0000000000..53ed260c93 --- /dev/null +++ b/testing/btest/Baseline/language.named-vector-ctors/out @@ -0,0 +1,3 @@ +[one, two, three] +[1.0, 2.0, 3.0] +[[min=, max=1], [min=, max=2], [min=, max=3]] diff --git a/testing/btest/language/named-vector-ctors.bro b/testing/btest/language/named-vector-ctors.bro new file mode 100644 index 0000000000..1e0e1e9e55 --- /dev/null +++ b/testing/btest/language/named-vector-ctors.bro @@ -0,0 +1,19 @@ +# @TEST-EXEC: bro -b %INPUT >out +# @TEST-EXEC: btest-diff out + +type MyRec: record { + min: count &optional; + max: count; +}; + +type FooVector: vector of string; +type FooVectorD: vector of double; +type FooVectorRec: vector of MyRec; + +global myvec: FooVector = FooVector("one", "two", "three"); +global myvecd: FooVectorD = FooVectorD(1, 2, 3); +global myvecrec: FooVectorRec = FooVectorRec([$max=1], [$max=2], [$max=3]); + +print myvec; +print myvecd; +print myvecrec;