prognode.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. #include "std.h"
  2. #include "nodes.h"
  3. //////////////////
  4. // The program! //
  5. //////////////////
  6. Environ *ProgNode::semant( Environ *e ){
  7. file_lab=genLabel();
  8. StmtSeqNode::reset( stmts->file,file_lab );
  9. a_ptr<Environ> env( d_new Environ( genLabel(),Type::int_type,0,e ) );
  10. consts->proto( env->decls,env );
  11. structs->proto( env->typeDecls,env );
  12. structs->semant( env );
  13. funcs->proto( env->funcDecls,env );
  14. stmts->semant( env );
  15. funcs->semant( env );
  16. datas->proto( env->decls,env );
  17. datas->semant( env );
  18. sem_env=env.release();
  19. return sem_env;
  20. }
  21. void ProgNode::translate( Codegen *g,const vector<UserFunc> &usrfuncs ){
  22. int k;
  23. if( g->debug ) g->s_data( stmts->file,file_lab );
  24. //enumerate locals
  25. int size=enumVars( sem_env );
  26. //'Main' label
  27. g->enter( "__MAIN",size );
  28. //reset data pointer
  29. g->code( call( "__bbRestore",global( "__DATA" ) ) );
  30. //load external libs
  31. g->code( call( "__bbLoadLibs",global( "__LIBS" ) ) );
  32. //call main program
  33. g->code( jsr( sem_env->funcLabel+"_begin" ) );
  34. g->code( jump( sem_env->funcLabel+"_leave" ) );
  35. g->label( sem_env->funcLabel+"_begin" );
  36. //create locals
  37. TNode *t=createVars( sem_env );
  38. if( t ) g->code( t );
  39. if( g->debug ){
  40. string t=genLabel();
  41. g->s_data( "<main program>",t );
  42. g->code( call( "__bbDebugEnter",local(0),iconst((int)sem_env),global(t) ) );
  43. }
  44. //no user funcs used!
  45. usedfuncs.clear();
  46. //program statements
  47. stmts->translate( g );
  48. //emit return
  49. g->code( ret() );
  50. //check labels
  51. for( k=0;k<sem_env->labels.size();++k ){
  52. if( sem_env->labels[k]->def<0 ) ex( "Undefined label '"+sem_env->labels[k]->name+"'",sem_env->labels[k]->ref,stmts->file );
  53. }
  54. //leave main program
  55. g->label( sem_env->funcLabel+"_leave" );
  56. t=deleteVars( sem_env );
  57. if( g->debug ) t=d_new TNode( IR_SEQ,call( "__bbDebugLeave" ),t );
  58. g->leave( t,0 );
  59. //structs
  60. structs->translate( g );
  61. //non-main functions
  62. funcs->translate( g );
  63. //data
  64. datas->translate( g );
  65. //library functions
  66. map<string,vector<int> > libFuncs;
  67. //lib ptrs
  68. g->flush();
  69. g->align_data(4);
  70. for( k=0;k<usrfuncs.size();++k ){
  71. const UserFunc &fn=usrfuncs[k];
  72. if( !usedfuncs.count(fn.ident) ) continue;
  73. libFuncs[fn.lib].push_back( k );
  74. g->i_data( 0,"_f"+fn.ident );
  75. }
  76. //LIBS chunk
  77. g->flush();
  78. g->label( "__LIBS" );
  79. map<string,vector<int> >::const_iterator lf_it;
  80. for( lf_it=libFuncs.begin();lf_it!=libFuncs.end();++lf_it ){
  81. //lib name
  82. g->s_data( lf_it->first );
  83. const vector<int> &fns=lf_it->second;
  84. for( int j=0;j<fns.size();++j ){
  85. const UserFunc &fn=usrfuncs[ fns[j] ];
  86. //proc name
  87. g->s_data( fn.proc );
  88. g->p_data( "_f"+fn.ident );
  89. }
  90. g->s_data( "" );
  91. }
  92. g->s_data( "" );
  93. //DATA chunk
  94. g->flush();
  95. g->align_data( 4 );
  96. g->label( "__DATA" );
  97. datas->transdata( g );
  98. g->i_data(0);
  99. //Thats IT!
  100. g->flush();
  101. }