diff --git a/src/Expr.cc b/src/Expr.cc index 535a267420..e95c3db825 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -3055,7 +3055,7 @@ void HasFieldExpr::ExprDescribe(ODesc* d) const } RecordConstructorExpr::RecordConstructorExpr(ListExprPtr constructor_list) - : UnaryExpr(EXPR_RECORD_CONSTRUCTOR, std::move(constructor_list)) + : Expr(EXPR_RECORD_CONSTRUCTOR), op(std::move(constructor_list)) { if ( IsError() ) return; @@ -3108,22 +3108,30 @@ ValPtr RecordConstructorExpr::InitVal(const zeek::Type* t, ValPtr aggr) const return nullptr; } -ValPtr RecordConstructorExpr::Fold(Val* v) const +ValPtr RecordConstructorExpr::Eval(Frame* f) const { - ListVal* lv = v->AsListVal(); + if ( IsError() ) + return nullptr; + + const auto& exprs = op->Exprs(); auto rt = cast_intrusive(type); - if ( lv->Length() != rt->NumFields() ) + if ( exprs.length() != rt->NumFields() ) RuntimeErrorWithCallStack("inconsistency evaluating record constructor"); auto rv = make_intrusive(std::move(rt)); - for ( int i = 0; i < lv->Length(); ++i ) - rv->Assign(i, lv->Idx(i)); + for ( int i = 0; i < exprs.length(); ++i ) + rv->Assign(i, exprs[i]->Eval(f)); return rv; } +bool RecordConstructorExpr::IsPure() const + { + return op->IsPure(); + } + void RecordConstructorExpr::ExprDescribe(ODesc* d) const { d->Add("["); @@ -3131,6 +3139,18 @@ void RecordConstructorExpr::ExprDescribe(ODesc* d) const d->Add("]"); } +TraversalCode RecordConstructorExpr::Traverse(TraversalCallback* cb) const + { + TraversalCode tc = cb->PreExpr(this); + HANDLE_TC_EXPR_PRE(tc); + + tc = op->Traverse(cb); + HANDLE_TC_EXPR_PRE(tc); + + tc = cb->PostExpr(this); + HANDLE_TC_EXPR_POST(tc); + } + TableConstructorExpr::TableConstructorExpr(ListExprPtr constructor_list, std::unique_ptr> arg_attrs, TypePtr arg_type) diff --git a/src/Expr.h b/src/Expr.h index a1dd60ac33..4456b6fa4f 100644 --- a/src/Expr.h +++ b/src/Expr.h @@ -630,16 +630,25 @@ protected: int field; }; -class RecordConstructorExpr final : public UnaryExpr { +class RecordConstructorExpr final : public Expr { public: explicit RecordConstructorExpr(ListExprPtr constructor_list); ~RecordConstructorExpr() override; + ListExpr* Op() const { return op.get(); } + + ValPtr Eval(Frame* f) const override; + + bool IsPure() const override; + + TraversalCode Traverse(TraversalCallback* cb) const override; + protected: ValPtr InitVal(const zeek::Type* t, ValPtr aggr) const override; - ValPtr Fold(Val* v) const override; void ExprDescribe(ODesc* d) const override; + + ListExprPtr op; }; class TableConstructorExpr final : public UnaryExpr {