#ifndef BB_DECLINFO_R_H #define BB_DECLINFO_R_H #include "bbdeclinfo.h" // ***** 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 ); } // ***** Extension Method ***** // template struct bbExtMethodDeclInfo : public bbDeclInfo{ R (*ptr)(C*,A...); bbExtMethodDeclInfo( bbString name,bbString meta,R (*ptr)(C*,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 ptr( p,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 bbExtMethodDeclInfo : public bbDeclInfo{ typedef void R; R (*ptr)(C*,A...); bbExtMethodDeclInfo( bbString name,bbString meta,R (*ptr)(C*,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 ptr( p,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 *bbExtMethodDecl( bbString name,R (*ptr)(C*,A...),bbString meta="" ){ return new bbExtMethodDeclInfo( 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 bbDeclInfo *bbPropertyDecl( bbString name,T(C::*getter)(),void(C::*setter)(T),bbString meta="" ){ return new bbPropertyDeclInfo( name,meta,getter,setter ); } // ***** Extension Property ***** // 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 *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 ); } // ***** Literal ***** // template struct bbLiteralDeclInfo : public bbDeclInfo{ T value; bbLiteralDeclInfo( bbString name,bbString meta,T value ):value( value ){ this->name=name; this->meta=meta; this->kind="Const"; this->type=bbGetType(); this->flags=BB_DECL_GETTABLE; } bbVariant get( bbVariant instance ){ return bbVariant( value ); } }; template bbDeclInfo *bbLiteralDecl( bbString name,T value,bbString meta="" ){ return new bbLiteralDeclInfo( name,meta,value ); } template bbDeclInfo **bbMembers( Ds...ds ){ int n=sizeof...(Ds); bbDeclInfo *ts[]={ ds...,0 }; bbDeclInfo **ps=new bbDeclInfo*[n+1]; for( int i=0;i