stm.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807
  1. #include "std.h"
  2. #include "stm.h"
  3. #include "toker.h"
  4. using namespace CG;
  5. //******************** Stm ************************
  6. Stm::~Stm(){
  7. }
  8. //***************** SourceInfo ********************
  9. void DebugInfoStm::eval( Block *b ){
  10. CGDat *d=genDebugStm( source_info );
  11. if( d ) b->emit( eva(jsr(CG_INT32,CG_CDECL,mem(CG_PTR,sym("bbOnDebugEnterStm",CG_IMPORT),0),d)) );
  12. }
  13. //******************** Rem ************************
  14. void RemStm::eval( Block *b ){
  15. if( comment.size() ) b->emit( rem(comment) );
  16. }
  17. //******************* StmStm **********************
  18. void StmStm::eval( Block *b ){
  19. b->emit( stm );
  20. }
  21. //***************** ClassInits ********************
  22. void EvalClassBlocksStm::eval( Block *b ){
  23. b->evalClassBlocks();
  24. }
  25. //******************* Label ***********************
  26. void LabelStm::eval( Block *b ){
  27. b->emit( CG::lab(goto_sym) );
  28. b->fun_block->dataStms()->push_back( lit(tobstring(restore_sym->value),CG_LABEL) );
  29. }
  30. //******************** Goto ***********************
  31. void GotoStm::eval( Block *b ){
  32. if( strictMode ) fail( "Goto cannot be used in strict mode" );
  33. FunBlock *f=b->fun_block;
  34. map<string,LabelStm*>::iterator it=f->labels.find( tolower(ident) );
  35. if( it==f->labels.end() ) fail( "Label '%s' not found",ident.c_str() );
  36. b->emit( CG::bra( it->second->goto_sym ) );
  37. }
  38. //******************** Eval ***********************
  39. void EvalStm::eval( Block *b ){
  40. Val *v=exp->eval(b);
  41. b->emit(eva(v->cg_exp));
  42. }
  43. //******************** Ctor ***********************
  44. void CtorStm::eval( Block *b ){
  45. CGExp *self=b->fun_block->fun_scope->cg_exp;
  46. CGDat *vtbl=block->class_decl->val->cg_exp->dat();
  47. ClassType *class_ty=block->type;
  48. Val *super_val=class_ty->superVal();
  49. ClassType *super_ty=class_ty->superClass();
  50. //invoke super ctor
  51. if( super_ty ){
  52. if( Val *super_ctor=super_ty->methods.find( "New" ) ){
  53. b->emit( eva( jsr( CG_PTR,CG_CDECL,vfn(super_ctor->cg_exp,self) ) ) );
  54. }
  55. }
  56. //install vtbl
  57. b->emit( mov( mem(CG_PTR,self,0),vtbl ) );
  58. //initialize fields
  59. block->field_ctors->eval();
  60. ctor_new->eval();
  61. }
  62. //******************** Dtor ***********************
  63. void DtorStm::eval( Block *b ){
  64. CGExp *self=b->fun_block->fun_scope->cg_exp;
  65. CGDat *vtbl=block->class_decl->val->cg_exp->dat();
  66. ClassType *class_ty=block->type;
  67. dtor_delete->eval();
  68. //return sym hack - dtor return jumps here...
  69. b->emit(lab(b->fun_block->ret_sym));
  70. b->fun_block->ret_sym=sym();
  71. //destroy fields
  72. for( int k=class_ty->fields.size()-1;k>=0;--k ){
  73. Val *v=class_ty->decls.find( class_ty->fields[k]->ident );
  74. v=v->renameTmps("@self",self);
  75. if( v->refCounted() ){
  76. b->emit( v->release() );
  77. }
  78. }
  79. Val *super_val=class_ty->superVal();
  80. ClassType *super_ty=class_ty->superClass();
  81. //invoke super dtor
  82. while( super_ty ){
  83. if( Val *super_dtor=super_ty->methods.find( "Delete" ) ){
  84. //Don't bother calling root object dtor
  85. if( !super_ty->superClass() ) return;
  86. //install super vtbl
  87. b->emit( mov( mem(CG_PTR,self,0),super_val->cg_exp ) );
  88. //invoke super dtor
  89. b->emit( eva( jsr( CG_PTR,CG_CDECL,vfn(super_dtor->cg_exp,self) ) ) );
  90. return;
  91. }
  92. super_val=super_ty->superVal();
  93. super_ty=super_ty->superClass();
  94. }
  95. /*
  96. //invoke super dtor
  97. if( super_ty ){
  98. //install super vtbl
  99. b->emit( mov( mem(CG_PTR,self,0),super_val->cg_exp ) );
  100. if( Val *super_dtor=super_ty->methods.find( "Delete" ) ){
  101. b->emit( eva( jsr( CG_PTR,CG_CDECL,vfn(super_dtor->cg_exp,self) ) ) );
  102. }
  103. }else{
  104. b->emit( mov( mem(CG_PTR,self,0),lit0 ) );
  105. }
  106. */
  107. }
  108. //***************** Local Decl ********************
  109. void LocalDeclStm::eval( Block *b ){
  110. Val *i=init->evalInit( b,type );
  111. Val *v=new Val(type,tmp(type->cgType()));
  112. Decl *d=new Decl( ident,v );
  113. FunBlock *f=b->fun_block;
  114. if( strictMode ){
  115. b->declLocal( d );
  116. b->initRef( v,i );
  117. }else{
  118. f->declLocal( d );
  119. b->assignRef( v,i );
  120. }
  121. if( !strictMode || opt_debug ){
  122. f->cg_enter->push_back( mov(v->cg_exp,Val::null(type)->cg_exp) );
  123. }
  124. }
  125. //***************** Field Decl ********************
  126. void FieldDeclStm::eval( Block *b ){
  127. Val *i=init->evalInit( b,type );
  128. Val *v=b->fun_block->fun_scope->find( ident );
  129. v=b->linearizeRef(v);
  130. b->initRef( v,i );
  131. }
  132. //***************** Global Decl *******************
  133. void GlobalDeclStm::eval( Block *b ){
  134. Val *i=init->evalInit( b,type );
  135. ClassBlock *cb=dynamic_cast<ClassBlock*>(b);
  136. CGDat *e;
  137. if( cb ){
  138. e=dat(mungMember(cb->class_decl->ident,ident));
  139. }else if( pub ){
  140. e=dat(mungGlobal(ident));
  141. }else{
  142. e=dat();
  143. }
  144. Val *v=new Val(type,mem(type->cgType(),e,0));
  145. Decl *d=new Decl( ident,v );
  146. if( i->constant() ){
  147. CGExp *t=i->cg_exp;
  148. if( i->type->cgType()==CG_INT8 || i->type->cgType()==CG_INT16 ){
  149. t=lit(t->lit()->int_value);
  150. t->type=i->type->cgType();
  151. }
  152. e->push_back( t );
  153. b->emit(eva(e));
  154. }else{
  155. e->push_back( (new Val(Type::null,0))->cast(type)->cg_exp );
  156. b->initGlobalRef( v,i );
  157. }
  158. b->decl(d);
  159. if( pub ) publish( d );
  160. }
  161. //***************** Extern Decl ******************
  162. void ExternDeclStm::eval( Block *b ){
  163. if( !cg ) cg=sym(ident,CG_IMPORT);
  164. switch( toke ){
  165. case T_GLOBAL:cg=mem(type->cgType(),cg,0);break;
  166. default:assert(0);
  167. }
  168. Decl *d=new Decl(ident,type,cg);
  169. b->decl(d);
  170. if( pub ) publish( d );
  171. }
  172. //****************** Import ***********************
  173. void ImportStm::eval( Block *b ){
  174. b->emit( eva(jsr(CG_INT32,CG_CDECL,entry)) );
  175. }
  176. //****************** Incbin ***********************
  177. IncbinStm::IncbinStm( string n ):name(n),path(realpath(n)){
  178. }
  179. void IncbinStm::eval( Block *b ){
  180. if( b!=mainFun ) fail( "Incbin can only be used in main program block" );
  181. Val *v=new Val( tobstring(name) );
  182. CGDat *d=dat();
  183. CGSym *q=sym();
  184. d->push_back(lit(tobstring(path),CG_BINFILE));
  185. d->push_back(lit(tobstring(q->value),CG_LABEL));
  186. b->cg_enter->push_back( eva(jsr(CG_INT32,"bbIncbinAdd",v->cg_exp,d,bop(CG_SUB,q,d))) );
  187. }
  188. //****************** Assign ***********************
  189. void AssignStm::eval( Block *b ){
  190. Val *v=lhs->evalRef(b);
  191. b->assignRef( v,rhs->evalInit(b,v->type) );
  192. }
  193. //****************** OpAssign *********************
  194. void OpAssignStm::eval( Block *b ){
  195. Val *v=lhs->evalRef(b);
  196. switch( op ){
  197. case T_ADDASSIGN:rhs=new ArithExp('+',v,rhs);break;
  198. case T_SUBASSIGN:rhs=new ArithExp('-',v,rhs);break;
  199. case T_MULASSIGN:rhs=new ArithExp('*',v,rhs);break;
  200. case T_DIVASSIGN:rhs=new ArithExp('/',v,rhs);break;
  201. case T_MODASSIGN:rhs=new ArithExp(T_MOD,v,rhs);break;
  202. case T_ORASSIGN:rhs=new BitwiseExp('|',v,rhs);break;
  203. case T_ANDASSIGN:rhs=new BitwiseExp('&',v,rhs);break;
  204. case T_XORASSIGN:rhs=new BitwiseExp('~',v,rhs);break;
  205. case T_SHLASSIGN:rhs=new BitwiseExp(T_SHL,v,rhs);break;
  206. case T_SHRASSIGN:rhs=new BitwiseExp(T_SHR,v,rhs);break;
  207. case T_SARASSIGN:rhs=new BitwiseExp(T_SAR,v,rhs);break;
  208. default:assert(0);
  209. }
  210. b->assignRef( v,rhs->eval(b,v->type) );
  211. }
  212. //***************** If Then Else ******************
  213. void IfStm::eval( Block *b ){
  214. Val *v=exp->eval(b)->cond();
  215. CGSym *t_sym=sym();
  216. b->emit( bcc(CG_EQ,v->cg_exp,lit0,t_sym) );
  217. then_block->eval();
  218. if( else_block ){
  219. CGSym *t_sym2=sym();
  220. b->emit( bra(t_sym2) );
  221. b->emit( lab(t_sym) );
  222. t_sym=t_sym2;
  223. else_block->eval();
  224. }
  225. b->emit(lab(t_sym));
  226. }
  227. //***************** Loop control ******************
  228. void LoopCtrlStm::eval( Block *b ){
  229. LoopBlock *loop=0;
  230. FunBlock *f=b->fun_block;
  231. Block *p=b;
  232. while( p!=f ){
  233. b->emit( p->cg_leave );
  234. if( loop=dynamic_cast<LoopBlock*>(p) ){
  235. if( !label.size() || label==loop->label ) break;
  236. }
  237. p=p->outer;
  238. }
  239. if( p==f ){
  240. if( !loop ){
  241. fail( "Continue/Exit must appear inside a loop" );
  242. }else{
  243. fail( "Continue/Exit label '%s' not found",label.c_str() );
  244. }
  245. }
  246. if( toke==T_CONTINUE ){
  247. b->emit( bra(loop->cont_sym) );
  248. }else{
  249. b->emit( bra(loop->exit_sym) );
  250. }
  251. }
  252. //****************** For/Next *********************
  253. void ForStm::eval( Block *b ){
  254. Val *v=var->evalRef(b);
  255. Type *ty=v->type;
  256. if( !ty->numericType() ) fail( "Loop index variable must be of numeric type" );
  257. Val *init_val=init->eval(b)->cast(ty);
  258. Val *to_val=to->eval(b)->cast(ty);
  259. Val *step_val;
  260. if( step ){
  261. step_val=step->eval(b)->cast(ty);
  262. if( !step_val->constant() ) fail( "Step expression must be constant" );
  263. }else{
  264. step_val=(new Val(1))->cast(ty);
  265. }
  266. int bcc_cc=CG_LE;
  267. if( ty->intType() && step_val->intValue()<0 ) bcc_cc=CG_GE;
  268. if( ty->floatType() && step_val->floatValue()<0 ) bcc_cc=CG_GE;
  269. if( until ) bcc_cc=(bcc_cc==CG_LE) ? CG_LT : CG_GT;
  270. CGSym *t_sym=sym();
  271. b->assignRef( v,init_val );
  272. CGExp *var_exp=v->cg_exp;
  273. if( !to_val->constant() ){
  274. CGTmp *t=tmp(ty->cgType());
  275. b->emit(mov(t,to_val->cg_exp));
  276. to_val=new Val(ty,t);
  277. }
  278. b->emit(bra(t_sym));
  279. b->emit(lab(block->loop_sym));
  280. block->eval();
  281. b->emit(lab(block->cont_sym));
  282. b->emit(mov(var_exp,bop(CG_ADD,var_exp,step_val->cg_exp)));
  283. b->emit(lab(t_sym));
  284. b->emit(bcc(bcc_cc,var_exp,to_val->cg_exp,block->loop_sym));
  285. b->emit(lab(block->exit_sym));
  286. }
  287. //****************** For Each *********************
  288. void ForEachStm::checkInt32Method( Val *v ){
  289. if( v ){
  290. if( FunType *ty=v->type->funType() ){
  291. if( ty->method() ){
  292. if( !ty->args.size() ){
  293. if( ty->return_type->intType() && ty->size()==4 ) return;
  294. }
  295. }
  296. }
  297. }
  298. fail( "Illegal EachIn expression" );
  299. }
  300. ObjectType *ForEachStm::checkObjMethod( Val *v ){
  301. if( v ){
  302. if( FunType *ty=v->type->funType() ){
  303. if( ty->method() ){
  304. if( !ty->args.size() ){
  305. if( ObjectType *t=ty->return_type->objectType() ) return t;
  306. }
  307. }
  308. }
  309. }
  310. fail( "Illegal EachIn expression" );
  311. return 0;
  312. }
  313. void ForEachStm::eval( Block *b ){
  314. Val *v=var->evalRef(b);
  315. Val *t=coll->eval(b);
  316. if( !t->type->arrayType() && !t->type->objectType() ){
  317. fail( "EachIn must be used with a string, array, or appropriate object" );
  318. }
  319. Val *c=new Val( t->type,tmp(CG_PTR) );
  320. b->emit( mov(c->cg_exp,t->cg_exp) );
  321. if( c->type->arrayType() ){
  322. evalArray( b,v,c );
  323. }else{
  324. evalCollection( b,v,c );
  325. }
  326. }
  327. void ForEachStm::evalArray( Block *b,Val *var,Val *coll ){
  328. Type *var_ty=var->type;
  329. ArrayType *arr_ty=coll->type->arrayType();
  330. Type *elem_ty=arr_ty->element_type;
  331. Val *arr=new Val( arr_ty,tmp(CG_PTR) );
  332. CGTmp *beg=tmp(CG_PTR);
  333. beg->owner=coll->cg_exp->tmp();
  334. CGTmp *end=tmp(CG_PTR);
  335. end->owner=coll->cg_exp->tmp();
  336. Val *next=new Val(elem_ty,mem(elem_ty->cgType(),beg,0));
  337. b->emit( mov(beg,bop(CG_ADD,coll->cg_exp,lit(20+arr_ty->dims*4))) );
  338. b->emit( mov(end,bop(CG_ADD,beg,mem(CG_INT32,coll->cg_exp,16))) );
  339. b->emit( bra(block->cont_sym) );
  340. //loop
  341. b->emit( lab(block->loop_sym) );
  342. b->assignRef( var,next->forEachCast(var_ty) );
  343. b->emit( mov(beg,bop(CG_ADD,beg,lit(elem_ty->size()))) );
  344. if( var_ty->objectType() ) b->emit( bcc(CG_EQ,var->cg_exp,sym("bbNullObject",CG_IMPORT),block->cont_sym) );
  345. //statements!
  346. block->eval();
  347. //continue
  348. b->emit( lab(block->cont_sym) );
  349. b->emit( bcc(CG_NE,beg,end,block->loop_sym) );
  350. //exit
  351. b->emit( lab(block->exit_sym) );
  352. }
  353. void ForEachStm::evalCollection( Block *b,Val *var,Val *coll ){
  354. ObjectType *var_ty=var->type->objectType();
  355. if( !var_ty ) fail( "EachIn index variable must be an object" );
  356. ObjectType *coll_ty=coll->type->objectType();
  357. Val *enumer=coll->find( "ObjectEnumerator" );
  358. ObjectType *enumer_ty=checkObjMethod( enumer );
  359. Val *enumer_tmp=new Val( enumer_ty,tmp(CG_PTR) );
  360. enumer_tmp->cg_exp->tmp()->owner=coll->cg_exp->tmp();
  361. Val *enumer_jsr=new Val( enumer_ty,jsr(CG_PTR,CG_CDECL,enumer->cg_exp) );
  362. Val *hasnext=enumer_tmp->find( "HasNext" );
  363. checkInt32Method( hasnext );
  364. Val *nextobj=enumer_tmp->find( "NextObject" );
  365. ObjectType *nextobj_ty=checkObjMethod( nextobj );
  366. Val *hasnext_jsr=new Val( Type::int32,jsr(CG_INT32,CG_CDECL,hasnext->cg_exp) );
  367. Val *nextobj_jsr=new Val( nextobj_ty,jsr(CG_PTR,CG_CDECL,nextobj->cg_exp) );
  368. //invoke 'ObjectEnumerator'
  369. b->emit( mov(enumer_tmp->cg_exp,enumer_jsr->cg_exp) );
  370. b->emit( bra(block->cont_sym) );
  371. //loop
  372. b->emit( lab(block->loop_sym) );
  373. b->assignRef( var,nextobj_jsr->forEachCast(var_ty) );
  374. b->emit( bcc(CG_EQ,var->cg_exp,sym("bbNullObject",CG_IMPORT),block->cont_sym) );
  375. //statements!
  376. block->eval();
  377. //continue
  378. b->emit( lab(block->cont_sym) );
  379. //invoke 'HasNext'
  380. b->emit( bcc(CG_NE,hasnext_jsr->cg_exp,lit0,block->loop_sym) );
  381. //exit
  382. b->emit( lab(block->exit_sym) );
  383. }
  384. //******************* While ***********************
  385. void WhileStm::eval( Block *b ){
  386. Val *v=exp->eval(b)->cond();
  387. b->emit(bra(block->cont_sym));
  388. b->emit(lab(block->loop_sym));
  389. block->eval();
  390. b->emit(lab(block->cont_sym));
  391. b->emit(bcc(CG_NE,v->cg_exp,lit0,block->loop_sym));
  392. b->emit(lab(block->exit_sym));
  393. }
  394. //****************** Repeat ***********************
  395. void RepeatStm::eval( Block *b ){
  396. b->emit(lab(block->loop_sym));
  397. if( !exp ) b->emit(lab(block->cont_sym));
  398. block->eval();
  399. ::source_info=source_info;
  400. if( exp ){
  401. Val *v=exp->eval(b)->cond();
  402. b->emit(lab(block->cont_sym));
  403. b->emit(bcc(CG_EQ,v->cg_exp,lit0,block->loop_sym));
  404. }else{
  405. b->emit(bra(block->loop_sym));
  406. }
  407. b->emit(lab(block->exit_sym));
  408. }
  409. //****************** Return ***********************
  410. void ReturnStm::eval( Block *b ){
  411. FunBlock *f=b->fun_block;
  412. Type *ty=f->type->return_type;
  413. if( exp ){
  414. if( strictMode>1 && (f->type->attrs & FunType::VOIDFUN) ) fail( "Function can not return a value" );
  415. }else{
  416. if( strictMode>1 && !(f->type->attrs & FunType::VOIDFUN) ) fail( "Function must return a value" );
  417. exp=new NullExp();
  418. }
  419. Val *v=exp->eval(b,ty);
  420. b->emit( mov(f->ret_tmp,v->cg_exp) );
  421. Block *t=b;
  422. while( t!=f ){
  423. b->emit(t->cg_leave);
  424. t=t->outer;
  425. }
  426. b->emit( bra(f->ret_sym) );
  427. }
  428. //****************** Release **********************
  429. void ReleaseStm::eval( Block *b ){
  430. Val *v=exp->evalRef(b);
  431. Type *ty=v->type;
  432. if( ty->cgType()==CG_INT32 ){
  433. b->emit( eva(jsr(CG_INT32,"bbHandleRelease",v->cg_exp)) );
  434. b->emit( mov(v->cg_exp,cvt(v->type->cgType(),lit0)) );
  435. }else{
  436. fail( "Subexpression for release must be an integer variable" );
  437. }
  438. }
  439. //****************** delete ***********************
  440. void DeleteStm::eval( Block *b ){
  441. Val *v=exp->eval(b);
  442. ObjectType *ty=v->type->objectType();
  443. if( !ty ) fail( "'Delete' expression does not evaluate to an object" );
  444. b->emit( eva(jsr(CG_INT32,"bbObjectDelete",v->cg_exp)) );
  445. }
  446. //****************** assert ***********************
  447. void AssertStm::eval( Block *b ){
  448. Val *e=exp->eval(b)->cond();
  449. Val *m=msg->eval(b)->cast( Type::stringObject );
  450. if( !opt_debug ) return;
  451. CGSym *q=sym();
  452. b->emit( bcc(CG_NE,e->cg_exp,lit0,q) );
  453. b->emit( eva(jsr(CG_INT32,"brl_blitz_RuntimeError",m->cg_exp)) );
  454. b->emit( lab(q) );
  455. }
  456. //******************** end ************************
  457. void EndStm::eval( Block *b ){
  458. b->emit( eva(jsr(CG_INT32,"bbEnd")) );
  459. }
  460. //***************** select/case *******************
  461. void SelectStm::eval( Block *b ){
  462. Val *tv=exp->eval(b);
  463. Type *ty=tv->type;
  464. Val *t_val=new Val(ty,tmp(ty->cgType()));
  465. b->emit( mov(t_val->cg_exp,tv->cg_exp) );
  466. CGSym *end=sym();
  467. vector<CGSym*> case_syms;
  468. int k;
  469. for( k=0;k<cases.size();++k ){
  470. SelCase *t=cases[k];
  471. ::source_info=t->source_info;
  472. case_syms.push_back( sym() );
  473. for( int j=0;j<t->exps.size();++j ){
  474. Val *r=t->exps[j]->eval( b,ty );
  475. if( ty->stringType() ){
  476. b->emit(
  477. bcc(CG_EQ,
  478. jsr(CG_INT32,"bbStringCompare",t_val->cg_exp,r->cg_exp),
  479. lit0,case_syms.back()) );
  480. }else{
  481. b->emit(
  482. bcc(CG_EQ,t_val->cg_exp,r->cg_exp,case_syms.back()) );
  483. }
  484. }
  485. }
  486. if( _default ) _default->eval();
  487. b->emit( bra(end) );
  488. for( k=0;k<cases.size();++k ){
  489. b->emit( lab(case_syms[k]) );
  490. Block *block=cases[k]->block;
  491. block->eval();
  492. b->emit( bra(end) );
  493. }
  494. b->emit( lab(end) );
  495. }
  496. //********************** Try *************************
  497. void TryStm::eval( Block *b ){
  498. block->cg_leave->push_back(eva(jsr(CG_INT32,"bbExLeave")));
  499. CGTmp *ex_tmp=tmp(CG_PTR);
  500. CGSym *catch_sym=sym(),*exit_sym=sym();
  501. if( opt_debug ) b->emit( eva(jsr(CG_INT32,CG_CDECL,mem(CG_PTR,sym("bbOnDebugPushExState",CG_IMPORT),0))) );
  502. b->emit( mov(ex_tmp,jsr(CG_PTR,"bbExEnter")) );
  503. b->emit( mov(ex_tmp,jsr(CG_PTR,"_bbExEnter",ex_tmp)) );
  504. b->emit( bcc(CG_NE,ex_tmp,lit0,catch_sym) );
  505. if( opt_debug ) block->cg_leave->push_back( eva(jsr(CG_INT32,CG_CDECL,mem(CG_PTR,sym("bbOnDebugPopExState",CG_IMPORT),0))) );
  506. block->eval();
  507. b->emit( bra(exit_sym) );
  508. b->emit( lab(catch_sym) );
  509. if( opt_debug ) b->emit( eva(jsr(CG_INT32,CG_CDECL,mem(CG_PTR,sym("bbOnDebugPopExState",CG_IMPORT),0))) );
  510. //exception thrown!
  511. vector<CGSym*> catch_syms;
  512. int k;
  513. for( k=0;k<catches.size();++k ){
  514. TryCatch *t=catches[k];
  515. catch_syms.push_back( sym() );
  516. ObjectType *type=t->type->objectType();
  517. if( !type ) fail( "'Catch' variables must be objects" );
  518. CGTmp *catch_tmp=tmp(CG_PTR);
  519. t->block->declLocal( new Decl(t->ident,type,catch_tmp) );
  520. b->emit( mov(catch_tmp,jsr(CG_PTR,"bbObjectDowncast",ex_tmp,type->class_val->cg_exp)) );
  521. b->emit( bcc(CG_NE,catch_tmp,sym("bbNullObject",CG_IMPORT),catch_syms.back()) );
  522. }
  523. b->emit( eva(jsr(CG_INT32,"bbExThrow",ex_tmp)) );
  524. for( k=0;k<catches.size();++k ){
  525. TryCatch *t=catches[k];
  526. b->emit( lab(catch_syms[k]) );
  527. t->block->eval();
  528. b->emit( bra(exit_sym) );
  529. }
  530. b->emit( lab(exit_sym) );
  531. }
  532. //******************** Throw *************************
  533. void ThrowStm::eval( Block *b ){
  534. Val *val=exp->eval( b );
  535. if( !val->type->objectType() ) fail( "'Throw' expression must be an object" );
  536. b->emit( eva(jsr(CG_INT32,"bbExThrow",val->cg_exp)) );
  537. }
  538. //********************* Data *************************
  539. void DataStm::eval( Block *b ){
  540. int k;
  541. if( b!=mainFun ) fail( "Data can only be declared in main program" );
  542. FunBlock *f=mainFun;
  543. CGDat *d=f->dataStms();
  544. for( k=0;k<exps.size();++k ){
  545. Val *v=exps[k]->eval( b );
  546. if( v->type->nullType() ) fail( "Data items can not be 'Null'" );
  547. if( !v->constant() ) fail( "Data items must be constant" );
  548. if( v->type->intType() ) v=v->cast(Type::int32);
  549. string t;
  550. switch( v->type->encoding()[0] ){
  551. case 'i':t="bbIntTypeTag";break;
  552. case 'f':t="bbFloatTypeTag";break;
  553. case 'd':t="bbDoubleTypeTag";break;
  554. case '$':t="bbStringTypeTag";break;
  555. default:fail( "Data items must be numeric or strings" );
  556. }
  557. d->push_back( sym(t,CG_IMPORT) );
  558. d->push_back( v->cg_exp );
  559. }
  560. }
  561. //******************** Restore ***********************
  562. void RestoreStm::eval( Block *b ){
  563. FunBlock *f=mainFun;
  564. map<string,LabelStm*>::iterator it=f->labels.find( tolower(ident) );
  565. if( it==f->labels.end() ) fail( "Label '%s' not found",ident.c_str() );
  566. b->emit( mov(mem(CG_PTR,f->dataPtr(),0),it->second->restore_sym) );
  567. }
  568. //********************* Read *************************
  569. void ReadStm::eval( Block *b ){
  570. int k;
  571. FunBlock *f=mainFun;
  572. CGDat *d=f->dataPtr();
  573. CGTmp *p=tmp(CG_PTR);
  574. CGTmp *q=tmp(CG_PTR);
  575. b->emit( mov(p,mem(CG_PTR,d,0)) );
  576. for( k=0;k<exps.size();++k ){
  577. Val *v=exps[k]->evalRef( b );
  578. Type *ty=v->type;
  579. if( !ty->refType() ) fail( "Read may only be used with variables" );
  580. if( !ty->numericType() && !ty->stringType() ) fail( "Read may only be used with numeric or string variables" );
  581. string f;
  582. int cg_ty;
  583. if( ty->intType() ){
  584. f="bbConvertToInt";
  585. cg_ty=CG_INT32;
  586. }else if( ty->floatType() ){
  587. f="bbConvertToFloat";
  588. cg_ty=CG_FLOAT64;
  589. }else if( ty->stringType() ){
  590. f="bbConvertToString";
  591. cg_ty=CG_PTR;
  592. }else{
  593. fail( "Read may only be used with numeric or string variables" );
  594. }
  595. b->emit( mov(q,mem(CG_PTR,p,0)) );
  596. if( opt_debug ){
  597. CGSym *skip=sym();
  598. b->emit( bcc(CG_NE,q,lit0,skip) );
  599. b->emit( eva(jsr(CG_INT32,"brl_blitz_OutOfDataError")) );
  600. b->emit( lab(skip) );
  601. }
  602. b->emit( mov(q,mem(CG_PTR,q,0)) );
  603. b->emit( mov(p,bop(CG_ADD,p,lit(4))) );
  604. CGExp *e=cvt(ty->cgType(),jsr(cg_ty,f,p,q));
  605. b->assignRef( v,new Val(ty,e) );
  606. b->emit( mov(p,bop(CG_ADD,p,lit(4))) );
  607. CGSym *skip=sym();
  608. b->emit( bcc(CG_NE,mem(CG_INT8,q,0),lit('d'),skip) );
  609. b->emit( mov(p,bop(CG_ADD,p,lit(4))) );
  610. b->emit( lab(skip) );
  611. }
  612. b->emit( mov(mem(CG_PTR,d,0),p) );
  613. }