From 0c27aa6c504c5e4408818b73413d8431160f3009 Mon Sep 17 00:00:00 2001 From: Evan Typanski Date: Fri, 24 Jan 2025 11:05:31 -0500 Subject: [PATCH] Make types into constants Closes #4173 This allows types to be used in expressions, but they can't be reassigned. Note that this was meant to be a special "type expression" - but that is unnecessary complexity. Type expressions would allow access to the type without going through its constant value, but the constant value is never changed, so it's simply a few more checks if necessary when functionality gets expanded. This way, ZAM and other code will not need updates, so the potential for increased work in the future is probably not worth caring about. --- NEWS | 3 + src/parse.y | 85 ++++++++++++------- .../btest/Baseline/language.type-expr/.stdout | 3 + testing/btest/language/type-expr.zeek | 10 +++ 4 files changed, 69 insertions(+), 32 deletions(-) create mode 100644 testing/btest/Baseline/language.type-expr/.stdout create mode 100644 testing/btest/language/type-expr.zeek diff --git a/NEWS b/NEWS index b0e99cb9c3..6a6c2a04be 100644 --- a/NEWS +++ b/NEWS @@ -16,6 +16,9 @@ New Functionality Zeek now raises a warning when a script declares these events while this option is set to true. +- Types can now be used as constants in Zeek script. This allows types to be + directly passed into BIFs without aliasing. + Changed Functionality --------------------- diff --git a/src/parse.y b/src/parse.y index eac4d95c4e..e02f2316e3 100644 --- a/src/parse.y +++ b/src/parse.y @@ -64,7 +64,7 @@ %type expr opt_expr rhs opt_init anonymous_function lambda_body index_slice opt_deprecated when_condition %type event %type stmt stmt_list func_body for_head -%type type opt_type enum_body +%type simple_type type opt_type enum_body %type func_hdr func_params %type type_list %type type_decl formal_args_decl @@ -1026,6 +1026,13 @@ expr: $$ = new ConstExpr({AdoptRef{}, $1}); } + | simple_type + { + set_location(@1); + TypePtr ty{AdoptRef(), $1}; + $$ = new ConstExpr(make_intrusive(ty, true)); + } + | '/' { begin_RE(); } TOK_PATTERN_TEXT TOK_PATTERN_END { set_location(@3); @@ -1153,63 +1160,75 @@ enum_body_elem: } ; -type: - TOK_BOOL { +simple_type: + TOK_BOOL + { set_location(@1); $$ = base_type(TYPE_BOOL)->Ref(); } - | TOK_INT { + | TOK_INT + { set_location(@1); $$ = base_type(TYPE_INT)->Ref(); } - | TOK_COUNT { + | TOK_COUNT + { set_location(@1); $$ = base_type(TYPE_COUNT)->Ref(); } - | TOK_DOUBLE { + | TOK_DOUBLE + { set_location(@1); $$ = base_type(TYPE_DOUBLE)->Ref(); } - | TOK_TIME { + | TOK_TIME + { set_location(@1); $$ = base_type(TYPE_TIME)->Ref(); } - | TOK_INTERVAL { + | TOK_INTERVAL + { set_location(@1); $$ = base_type(TYPE_INTERVAL)->Ref(); } - | TOK_STRING { + | TOK_STRING + { set_location(@1); $$ = base_type(TYPE_STRING)->Ref(); } - | TOK_PATTERN { + | TOK_PATTERN + { set_location(@1); $$ = base_type(TYPE_PATTERN)->Ref(); } - | TOK_PORT { + | TOK_PORT + { set_location(@1); $$ = base_type(TYPE_PORT)->Ref(); } - | TOK_ADDR { + | TOK_ADDR + { set_location(@1); $$ = base_type(TYPE_ADDR)->Ref(); } - | TOK_SUBNET { + | TOK_SUBNET + { set_location(@1); $$ = base_type(TYPE_SUBNET)->Ref(); } - | TOK_ANY { + | TOK_ANY + { set_location(@1); $$ = base_type(TYPE_ANY)->Ref(); } @@ -1265,24 +1284,6 @@ type: $$ = new VectorType({AdoptRef{}, $3}); } - | TOK_FUNCTION func_params - { - set_location(@1, @2); - $$ = $2; - } - - | TOK_EVENT '(' formal_args ')' - { - set_location(@1, @3); - $$ = new FuncType({AdoptRef{}, $3}, nullptr, FUNC_FLAVOR_EVENT); - } - - | TOK_HOOK '(' formal_args ')' - { - set_location(@1, @3); - $$ = new FuncType({AdoptRef{}, $3}, base_type(TYPE_BOOL), FUNC_FLAVOR_HOOK); - } - | TOK_FILE TOK_OF type { set_location(@1, @3); @@ -1301,6 +1302,26 @@ type: $$ = new OpaqueType($3); } +type: + simple_type + | TOK_FUNCTION func_params + { + set_location(@1, @2); + $$ = $2; + } + + | TOK_HOOK '(' formal_args ')' + { + set_location(@1, @3); + $$ = new FuncType({AdoptRef{}, $3}, base_type(TYPE_BOOL), FUNC_FLAVOR_HOOK); + } + + | TOK_EVENT '(' formal_args ')' + { + set_location(@1, @3); + $$ = new FuncType({AdoptRef{}, $3}, nullptr, FUNC_FLAVOR_EVENT); + } + | resolve_id { if ( ! $1 || ! ($$ = $1->IsType() ? $1->GetType().get() : nullptr) ) diff --git a/testing/btest/Baseline/language.type-expr/.stdout b/testing/btest/Baseline/language.type-expr/.stdout new file mode 100644 index 0000000000..893a7b5d8f --- /dev/null +++ b/testing/btest/Baseline/language.type-expr/.stdout @@ -0,0 +1,3 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +[v=aoeu, valid=T] +type diff --git a/testing/btest/language/type-expr.zeek b/testing/btest/language/type-expr.zeek new file mode 100644 index 0000000000..bf95e4b2df --- /dev/null +++ b/testing/btest/language/type-expr.zeek @@ -0,0 +1,10 @@ +# @TEST-DOC: Test valid use of type expressions in scripts +# @TEST-EXEC: zeek -b %INPUT +# @TEST-EXEC: TEST_DIFF_CANONIFIER= btest-diff .stdout + +event zeek_init() + { + # Try a couple of functions that take types + print from_json("\"aoeu\"", string); + print type_name(string); + }