#ifndef BB_TYPEINFO_H #define BB_TYPEINFO_H #include "bbassert.h" #include "bbobject.h" #include "bbarray.h" #include "bbfunction.h" struct bbClassTypeInfo; struct bbTypeInfo{ bbString name; bbString kind; bbString getName(){ return name; } bbString getKind(){ return kind; } virtual bbString toString(); virtual bbTypeInfo *pointeeType(); virtual bbTypeInfo *elementType(); virtual int arrayRank(); virtual bbTypeInfo *returnType(); virtual bbArray paramTypes(); virtual bbTypeInfo *superType(); virtual bbArray interfaceTypes(); virtual bbBool extendsType( bbTypeInfo *type ); virtual bbArray getDecls(); bbDeclInfo *getDecl( bbString name ); bbDeclInfo *getDecl( bbString name,bbTypeInfo *type ); bbArray getDecls( bbString name ); static bbTypeInfo *getType( bbString cname ); static bbArray getTypes(); }; template bbTypeInfo *bbGetType(); struct bbUnknownTypeInfo : public bbTypeInfo{ bbUnknownTypeInfo(); }; struct bbVoidTypeInfo : public bbTypeInfo{ static bbVoidTypeInfo instance; bbVoidTypeInfo(); }; struct bbObjectTypeInfo : public bbTypeInfo{ static bbObjectTypeInfo instance; bbObjectTypeInfo(); bbTypeInfo *superType(); bbBool extendsType( bbTypeInfo *type ); bbArray getDecls(); }; struct bbPrimTypeInfo : public bbTypeInfo{ bbPrimTypeInfo( bbString name ); }; template struct bbPointerTypeInfo : public bbTypeInfo{ bbPointerTypeInfo(){ this->name=bbGetType()->name+" Ptr"; this->kind="Pointer"; } bbTypeInfo *pointeeType(){ return bbGetType(); } }; template struct bbArrayTypeInfo : public bbTypeInfo{ bbArrayTypeInfo(){ this->name=bbGetType()->name+"["+BB_T(",").dup(D-1)+"]"; this->kind="Array"; } bbTypeInfo *elementType(){ return bbGetType(); } int arrayRank(){ return D; } }; template struct bbFunctionTypeInfo : public bbTypeInfo{ bbFunctionTypeInfo(){ this->name=bbGetType()->name+"("+BB_T(",").join( bbArray( { bbGetType()->name... },int(sizeof...(A)) ) )+")"; this->kind="Function"; } bbTypeInfo *returnType(){ return bbGetType(); } bbArray paramTypes(){ return bbArray( { bbGetType()... },int(sizeof...(A)) ); } }; template struct bbFunctionTypeInfo : public bbTypeInfo{ bbFunctionTypeInfo(){ this->name=BB_T("Void(")+BB_T(",").join( bbArray( { bbGetType()->name... },int(sizeof...(A)) ) )+")"; this->kind="Function"; } bbTypeInfo *returnType(){ return &bbVoidTypeInfo::instance; } bbArray paramTypes(){ return bbArray( { bbGetType()... },int(sizeof...(A)) ); } }; struct bbClassDecls{ bbClassDecls *_succ; bbDeclInfo **_decls=0; int _numDecls=0; bbClassDecls( bbClassTypeInfo *classType ); bbDeclInfo **decls(); int numDecls(); virtual bbDeclInfo **initDecls(){ return 0; } }; struct bbClassTypeInfo : public bbTypeInfo{ bbClassTypeInfo *_succ=0; bbClassDecls *_decls=0; bbClassTypeInfo( bbString name,bbString kind ); bbTypeInfo *superType(); bbArray interfaceTypes(); bbBool extendsType( bbTypeInfo *type ); bbArray getDecls(); bbString toString(){ return kind+" "+name; } static bbClassTypeInfo *getNamespace( bbString name ); }; #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 bbTypeInfo *bbGetType( T const& ){ static bbUnknownTypeInfo info; return &info; } template bbTypeInfo *bbGetType( T* const& ){ static bbPointerTypeInfo info; return &info; } template bbTypeInfo *bbGetType( bbArray const& ){ static bbArrayTypeInfo info; return &info; } template bbTypeInfo *bbGetFuncType(){ static bbFunctionTypeInfo info; return &info; } template bbTypeInfo *bbGetType( R(*)(A...) ){ return bbGetFuncType(); } template bbTypeInfo *bbGetType( bbFunction const& ){ return bbGetFuncType(); } template bbTypeInfo *bbGetType( bbGCVar const& ){ return bbGetType(); } template<> inline bbTypeInfo *bbGetType(){ return &bbVoidTypeInfo::instance; } template bbTypeInfo *bbGetType(){ return bbGetType( *(T*)0 ); } #endif