mirror of
https://github.com/zeek/zeek.git
synced 2025-10-06 00:28:21 +00:00
Change record field anonymous functions to use lambda expressions
There was an alternate syntax to assign anonymous functions to record fields that was never migrated to use the new lambda expression machinery (and so didn't allow referencing variables in outer scope): type myrec: record { foo: function(a: string); }; local o = "o"; local mr = myrec($foo(a: string) = { print a + o; });
This commit is contained in:
parent
66156b4eee
commit
f032885085
5 changed files with 40 additions and 35 deletions
10
src/Var.cc
10
src/Var.cc
|
@ -476,16 +476,6 @@ void end_func(IntrusivePtr<Stmt> body)
|
||||||
{
|
{
|
||||||
auto ingredients = std::make_unique<function_ingredients>(pop_scope(), std::move(body));
|
auto ingredients = std::make_unique<function_ingredients>(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() )
|
if ( ingredients->id->HasVal() )
|
||||||
ingredients->id->ID_Val()->AsFunc()->AddBody(
|
ingredients->id->ID_Val()->AsFunc()->AddBody(
|
||||||
ingredients->body,
|
ingredients->body,
|
||||||
|
|
23
src/parse.y
23
src/parse.y
|
@ -57,7 +57,7 @@
|
||||||
%type <ic> init_class
|
%type <ic> init_class
|
||||||
%type <expr> opt_init
|
%type <expr> opt_init
|
||||||
%type <val> TOK_CONSTANT
|
%type <val> TOK_CONSTANT
|
||||||
%type <expr> expr opt_expr init anonymous_function index_slice opt_deprecated
|
%type <expr> expr opt_expr init anonymous_function lambda_body index_slice opt_deprecated
|
||||||
%type <event_expr> event
|
%type <event_expr> event
|
||||||
%type <stmt> stmt stmt_list func_body for_head
|
%type <stmt> stmt stmt_list func_body for_head
|
||||||
%type <type> type opt_type enum_body
|
%type <type> type opt_type enum_body
|
||||||
|
@ -504,7 +504,7 @@ expr:
|
||||||
$$ = new FieldAssignExpr($2, {AdoptRef{}, $4});
|
$$ = new FieldAssignExpr($2, {AdoptRef{}, $4});
|
||||||
}
|
}
|
||||||
|
|
||||||
| '$' TOK_ID func_params '='
|
| '$' TOK_ID func_params '='
|
||||||
{
|
{
|
||||||
func_hdr_location = @1;
|
func_hdr_location = @1;
|
||||||
func_id = current_scope()->GenerateTemporary("anonymous-function");
|
func_id = current_scope()->GenerateTemporary("anonymous-function");
|
||||||
|
@ -512,11 +512,9 @@ expr:
|
||||||
begin_func(func_id, current_module.c_str(), FUNC_FLAVOR_FUNCTION,
|
begin_func(func_id, current_module.c_str(), FUNC_FLAVOR_FUNCTION,
|
||||||
0, {AdoptRef{}, $3});
|
0, {AdoptRef{}, $3});
|
||||||
}
|
}
|
||||||
func_body
|
lambda_body
|
||||||
{
|
{
|
||||||
$$ = new FieldAssignExpr($2,
|
$$ = new FieldAssignExpr($2, IntrusivePtr{AdoptRef{}, $6});
|
||||||
make_intrusive<ConstExpr>(
|
|
||||||
IntrusivePtr<Val>{NewRef{}, func_id->ID_Val()}));
|
|
||||||
Unref(func_id);
|
Unref(func_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1237,9 +1235,7 @@ func_body:
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
anonymous_function:
|
lambda_body:
|
||||||
TOK_FUNCTION begin_func
|
|
||||||
|
|
||||||
'{'
|
'{'
|
||||||
{
|
{
|
||||||
saved_in_init.push_back(in_init);
|
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
|
// 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
|
// and associates it with an ID. We perform that association later and need to return
|
||||||
// a lambda expression.
|
// a lambda expression.
|
||||||
|
|
||||||
// Gather the ingredients for a BroFunc from the current scope
|
// Gather the ingredients for a BroFunc from the current scope
|
||||||
auto ingredients = std::make_unique<function_ingredients>(IntrusivePtr{NewRef{}, current_scope()}, IntrusivePtr{AdoptRef{}, $5});
|
auto ingredients = std::make_unique<function_ingredients>(IntrusivePtr{NewRef{}, current_scope()}, IntrusivePtr{AdoptRef{}, $3});
|
||||||
id_list outer_ids = gather_outer_ids(pop_scope().get(), ingredients->body.get());
|
id_list outer_ids = gather_outer_ids(pop_scope().get(), ingredients->body.get());
|
||||||
|
|
||||||
$$ = new LambdaExpr(std::move(ingredients), std::move(outer_ids));
|
$$ = new LambdaExpr(std::move(ingredients), std::move(outer_ids));
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
anonymous_function:
|
||||||
|
TOK_FUNCTION begin_func lambda_body
|
||||||
|
{ $$ = $3; }
|
||||||
|
;
|
||||||
|
|
||||||
begin_func:
|
begin_func:
|
||||||
func_params
|
func_params
|
||||||
{
|
{
|
||||||
|
|
1
testing/btest/Baseline/language.lambda-record-field/out
Normal file
1
testing/btest/Baseline/language.lambda-record-field/out
Normal file
|
@ -0,0 +1 @@
|
||||||
|
helloworld
|
|
@ -39,7 +39,7 @@ print A::outfile, Left;
|
||||||
print A::outfile, A::left;
|
print A::outfile, A::left;
|
||||||
print A::outfile, Right;
|
print A::outfile, Right;
|
||||||
print A::outfile, A::right;
|
print A::outfile, A::right;
|
||||||
}, pred=anonymous-function
|
}, pred=lambda_<10906653936191056190>
|
||||||
{
|
{
|
||||||
print A::outfile, ============PREDICATE============;
|
print A::outfile, ============PREDICATE============;
|
||||||
print A::outfile, A::typ;
|
print A::outfile, A::typ;
|
||||||
|
@ -134,7 +134,7 @@ print A::outfile, Left;
|
||||||
print A::outfile, A::left;
|
print A::outfile, A::left;
|
||||||
print A::outfile, Right;
|
print A::outfile, Right;
|
||||||
print A::outfile, A::right;
|
print A::outfile, A::right;
|
||||||
}, pred=anonymous-function
|
}, pred=lambda_<10906653936191056190>
|
||||||
{
|
{
|
||||||
print A::outfile, ============PREDICATE============;
|
print A::outfile, ============PREDICATE============;
|
||||||
print A::outfile, A::typ;
|
print A::outfile, A::typ;
|
||||||
|
@ -241,7 +241,7 @@ print A::outfile, Left;
|
||||||
print A::outfile, A::left;
|
print A::outfile, A::left;
|
||||||
print A::outfile, Right;
|
print A::outfile, Right;
|
||||||
print A::outfile, A::right;
|
print A::outfile, A::right;
|
||||||
}, pred=anonymous-function
|
}, pred=lambda_<10906653936191056190>
|
||||||
{
|
{
|
||||||
print A::outfile, ============PREDICATE============;
|
print A::outfile, ============PREDICATE============;
|
||||||
print A::outfile, A::typ;
|
print A::outfile, A::typ;
|
||||||
|
@ -468,7 +468,7 @@ print A::outfile, Left;
|
||||||
print A::outfile, A::left;
|
print A::outfile, A::left;
|
||||||
print A::outfile, Right;
|
print A::outfile, Right;
|
||||||
print A::outfile, A::right;
|
print A::outfile, A::right;
|
||||||
}, pred=anonymous-function
|
}, pred=lambda_<10906653936191056190>
|
||||||
{
|
{
|
||||||
print A::outfile, ============PREDICATE============;
|
print A::outfile, ============PREDICATE============;
|
||||||
print A::outfile, A::typ;
|
print A::outfile, A::typ;
|
||||||
|
@ -593,7 +593,7 @@ print A::outfile, Left;
|
||||||
print A::outfile, A::left;
|
print A::outfile, A::left;
|
||||||
print A::outfile, Right;
|
print A::outfile, Right;
|
||||||
print A::outfile, A::right;
|
print A::outfile, A::right;
|
||||||
}, pred=anonymous-function
|
}, pred=lambda_<10906653936191056190>
|
||||||
{
|
{
|
||||||
print A::outfile, ============PREDICATE============;
|
print A::outfile, ============PREDICATE============;
|
||||||
print A::outfile, A::typ;
|
print A::outfile, A::typ;
|
||||||
|
@ -718,7 +718,7 @@ print A::outfile, Left;
|
||||||
print A::outfile, A::left;
|
print A::outfile, A::left;
|
||||||
print A::outfile, Right;
|
print A::outfile, Right;
|
||||||
print A::outfile, A::right;
|
print A::outfile, A::right;
|
||||||
}, pred=anonymous-function
|
}, pred=lambda_<10906653936191056190>
|
||||||
{
|
{
|
||||||
print A::outfile, ============PREDICATE============;
|
print A::outfile, ============PREDICATE============;
|
||||||
print A::outfile, A::typ;
|
print A::outfile, A::typ;
|
||||||
|
@ -843,7 +843,7 @@ print A::outfile, Left;
|
||||||
print A::outfile, A::left;
|
print A::outfile, A::left;
|
||||||
print A::outfile, Right;
|
print A::outfile, Right;
|
||||||
print A::outfile, A::right;
|
print A::outfile, A::right;
|
||||||
}, pred=anonymous-function
|
}, pred=lambda_<10906653936191056190>
|
||||||
{
|
{
|
||||||
print A::outfile, ============PREDICATE============;
|
print A::outfile, ============PREDICATE============;
|
||||||
print A::outfile, A::typ;
|
print A::outfile, A::typ;
|
||||||
|
@ -968,7 +968,7 @@ print A::outfile, Left;
|
||||||
print A::outfile, A::left;
|
print A::outfile, A::left;
|
||||||
print A::outfile, Right;
|
print A::outfile, Right;
|
||||||
print A::outfile, A::right;
|
print A::outfile, A::right;
|
||||||
}, pred=anonymous-function
|
}, pred=lambda_<10906653936191056190>
|
||||||
{
|
{
|
||||||
print A::outfile, ============PREDICATE============;
|
print A::outfile, ============PREDICATE============;
|
||||||
print A::outfile, A::typ;
|
print A::outfile, A::typ;
|
||||||
|
@ -1198,7 +1198,7 @@ print A::outfile, Left;
|
||||||
print A::outfile, A::left;
|
print A::outfile, A::left;
|
||||||
print A::outfile, Right;
|
print A::outfile, Right;
|
||||||
print A::outfile, A::right;
|
print A::outfile, A::right;
|
||||||
}, pred=anonymous-function
|
}, pred=lambda_<10906653936191056190>
|
||||||
{
|
{
|
||||||
print A::outfile, ============PREDICATE============;
|
print A::outfile, ============PREDICATE============;
|
||||||
print A::outfile, A::typ;
|
print A::outfile, A::typ;
|
||||||
|
@ -1251,7 +1251,7 @@ print A::outfile, Left;
|
||||||
print A::outfile, A::left;
|
print A::outfile, A::left;
|
||||||
print A::outfile, Right;
|
print A::outfile, Right;
|
||||||
print A::outfile, A::right;
|
print A::outfile, A::right;
|
||||||
}, pred=anonymous-function
|
}, pred=lambda_<10906653936191056190>
|
||||||
{
|
{
|
||||||
print A::outfile, ============PREDICATE============;
|
print A::outfile, ============PREDICATE============;
|
||||||
print A::outfile, A::typ;
|
print A::outfile, A::typ;
|
||||||
|
@ -1304,7 +1304,7 @@ print A::outfile, Left;
|
||||||
print A::outfile, A::left;
|
print A::outfile, A::left;
|
||||||
print A::outfile, Right;
|
print A::outfile, Right;
|
||||||
print A::outfile, A::right;
|
print A::outfile, A::right;
|
||||||
}, pred=anonymous-function
|
}, pred=lambda_<10906653936191056190>
|
||||||
{
|
{
|
||||||
print A::outfile, ============PREDICATE============;
|
print A::outfile, ============PREDICATE============;
|
||||||
print A::outfile, A::typ;
|
print A::outfile, A::typ;
|
||||||
|
@ -1357,7 +1357,7 @@ print A::outfile, Left;
|
||||||
print A::outfile, A::left;
|
print A::outfile, A::left;
|
||||||
print A::outfile, Right;
|
print A::outfile, Right;
|
||||||
print A::outfile, A::right;
|
print A::outfile, A::right;
|
||||||
}, pred=anonymous-function
|
}, pred=lambda_<10906653936191056190>
|
||||||
{
|
{
|
||||||
print A::outfile, ============PREDICATE============;
|
print A::outfile, ============PREDICATE============;
|
||||||
print A::outfile, A::typ;
|
print A::outfile, A::typ;
|
||||||
|
@ -1410,7 +1410,7 @@ print A::outfile, Left;
|
||||||
print A::outfile, A::left;
|
print A::outfile, A::left;
|
||||||
print A::outfile, Right;
|
print A::outfile, Right;
|
||||||
print A::outfile, A::right;
|
print A::outfile, A::right;
|
||||||
}, pred=anonymous-function
|
}, pred=lambda_<10906653936191056190>
|
||||||
{
|
{
|
||||||
print A::outfile, ============PREDICATE============;
|
print A::outfile, ============PREDICATE============;
|
||||||
print A::outfile, A::typ;
|
print A::outfile, A::typ;
|
||||||
|
@ -1463,7 +1463,7 @@ print A::outfile, Left;
|
||||||
print A::outfile, A::left;
|
print A::outfile, A::left;
|
||||||
print A::outfile, Right;
|
print A::outfile, Right;
|
||||||
print A::outfile, A::right;
|
print A::outfile, A::right;
|
||||||
}, pred=anonymous-function
|
}, pred=lambda_<10906653936191056190>
|
||||||
{
|
{
|
||||||
print A::outfile, ============PREDICATE============;
|
print A::outfile, ============PREDICATE============;
|
||||||
print A::outfile, A::typ;
|
print A::outfile, A::typ;
|
||||||
|
|
13
testing/btest/language/lambda-record-field.zeek
Normal file
13
testing/btest/language/lambda-record-field.zeek
Normal file
|
@ -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");
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue