浏览代码

Added TypeInfo.NullValue.

Mark Sibly 7 年之前
父节点
当前提交
aa254e4af3

+ 1 - 1
modules/monkey/native/bbmonkey.h

@@ -12,7 +12,7 @@
 #include "bbfunction.h"
 #include "bbobject.h"
 #include "bbvariant.h"
-#include "bbtypeinfo.h"
+#include "bbtypeinfo_t.h"
 #include "bbdeclinfo.h"
 
 extern int bb_argc;

+ 4 - 0
modules/monkey/native/bbstring.h

@@ -275,6 +275,8 @@ class bbCString{
 	
 	public:
 
+	bbCString():_data(0){}
+	
 	bbCString( const bbString &str );
 	
 	~bbCString();
@@ -291,6 +293,8 @@ class bbWString{
 	
 	public:
 	
+	bbWString():_data(0){}
+	
 	bbWString( const bbString &str );
 	
 	~bbWString();

+ 6 - 0
modules/monkey/native/bbtypeinfo.cpp

@@ -1,4 +1,5 @@
 
+#include "bbvariant.h"
 #include "bbtypeinfo_r.h"
 #include "bbdeclinfo.h"
 
@@ -87,6 +88,11 @@ int bbTypeInfo::getEnum( bbVariant ){
 	return {};
 }
 
+bbVariant bbTypeInfo::nullValue(){
+	bbRuntimeError( "Type '"+name+"' has no null value" );
+	return {};
+}
+
 bbDeclInfo *bbTypeInfo::getDecl( bbString name ){
 
 	bbArray<bbDeclInfo*> decls=getDecls();

+ 6 - 0
modules/monkey/native/bbtypeinfo.h

@@ -46,6 +46,8 @@ struct bbTypeInfo{
 	
 	virtual int getEnum( bbVariant );
 	
+	virtual bbVariant nullValue();
+	
 	
 	bbDeclInfo *getDecl( bbString name );
 	
@@ -85,6 +87,8 @@ struct bbObjectTypeInfo : public bbTypeInfo{
 	bbArray<bbDeclInfo*> getDecls();
 };
 
+/*
+
 template<class T> struct bbPrimTypeInfo : public bbTypeInfo{
 
 	bbPrimTypeInfo( bbString name ){
@@ -226,4 +230,6 @@ template<class T> bbTypeInfo *bbGetType(){
 	return bbGetType( *(T*)0 );
 }
 
+*/
+
 #endif

+ 1 - 1
modules/monkey/native/bbtypeinfo_r.h

@@ -2,7 +2,7 @@
 #ifndef BB_TYPEINFO_R_H
 #define BB_TYPEINFO_R_H
 
-#include "bbtypeinfo.h"
+#include "bbtypeinfo_t.h"
 
 struct bbClassTypeInfo;
 

+ 165 - 0
modules/monkey/native/bbtypeinfo_t.h

@@ -0,0 +1,165 @@
+
+#ifndef BB_TYPEINFO_T_H
+#define BB_TYPEINFO_T_H
+
+#include "bbtypeinfo.h"
+
+template<class T> struct bbPrimTypeInfo : public bbTypeInfo{
+
+	bbPrimTypeInfo( bbString name ){
+		this->name=name;
+		this->kind="Primitive";
+	}
+	
+	bbVariant nullValue(){
+		return bbVariant( T{} );
+	}
+};
+
+template<class T> struct bbPointerTypeInfo : public bbTypeInfo{
+
+	bbPointerTypeInfo(){
+		this->name=bbGetType<T>()->name+" Ptr";
+		this->kind="Pointer";
+	}
+
+	bbTypeInfo *pointeeType(){
+		return bbGetType<T>();
+	}
+
+	bbVariant nullValue(){
+		return bbVariant( (T*)0 );
+	}
+};
+
+template<class T,int D> struct bbArrayTypeInfo : public bbTypeInfo{
+
+	bbArrayTypeInfo(){
+		this->name=bbGetType<T>()->name+"["+BB_T(",").dup(D-1)+"]";
+		this->kind="Array";
+	}
+	
+	bbTypeInfo *elementType(){
+		return bbGetType<T>();
+	}
+	
+	int arrayRank(){
+		return D;
+	}
+
+	bbVariant nullValue(){
+		return bbVariant( bbArray<T,D>{} );
+	}
+	
+};
+
+template<class R,class...A> struct bbFunctionTypeInfo : public bbTypeInfo{
+
+	bbFunctionTypeInfo(){
+		this->name=bbGetType<R>()->name+"("+BB_T(",").join( bbArray<bbString>( { bbGetType<A>()->name... },int(sizeof...(A)) ) )+")";
+		this->kind="Function";
+	}
+	
+	bbTypeInfo *returnType(){
+		return bbGetType<R>();
+	}
+	
+	bbArray<bbTypeInfo*> paramTypes(){
+		return bbArray<bbTypeInfo*>( { bbGetType<A>()... },int(sizeof...(A)) );
+	}
+
+	bbVariant nullValue(){
+		return bbVariant( bbFunction<R(A...)>{} );
+	}
+};
+
+template<class...A> struct bbFunctionTypeInfo<void,A...> : public bbTypeInfo{
+
+	bbFunctionTypeInfo(){
+		this->name=BB_T("Void(")+BB_T(",").join( bbArray<bbString>( { bbGetType<A>()->name... },int(sizeof...(A)) ) )+")";
+		this->kind="Function";
+	}
+	
+	bbTypeInfo *returnType(){
+		return &bbVoidTypeInfo::instance;
+	}
+	
+	bbArray<bbTypeInfo*> paramTypes(){
+		return bbArray<bbTypeInfo*>( { bbGetType<A>()... },int(sizeof...(A)) );
+	}
+
+	bbVariant nullValue(){
+		return bbVariant( bbFunction<void(A...)>{} );
+	}
+};
+
+#define BB_GETTYPE_DECL( TYPE ) bbTypeInfo *bbGetType( TYPE const& );
+
+BB_GETTYPE_DECL( bbBool )
+BB_GETTYPE_DECL( bbByte )
+BB_GETTYPE_DECL( bbUByte )
+BB_GETTYPE_DECL( bbShort )
+BB_GETTYPE_DECL( bbUShort )
+BB_GETTYPE_DECL( bbInt )
+BB_GETTYPE_DECL( bbUInt )
+BB_GETTYPE_DECL( bbLong )
+BB_GETTYPE_DECL( bbULong )
+BB_GETTYPE_DECL( bbFloat )
+BB_GETTYPE_DECL( bbDouble )
+BB_GETTYPE_DECL( bbString )
+BB_GETTYPE_DECL( bbCString )
+BB_GETTYPE_DECL( bbVariant )
+
+inline bbTypeInfo *bbGetType( bbObject* const& ){
+	return &bbObjectTypeInfo::instance;
+}
+
+template<class T> bbTypeInfo *bbGetUnknownType(){
+ 	static bbUnknownTypeInfo info;
+	
+	return &info;
+}
+
+template<class T> bbTypeInfo *bbGetType( T const& ){
+	return bbGetUnknownType<T>();
+}
+
+template<class T> bbTypeInfo *bbGetType( T* const& ){
+	static bbPointerTypeInfo<T> info;
+	
+	return &info;
+}
+
+template<class T,int D> bbTypeInfo *bbGetType( bbArray<T,D> const& ){
+	static bbArrayTypeInfo<T,D> info;
+	
+	return &info;
+}
+
+template<class R,class...A> bbTypeInfo *bbGetFuncType(){
+	static bbFunctionTypeInfo<R,A...> info;
+	
+	return &info;
+}
+
+template<class R,class...A> bbTypeInfo *bbGetType( R(*)(A...) ){
+	return bbGetFuncType<R,A...>();
+}
+
+template<class R,class...A> bbTypeInfo *bbGetType( bbFunction<R(A...)> const& ){
+	return bbGetFuncType<R,A...>();
+}
+
+template<class T> bbTypeInfo *bbGetType( bbGCVar<T> const& ){
+	return bbGetType<T*>();
+}
+
+template<> inline bbTypeInfo *bbGetType<void>(){
+	return &bbVoidTypeInfo::instance;
+}
+
+template<class T> bbTypeInfo *bbGetType(){
+	return bbGetType( *(T*)0 );
+}
+
+#endif

+ 1 - 1
modules/monkey/native/bbvariant.h

@@ -35,7 +35,7 @@ struct bbVariant{
 		}
 		
 		virtual bbTypeInfo *getType(){
-			return &bbVoidTypeInfo::instance;
+			return 0;
 		}
 		
 		virtual bbObject *getObject(){

+ 4 - 0
modules/monkey/types.monkey2

@@ -555,6 +555,10 @@ Class @TypeInfo Extends Void="bbTypeInfo"
 	
 	#end
 	Property Kind:String()="getKind"
+
+	#rem monkeydoc A variant containing a null value of this type.
+	#end		
+	Property NullValue:Variant()="nullValue"
 	
 	#rem monkeydoc Pointer pointee type.
 	

+ 13 - 6
src/mx2cc/test.monkey2

@@ -1,14 +1,21 @@
 
-Namespace myapp
+#reflect test
+
+Namespace test
+
+Class C
 
-Enum E
-	A,B,C
 End
 
 Function Main()
 	
-	Local e:=E.A.B
-	
-	Print Int(e)
+'	Local c:C'=New C
 
+	Local v:=Typeof<C>.NullValue
+	
+	Local c:=Cast<C>( v )
+	
+	If c Print "no null" Else Print "null"
+		
+	Print Typeof(c)=Typeof<C>
 End

+ 13 - 1
src/mx2cc/translator_cpp.monkey2

@@ -1226,7 +1226,12 @@ Class Translator_CPP Extends Translator
 			Emit( "}" )
 		Endif
 		
-		Emit( "};" )
+		'nullvalue
+		Emit( "bbVariant nullValue(){" )
+		Emit( "return bbVariant( ("+cname+"*)0 );")
+		Emit( "}" )
+		
+		Emit( "};" )		
 		
 		Emit( rcname+" "+rcname+"::instance;" )
 		
@@ -2223,6 +2228,13 @@ Class Translator_CPP Extends Translator
 		Case "=","<>","<",">","<=",">="
 		
 			If op="=" op="==" Else If op="<>" op="!="
+				
+			Local ptype:=TCast<PrimType>( value.lhs.type )
+			
+			If ptype And ptype=Type.VariantType
+				
+				Return "(bbCompare("+Trans( value.lhs )+","+Trans( value.rhs )+")"+op+"0)"
+			Endif
 			
 			Local ctype:=TCast<ClassType>( value.lhs.type )
 			Local ftype:=TCast<FuncType>( value.lhs.type )