Kaynağa Gözat

mx2cc tweaks.

Mark Sibly 7 yıl önce
ebeveyn
işleme
4daa138be2

+ 4 - 1
modules/monkey/native/bbtypeinfo.cpp

@@ -89,7 +89,10 @@ int bbTypeInfo::getEnum( bbVariant ){
 }
 
 bbVariant bbTypeInfo::nullValue(){
-	bbRuntimeError( "Type '"+name+"' has no null value" );
+	return {};
+}
+
+bbVariant bbTypeInfo::newArray( int length ){
 	return {};
 }
 

+ 2 - 1
modules/monkey/native/bbtypeinfo.h

@@ -47,7 +47,8 @@ struct bbTypeInfo{
 	virtual int getEnum( bbVariant );
 	
 	virtual bbVariant nullValue();
-	
+
+	virtual bbVariant newArray( int length );
 	
 	bbDeclInfo *getDecl( bbString name );
 	

+ 43 - 8
modules/monkey/native/bbtypeinfo_t.h

@@ -4,19 +4,35 @@
 
 #include "bbtypeinfo.h"
 
-template<class T> struct bbPrimTypeInfo : public bbTypeInfo{
+template<class T> struct bbBaseTypeInfo : public bbTypeInfo{
+
+	bbVariant nullValue(){
+		return bbVariant( T{} );
+	}
+
+	bbVariant newArray( int length ){
+		return bbVariant( bbArray<T>( length ) );
+	}
+};
+
+template<class T> struct bbPrimTypeInfo : public bbBaseTypeInfo<T>{
 
 	bbPrimTypeInfo( bbString name ){
 		this->name=name;
 		this->kind="Primitive";
 	}
-	
+/*
 	bbVariant nullValue(){
 		return bbVariant( T{} );
 	}
+
+	bbVariant newArray( int length ){
+		return bbVariant( bbArray<T>{ length } );
+	}
+*/
 };
 
-template<class T> struct bbPointerTypeInfo : public bbTypeInfo{
+template<class T> struct bbPointerTypeInfo : public bbBaseTypeInfo<T*>{
 
 	bbPointerTypeInfo(){
 		this->name=bbGetType<T>()->name+" Ptr";
@@ -26,13 +42,18 @@ template<class T> struct bbPointerTypeInfo : public bbTypeInfo{
 	bbTypeInfo *pointeeType(){
 		return bbGetType<T>();
 	}
-
+/*	
 	bbVariant nullValue(){
 		return bbVariant( (T*)0 );
 	}
+	
+	bbVariant newArray( int length ){
+		return bbVariant( bbArray<T*>{ length } );
+	}
+*/
 };
 
-template<class T,int D> struct bbArrayTypeInfo : public bbTypeInfo{
+template<class T,int D> struct bbArrayTypeInfo : public bbTypeInfo{	//bbBaseTypeInfo<bbArray<T,D>>{
 
 	bbArrayTypeInfo(){
 		this->name=bbGetType<T>()->name+"["+BB_T(",").dup(D-1)+"]";
@@ -50,10 +71,14 @@ template<class T,int D> struct bbArrayTypeInfo : public bbTypeInfo{
 	bbVariant nullValue(){
 		return bbVariant( bbArray<T,D>{} );
 	}
-	
+/*
+	bbVariant newArray( int length )
+		return bbVariant( bbArray<T>{ length } );
+	}
+*/
 };
 
-template<class R,class...A> struct bbFunctionTypeInfo : public bbTypeInfo{
+template<class R,class...A> struct bbFunctionTypeInfo : public bbTypeInfo{	//bbBaseTypeInfo<bbFunction<R(A...)>>{
 
 	bbFunctionTypeInfo(){
 		this->name=bbGetType<R>()->name+"("+BB_T(",").join( bbArray<bbString>( { bbGetType<A>()->name... },int(sizeof...(A)) ) )+")";
@@ -71,9 +96,14 @@ template<class R,class...A> struct bbFunctionTypeInfo : public bbTypeInfo{
 	bbVariant nullValue(){
 		return bbVariant( bbFunction<R(A...)>{} );
 	}
+/*
+	bbVariant newArray( int length ){
+		return bbVariant( bbArray<bbFunction<R(A...)>>{ length } );
+	}
+*/
 };
 
-template<class...A> struct bbFunctionTypeInfo<void,A...> : public bbTypeInfo{
+template<class...A> struct bbFunctionTypeInfo<void,A...> : public bbTypeInfo{	//bbBaseTypeInfo<bbFunction<void(A...)>>{
 
 	bbFunctionTypeInfo(){
 		this->name=BB_T("Void(")+BB_T(",").join( bbArray<bbString>( { bbGetType<A>()->name... },int(sizeof...(A)) ) )+")";
@@ -91,6 +121,11 @@ template<class...A> struct bbFunctionTypeInfo<void,A...> : public bbTypeInfo{
 	bbVariant nullValue(){
 		return bbVariant( bbFunction<void(A...)>{} );
 	}
+/*
+	bbVariant newArray( int length ){
+		return bbVariant( bbArray<bbFunction<void(A...)>>{ length } );
+	}	
+*/
 };
 
 inline bbTypeInfo *bbGetType( bbObject* const& ){

+ 30 - 0
modules/monkey/native/bbtypes.h

@@ -54,4 +54,34 @@ template<class X,class Y> int bbCompare( const X &x,const Y &y ){
 	return y<x;
 }
 
+#ifdef NDEBUG
+
+#define BB_CLASS(X) struct X; \
+bbTypeInfo *bbGetType(X*const&);
+
+#define BB_STRUCT(X) struct X; \
+bbTypeInfo *bbGetType(X const&); 
+
+#define BB_ENUM(X) enum class X; \
+bbTypeInfo *bbGetType(X const&);
+
+#else
+ 
+#define BB_CLASS(X) struct X; \
+bbTypeInfo *bbGetType(X*const&); \
+bbString bbDBType(X**); \
+bbString bbDBValue(X**);
+
+#define BB_STRUCT(X) struct X; \
+bbTypeInfo *bbGetType(X const&); \
+bbString bbDBType(X*); \
+bbString bbDBValue(X*);
+
+#define BB_ENUM(X) enum class X; \
+bbTypeInfo *bbGetType(X const&); \
+bbString bbDBType(X*); \
+bbString bbDBValue(X*);
+
+#endif
+
 #endif

+ 95 - 60
modules/monkey/native/bbvariant.h

@@ -5,25 +5,18 @@
 #include "bbtypeinfo.h"
 
 struct bbVariant{
-
-	template<class T,class R=typename T::bb_object_type> static bbObject *toObject( T *p ){
-		return dynamic_cast<bbObject*>( p );
-	}
-
-	template<class T> static bbObject *toObject( T const& ){
-		bbRuntimeError( "Variant cast failed" );
-		return 0;
-	}
-
-	template<class T,class C> static T castObject( bbObject *p,typename C::bb_object_type d=0 ){
-		return dynamic_cast<T>( p );
-	}
-
-	template<class T,class C> static T castObject(...){
-		bbRuntimeError( "Variant cast failed" );
-		return {};
-	}
 	
+	template<class T> static bbObject *_getObject( T const& ){ bbRuntimeError( "Variant cast failed" );return 0; }
+	template<class T,class R=typename T::bb_object_type> static bbObject *_getObject( T *p ){ return dynamic_cast<bbObject*>( p ); }
+	
+	template<class T> static int _getArrayLength( T const& ){ bbRuntimeError( "Variant is not an array" );return 0; }
+	template<class T> static bbVariant _getArrayElement( T const&,int index ){ bbRuntimeError( "Variant is not an array" );return {}; }
+	template<class T> static void _setArrayElement( T const&,int index,bbVariant value ){ bbRuntimeError( "Variant is not an array" ); }
+	
+	template<class T,int D> static int _getArrayLength( bbArray<T,D> v ){ return v.length(); }
+	template<class T,int D> static bbVariant _getArrayElement( bbArray<T,D> v,int index );
+	template<class T,int D> static void _setArrayElement( bbArray<T,D> v,int index,bbVariant value );
+ 
 	struct RepBase{
 	
 		int _refs=1;
@@ -42,10 +35,22 @@ struct bbVariant{
 			return 0;
 		}
 		
+		virtual int getArrayLength(){ 
+			return 0; 
+		}
+		
+		virtual bbVariant getArrayElement( int index ){
+			return {}; 
+		}
+		
+		virtual void setArrayElement( int index,bbVariant value ){
+		}
+		
 		virtual bbVariant invoke( bbArray<bbVariant> params ){
 			bbRuntimeError( "Variant is not invokable" );
 			return {};
 		}
+		
 	};
 	
 	template<class T> struct Rep : public RepBase{
@@ -64,8 +69,21 @@ struct bbVariant{
 		}
 		
 		virtual bbObject *getObject(){
-			return toObject( value );
+			return _getObject( value );
 		}
+		
+		virtual int getArrayLength(){
+			return _getArrayLength( value );
+		}
+		
+		virtual bbVariant getArrayElement( int index ){
+			return _getArrayElement( value,index );
+		}
+		
+		virtual void setArrayElement( int index,bbVariant evalue ){
+			_setArrayElement( value,index,evalue );
+		}
+
 	};
 	
 	static RepBase _null;
@@ -106,79 +124,96 @@ struct bbVariant{
 		return *this;
 	}
 	
-	bbTypeInfo *getType()const{
-		
-		return _rep->getType();
-	}
-	
-	bbTypeInfo *getDynamicType()const{
-	
-		if( bbObject *obj=_rep->getObject() ) return obj->typeof();
-		
-		return _rep->getType();
+	template<class T,class R=typename T::bb_object_type> T *_get( T* const& )const{
+		bbObject *obj=_rep->getObject();
+		return dynamic_cast<T*>( obj );
 	}
 	
-	operator bool()const{
-		
-		return _rep!=&_null;
+	template<class T> T _get( T const& )const{
+		bbRuntimeError( "Variant cast failed" );
+		return {};
 	}
 	
 	template<class T> T get()const{
-	
-		Rep<T> *p=dynamic_cast<Rep<T>*>( _rep );
-		
-		if( p ) return p->value;
-		
-//		bbTypeInfo *type=bbGetType<T>();
-		
-//		if( type->kind=="Class" ){
-		
-			bbObject *obj=_rep->getObject();
-			
-			typedef typename detail::remove_pointer<T>::type C;
-			
-			return castObject<T,C>( obj );
-//		}
-		
-		bbRuntimeError( "Variant cast failed" );
-		
-		return T{};
+		Rep<T> *r=dynamic_cast<Rep<T>*>( _rep );
+		if( !r ) return _get( *(T*)0 );
+		return r->value;
 	}
 	
-	template<class T> T *_ref( typename T::bb_object_type *p=0 )const{
-	
+	template<class T,class R=typename T::bb_object_type> T *_ref( T** )const{
 		return get<T*>();
 	}
 	
-	template<class T> T *_ref( T *p=0 )const{
-	
+	template<class T> T *_ref( T* )const{
 		Rep<T> *r=dynamic_cast<Rep<T>*>( _rep );
-		
 		if( !r ) bbRuntimeError( "Variant cast failed" );
-		
 		return &r->value;
 	}
 	
 	template<class T> T *ref()const{
+		return _ref<T>( 0 );
+	}
+
+	/*
+	template<class T> T *_ref( typename T::bb_object_type *p )const{
+		return get<T>();
+	}
 	
+	template<class T> T *_ref( T *p )const{
+		Rep<T> *r=dynamic_cast<Rep<T>*>( _rep );
+		if( !r ) bbRuntimeError( "Variant cast failed" );
+		return &r->value;
+	}
+	
+	template<class T> T *ref()const{
 		return _ref<T>( 0 );
 	}
+	*/
 	
-	int enumValue()const{
+	bbTypeInfo *getType()const{
+		return _rep->getType();
+	}
+	
+	bbTypeInfo *getDynamicType()const{
+		if( bbObject *obj=_rep->getObject() ) return obj->typeof();
+		return _rep->getType();
+	}
 	
+	operator bool()const{
+		return _rep!=&_null;
+	}
+	
+	int enumValue()const{
 		return getType()->getEnum( *this );
 	}
+
+	int getArrayLength(){
+		return _rep->getArrayLength();
+	}
+	
+	bbVariant getArrayElement( int index ){
+		return _rep->getArrayElement( index );
+	}
 	
+	void setArrayElement( int index,bbVariant value ){
+		_rep->setArrayElement( index,value );
+	}
 };
 
 inline void bbGCMark( const bbVariant &v ){
-
 	v._rep->gcMark();
 }
 
 inline int bbCompare( const bbVariant &x,const bbVariant &y ){
-
 	return y._rep>x._rep ? -1 : x._rep>y._rep;
 }
 
+template<class T,int D> bbVariant bbVariant::_getArrayElement( bbArray<T,D> v,int index ){
+	return bbVariant( v[index] );
+}
+
+template<class T,int D> void bbVariant::_setArrayElement( bbArray<T,D> v,int index,bbVariant value ){
+	v[index]=value.get<T>();
+}
+
 #endif

+ 29 - 0
modules/monkey/types.monkey2

@@ -430,6 +430,29 @@ Struct @Variant="bbVariant"
 	
 	#end
 	Property EnumValue:Int()="enumValue"
+		
+	#rem monkeydoc Gets the length of an array.
+	
+	The type of the variant must be an array type, or a runtime error will occur.
+	
+	#end
+	Method GetArrayLength:Int()="getArrayLength"
+		
+	#rem monkeydoc Gets an element from an array.
+	
+	The type of the variant must be an array type, or a runtime error will occur.
+	
+	#end
+	Method GetArrayElement:Variant( index:Int )="getArrayElement"
+		
+	#rem monkeydoc Sets an element of an array.
+	
+	The type of the variant must be an array type, or a runtime error will occur.
+	
+	#end
+	Method SetArrayElement( index:Int,value:Variant )="setArrayElement"
+		
+	
 End
 
 #rem monkeydoc Primtive array type.
@@ -661,6 +684,12 @@ Class @TypeInfo Extends Void="bbTypeInfo"
 	
 	#end
 	Method MakeEnum:Variant( enumValue:Int )="makeEnum"
+		
+	
+	#rem monkeydoc Creates a new array of this type.
+	#end
+	Method NewArray:Variant( length:Int )="newArray"
+
 
 	#rem monkeydoc Gets a user defined type by name.