stmtnode.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  1. #include "std.h"
  2. #include "nodes.h"
  3. static string fileLabel;
  4. static map<string,string> fileMap;
  5. void StmtNode::debug( int pos,Codegen *g ){
  6. if( g->debug ){
  7. TNode *t=fileLabel.size() ? global( fileLabel ) : iconst(0);
  8. g->code( call( "__bbDebugStmt",iconst( pos ),t ) );
  9. }
  10. }
  11. void StmtSeqNode::reset( const string &file,const string &lab ){
  12. fileLabel="";
  13. fileMap.clear();
  14. fileMap[file]=lab;
  15. }
  16. ////////////////////////
  17. // Statement Sequence //
  18. ////////////////////////
  19. void StmtSeqNode::semant( Environ *e ){
  20. for( int k=0;k<stmts.size();++k ){
  21. try{ stmts[k]->semant( e ); }
  22. catch( Ex &x ){
  23. if( x.pos<0 ) x.pos=stmts[k]->pos;
  24. if( !x.file.size() ) x.file=file;
  25. throw;
  26. }
  27. }
  28. }
  29. void StmtSeqNode::translate( Codegen *g ){
  30. string t=fileLabel;
  31. fileLabel=file.size() ? fileMap[file] : "";
  32. for( int k=0;k<stmts.size();++k ){
  33. StmtNode *stmt=stmts[k];
  34. stmt->debug( stmts[k]->pos,g );
  35. try{
  36. stmt->translate( g );
  37. }
  38. catch( Ex &x ){
  39. if( x.pos<0 ) x.pos=stmts[k]->pos;
  40. if( !x.file.size() ) x.file=file;
  41. throw;
  42. }
  43. }
  44. fileLabel=t;
  45. }
  46. /////////////////
  47. // An Include! //
  48. /////////////////
  49. void IncludeNode::semant( Environ *e ){
  50. label=genLabel();
  51. fileMap[file]=label;
  52. stmts->semant( e );
  53. }
  54. void IncludeNode::translate( Codegen *g ){
  55. if( g->debug ) g->s_data( file,label );
  56. stmts->translate( g );
  57. }
  58. ///////////////////
  59. // a declaration //
  60. ///////////////////
  61. void DeclStmtNode::semant( Environ *e ){
  62. decl->proto( e->decls,e );
  63. decl->semant( e );
  64. }
  65. void DeclStmtNode::translate( Codegen *g ){
  66. decl->translate( g );
  67. }
  68. //////////////////////////////
  69. // Dim AND declare an Array //
  70. //////////////////////////////
  71. void DimNode::semant( Environ *e ){
  72. Type *t=tagType( tag,e );
  73. if( Decl *d=e->findDecl( ident ) ){
  74. ArrayType *a=d->type->arrayType();
  75. if( !a || a->dims!=exprs->size() || (t && a->elementType!=t) ){
  76. ex( "Duplicate identifier" );
  77. }
  78. sem_type=a;sem_decl=0;
  79. }else{
  80. if( e->level>0 ) ex( "Array not found in main program" );
  81. if( !t ) t=Type::int_type;
  82. sem_type=d_new ArrayType( t,exprs->size() );
  83. sem_decl=e->decls->insertDecl( ident,sem_type,DECL_ARRAY );
  84. e->types.push_back( sem_type );
  85. }
  86. exprs->semant( e );
  87. exprs->castTo( Type::int_type,e );
  88. }
  89. void DimNode::translate( Codegen *g ){
  90. TNode *t;
  91. g->code( call( "__bbUndimArray",global( "_a"+ident ) ) );
  92. for( int k=0;k<exprs->size();++k ){
  93. t=add( global( "_a"+ident ),iconst( k*4+12 ) );
  94. t=move( exprs->exprs[k]->translate(g),mem( t ) );
  95. g->code( t );
  96. }
  97. g->code( call( "__bbDimArray",global( "_a"+ident ) ) );
  98. if( !sem_decl ) return;
  99. int et;
  100. Type *ty=sem_type->arrayType()->elementType;
  101. if( ty==Type::int_type ) et=1;
  102. else if( ty==Type::float_type ) et=2;
  103. else if( ty==Type::string_type ) et=3;
  104. else et=5;
  105. g->align_data( 4 );
  106. g->i_data( 0,"_a"+ident );
  107. g->i_data( et );
  108. g->i_data( exprs->size() );
  109. for( k=0;k<exprs->size();++k ) g->i_data( 0 );
  110. }
  111. ////////////////
  112. // Assignment //
  113. ////////////////
  114. void AssNode::semant( Environ *e ){
  115. var->semant( e );
  116. if( var->sem_type->constType() ) ex( "Constants can not be assigned to" );
  117. if( var->sem_type->vectorType() ) ex( "Blitz arrays can not be assigned to" );
  118. expr=expr->semant( e );
  119. expr=expr->castTo( var->sem_type,e );
  120. }
  121. void AssNode::translate( Codegen *g ){
  122. g->code( var->store( g,expr->translate( g ) ) );
  123. }
  124. //////////////////////////
  125. // Expression statement //
  126. //////////////////////////
  127. void ExprStmtNode::semant( Environ *e ){
  128. expr=expr->semant( e );
  129. }
  130. void ExprStmtNode::translate( Codegen *g ){
  131. TNode *t=expr->translate( g );
  132. if( expr->sem_type==Type::string_type ) t=call( "__bbStrRelease",t );
  133. g->code( t );
  134. }
  135. ////////////////
  136. // user label //
  137. ////////////////
  138. void LabelNode::semant( Environ *e ){
  139. if( Label *l=e->findLabel( ident ) ){
  140. if( l->def>=0 ) ex( "duplicate label" );
  141. l->def=pos;l->data_sz=data_sz;
  142. }else e->insertLabel( ident,pos,-1,data_sz );
  143. ident=e->funcLabel+ident;
  144. }
  145. void LabelNode::translate( Codegen *g ){
  146. g->label( "_l"+ident );
  147. }
  148. //////////////////
  149. // Restore data //
  150. //////////////////
  151. void RestoreNode::semant( Environ *e ){
  152. if( e->level>0 ) e=e->globals;
  153. if( ident.size()==0 ) sem_label=0;
  154. else{
  155. sem_label=e->findLabel( ident );
  156. if( !sem_label ) sem_label=e->insertLabel( ident,-1,pos,-1 );
  157. }
  158. }
  159. void RestoreNode::translate( Codegen *g ){
  160. TNode *t=global( "__DATA" );
  161. if( sem_label ) t=add( t,iconst( sem_label->data_sz*8 ) );
  162. g->code( call( "__bbRestore",t ) );
  163. }
  164. ////////////////////
  165. // Goto statement //
  166. ////////////////////
  167. void GotoNode::semant( Environ *e ){
  168. if( !e->findLabel( ident ) ){
  169. e->insertLabel( ident,-1,pos,-1 );
  170. }
  171. ident=e->funcLabel+ident;
  172. }
  173. void GotoNode::translate( Codegen *g ){
  174. g->code( jump( "_l"+ident ) );
  175. }
  176. /////////////////////
  177. // Gosub statement //
  178. /////////////////////
  179. void GosubNode::semant( Environ *e ){
  180. if( e->level>0 ) ex( "'Gosub' may not be used inside a function" );
  181. if( !e->findLabel( ident ) ) e->insertLabel( ident,-1,pos,-1 );
  182. ident=e->funcLabel+ident;
  183. }
  184. void GosubNode::translate( Codegen *g ){
  185. g->code( jsr( "_l"+ident ) );
  186. }
  187. //////////////////
  188. // If statement //
  189. //////////////////
  190. void IfNode::semant( Environ *e ){
  191. expr=expr->semant( e );
  192. expr=expr->castTo( Type::int_type,e );
  193. stmts->semant( e );
  194. if( elseOpt ) elseOpt->semant( e );
  195. }
  196. void IfNode::translate( Codegen *g ){
  197. if( ConstNode *c=expr->constNode() ){
  198. if( c->intValue() ) stmts->translate( g );
  199. else if( elseOpt ) elseOpt->translate( g );
  200. }else{
  201. string _else=genLabel();
  202. g->code( jumpf( expr->translate( g ),_else ) );
  203. stmts->translate( g );
  204. if( elseOpt ){
  205. string _else2=genLabel();
  206. g->code( jump( _else2 ) );
  207. g->label( _else );
  208. elseOpt->translate( g );
  209. _else=_else2;
  210. }
  211. g->label( _else );
  212. }
  213. }
  214. ///////////
  215. // Break //
  216. ///////////
  217. void ExitNode::semant( Environ *e ){
  218. sem_brk=e->breakLabel;
  219. if( !sem_brk.size() ) ex( "break must appear inside a loop" );
  220. }
  221. void ExitNode::translate( Codegen *g ){
  222. g->code( d_new TNode( IR_JUMP,0,0,sem_brk ) );
  223. }
  224. /////////////////////
  225. // While statement //
  226. /////////////////////
  227. void WhileNode::semant( Environ *e ){
  228. expr=expr->semant( e );
  229. expr=expr->castTo( Type::int_type,e );
  230. string brk=e->setBreak( sem_brk=genLabel() );
  231. stmts->semant( e );
  232. e->setBreak( brk );
  233. }
  234. void WhileNode::translate( Codegen *g ){
  235. string loop=genLabel();
  236. if( ConstNode *c=expr->constNode() ){
  237. if( !c->intValue() ) return;
  238. g->label( loop );
  239. stmts->translate( g );
  240. g->code( jump( loop ) );
  241. }else{
  242. string cond=genLabel();
  243. g->code( jump( cond ) );
  244. g->label( loop );
  245. stmts->translate( g );
  246. debug( wendPos,g );
  247. g->label( cond );
  248. g->code( jumpt( expr->translate( g ),loop ) );
  249. }
  250. g->label( sem_brk );
  251. }
  252. ///////////////////
  253. // For/Next loop //
  254. ///////////////////
  255. ForNode::ForNode( VarNode *var,ExprNode *from,ExprNode *to,ExprNode *step,StmtSeqNode *ss,int np )
  256. :var(var),fromExpr(from),toExpr(to),stepExpr(step),stmts(ss),nextPos(np){
  257. }
  258. ForNode::~ForNode(){
  259. delete stmts;
  260. delete stepExpr;
  261. delete toExpr;
  262. delete fromExpr;
  263. delete var;
  264. }
  265. void ForNode::semant( Environ *e ){
  266. var->semant( e );
  267. Type *ty=var->sem_type;
  268. if( ty->constType() ) ex( "Index variable can not be constant" );
  269. if( ty!=Type::int_type && ty!=Type::float_type ){
  270. ex( "index variable must be integer or real" );
  271. }
  272. fromExpr=fromExpr->semant( e );
  273. fromExpr=fromExpr->castTo( ty,e );
  274. toExpr=toExpr->semant( e );
  275. toExpr=toExpr->castTo( ty,e );
  276. stepExpr=stepExpr->semant( e );
  277. stepExpr=stepExpr->castTo( ty,e );
  278. if( !stepExpr->constNode() ) ex( "Step value must be constant" );
  279. string brk=e->setBreak( sem_brk=genLabel() );
  280. stmts->semant( e );
  281. e->setBreak( brk );
  282. }
  283. void ForNode::translate( Codegen *g ){
  284. TNode *t;Type *ty=var->sem_type;
  285. //initial assignment
  286. g->code( var->store( g,fromExpr->translate( g ) ) );
  287. string cond=genLabel();
  288. string loop=genLabel();
  289. g->code( jump( cond ) );
  290. g->label( loop );
  291. stmts->translate( g );
  292. //execute the step part
  293. debug( nextPos,g );
  294. int op=ty==Type::int_type ? IR_ADD : IR_FADD;
  295. t=d_new TNode( op,var->load( g ),stepExpr->translate( g ) );
  296. g->code( var->store( g,t ) );
  297. //test for loop cond
  298. g->label( cond );
  299. op=stepExpr->constNode()->floatValue()>0 ? '>' : '<';
  300. t=compare( op,var->load( g ),toExpr->translate( g ),ty );
  301. g->code( jumpf( t,loop ) );
  302. g->label( sem_brk );
  303. }
  304. ///////////////////////////////
  305. // For each object of a type //
  306. ///////////////////////////////
  307. void ForEachNode::semant( Environ *e ){
  308. var->semant( e );
  309. Type *ty=var->sem_type;
  310. if( ty->structType()==0 ) ex( "Index variable is not a NewType" );
  311. Type *t=e->findType( typeIdent );
  312. if( !t ) ex( "Type name not found" );
  313. if( t!=ty ) ex( "Type mismatch" );
  314. string brk=e->setBreak( sem_brk=genLabel() );
  315. stmts->semant( e );
  316. e->setBreak( brk );
  317. }
  318. void ForEachNode::translate( Codegen *g ){
  319. TNode *t,*l,*r;
  320. string _loop=genLabel();
  321. string objFirst,objNext;
  322. if( var->isObjParam() ){
  323. objFirst="__bbObjEachFirst2";
  324. objNext="__bbObjEachNext2";
  325. }else{
  326. objFirst="__bbObjEachFirst";
  327. objNext="__bbObjEachNext";
  328. }
  329. l=var->translate( g );
  330. r=global( "_t"+typeIdent );
  331. t=jumpf( call( objFirst,l,r ),sem_brk );
  332. g->code( t );
  333. g->label( _loop );
  334. stmts->translate( g );
  335. debug( nextPos,g );
  336. t=jumpt( call( objNext,var->translate( g ) ),_loop );
  337. g->code( t );
  338. g->label( sem_brk );
  339. }
  340. ////////////////////////////
  341. // Return from a function //
  342. ////////////////////////////
  343. void ReturnNode::semant( Environ *e ){
  344. if( e->level<=0 && expr ){
  345. ex( "Main program cannot return a value" );
  346. }
  347. if( e->level>0 ){
  348. if( !expr ){
  349. if( e->returnType==Type::float_type ){
  350. expr=d_new FloatConstNode( 0 );
  351. }else if( e->returnType==Type::string_type ){
  352. expr=d_new StringConstNode( "" );
  353. }else if( e->returnType->structType() ){
  354. expr=d_new NullNode();
  355. }else{
  356. expr=d_new IntConstNode( 0 );
  357. }
  358. }
  359. expr=expr->semant( e );
  360. expr=expr->castTo( e->returnType,e );
  361. returnLabel=e->funcLabel+"_leave";
  362. }
  363. }
  364. void ReturnNode::translate( Codegen *g ){
  365. if( !expr ){
  366. g->code( d_new TNode( IR_RET,0,0 ) );
  367. return;
  368. }
  369. TNode *t=expr->translate( g );
  370. if( expr->sem_type==Type::float_type ){
  371. g->code( d_new TNode( IR_FRETURN,t,0,returnLabel ) );
  372. }else{
  373. g->code( d_new TNode( IR_RETURN,t,0,returnLabel ) );
  374. }
  375. }
  376. //////////////////////
  377. // Delete statement //
  378. //////////////////////
  379. void DeleteNode::semant( Environ *e ){
  380. expr=expr->semant( e );
  381. if( expr->sem_type->structType()==0 ) ex( "Can't delete non-Newtype" );
  382. }
  383. void DeleteNode::translate( Codegen *g ){
  384. TNode *t=expr->translate( g );
  385. g->code( call( "__bbObjDelete",t ) );
  386. }
  387. ///////////////////////////
  388. // Delete each of a type //
  389. ///////////////////////////
  390. void DeleteEachNode::semant( Environ *e ){
  391. Type *t=e->findType( typeIdent );
  392. if( !t || t->structType()==0 ) ex( "Specified name is not a NewType name" );
  393. }
  394. void DeleteEachNode::translate( Codegen *g ){
  395. g->code( call( "__bbObjDeleteEach",global( "_t"+typeIdent ) ) );
  396. }
  397. ///////////////////////////
  398. // Insert object in list //
  399. ///////////////////////////
  400. void InsertNode::semant( Environ *e ){
  401. expr1=expr1->semant( e );
  402. expr2=expr2->semant( e );
  403. StructType *t1=expr1->sem_type->structType();
  404. StructType *t2=expr2->sem_type->structType();
  405. if( !t1 || !t2 ) ex( "Illegal expression type" );
  406. if( t1!=t2 ) ex( "Objects types are differnt" );
  407. }
  408. void InsertNode::translate( Codegen *g ){
  409. TNode *t1=expr1->translate( g );
  410. if( g->debug ) t1=jumpf( t1,"__bbNullObjEx" );
  411. TNode *t2=expr2->translate( g );
  412. if( g->debug ) t2=jumpf( t2,"__bbNullObjEx" );
  413. string s=before ? "__bbObjInsBefore" : "__bbObjInsAfter";
  414. g->code( call( s,t1,t2 ) );
  415. }
  416. ////////////////////////
  417. // A select statement //
  418. ////////////////////////
  419. void SelectNode::semant( Environ *e ){
  420. expr=expr->semant( e );
  421. Type *ty=expr->sem_type;
  422. if( ty->structType() ) ex( "Select cannot be used with objects" );
  423. //we need a temp var
  424. Decl *d=e->decls->insertDecl( genLabel(),expr->sem_type,DECL_LOCAL );
  425. sem_temp=d_new DeclVarNode( d );
  426. for( int k=0;k<cases.size();++k ){
  427. CaseNode *c=cases[k];
  428. c->exprs->semant( e );
  429. c->exprs->castTo( ty,e );
  430. c->stmts->semant( e );
  431. }
  432. if( defStmts ) defStmts->semant( e );
  433. }
  434. void SelectNode::translate( Codegen *g ){
  435. Type *ty=expr->sem_type;
  436. g->code( sem_temp->store( g,expr->translate( g ) ) );
  437. vector<string> labs;
  438. string brk=genLabel();
  439. for( int k=0;k<cases.size();++k ){
  440. CaseNode *c=cases[k];
  441. labs.push_back( genLabel() );
  442. for( int j=0;j<c->exprs->size();++j ){
  443. ExprNode *e=c->exprs->exprs[j];
  444. TNode *t=compare( '=',sem_temp->load( g ),e->translate( g ),ty );
  445. g->code( jumpt( t,labs.back() ) );
  446. }
  447. }
  448. if( defStmts ) defStmts->translate( g );
  449. g->code( jump( brk ) );
  450. for( k=0;k<cases.size();++k ){
  451. CaseNode *c=cases[k];
  452. g->label( labs[k] );
  453. c->stmts->translate( g );
  454. g->code( jump( brk ) );
  455. }
  456. g->label( brk );
  457. }
  458. ////////////////////////////
  459. // Repeat...Until/Forever //
  460. ////////////////////////////
  461. void RepeatNode::semant( Environ *e ){
  462. sem_brk=genLabel();
  463. string brk=e->setBreak( sem_brk );
  464. stmts->semant( e );
  465. e->setBreak( brk );
  466. if( expr ){
  467. expr=expr->semant( e );
  468. expr=expr->castTo( Type::int_type,e );
  469. }
  470. }
  471. void RepeatNode::translate( Codegen *g ){
  472. string loop=genLabel();
  473. g->label( loop );
  474. stmts->translate( g );
  475. debug( untilPos,g );
  476. if( ConstNode *c=expr ? expr->constNode() : 0 ){
  477. if( !c->intValue() ) g->code( jump( loop ) );
  478. }else{
  479. if( expr ) g->code( jumpf( expr->translate( g ),loop ) );
  480. else g->code( jump( loop ) );
  481. }
  482. g->label( sem_brk );
  483. }
  484. ///////////////
  485. // Read data //
  486. ///////////////
  487. void ReadNode::semant( Environ *e ){
  488. var->semant( e );
  489. if( var->sem_type->constType() ) ex( "Constants can not be modified" );
  490. if( var->sem_type->structType() ) ex( "Data can not be read into an object" );
  491. }
  492. void ReadNode::translate( Codegen *g ){
  493. TNode *t;
  494. if( var->sem_type==Type::int_type ) t=call( "__bbReadInt" );
  495. else if( var->sem_type==Type::float_type ) t=fcall( "__bbReadFloat" );
  496. else t=call( "__bbReadStr" );
  497. g->code( var->store( g,t ) );
  498. }