varnode.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. #include "std.h"
  2. #include "nodes.h"
  3. //////////////////////////////////
  4. // Common get/set for variables //
  5. //////////////////////////////////
  6. TNode *VarNode::load( Codegen *g ){
  7. TNode *t=translate( g );
  8. if( sem_type==Type::string_type ) return call( "__bbStrLoad",t );
  9. return mem( t );
  10. }
  11. TNode *VarNode::store( Codegen *g,TNode *n ){
  12. TNode *t=translate( g );
  13. if( sem_type->structType() ) return call( "__bbObjStore",t,n );
  14. if( sem_type==Type::string_type ) return call( "__bbStrStore",t,n );
  15. return move( n,mem( t ) );
  16. }
  17. bool VarNode::isObjParam(){
  18. return false;
  19. }
  20. //////////////////
  21. // Declared var //
  22. //////////////////
  23. void DeclVarNode::semant( Environ *e ){
  24. }
  25. TNode *DeclVarNode::translate( Codegen *g ){
  26. if( sem_decl->kind==DECL_GLOBAL ) return global( "_v"+sem_decl->name );
  27. return local( sem_decl->offset );
  28. }
  29. TNode *DeclVarNode::store( Codegen *g,TNode *n ){
  30. if( isObjParam() ){
  31. TNode *t=translate( g );
  32. return move( n,mem( t ) );
  33. }
  34. return VarNode::store( g,n );
  35. }
  36. bool DeclVarNode::isObjParam(){
  37. return sem_type->structType() && sem_decl->kind==DECL_PARAM;
  38. }
  39. ///////////////
  40. // Ident var //
  41. ///////////////
  42. void IdentVarNode::semant( Environ *e ){
  43. if( sem_decl ) return;
  44. Type *t=tagType( tag,e );if( !t ) t=Type::int_type;
  45. if( sem_decl=e->findDecl( ident ) ){
  46. if( !(sem_decl->kind&(DECL_GLOBAL|DECL_LOCAL|DECL_PARAM)) ){
  47. ex( "Identifier '"+sem_decl->name+"' may not be used like this" );
  48. }
  49. Type *ty=sem_decl->type;
  50. if( ty->constType() ) ty=ty->constType()->valueType;
  51. if( tag.size() && t!=ty ) ex( "Variable type mismatch" );
  52. }else{
  53. //ugly auto decl!
  54. sem_decl=e->decls->insertDecl( ident,t,DECL_LOCAL );
  55. }
  56. sem_type=sem_decl->type;
  57. }
  58. /////////////////
  59. // Indexed Var //
  60. /////////////////
  61. void ArrayVarNode::semant( Environ *e ){
  62. exprs->semant( e );
  63. exprs->castTo( Type::int_type,e );
  64. Type *t=e->findType( tag );
  65. sem_decl=e->findDecl( ident );
  66. if( !sem_decl || !(sem_decl->kind&DECL_ARRAY) ) ex( "Array not found" );
  67. ArrayType *a=sem_decl->type->arrayType();
  68. if( t && t!=a->elementType ) ex( "array type mismtach" );
  69. if( a->dims!=exprs->size() ) ex( "incorrect number of dimensions" );
  70. sem_type=a->elementType;
  71. }
  72. TNode *ArrayVarNode::translate( Codegen *g ){
  73. TNode *t=0;
  74. for( int k=0;k<exprs->size();++k ){
  75. TNode *e=exprs->exprs[k]->translate( g );
  76. if( k ){
  77. TNode *s=mem( add( global( "_a"+ident ),iconst( k*4+8 ) ) );
  78. e=add( t,mul( e,s ) );
  79. }
  80. if( g->debug ){
  81. TNode *s=mem( add( global( "_a"+ident ),iconst( k*4+12 ) ) );
  82. t=jumpge( e,s,"__bbArrayBoundsEx" );
  83. }else t=e;
  84. }
  85. t=add( mem( global( "_a"+ident ) ),mul( t,iconst( 4 ) ) );
  86. return t;
  87. }
  88. ///////////////
  89. // Field var //
  90. ///////////////
  91. void FieldVarNode::semant( Environ *e ){
  92. expr=expr->semant( e );
  93. StructType *s=expr->sem_type->structType();
  94. if( !s ) ex( "Variable must be a Type" );
  95. sem_field=s->fields->findDecl( ident );
  96. if( !sem_field ) ex( "Type field not found" );
  97. sem_type=sem_field->type;
  98. }
  99. TNode *FieldVarNode::translate( Codegen *g ){
  100. TNode *t=expr->translate( g );
  101. if( g->debug ) t=jumpf( t,"__bbNullObjEx" );
  102. t=mem( t );if( g->debug ) t=jumpf( t,"__bbNullObjEx" );
  103. return add( t,iconst( sem_field->offset ) );
  104. }
  105. ////////////////
  106. // Vector var //
  107. ////////////////
  108. void VectorVarNode::semant( Environ *e ){
  109. expr=expr->semant( e );
  110. vec_type=expr->sem_type->vectorType();
  111. if( !vec_type ) ex( "Variable must be a Blitz array" );
  112. if( vec_type->sizes.size()!=exprs->size() ) ex( "Incorrect number of subscripts" );
  113. exprs->semant( e );
  114. exprs->castTo( Type::int_type,e );
  115. for( int k=0;k<exprs->size();++k ){
  116. if( ConstNode *t=exprs->exprs[k]->constNode() ){
  117. if( t->intValue()>=vec_type->sizes[k] ){
  118. ex( "Blitz array subscript out of range" );
  119. }
  120. }
  121. }
  122. sem_type=vec_type->elementType;
  123. }
  124. TNode *VectorVarNode::translate( Codegen *g ){
  125. int sz=4;
  126. TNode *t=0;
  127. for( int k=0;k<exprs->size();++k ){
  128. TNode *p;
  129. ExprNode *e=exprs->exprs[k];
  130. if( ConstNode *t=e->constNode() ){
  131. p=iconst( t->intValue() * sz );
  132. }else{
  133. p=e->translate( g );
  134. if( g->debug ){
  135. p=jumpge( p,iconst( vec_type->sizes[k] ),"__bbVecBoundsEx" );
  136. }
  137. p=mul( p,iconst( sz ) );
  138. }
  139. sz=sz*vec_type->sizes[k];
  140. t=t ? add( t,p ) : p;
  141. }
  142. return add( t,expr->translate( g ) );
  143. }