mirror of
https://github.com/zeek/zeek.git
synced 2025-10-17 14:08:20 +00:00
parsing of new []-style captures, and creation of associated data structures
This commit is contained in:
parent
f673f85acc
commit
955384291d
3 changed files with 107 additions and 13 deletions
18
src/Type.cc
18
src/Type.cc
|
@ -622,6 +622,8 @@ FuncType::FuncType(RecordTypePtr arg_args,
|
|||
}
|
||||
|
||||
prototypes.emplace_back(Prototype{false, "", args, std::move(offsets)});
|
||||
|
||||
captures = nullptr;
|
||||
}
|
||||
|
||||
TypePtr FuncType::ShallowClone()
|
||||
|
@ -632,6 +634,7 @@ TypePtr FuncType::ShallowClone()
|
|||
f->yield = yield;
|
||||
f->flavor = flavor;
|
||||
f->prototypes = prototypes;
|
||||
f->captures = captures;
|
||||
return f;
|
||||
}
|
||||
|
||||
|
@ -654,7 +657,15 @@ string FuncType::FlavorString() const
|
|||
}
|
||||
}
|
||||
|
||||
FuncType::~FuncType() = default;
|
||||
FuncType::~FuncType()
|
||||
{
|
||||
if ( captures )
|
||||
{
|
||||
for ( auto c : *captures )
|
||||
delete c;
|
||||
delete captures;
|
||||
}
|
||||
}
|
||||
|
||||
int FuncType::MatchesIndex(detail::ListExpr* const index) const
|
||||
{
|
||||
|
@ -698,6 +709,11 @@ bool FuncType::CheckArgs(const std::vector<TypePtr>& args,
|
|||
return success;
|
||||
}
|
||||
|
||||
void FuncType::SetCaptures(std::vector<Capture*>* _captures)
|
||||
{
|
||||
captures = _captures;
|
||||
}
|
||||
|
||||
void FuncType::Describe(ODesc* d) const
|
||||
{
|
||||
if ( d->IsReadable() )
|
||||
|
|
26
src/Type.h
26
src/Type.h
|
@ -10,6 +10,7 @@
|
|||
#include <optional>
|
||||
|
||||
#include "zeek/Obj.h"
|
||||
#include "zeek/ID.h"
|
||||
#include "zeek/Attr.h"
|
||||
#include "zeek/ZeekList.h"
|
||||
#include "zeek/IntrusivePtr.h"
|
||||
|
@ -540,6 +541,29 @@ public:
|
|||
const std::vector<Prototype>& Prototypes() const
|
||||
{ return prototypes; }
|
||||
|
||||
/**
|
||||
* A single lambda "capture" (outer variable used in a lambda's body).
|
||||
*/
|
||||
struct Capture {
|
||||
detail::IDPtr id;
|
||||
bool deep_copy;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets this function's set of captures. Only valid for lambdas.
|
||||
*
|
||||
* @param captures if non-nil, a list of the lambda's captures
|
||||
*/
|
||||
void SetCaptures(std::vector<Capture*>* captures);
|
||||
|
||||
/**
|
||||
* Returns the captures declared for this function, or nil if none.
|
||||
*
|
||||
* @return a vector giving the captures
|
||||
*/
|
||||
const std::vector<Capture*>* GetCaptures() const
|
||||
{ return captures; }
|
||||
|
||||
protected:
|
||||
friend FuncTypePtr make_intrusive<FuncType>();
|
||||
|
||||
|
@ -549,6 +573,8 @@ protected:
|
|||
TypePtr yield;
|
||||
FunctionFlavor flavor;
|
||||
std::vector<Prototype> prototypes;
|
||||
|
||||
std::vector<Capture*>* captures; // if nil then no captures specified
|
||||
};
|
||||
|
||||
class TypeType final : public Type {
|
||||
|
|
76
src/parse.y
76
src/parse.y
|
@ -51,9 +51,9 @@
|
|||
%left '$' '[' ']' '(' ')' TOK_HAS_FIELD TOK_HAS_ATTR
|
||||
%nonassoc TOK_AS TOK_IS
|
||||
|
||||
%type <b> opt_no_test opt_no_test_block TOK_PATTERN_END
|
||||
%type <b> opt_no_test opt_no_test_block TOK_PATTERN_END opt_deep
|
||||
%type <str> TOK_ID TOK_PATTERN_TEXT
|
||||
%type <id> local_id global_id def_global_id event_id global_or_event_id resolve_id begin_func case_type
|
||||
%type <id> local_id global_id def_global_id event_id global_or_event_id resolve_id begin_lambda case_type
|
||||
%type <id_l> local_id_list case_type_list
|
||||
%type <ic> init_class
|
||||
%type <expr> opt_init
|
||||
|
@ -72,6 +72,8 @@
|
|||
%type <case_l> case_list
|
||||
%type <attr> attr
|
||||
%type <attr_l> attr_list opt_attr
|
||||
%type <capture> capture
|
||||
%type <captures> capture_list opt_captures
|
||||
|
||||
%{
|
||||
#include <stdlib.h>
|
||||
|
@ -254,6 +256,8 @@ static bool expr_is_table_type_name(const zeek::detail::Expr* expr)
|
|||
zeek::detail::Attr* attr;
|
||||
std::vector<zeek::detail::AttrPtr>* attr_l;
|
||||
zeek::detail::AttrTag attrtag;
|
||||
zeek::FuncType::Capture* capture;
|
||||
std::vector<zeek::FuncType::Capture*>* captures;
|
||||
}
|
||||
|
||||
%%
|
||||
|
@ -532,14 +536,10 @@ expr:
|
|||
$$ = new zeek::detail::FieldAssignExpr($2, {zeek::AdoptRef{}, $4});
|
||||
}
|
||||
|
||||
| '$' TOK_ID func_params '='
|
||||
| '$' TOK_ID begin_lambda '='
|
||||
{
|
||||
func_hdr_location = @1;
|
||||
auto func_id = zeek::detail::current_scope()->GenerateTemporary("anonymous-function");
|
||||
func_id->SetInferReturnType(true);
|
||||
zeek::detail::begin_func(std::move(func_id), zeek::detail::current_module.c_str(),
|
||||
zeek::FUNC_FLAVOR_FUNCTION, false,
|
||||
{zeek::AdoptRef{}, $3});
|
||||
$3->SetInferReturnType(true);
|
||||
}
|
||||
lambda_body
|
||||
{
|
||||
|
@ -1306,19 +1306,71 @@ lambda_body:
|
|||
;
|
||||
|
||||
anonymous_function:
|
||||
TOK_FUNCTION begin_func lambda_body
|
||||
TOK_FUNCTION begin_lambda lambda_body
|
||||
{ $$ = $3; }
|
||||
;
|
||||
|
||||
begin_func:
|
||||
func_params
|
||||
begin_lambda:
|
||||
opt_captures func_params
|
||||
{
|
||||
auto id = zeek::detail::current_scope()->GenerateTemporary("anonymous-function");
|
||||
zeek::detail::begin_func(id, zeek::detail::current_module.c_str(), zeek::FUNC_FLAVOR_FUNCTION, 0, {zeek::AdoptRef{}, $1});
|
||||
zeek::detail::begin_func(id, zeek::detail::current_module.c_str(), zeek::FUNC_FLAVOR_FUNCTION, false, {zeek::AdoptRef{}, $2});
|
||||
$2->SetCaptures($1);
|
||||
$$ = id.release();
|
||||
}
|
||||
;
|
||||
|
||||
opt_captures:
|
||||
'[' capture_list ']'
|
||||
{ $$ = $2; }
|
||||
|
|
||||
{ $$ = nullptr; }
|
||||
;
|
||||
|
||||
capture_list:
|
||||
capture_list ',' capture
|
||||
{ $1->push_back($3); }
|
||||
| capture
|
||||
{
|
||||
$$ = new std::vector<zeek::FuncType::Capture*>;
|
||||
$$->push_back($1);
|
||||
}
|
||||
;
|
||||
|
||||
capture:
|
||||
opt_deep TOK_ID
|
||||
{
|
||||
zeek::detail::set_location(@2);
|
||||
auto id = zeek::detail::lookup_ID($2,
|
||||
zeek::detail::current_module.c_str());
|
||||
|
||||
if ( ! id )
|
||||
zeek::reporter->Error("no such local identifier: %s", $2);
|
||||
else if ( id->IsType() )
|
||||
{
|
||||
zeek::reporter->Error("cannot specify type in capture: %s", $2);
|
||||
id = nullptr;
|
||||
}
|
||||
else if ( id->IsGlobal() )
|
||||
{
|
||||
zeek::reporter->Error("cannot specify global in capture: %s", $2);
|
||||
id = nullptr;
|
||||
}
|
||||
|
||||
delete [] $2;
|
||||
|
||||
$$ = new zeek::FuncType::Capture;
|
||||
$$->id = id;
|
||||
$$->deep_copy = $1;
|
||||
}
|
||||
;
|
||||
|
||||
opt_deep: TOK_COPY
|
||||
{ $$ = true; }
|
||||
|
|
||||
{ $$ = false; }
|
||||
;
|
||||
|
||||
func_params:
|
||||
'(' formal_args ')' ':' type
|
||||
{ $$ = new zeek::FuncType({zeek::AdoptRef{}, $2}, {zeek::AdoptRef{}, $5}, zeek::FUNC_FLAVOR_FUNCTION); }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue