diff --git a/src/Var.cc b/src/Var.cc index c447517b53..d49323b7f3 100644 --- a/src/Var.cc +++ b/src/Var.cc @@ -476,16 +476,6 @@ void end_func(IntrusivePtr body) { auto ingredients = std::make_unique(pop_scope(), std::move(body)); - if ( streq(ingredients->id->Name(), "anonymous-function") ) - { - OuterIDBindingFinder cb(ingredients->scope.get()); - ingredients->body->Traverse(&cb); - - for ( size_t i = 0; i < cb.outer_id_references.size(); ++i ) - cb.outer_id_references[i]->Error( - "referencing outer function IDs not supported"); - } - if ( ingredients->id->HasVal() ) ingredients->id->ID_Val()->AsFunc()->AddBody( ingredients->body, diff --git a/src/parse.y b/src/parse.y index 7f379d44ec..dd22fbee04 100644 --- a/src/parse.y +++ b/src/parse.y @@ -57,7 +57,7 @@ %type init_class %type opt_init %type TOK_CONSTANT -%type expr opt_expr init anonymous_function index_slice opt_deprecated +%type expr opt_expr init anonymous_function lambda_body index_slice opt_deprecated %type event %type stmt stmt_list func_body for_head %type type opt_type enum_body @@ -504,7 +504,7 @@ expr: $$ = new FieldAssignExpr($2, {AdoptRef{}, $4}); } - | '$' TOK_ID func_params '=' + | '$' TOK_ID func_params '=' { func_hdr_location = @1; func_id = current_scope()->GenerateTemporary("anonymous-function"); @@ -512,11 +512,9 @@ expr: begin_func(func_id, current_module.c_str(), FUNC_FLAVOR_FUNCTION, 0, {AdoptRef{}, $3}); } - func_body + lambda_body { - $$ = new FieldAssignExpr($2, - make_intrusive( - IntrusivePtr{NewRef{}, func_id->ID_Val()})); + $$ = new FieldAssignExpr($2, IntrusivePtr{AdoptRef{}, $6}); Unref(func_id); } @@ -1237,9 +1235,7 @@ func_body: } ; -anonymous_function: - TOK_FUNCTION begin_func - +lambda_body: '{' { saved_in_init.push_back(in_init); @@ -1254,20 +1250,25 @@ anonymous_function: '}' { - set_location(@1, @7); + set_location(@1, @5); // Code duplication here is sad but needed. end_func actually instantiates the function // and associates it with an ID. We perform that association later and need to return // a lambda expression. // Gather the ingredients for a BroFunc from the current scope - auto ingredients = std::make_unique(IntrusivePtr{NewRef{}, current_scope()}, IntrusivePtr{AdoptRef{}, $5}); + auto ingredients = std::make_unique(IntrusivePtr{NewRef{}, current_scope()}, IntrusivePtr{AdoptRef{}, $3}); id_list outer_ids = gather_outer_ids(pop_scope().get(), ingredients->body.get()); $$ = new LambdaExpr(std::move(ingredients), std::move(outer_ids)); } ; +anonymous_function: + TOK_FUNCTION begin_func lambda_body + { $$ = $3; } + ; + begin_func: func_params { diff --git a/testing/btest/Baseline/language.lambda-record-field/out b/testing/btest/Baseline/language.lambda-record-field/out new file mode 100644 index 0000000000..31e0fce560 --- /dev/null +++ b/testing/btest/Baseline/language.lambda-record-field/out @@ -0,0 +1 @@ +helloworld diff --git a/testing/btest/Baseline/scripts.base.frameworks.input.reread/out b/testing/btest/Baseline/scripts.base.frameworks.input.reread/out index 19d323afcb..13adcdd31d 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.input.reread/out +++ b/testing/btest/Baseline/scripts.base.frameworks.input.reread/out @@ -39,7 +39,7 @@ print A::outfile, Left; print A::outfile, A::left; print A::outfile, Right; print A::outfile, A::right; -}, pred=anonymous-function +}, pred=lambda_<10906653936191056190> { print A::outfile, ============PREDICATE============; print A::outfile, A::typ; @@ -134,7 +134,7 @@ print A::outfile, Left; print A::outfile, A::left; print A::outfile, Right; print A::outfile, A::right; -}, pred=anonymous-function +}, pred=lambda_<10906653936191056190> { print A::outfile, ============PREDICATE============; print A::outfile, A::typ; @@ -241,7 +241,7 @@ print A::outfile, Left; print A::outfile, A::left; print A::outfile, Right; print A::outfile, A::right; -}, pred=anonymous-function +}, pred=lambda_<10906653936191056190> { print A::outfile, ============PREDICATE============; print A::outfile, A::typ; @@ -468,7 +468,7 @@ print A::outfile, Left; print A::outfile, A::left; print A::outfile, Right; print A::outfile, A::right; -}, pred=anonymous-function +}, pred=lambda_<10906653936191056190> { print A::outfile, ============PREDICATE============; print A::outfile, A::typ; @@ -593,7 +593,7 @@ print A::outfile, Left; print A::outfile, A::left; print A::outfile, Right; print A::outfile, A::right; -}, pred=anonymous-function +}, pred=lambda_<10906653936191056190> { print A::outfile, ============PREDICATE============; print A::outfile, A::typ; @@ -718,7 +718,7 @@ print A::outfile, Left; print A::outfile, A::left; print A::outfile, Right; print A::outfile, A::right; -}, pred=anonymous-function +}, pred=lambda_<10906653936191056190> { print A::outfile, ============PREDICATE============; print A::outfile, A::typ; @@ -843,7 +843,7 @@ print A::outfile, Left; print A::outfile, A::left; print A::outfile, Right; print A::outfile, A::right; -}, pred=anonymous-function +}, pred=lambda_<10906653936191056190> { print A::outfile, ============PREDICATE============; print A::outfile, A::typ; @@ -968,7 +968,7 @@ print A::outfile, Left; print A::outfile, A::left; print A::outfile, Right; print A::outfile, A::right; -}, pred=anonymous-function +}, pred=lambda_<10906653936191056190> { print A::outfile, ============PREDICATE============; print A::outfile, A::typ; @@ -1198,7 +1198,7 @@ print A::outfile, Left; print A::outfile, A::left; print A::outfile, Right; print A::outfile, A::right; -}, pred=anonymous-function +}, pred=lambda_<10906653936191056190> { print A::outfile, ============PREDICATE============; print A::outfile, A::typ; @@ -1251,7 +1251,7 @@ print A::outfile, Left; print A::outfile, A::left; print A::outfile, Right; print A::outfile, A::right; -}, pred=anonymous-function +}, pred=lambda_<10906653936191056190> { print A::outfile, ============PREDICATE============; print A::outfile, A::typ; @@ -1304,7 +1304,7 @@ print A::outfile, Left; print A::outfile, A::left; print A::outfile, Right; print A::outfile, A::right; -}, pred=anonymous-function +}, pred=lambda_<10906653936191056190> { print A::outfile, ============PREDICATE============; print A::outfile, A::typ; @@ -1357,7 +1357,7 @@ print A::outfile, Left; print A::outfile, A::left; print A::outfile, Right; print A::outfile, A::right; -}, pred=anonymous-function +}, pred=lambda_<10906653936191056190> { print A::outfile, ============PREDICATE============; print A::outfile, A::typ; @@ -1410,7 +1410,7 @@ print A::outfile, Left; print A::outfile, A::left; print A::outfile, Right; print A::outfile, A::right; -}, pred=anonymous-function +}, pred=lambda_<10906653936191056190> { print A::outfile, ============PREDICATE============; print A::outfile, A::typ; @@ -1463,7 +1463,7 @@ print A::outfile, Left; print A::outfile, A::left; print A::outfile, Right; print A::outfile, A::right; -}, pred=anonymous-function +}, pred=lambda_<10906653936191056190> { print A::outfile, ============PREDICATE============; print A::outfile, A::typ; diff --git a/testing/btest/language/lambda-record-field.zeek b/testing/btest/language/lambda-record-field.zeek new file mode 100644 index 0000000000..bcb7e1bc75 --- /dev/null +++ b/testing/btest/language/lambda-record-field.zeek @@ -0,0 +1,13 @@ +# @TEST-EXEC: zeek -b %INPUT >out +# @TEST-EXEC: btest-diff out + +type myrec: record { + foo: function(a: string); +}; + +event zeek_init() + { + local w = "world"; + local mr = myrec($foo(a: string) = { print a + w; }); + mr$foo("hello"); + }