#include "bbvariant.h" #include "bbtypeinfo_r.h" #include "bbdeclinfo.h" namespace{ bbClassTypeInfo *_classes; } #define BB_PRIM_GETTYPE( TYPE,ID ) bbTypeInfo *bbGetType( TYPE const& ){ \ static bbPrimTypeInfo info( ID ); \ return &info; \ } BB_PRIM_GETTYPE( bbBool,"Bool" ) BB_PRIM_GETTYPE( bbByte,"Byte" ) BB_PRIM_GETTYPE( bbUByte,"UByte" ) BB_PRIM_GETTYPE( bbShort,"Short" ) BB_PRIM_GETTYPE( bbUShort,"UShort" ) BB_PRIM_GETTYPE( bbInt,"Int" ) BB_PRIM_GETTYPE( bbUInt,"UInt" ) BB_PRIM_GETTYPE( bbLong,"Long" ) BB_PRIM_GETTYPE( bbULong,"ULong" ) BB_PRIM_GETTYPE( bbFloat,"Float" ) BB_PRIM_GETTYPE( bbDouble,"Double" ) BB_PRIM_GETTYPE( bbString,"String" ) BB_PRIM_GETTYPE( bbCString,"CString" ) BB_PRIM_GETTYPE( bbVariant,"Variant" ) // ***** bbTypeInfo ***** bbString bbTypeInfo::toString(){ return name; } bbTypeInfo *bbTypeInfo::pointeeType(){ bbRuntimeError( "Type '"+name+"' is not a pointer type" ); return 0; } bbTypeInfo *bbTypeInfo::elementType(){ bbRuntimeError( "Type '"+name+"' is not an array type" ); return 0; } int bbTypeInfo::arrayRank(){ bbRuntimeError( "Type '"+name+"' is not an array type" ); return 0; } bbTypeInfo *bbTypeInfo::returnType(){ bbRuntimeError( "Type '"+name+"' is not a function type" ); return 0; } bbArray bbTypeInfo::paramTypes(){ bbRuntimeError( "Type '"+name+"' is not a function type" ); return {}; } bbTypeInfo *bbTypeInfo::superType(){ bbRuntimeError( "Type '"+name+"' is not a class type" ); return 0; } bbArray bbTypeInfo::interfaceTypes(){ bbRuntimeError( "Type '"+name+"' is not a class or interface type" ); return {}; } bbBool bbTypeInfo::extendsType( bbTypeInfo *type ){ return this==type; } bbArray bbTypeInfo::getDecls(){ bbRuntimeError( "Type '"+name+"' is not a class or interface type" ); return {}; } bbVariant bbTypeInfo::makeEnum( int ){ bbRuntimeError( "Type '"+name+"' is not an enum type" ); return {}; } int bbTypeInfo::getEnum( bbVariant ){ bbRuntimeError( "Type '"+name+"' is not an enum type" ); return {}; } bbVariant bbTypeInfo::nullValue(){ return {}; } bbVariant bbTypeInfo::newArray( int length ){ return {}; } bbDeclInfo *bbTypeInfo::getDecl( bbString name ){ bbArray decls=getDecls(); bbDeclInfo *found=0; for( int i=0;iname!=name ) continue; if( found ) return 0; found=decl; } return found; } bbArray bbTypeInfo::getDecls( bbString name ){ bbArray decls=getDecls(); int n=0; for( int i=0;iname==name ) ++n; } if( !n ) return {}; bbArray rdecls( n ); int j=0; for( int i=0;iname==name ) rdecls[j++]=decls[i]; } return rdecls; } bbDeclInfo *bbTypeInfo::getDecl( bbString name,bbTypeInfo *type ){ bbArray decls=getDecls(); for( int i=0;iname==name && decl->type==type ) return decl; } return 0; } bbTypeInfo *bbTypeInfo::getType( bbString cname ){ for( bbClassTypeInfo *c=_classes;c;c=c->_succ ){ if( c->name==cname ) return c; } return 0; } bbArray bbTypeInfo::getTypes(){ int n=0; for( bbClassTypeInfo *c=_classes;c;c=c->_succ ) ++n; bbArray types( n ); int i=0; for( bbClassTypeInfo *c=_classes;c;c=c->_succ ) types[i++]=c; return types; } // ***** bbUnknownTypeInfo ***** bbUnknownTypeInfo::bbUnknownTypeInfo( const char *name ){ this->name=name ? bbString( name ) : BB_T("Unknown@")+bbString( bbLong( this ) ); this->kind="Unknown"; } // ***** bbVoidTypeInfo ***** bbVoidTypeInfo bbVoidTypeInfo::instance; bbVoidTypeInfo::bbVoidTypeInfo(){ this->name="Void"; this->kind="Void"; } // ***** bbObjectTypeInfo ***** bbObjectTypeInfo bbObjectTypeInfo::instance; bbObjectTypeInfo::bbObjectTypeInfo(){ this->name="Object"; this->kind="Class"; } bbTypeInfo *bbObjectTypeInfo::superType(){ return 0; } bbBool bbObjectTypeInfo::extendsType( bbTypeInfo *type ){ return type==&instance; } bbArray bbObjectTypeInfo::getDecls(){ return {}; } bbTypeInfo *bbObject::typeof()const{ return &bbObjectTypeInfo::instance; } // ***** bbClassDecls ***** bbClassDecls::bbClassDecls( bbClassTypeInfo *classType ){ _succ=classType->_decls; classType->_decls=this; } bbDeclInfo **bbClassDecls::decls(){ if( !_decls ){ _decls=initDecls(); bbDeclInfo **p=_decls; while( *p ) ++p; _numDecls=p-_decls; } return _decls; } int bbClassDecls::numDecls(){ if( !_decls ) decls(); return _numDecls; } // ***** bbClassTypeInfo ***** bbClassTypeInfo::bbClassTypeInfo( bbString name,bbString kind ){ // printf( "ClassTypeInfo:%s\n",name.c_str() ); this->name=name; this->kind=kind; _succ=_classes; _classes=this; } bbTypeInfo *bbClassTypeInfo::superType(){ return 0; } bbArray bbClassTypeInfo::interfaceTypes(){ return {}; } bbBool bbClassTypeInfo::extendsType( bbTypeInfo *type ){ if( type==this ) return true; bbArray ifaces=interfaceTypes(); for( int i=0;iextendsType( type ) ) return true; } if( bbTypeInfo *super=superType() ) return super->extendsType( type ); return false; } bbArray bbClassTypeInfo::getDecls(){ int n=0; for( bbClassDecls *m=_decls;m;m=m->_succ ) n+=m->numDecls(); bbArray rdecls( n ); int i=0; for( bbClassDecls *m=_decls;m;m=m->_succ ){ bbDeclInfo **decls=m->decls(); int n=m->numDecls(); for( int j=0;j_succ ){ if( nmspace->name==name ) return nmspace; } bbClassTypeInfo *nmspace=new bbClassTypeInfo( name,"Namespace" ); return nmspace; } // ***** EnumTypeInfo *****