#ifndef BB_DECLINFO_H #define BB_DECLINFO_H #include "bbtypeinfo.h" #include "bbvariant.h" #define BB_DECL_PUBLIC 0x000001 #define BB_DECL_PRIVATE 0x000002 #define BB_DECL_PROTECTED 0x000004 #define BB_DECL_INTERNAL 0x000008 #define BB_DECL_VIRTUAL 0x000100 #define BB_DECL_OVERRIDE 0x000200 #define BB_DECL_ABSTRACT 0x000400 #define BB_DECL_FINAL 0x000800 #define BB_DECL_EXTERN 0x001000 #define BB_DECL_EXTENSION 0x002000 #define BB_DECL_DEFAULT 0x004000 #define BB_DECL_GETTER 0x010000 #define BB_DECL_SETTER 0x020000 #define BB_DECL_OPERATOR 0x040000 #define BB_DECL_IFACEMEMBER 0x080000 #define BB_DECL_GETTABLE 0x10000000 #define BB_DECL_SETTABLE 0x20000000 #define BB_DECL_INVOKABLE 0x40000000 struct bbDeclInfo{ bbString name; bbString meta; bbString kind; bbTypeInfo *type; int flags=0; bbString getName(){ return name; } bbString getKind(){ return kind; } bbTypeInfo *getType(){ return type; } bbBool gettable(){ return flags & BB_DECL_GETTABLE; } bbBool settable(){ return flags & BB_DECL_SETTABLE; } bbBool invokable(){ return flags & BB_DECL_INVOKABLE; } bbArray getMetaKeys(); bbArray getMetaData(); bbString getMetaValue( bbString key ); virtual bbString toString(); virtual bbVariant get( bbVariant instance ); virtual void set( bbVariant instance,bbVariant value ); virtual bbVariant invoke( bbVariant instance,bbArray params ); }; /* // ***** Global ***** // template struct bbGlobalDeclInfo : public bbDeclInfo{ T *ptr; bbGlobalDeclInfo( bbString name,T *ptr,bbString meta,bool isconst ):ptr( ptr ){ this->name=name; this->meta=meta; this->kind=isconst ? "Const" : "Global"; this->type=bbGetType(); this->flags=BB_DECL_GETTABLE|(isconst ? 0 : BB_DECL_SETTABLE); } bbVariant get( bbVariant instance ){ return bbVariant( *ptr ); } void set( bbVariant instance,bbVariant value ){ *ptr=value.get(); } }; template struct bbGlobalVarDeclInfo : public bbDeclInfo{ bbGCVar *ptr; bbGlobalVarDeclInfo( bbString name,bbGCVar *ptr,bbString meta,bool isconst ):ptr( ptr ){ this->name=name; this->meta=meta; this->kind=isconst ? "Const" : "Global"; this->type=bbGetType(); this->flags=BB_DECL_GETTABLE|(isconst ? 0 : BB_DECL_SETTABLE); } bbVariant get( bbVariant instance ){ return bbVariant( ptr->get() ); } void set( bbVariant instance,bbVariant value ){ *ptr=value.get(); } }; template bbDeclInfo *bbGlobalDecl( bbString name,T *ptr,bbString meta="" ){ return new bbGlobalDeclInfo( name,ptr,meta,false ); } template bbDeclInfo *bbGlobalDecl( bbString name,bbGCVar *ptr,bbString meta="" ){ return new bbGlobalVarDeclInfo( name,ptr,meta,false ); } template bbDeclInfo *bbConstDecl( bbString name,T *ptr,bbString meta="" ){ return new bbGlobalDeclInfo( name,ptr,meta,true ); } template bbDeclInfo *bbConstDecl( bbString name,bbGCVar *ptr,bbString meta="" ){ return new bbGlobalVarDeclInfo( name,ptr,meta,true ); } // ***** Field ***** // template struct bbFieldDeclInfo : public bbDeclInfo{ T C::*ptr; bbFieldDeclInfo( bbString name,bbString meta,T C::*ptr ):ptr( ptr ){ this->name=name; this->meta=meta; this->kind="Field"; this->type=bbGetType(); this->flags=BB_DECL_GETTABLE|BB_DECL_SETTABLE; } bbVariant get( bbVariant instance ){ // C *p=instance.get(); C *p=instance.ref(); return bbVariant( p->*ptr ); } void set( bbVariant instance,bbVariant value ){ // C *p=instance.get(); C *p=instance.ref(); p->*ptr=value.get(); } }; template struct bbFieldVarDeclInfo : public bbDeclInfo{ bbGCVar C::*ptr; bbFieldVarDeclInfo( bbString name,bbString meta,bbGCVar C::*ptr ):ptr( ptr ){ this->name=name; this->meta=meta; this->kind="Field"; this->type=bbGetType(); this->flags=BB_DECL_GETTABLE|BB_DECL_SETTABLE; } bbVariant get( bbVariant instance ){ // C *p=instance.get(); C *p=instance.ref(); return bbVariant( (p->*ptr).get() ); } void set( bbVariant instance,bbVariant value ){ // C *p=instance.get(); C *p=instance.ref(); p->*ptr=value.get(); } }; template bbDeclInfo *bbFieldDecl( bbString name,T C::*ptr,bbString meta="" ){ return new bbFieldDeclInfo( name,meta,ptr ); } template bbDeclInfo *bbFieldDecl( bbString name,bbGCVar C::*ptr,bbString meta="" ){ return new bbFieldVarDeclInfo( name,meta,ptr ); } // ***** Constructor ***** // template struct bbCtorDeclInfo : public bbDeclInfo{ bbCtorDeclInfo( bbString meta ){ this->name="New"; this->meta=meta; this->kind="Constructor"; this->type=bbGetType>(); this->flags=BB_DECL_INVOKABLE; } template C *invoke( bbArray params,detail::seq ){ return bbGCNew( params[I].get()... ); } bbVariant invoke( bbVariant instance,bbArray params ){ return bbVariant( invoke( params,detail::gen_seq{} ) ); } }; template bbDeclInfo *bbCtorDecl( bbString meta="" ){ return new bbCtorDeclInfo( meta ); } // ***** Method ***** // template struct bbMethodDeclInfo : public bbDeclInfo{ R (C::*ptr)(A...); bbMethodDeclInfo( bbString name,bbString meta,R (C::*ptr)(A...) ):ptr( ptr ){ this->name=name; this->meta=meta; this->kind="Method"; this->type=bbGetType>(); this->flags=BB_DECL_INVOKABLE; } template R invoke( C *p,bbArray params,detail::seq ){ return (p->*ptr)( params[I].get()... ); } bbVariant invoke( bbVariant instance,bbArray params ){ // C *p=instance.get(); C *p=instance.ref(); return bbVariant( invoke( p,params,detail::gen_seq{} ) ); } }; template struct bbMethodDeclInfo : public bbDeclInfo{ typedef void R; R (C::*ptr)(A...); bbMethodDeclInfo( bbString name,bbString meta,R (C::*ptr)(A...) ):ptr( ptr ){ this->name=name; this->meta=meta; this->kind="Method"; this->type=bbGetType>(); this->flags=BB_DECL_INVOKABLE; } template R invoke( C *p,bbArray params,detail::seq ){ return (p->*ptr)( params[I].get()... ); } bbVariant invoke( bbVariant instance,bbArray params ){ // C *p=instance.get(); C *p=instance.ref(); invoke( p,params,detail::gen_seq{} ); return {}; } }; template bbDeclInfo *bbMethodDecl( bbString name,R (C::*ptr)(A...),bbString meta="" ){ return new bbMethodDeclInfo( name,meta,ptr ); } // ***** Property ***** // template struct bbPropertyDeclInfo : public bbDeclInfo{ T (C::*getter)(); void (C::*setter)(T); bbPropertyDeclInfo( bbString name,bbString meta,T(C::*getter)(),void(C::*setter)(T) ):getter( getter ),setter( setter ){ this->name=name; this->meta=meta; this->kind="Property"; this->type=bbGetType(); this->flags=(getter ? BB_DECL_GETTABLE : 0) | (setter ? BB_DECL_SETTABLE : 0); } bbVariant get( bbVariant instance ){ if( !getter ) bbRuntimeError( "Property has not getter" ); // C *p=instance.get(); C *p=instance.ref(); return bbVariant( (p->*getter)() ); } void set( bbVariant instance,bbVariant value ){ if( !setter ) bbRuntimeError( "Property has not setter" ); // C *p=instance.get(); C *p=instance.ref(); (p->*setter)( value.get() ); } }; template struct bbExtPropertyDeclInfo : public bbDeclInfo{ T (*getter)(C*); void (*setter)(C*,T); bbExtPropertyDeclInfo( bbString name,bbString meta,T(*getter)(C*),void(*setter)(C*,T) ):getter( getter ),setter( setter ){ this->name=name; this->meta=meta; this->kind="Property"; this->type=bbGetType(); this->flags=(getter ? BB_DECL_GETTABLE : 0) | (setter ? BB_DECL_SETTABLE : 0); } bbVariant get( bbVariant instance ){ if( !getter ) bbRuntimeError( "Property has no getter" ); C *p=instance.ref(); return bbVariant( getter(p) ); } void set( bbVariant instance,bbVariant value ){ if( !setter ) bbRuntimeError( "Property has no setter" ); C *p=instance.ref(); setter(p,value.get() ); } }; template bbDeclInfo *bbPropertyDecl( bbString name,T(C::*getter)(),void(C::*setter)(T),bbString meta="" ){ return new bbPropertyDeclInfo( name,meta,getter,setter ); } template bbDeclInfo *bbExtPropertyDecl( bbString name,T(*getter)(C*),void(*setter)(C*,T),bbString meta="" ){ return new bbExtPropertyDeclInfo( name,meta,getter,setter ); } // ***** Function ***** // template struct bbFunctionDeclInfo : public bbDeclInfo{ R (*ptr)(A...); bbFunctionDeclInfo( bbString name,bbString meta,R (*ptr)(A...) ):ptr( ptr ){ this->name=name; this->meta=meta; this->kind="Function"; this->type=bbGetType>(); this->flags=BB_DECL_INVOKABLE; } template R invoke( bbArray params,detail::seq ){ return (*ptr)( params[I].get()... ); } bbVariant invoke( bbVariant instance,bbArray params ){ return bbVariant( invoke( params,detail::gen_seq{} ) ); } }; template struct bbFunctionDeclInfo : public bbDeclInfo{ typedef void R; R (*ptr)(A...); bbFunctionDeclInfo( bbString name,bbString meta,R (*ptr)(A...) ):ptr( ptr ){ this->name=name; this->meta=meta; this->kind="Function"; this->type=bbGetType>(); this->flags=BB_DECL_INVOKABLE; } template R invoke( bbArray params,detail::seq ){ return (*ptr)( params[I].get()... ); } bbVariant invoke( bbVariant instance,bbArray params ){ invoke( params,detail::gen_seq{} ); return {}; } }; template bbDeclInfo *bbFunctionDecl( bbString name,R (*ptr)(A...),bbString meta="" ){ return new bbFunctionDeclInfo( name,meta,ptr ); } template bbDeclInfo **bbMembers( Ds...ds ){ int n=sizeof...(Ds); bbDeclInfo *ts[]={ ds...,0 }; bbDeclInfo **ps=new bbDeclInfo*[n+1]; for( int i=0;i