| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284 |
- #include "std.h"
- #include "nodes.h"
- set<string> Node::usedfuncs;
- ///////////////////////////////
- // generic exception thrower //
- ///////////////////////////////
- void Node::ex(){
- ex( "INTERNAL COMPILER ERROR" );
- }
- void Node::ex( const string &e ){
- throw Ex( e,-1,"" );
- }
- void Node::ex( const string &e,int pos ){
- throw Ex( e,pos,"" );
- }
- void Node::ex( const string &e,int pos,const string &f ){
- throw Ex( e,pos,f );
- }
- ///////////////////////////////
- // Generate a local variable //
- ///////////////////////////////
- VarNode *Node::genLocal( Environ *e,Type *ty ){
- string t=genLabel();
- Decl *d=e->decls->insertDecl( t,ty,DECL_LOCAL );
- return d_new DeclVarNode( d );
- }
- /////////////////////////////////////////////////
- // if type is const, return const value else 0 //
- /////////////////////////////////////////////////
- ConstNode *Node::constValue( Type *ty ){
- ConstType *c=ty->constType();
- if( !c ) return 0;
- ty=c->valueType;
- if( ty==Type::int_type ) return d_new IntConstNode( c->intValue );
- if( ty==Type::float_type ) return d_new FloatConstNode( c->floatValue );
- return d_new StringConstNode( c->stringValue );
- }
- ///////////////////////////////////////////////////////
- // work out var offsets - return size of local frame //
- ///////////////////////////////////////////////////////
- int Node::enumVars( Environ *e ){
- //calc offsets
- int p_size=0,l_size=0;
- for( int k=0;k<e->decls->size();++k ){
- Decl *d=e->decls->decls[k];
- if( d->kind & DECL_PARAM ){
- d->offset=p_size+20;
- p_size+=4;
- }else if( d->kind & DECL_LOCAL ){
- d->offset=-4-l_size;
- l_size+=4;
- }
- }
- return l_size;
- }
- //////////////////////////////
- // initialize all vars to 0 //
- //////////////////////////////
- TNode *Node::createVars( Environ *e ){
- int k;
- TNode *t=0;
- //initialize locals
- for( k=0;k<e->decls->size();++k ){
- Decl *d=e->decls->decls[k];
- if( d->kind!=DECL_LOCAL ) continue;
- if( d->type->vectorType() ) continue;
- if( !t ) t=d_new TNode( IR_CONST,0,0,0 );
- TNode *p=d_new TNode( IR_LOCAL,0,0,d->offset );
- p=d_new TNode( IR_MEM,p,0 );
- t=d_new TNode( IR_MOVE,t,p );
- }
- //initialize vectors
- for( k=0;k<e->decls->size();++k ){
- Decl *d=e->decls->decls[k];
- if( d->kind==DECL_PARAM ) continue;
- VectorType *v=d->type->vectorType();
- if( !v ) continue;
- TNode *p=call( "__bbVecAlloc",global( v->label ) );
- TNode *m=d->kind==DECL_GLOBAL ? global( "_v"+d->name ) : local( d->offset );
- p=move( p,mem( m ) );
- if( t ) t=seq( t,p );
- else t=p;
- }
- return t;
- }
- ////////////////////////
- // release local vars //
- ////////////////////////
- TNode *Node::deleteVars( Environ *e ){
- TNode *t=0,*l=0,*p,*p1,*p2;
- for( int k=0;k<e->decls->size();++k ){
- Decl *d=e->decls->decls[k];
- Type *type=d->type;
- string func;
- if( type==Type::string_type ){
- if( d->kind==DECL_LOCAL || d->kind==DECL_PARAM ){
- func="__bbStrRelease";
- p1=mem( local( d->offset ) );
- p2=0;
- }
- }else if( type->structType() ){
- if( d->kind==DECL_LOCAL ){
- func="__bbObjRelease";
- p1=mem( local( d->offset ) );
- p2=0;
- }
- }else if( VectorType *v=type->vectorType() ){
- if( d->kind==DECL_LOCAL ){
- func="__bbVecFree";
- p1=mem( local( d->offset ) );
- p2=global( v->label );
- }
- }
- if( !func.size() ) continue;
- p=d_new TNode( IR_SEQ,call( func,p1,p2 ),0 );
- (l ? l->r : t)=p;
- l=p;
- }
- return t;
- }
- //////////////////////////////////////////////////////////////
- // compare 2 translated operands - return 1 if true, else 0 //
- //////////////////////////////////////////////////////////////
- TNode *Node::compare( int op,TNode *l,TNode *r,Type *ty ){
- int n=0;
- if( ty==Type::float_type ){
- switch( op ){
- case '=':n=IR_FSETEQ;break;case NE :n=IR_FSETNE;break;
- case '<':n=IR_FSETLT;break;case '>':n=IR_FSETGT;break;
- case LE :n=IR_FSETLE;break;case GE :n=IR_FSETGE;break;
- }
- }else{
- switch( op ){
- case '=':n=IR_SETEQ;break;case NE :n=IR_SETNE;break;
- case '<':n=IR_SETLT;break;case '>':n=IR_SETGT;break;
- case LE :n=IR_SETLE;break;case GE :n=IR_SETGE;break;
- }
- }
- if( ty==Type::string_type ){
- l=call( "__bbStrCompare",l,r );
- r=d_new TNode( IR_CONST,0,0,0 );
- }else if( ty->structType() ){
- l=call( "__bbObjCompare",l,r );
- r=d_new TNode( IR_CONST,0,0,0 );
- }
- return d_new TNode( n,l,r );
- }
- /////////////////////////////////
- // calculate the type of a tag //
- /////////////////////////////////
- Type *Node::tagType( const string &tag,Environ *e ){
- Type *t;
- if( tag.size() ){
- t=e->findType( tag );
- if( !t ) ex( "Type \""+tag+"\" not found" );
- }else t=0;
- return t;
- }
- ////////////////////////////////
- // Generate a fresh ASM label //
- ////////////////////////////////
- string Node::genLabel(){
- static int cnt;
- return "_"+itoa( ++cnt & 0x7fffffff );
- }
- //////////////////////////////////////////////////////
- // create a stmt-type function call with int result //
- //////////////////////////////////////////////////////
- TNode *Node::call( const string &func,TNode *a0,TNode *a1,TNode *a2 ){
- int size=0;
- TNode *t=0;
- if( a0 ){
- t=move( a0,mem( arg(0) ) );
- size+=4;
- if( a1 ){
- t=seq( t,move( a1,mem( arg(4) ) ) );
- size+=4;
- if( a2 ){
- t=seq( t,move( a2,mem( arg(8) ) ) );
- size+=4;
- }
- }
- }
- TNode *l=d_new TNode( IR_GLOBAL,0,0,func );
- return d_new TNode( IR_CALL,l,t,size );
- }
- ////////////////////////////////////////////////////////
- // create a stmt-type function call with float result //
- ////////////////////////////////////////////////////////
- TNode *Node::fcall( const string &func,TNode *a0,TNode *a1,TNode *a2 ){
- int size=0;
- TNode *t=0;
- if( a0 ){
- t=move( a0,mem( arg(0) ) );
- size+=4;
- if( a1 ){
- t=seq( t,move( a1,mem( arg(4) ) ) );
- size+=4;
- if( a2 ){
- t=seq( t,move( a2,mem( arg(8) ) ) );
- size+=4;
- }
- }
- }
- TNode *l=d_new TNode( IR_GLOBAL,0,0,func );
- return d_new TNode( IR_FCALL,l,t,size );
- }
- TNode *Node::seq( TNode *l,TNode *r ){
- return d_new TNode( IR_SEQ,l,r );
- }
- TNode *Node::move( TNode *src,TNode *dest ){
- return d_new TNode( IR_MOVE,src,dest );
- }
- TNode *Node::global( const string &s ){
- return d_new TNode( IR_GLOBAL,0,0,s );
- }
- TNode *Node::local( int offset ){
- return d_new TNode( IR_LOCAL,0,0,offset );
- }
- TNode *Node::arg( int offset ){
- return d_new TNode( IR_ARG,0,0,offset );
- }
- TNode *Node::mem( TNode *ref ){
- return d_new TNode( IR_MEM,ref,0 );
- }
- TNode *Node::add( TNode *l,TNode *r ){
- return d_new TNode( IR_ADD,l,r );
- }
- TNode *Node::mul( TNode *l,TNode *r ){
- return d_new TNode( IR_MUL,l,r );
- }
- TNode *Node::iconst( int n ){
- return d_new TNode( IR_CONST,0,0,n );
- }
- TNode *Node::ret(){
- return d_new TNode( IR_RET,0,0 );
- }
- TNode *Node::jsr( const string &s ){
- return d_new TNode( IR_JSR,0,0,s );
- }
- TNode *Node::jump( const string &s ){
- return d_new TNode( IR_JUMP,0,0,s );
- }
- TNode *Node::jumpt( TNode *expr,const string &s ){
- return d_new TNode( IR_JUMPT,expr,0,s );
- }
- TNode *Node::jumpf( TNode *expr,const string &s ){
- return d_new TNode( IR_JUMPF,expr,0,s );
- }
- TNode *Node::jumpge( TNode *l,TNode *r,const string &s ){
- return d_new TNode( IR_JUMPGE,l,r,s );
- }
|