From 00040534567fbc1125dd4e2ef8e82ad593409e70 Mon Sep 17 00:00:00 2001 From: Ge Wang Date: Thu, 31 Oct 2024 22:41:34 -0700 Subject: [PATCH] add Object.typeOfInstance(); update type_engine_init() to reset [user] namespace --- VERSIONS | 3 +++ examples/type/type_type.ck | 9 +++++++++ src/core/chuck_lang.cpp | 19 ++++++++++++++++++- src/core/chuck_lang.h | 1 + src/core/chuck_type.cpp | 18 ++++++++++++++---- src/test/01-Basic/255-type-of-instance.ck | 9 +++++++++ 6 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 src/test/01-Basic/255-type-of-instance.ck diff --git a/VERSIONS b/VERSIONS index f2d102343..f5d78679d 100644 --- a/VERSIONS +++ b/VERSIONS @@ -55,6 +55,9 @@ ChucK VERSIONS log suffice, assuming there are no filename conflicts elsewhere in the import paths) ****************************************************** +- (added) member function in Object: + Type Object.typeOfInstance() + Get the instanced type of this object. - (fixed) specific internal UGen connection error now handled without exiting - (fixed, windows) single letter filenames without extensions (e.g., "A") diff --git a/examples/type/type_type.ck b/examples/type/type_type.ck index 66f330d63..db57dfac9 100644 --- a/examples/type/type_type.ck +++ b/examples/type/type_type.ck @@ -118,3 +118,12 @@ for( int i; i < kids.size(); i++ ) { cherr <= "UAna: " <= kids[i].name() <= IO.newline(); } + +// instantiate a SinOsc; assign reference to a parent class +SinOsc theChild @=> UGen @ theParent; +// static typing: should be `SinOsc UGen` +<<< theChild.typeOf().name(), + theParent.typeOf().name() >>>; +// instanced typing: should be `SinOsc SinOsc` +<<< theChild.typeOfInstance().name(), + theParent.typeOfInstance().name() >>>; diff --git a/src/core/chuck_lang.cpp b/src/core/chuck_lang.cpp index 8ce42741f..22f855a5c 100644 --- a/src/core/chuck_lang.cpp +++ b/src/core/chuck_lang.cpp @@ -86,11 +86,16 @@ t_CKBOOL init_class_object( Chuck_Env * env, Chuck_Type * type ) func->doc = "output helpful information about a class or an instance thereof."; if( !type_engine_import_sfun( env, func ) ) goto error; - // add getType() // 1.5.0.0 + // add typeOf() // 1.5.0.0 func = make_new_sfun( "Type", "typeOf", object_typeInfo ); func->doc = "get the type of this object (or class)."; if( !type_engine_import_sfun( env, func ) ) goto error; + // add typeOfInstance() // 1.5.4.0 (nshaheed, ge) added + func = make_new_mfun( "Type", "typeOfInstance", object_typeInstanceInfo ); + func->doc = "get the instanced type of this object."; + if( !type_engine_import_mfun( env, func ) ) goto error; + // // add dump() // func = make_new_mfun( "void", "dump", object_dump ); // func->doc = "output current state of the object."; @@ -1633,6 +1638,18 @@ CK_DLL_SFUN( object_typeInfo ) } } +// get the instanced type info +CK_DLL_MFUN( object_typeInstanceInfo ) +{ + // get the object reference + Chuck_Object * self = SELF; + + // if null, return null + if( !self ) return; + + // return the type + RETURN->v_object = self->type_ref; +} // ctor CK_DLL_CTOR( ugen_ctor ) diff --git a/src/core/chuck_lang.h b/src/core/chuck_lang.h index 1a61fc79e..a3ff4b3b8 100644 --- a/src/core/chuck_lang.h +++ b/src/core/chuck_lang.h @@ -75,6 +75,7 @@ CK_DLL_MFUN( object_equals ); CK_DLL_MFUN( object_hashCode ); CK_DLL_MFUN( object_toString ); CK_DLL_MFUN( object_dump ); +CK_DLL_MFUN( object_typeInstanceInfo ); CK_DLL_SFUN( object_help ); CK_DLL_SFUN( object_typeInfo ); diff --git a/src/core/chuck_type.cpp b/src/core/chuck_type.cpp index e035f1dd2..9a44e9916 100644 --- a/src/core/chuck_type.cpp +++ b/src/core/chuck_type.cpp @@ -373,11 +373,11 @@ void Chuck_Env::clear_user_namespace() // clean up user namesapce CK_SAFE_RELEASE( user_nspc ); // load new user namespace - load_user_namespace(); + this->load_user_namespace(); // reset it this->reset(); // reset operator overloads, including public (env->reset() only resets local) - op_registry.reset2public(); + this->op_registry.reset2public(); // reset @import registry | 1.5.4.0 (ge) added this->compiler()->imports()->clearAllUserImports(); } @@ -564,6 +564,10 @@ t_CKBOOL type_engine_init( Chuck_Carrier * carrier ) EM_log( CK_LOG_HERALD, "adding base classes..." ); EM_pushlog(); + //------------------------- + // initialize internal classes; for now these are assumed to not error out + // NOTE: alternately, could test for return values and bailing out gracefully + // however, there may be inconstencies for cleaning up ChucK::init() fails //------------------------- // disable array type cache until ckt_array is initialized | 1.5.4.0 (ge) added env->arrayTypeCache()->enable( FALSE ); @@ -719,17 +723,23 @@ t_CKBOOL type_engine_init( Chuck_Carrier * carrier ) // initialize operator mappings if( !type_engine_init_op_overload( env ) ) return FALSE; - // create [user] namespace | 1.5.4.0 (ge) added/moved here + // clear/create/reset [user] namespace | 1.5.4.0 (ge) added/moved here // subsequent definitions (e.g., public classes) would be added // to this namespace, unless explicitly specified; // types added to the [user] namespace will be cleared during clearVM // whereas types in the [global] namespace persists - env->load_user_namespace(); + env->clear_user_namespace(); // pop indent level EM_poplog(); return TRUE; + +error: + EM_error2( 0, "(internal error) during type initialization..." ); + EM_error2( 0, "...bailing out; please contact the ChucK Team" ); + + return FALSE; } diff --git a/src/test/01-Basic/255-type-of-instance.ck b/src/test/01-Basic/255-type-of-instance.ck new file mode 100644 index 000000000..7a3a75f46 --- /dev/null +++ b/src/test/01-Basic/255-type-of-instance.ck @@ -0,0 +1,9 @@ +SinOsc foo @=> UGen @ bar; + +// static typing +if( foo.typeOf().name() != "SinOsc" && bar.typeOf().name() != "UGen" ) +{ <<< "error" >>>; me.exit(); } + +// get the instanced type +if( foo.typeOfInstance().name() == "SinOsc" && + bar.typeOfInstance().name() == "SinOsc" ) <<< "success" >>>;