node.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. #include "std.h"
  2. #include "nodes.h"
  3. set<string> Node::usedfuncs;
  4. ///////////////////////////////
  5. // generic exception thrower //
  6. ///////////////////////////////
  7. void Node::ex(){
  8. ex( "INTERNAL COMPILER ERROR" );
  9. }
  10. void Node::ex( const string &e ){
  11. throw Ex( e,-1,"" );
  12. }
  13. void Node::ex( const string &e,int pos ){
  14. throw Ex( e,pos,"" );
  15. }
  16. void Node::ex( const string &e,int pos,const string &f ){
  17. throw Ex( e,pos,f );
  18. }
  19. ///////////////////////////////
  20. // Generate a local variable //
  21. ///////////////////////////////
  22. VarNode *Node::genLocal( Environ *e,Type *ty ){
  23. string t=genLabel();
  24. Decl *d=e->decls->insertDecl( t,ty,DECL_LOCAL );
  25. return d_new DeclVarNode( d );
  26. }
  27. /////////////////////////////////////////////////
  28. // if type is const, return const value else 0 //
  29. /////////////////////////////////////////////////
  30. ConstNode *Node::constValue( Type *ty ){
  31. ConstType *c=ty->constType();
  32. if( !c ) return 0;
  33. ty=c->valueType;
  34. if( ty==Type::int_type ) return d_new IntConstNode( c->intValue );
  35. if( ty==Type::float_type ) return d_new FloatConstNode( c->floatValue );
  36. return d_new StringConstNode( c->stringValue );
  37. }
  38. ///////////////////////////////////////////////////////
  39. // work out var offsets - return size of local frame //
  40. ///////////////////////////////////////////////////////
  41. int Node::enumVars( Environ *e ){
  42. //calc offsets
  43. int p_size=0,l_size=0;
  44. for( int k=0;k<e->decls->size();++k ){
  45. Decl *d=e->decls->decls[k];
  46. if( d->kind & DECL_PARAM ){
  47. d->offset=p_size+20;
  48. p_size+=4;
  49. }else if( d->kind & DECL_LOCAL ){
  50. d->offset=-4-l_size;
  51. l_size+=4;
  52. }
  53. }
  54. return l_size;
  55. }
  56. //////////////////////////////
  57. // initialize all vars to 0 //
  58. //////////////////////////////
  59. TNode *Node::createVars( Environ *e ){
  60. int k;
  61. TNode *t=0;
  62. //initialize locals
  63. for( k=0;k<e->decls->size();++k ){
  64. Decl *d=e->decls->decls[k];
  65. if( d->kind!=DECL_LOCAL ) continue;
  66. if( d->type->vectorType() ) continue;
  67. if( !t ) t=d_new TNode( IR_CONST,0,0,0 );
  68. TNode *p=d_new TNode( IR_LOCAL,0,0,d->offset );
  69. p=d_new TNode( IR_MEM,p,0 );
  70. t=d_new TNode( IR_MOVE,t,p );
  71. }
  72. //initialize vectors
  73. for( k=0;k<e->decls->size();++k ){
  74. Decl *d=e->decls->decls[k];
  75. if( d->kind==DECL_PARAM ) continue;
  76. VectorType *v=d->type->vectorType();
  77. if( !v ) continue;
  78. TNode *p=call( "__bbVecAlloc",global( v->label ) );
  79. TNode *m=d->kind==DECL_GLOBAL ? global( "_v"+d->name ) : local( d->offset );
  80. p=move( p,mem( m ) );
  81. if( t ) t=seq( t,p );
  82. else t=p;
  83. }
  84. return t;
  85. }
  86. ////////////////////////
  87. // release local vars //
  88. ////////////////////////
  89. TNode *Node::deleteVars( Environ *e ){
  90. TNode *t=0,*l=0,*p,*p1,*p2;
  91. for( int k=0;k<e->decls->size();++k ){
  92. Decl *d=e->decls->decls[k];
  93. Type *type=d->type;
  94. string func;
  95. if( type==Type::string_type ){
  96. if( d->kind==DECL_LOCAL || d->kind==DECL_PARAM ){
  97. func="__bbStrRelease";
  98. p1=mem( local( d->offset ) );
  99. p2=0;
  100. }
  101. }else if( type->structType() ){
  102. if( d->kind==DECL_LOCAL ){
  103. func="__bbObjRelease";
  104. p1=mem( local( d->offset ) );
  105. p2=0;
  106. }
  107. }else if( VectorType *v=type->vectorType() ){
  108. if( d->kind==DECL_LOCAL ){
  109. func="__bbVecFree";
  110. p1=mem( local( d->offset ) );
  111. p2=global( v->label );
  112. }
  113. }
  114. if( !func.size() ) continue;
  115. p=d_new TNode( IR_SEQ,call( func,p1,p2 ),0 );
  116. (l ? l->r : t)=p;
  117. l=p;
  118. }
  119. return t;
  120. }
  121. //////////////////////////////////////////////////////////////
  122. // compare 2 translated operands - return 1 if true, else 0 //
  123. //////////////////////////////////////////////////////////////
  124. TNode *Node::compare( int op,TNode *l,TNode *r,Type *ty ){
  125. int n=0;
  126. if( ty==Type::float_type ){
  127. switch( op ){
  128. case '=':n=IR_FSETEQ;break;case NE :n=IR_FSETNE;break;
  129. case '<':n=IR_FSETLT;break;case '>':n=IR_FSETGT;break;
  130. case LE :n=IR_FSETLE;break;case GE :n=IR_FSETGE;break;
  131. }
  132. }else{
  133. switch( op ){
  134. case '=':n=IR_SETEQ;break;case NE :n=IR_SETNE;break;
  135. case '<':n=IR_SETLT;break;case '>':n=IR_SETGT;break;
  136. case LE :n=IR_SETLE;break;case GE :n=IR_SETGE;break;
  137. }
  138. }
  139. if( ty==Type::string_type ){
  140. l=call( "__bbStrCompare",l,r );
  141. r=d_new TNode( IR_CONST,0,0,0 );
  142. }else if( ty->structType() ){
  143. l=call( "__bbObjCompare",l,r );
  144. r=d_new TNode( IR_CONST,0,0,0 );
  145. }
  146. return d_new TNode( n,l,r );
  147. }
  148. /////////////////////////////////
  149. // calculate the type of a tag //
  150. /////////////////////////////////
  151. Type *Node::tagType( const string &tag,Environ *e ){
  152. Type *t;
  153. if( tag.size() ){
  154. t=e->findType( tag );
  155. if( !t ) ex( "Type \""+tag+"\" not found" );
  156. }else t=0;
  157. return t;
  158. }
  159. ////////////////////////////////
  160. // Generate a fresh ASM label //
  161. ////////////////////////////////
  162. string Node::genLabel(){
  163. static int cnt;
  164. return "_"+itoa( ++cnt & 0x7fffffff );
  165. }
  166. //////////////////////////////////////////////////////
  167. // create a stmt-type function call with int result //
  168. //////////////////////////////////////////////////////
  169. TNode *Node::call( const string &func,TNode *a0,TNode *a1,TNode *a2 ){
  170. int size=0;
  171. TNode *t=0;
  172. if( a0 ){
  173. t=move( a0,mem( arg(0) ) );
  174. size+=4;
  175. if( a1 ){
  176. t=seq( t,move( a1,mem( arg(4) ) ) );
  177. size+=4;
  178. if( a2 ){
  179. t=seq( t,move( a2,mem( arg(8) ) ) );
  180. size+=4;
  181. }
  182. }
  183. }
  184. TNode *l=d_new TNode( IR_GLOBAL,0,0,func );
  185. return d_new TNode( IR_CALL,l,t,size );
  186. }
  187. ////////////////////////////////////////////////////////
  188. // create a stmt-type function call with float result //
  189. ////////////////////////////////////////////////////////
  190. TNode *Node::fcall( const string &func,TNode *a0,TNode *a1,TNode *a2 ){
  191. int size=0;
  192. TNode *t=0;
  193. if( a0 ){
  194. t=move( a0,mem( arg(0) ) );
  195. size+=4;
  196. if( a1 ){
  197. t=seq( t,move( a1,mem( arg(4) ) ) );
  198. size+=4;
  199. if( a2 ){
  200. t=seq( t,move( a2,mem( arg(8) ) ) );
  201. size+=4;
  202. }
  203. }
  204. }
  205. TNode *l=d_new TNode( IR_GLOBAL,0,0,func );
  206. return d_new TNode( IR_FCALL,l,t,size );
  207. }
  208. TNode *Node::seq( TNode *l,TNode *r ){
  209. return d_new TNode( IR_SEQ,l,r );
  210. }
  211. TNode *Node::move( TNode *src,TNode *dest ){
  212. return d_new TNode( IR_MOVE,src,dest );
  213. }
  214. TNode *Node::global( const string &s ){
  215. return d_new TNode( IR_GLOBAL,0,0,s );
  216. }
  217. TNode *Node::local( int offset ){
  218. return d_new TNode( IR_LOCAL,0,0,offset );
  219. }
  220. TNode *Node::arg( int offset ){
  221. return d_new TNode( IR_ARG,0,0,offset );
  222. }
  223. TNode *Node::mem( TNode *ref ){
  224. return d_new TNode( IR_MEM,ref,0 );
  225. }
  226. TNode *Node::add( TNode *l,TNode *r ){
  227. return d_new TNode( IR_ADD,l,r );
  228. }
  229. TNode *Node::mul( TNode *l,TNode *r ){
  230. return d_new TNode( IR_MUL,l,r );
  231. }
  232. TNode *Node::iconst( int n ){
  233. return d_new TNode( IR_CONST,0,0,n );
  234. }
  235. TNode *Node::ret(){
  236. return d_new TNode( IR_RET,0,0 );
  237. }
  238. TNode *Node::jsr( const string &s ){
  239. return d_new TNode( IR_JSR,0,0,s );
  240. }
  241. TNode *Node::jump( const string &s ){
  242. return d_new TNode( IR_JUMP,0,0,s );
  243. }
  244. TNode *Node::jumpt( TNode *expr,const string &s ){
  245. return d_new TNode( IR_JUMPT,expr,0,s );
  246. }
  247. TNode *Node::jumpf( TNode *expr,const string &s ){
  248. return d_new TNode( IR_JUMPF,expr,0,s );
  249. }
  250. TNode *Node::jumpge( TNode *l,TNode *r,const string &s ){
  251. return d_new TNode( IR_JUMPGE,l,r,s );
  252. }