@@ -352,6 +352,10 @@ impl Engine {
352352 ) -> RhaiResultOf < ( Dynamic , bool ) > {
353353 self . track_operation ( global, pos) ?;
354354
355+ if let Some ( result) = self . exec_syntactic_fn_call ( global, caches, name, args, pos) ? {
356+ return Ok ( ( result, false ) ) ;
357+ }
358+
355359 // Check if function access already in the cache
356360 let local_entry = & mut None ;
357361 let a = Some ( & mut * args) ;
@@ -577,12 +581,14 @@ impl Engine {
577581 }
578582 }
579583
580- /// Implement built-in functions.
584+ /// Implement built-in syntactic functions.
581585 ///
582586 /// These are functions (e.g. `type_of`, `is_shared`) that are not registered as normal
583587 /// functions but provided by Rhai.
584588 pub ( crate ) fn exec_syntactic_fn_call (
585589 & self ,
590+ global : & mut GlobalRuntimeState ,
591+ caches : & mut Caches ,
586592 fn_name : & str ,
587593 args : & FnCallArgs ,
588594 pos : Position ,
@@ -593,20 +599,68 @@ impl Engine {
593599 let typ = self . get_interned_string ( self . map_type_name ( args[ 0 ] . type_name ( ) ) ) ;
594600 return Ok ( Some ( typ. into ( ) ) ) ;
595601 }
602+ KEYWORD_TYPE_OF => ( ) ,
596603
604+ // Handle is_shared()
597605 #[ cfg( not( feature = "no_closure" ) ) ]
598606 crate :: engine:: KEYWORD_IS_SHARED if args. len ( ) == 1 => {
599607 return Ok ( Some ( args[ 0 ] . is_shared ( ) . into ( ) ) )
600608 }
601609 #[ cfg( not( feature = "no_closure" ) ) ]
602610 crate :: engine:: KEYWORD_IS_SHARED => ( ) ,
603611
612+ // Handle is_def_fn()
613+ #[ cfg( not( feature = "no_function" ) ) ]
614+ crate :: engine:: KEYWORD_IS_DEF_FN if args. len ( ) == 2 => {
615+ let fn_name = args[ 0 ]
616+ . as_immutable_string_ref ( )
617+ . map_err ( |typ| self . make_type_mismatch_err :: < ImmutableString > ( typ, pos) ) ?;
618+ let num_params = args[ 1 ]
619+ . as_int ( )
620+ . map_err ( |typ| self . make_type_mismatch_err :: < crate :: INT > ( typ, pos) ) ?;
621+
622+ return Ok ( Some (
623+ usize:: try_from ( num_params)
624+ . map ( |num_params| {
625+ let hash_script = calc_fn_hash ( None , & fn_name, num_params) ;
626+ self . has_script_fn ( global, caches, hash_script) . into ( )
627+ } )
628+ . unwrap_or ( Dynamic :: FALSE ) ,
629+ ) ) ;
630+ }
631+ #[ cfg( not( feature = "no_function" ) ) ]
632+ #[ cfg( not( feature = "no_object" ) ) ]
633+ crate :: engine:: KEYWORD_IS_DEF_FN if args. len ( ) == 3 => {
634+ let this_type = args[ 0 ]
635+ . as_immutable_string_ref ( )
636+ . map_err ( |typ| self . make_type_mismatch_err :: < ImmutableString > ( typ, pos) ) ?;
637+ let fn_name = args[ 1 ]
638+ . as_immutable_string_ref ( )
639+ . map_err ( |typ| self . make_type_mismatch_err :: < ImmutableString > ( typ, pos) ) ?;
640+ let num_params = args[ 2 ]
641+ . as_int ( )
642+ . map_err ( |typ| self . make_type_mismatch_err :: < crate :: INT > ( typ, pos) ) ?;
643+
644+ return Ok ( Some (
645+ usize:: try_from ( num_params)
646+ . map ( |num_params| {
647+ let hash_script = crate :: calc_typed_method_hash (
648+ calc_fn_hash ( None , & fn_name, num_params) ,
649+ & this_type,
650+ ) ;
651+ self . has_script_fn ( global, caches, hash_script) . into ( )
652+ } )
653+ . unwrap_or ( Dynamic :: FALSE ) ,
654+ ) ) ;
655+ }
604656 #[ cfg( not( feature = "no_function" ) ) ]
605657 crate :: engine:: KEYWORD_IS_DEF_FN => ( ) ,
606658
607- KEYWORD_TYPE_OF | KEYWORD_FN_PTR | KEYWORD_EVAL | KEYWORD_IS_DEF_VAR
608- | KEYWORD_FN_PTR_CALL | KEYWORD_FN_PTR_CURRY => ( ) ,
659+ // Other syntactic functions
660+ KEYWORD_IS_DEF_VAR | KEYWORD_FN_PTR | KEYWORD_EVAL | KEYWORD_FN_PTR_CALL
661+ | KEYWORD_FN_PTR_CURRY => ( ) ,
609662
663+ // Normal functions
610664 _ => return Ok ( None ) ,
611665 }
612666
@@ -637,10 +691,8 @@ impl Engine {
637691 pos : Position ,
638692 ) -> RhaiResultOf < ( Dynamic , bool ) > {
639693 // These may be redirected from method style calls.
640- if hashes. is_native_only ( ) {
641- if let Some ( result) = self . exec_syntactic_fn_call ( fn_name, args, pos) ? {
642- return Ok ( ( result, false ) ) ;
643- }
694+ if let Some ( result) = self . exec_syntactic_fn_call ( global, caches, fn_name, args, pos) ? {
695+ return Ok ( ( result, false ) ) ;
644696 }
645697
646698 // Check for data race.
@@ -1314,74 +1366,6 @@ impl Engine {
13141366 return Ok ( arg_value. is_shared ( ) . into ( ) ) ;
13151367 }
13161368
1317- // Handle is_def_fn(fn_name, arity)
1318- #[ cfg( not( feature = "no_function" ) ) ]
1319- crate :: engine:: KEYWORD_IS_DEF_FN if num_args == 2 => {
1320- let first = first_arg. unwrap ( ) ;
1321- let ( arg_value, arg_pos) =
1322- self . get_arg_value ( global, caches, scope, this_ptr. as_deref_mut ( ) , first) ?;
1323-
1324- let fn_name = arg_value
1325- . into_immutable_string ( )
1326- . map_err ( |typ| self . make_type_mismatch_err :: < ImmutableString > ( typ, arg_pos) ) ?;
1327-
1328- let ( arg_value, arg_pos) =
1329- self . get_arg_value ( global, caches, scope, this_ptr, & args_expr[ 0 ] ) ?;
1330-
1331- let num_params = arg_value
1332- . as_int ( )
1333- . map_err ( |typ| self . make_type_mismatch_err :: < crate :: INT > ( typ, arg_pos) ) ?;
1334-
1335- return Ok ( usize:: try_from ( num_params)
1336- . map ( |num_params| {
1337- let hash_script = calc_fn_hash ( None , & fn_name, num_params) ;
1338- self . has_script_fn ( global, caches, hash_script) . into ( )
1339- } )
1340- . unwrap_or ( Dynamic :: FALSE ) ) ;
1341- }
1342-
1343- // Handle is_def_fn(this_type, fn_name, arity)
1344- #[ cfg( not( feature = "no_function" ) ) ]
1345- #[ cfg( not( feature = "no_object" ) ) ]
1346- crate :: engine:: KEYWORD_IS_DEF_FN if num_args == 3 => {
1347- let first = first_arg. unwrap ( ) ;
1348- let ( arg_value, arg_pos) =
1349- self . get_arg_value ( global, caches, scope, this_ptr. as_deref_mut ( ) , first) ?;
1350-
1351- let this_type = arg_value
1352- . into_immutable_string ( )
1353- . map_err ( |typ| self . make_type_mismatch_err :: < ImmutableString > ( typ, arg_pos) ) ?;
1354-
1355- let ( arg_value, arg_pos) = self . get_arg_value (
1356- global,
1357- caches,
1358- scope,
1359- this_ptr. as_deref_mut ( ) ,
1360- & args_expr[ 0 ] ,
1361- ) ?;
1362-
1363- let fn_name = arg_value
1364- . into_immutable_string ( )
1365- . map_err ( |typ| self . make_type_mismatch_err :: < ImmutableString > ( typ, arg_pos) ) ?;
1366-
1367- let ( arg_value, arg_pos) =
1368- self . get_arg_value ( global, caches, scope, this_ptr, & args_expr[ 1 ] ) ?;
1369-
1370- let num_params = arg_value
1371- . as_int ( )
1372- . map_err ( |typ| self . make_type_mismatch_err :: < crate :: INT > ( typ, arg_pos) ) ?;
1373-
1374- return Ok ( usize:: try_from ( num_params)
1375- . map ( |num_params| {
1376- let hash_script = crate :: calc_typed_method_hash (
1377- calc_fn_hash ( None , & fn_name, num_params) ,
1378- & this_type,
1379- ) ;
1380- self . has_script_fn ( global, caches, hash_script) . into ( )
1381- } )
1382- . unwrap_or ( Dynamic :: FALSE ) ) ;
1383- }
1384-
13851369 // Handle is_def_var(fn_name)
13861370 KEYWORD_IS_DEF_VAR if num_args == 1 => {
13871371 let arg = first_arg. unwrap ( ) ;
0 commit comments