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..06286dfa24 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 @@ -765,6 +765,10 @@ expr: reporter->Error("index slice assignment may not be used" " in arbitrary expression contexts, only" " as a statement"); + // Type types cannot be reassigned because that could require parse-time + // control flow to resolve a variable's type + if ( $1->Tag() == EXPR_NAME && $1->GetType()->Tag() == TYPE_TYPE ) + $1->Error("type variables cannot be reassigned"); $$ = get_assign_expr({AdoptRef{}, $1}, {AdoptRef{}, $4}, in_init).release(); } @@ -1026,6 +1030,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 +1164,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 +1288,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,9 +1306,31 @@ 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) ) + if ( $1 && $1->GetType()->Tag() == TYPE_TYPE ) + $$ = $1->GetType()->AsTypeType()->GetType()->Ref(); + else if ( ! $1 || ! ($$ = $1->IsType() ? $1->GetType().get() : nullptr) ) { NullStmt here; if ( $1 ) diff --git a/testing/btest/Baseline/language.type-expr-assignment/.stderr b/testing/btest/Baseline/language.type-expr-assignment/.stderr new file mode 100644 index 0000000000..cc3e8e6964 --- /dev/null +++ b/testing/btest/Baseline/language.type-expr-assignment/.stderr @@ -0,0 +1,2 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +error in <...>/type-expr-assignment.zeek, line 8: type variables cannot be reassigned (str) diff --git a/testing/btest/Baseline/language.type-expr/.stdout b/testing/btest/Baseline/language.type-expr/.stdout new file mode 100644 index 0000000000..08b4f709b2 --- /dev/null +++ b/testing/btest/Baseline/language.type-expr/.stdout @@ -0,0 +1,6 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +hi there :) +hey!! +42 +[v=aoeu, valid=T] +type diff --git a/testing/btest/language/type-expr-assignment.zeek b/testing/btest/language/type-expr-assignment.zeek new file mode 100644 index 0000000000..7311fef4a7 --- /dev/null +++ b/testing/btest/language/type-expr-assignment.zeek @@ -0,0 +1,11 @@ +# @TEST-DOC: Ensure redefining a type expression ID is an error +# @TEST-EXEC-FAIL: zeek -b %INPUT +# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff .stderr + +event zeek_init() + { + local str = string; + str = count; + local my_string: str = "aoeu"; # This will still be a string + print my_string; + } diff --git a/testing/btest/language/type-expr.zeek b/testing/btest/language/type-expr.zeek new file mode 100644 index 0000000000..fe64754a74 --- /dev/null +++ b/testing/btest/language/type-expr.zeek @@ -0,0 +1,23 @@ +# @TEST-DOC: Test valid use of type expressions in scripts +# @TEST-EXEC: zeek -b %INPUT +# @TEST-EXEC: TEST_DIFF_CANONIFIER= btest-diff .stdout + +global global_str = string; +global my_global_string: global_str = "hey!!"; + +event zeek_init() + { + local str = string; + local my_string: str = "hi there :)"; + print my_string; + print my_global_string; + + local integer = int; + local my_int: integer = 41; + my_int += 1; + print my_int; + + # Try a couple of functions that take types + print from_json("\"aoeu\"", string); + print type_name(string); + }