| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627 |
- #include "std.h"
- #include "nodes.h"
- #include <math.h>
- #include <float.h>
- //////////////////////////////////
- // Cast an expression to a type //
- //////////////////////////////////
- ExprNode *ExprNode::castTo( Type *ty,Environ *e ){
- if( !sem_type->canCastTo( ty ) ){
- ex( "Illegal type conversion" );
- }
- ExprNode *cast=d_new CastNode( this,ty );
- return cast->semant( e );
- }
- ExprNode *CastNode::semant( Environ *e ){
- if( !expr->sem_type ){
- expr=expr->semant( e );
- }
- if( ConstNode *c=expr->constNode() ){
- ExprNode *e;
- if( type==Type::int_type ) e=d_new IntConstNode( c->intValue() );
- else if( type==Type::float_type ) e=d_new FloatConstNode( c->floatValue() );
- else e=d_new StringConstNode( c->stringValue() );
- delete this;
- return e;
- }
- sem_type=type;
- return this;
- }
- //////////////////////////////////
- // Cast an expression to a type //
- //////////////////////////////////
- TNode *CastNode::translate( Codegen *g ){
- TNode *t=expr->translate( g );
- if( expr->sem_type==Type::float_type && sem_type==Type::int_type ){
- //float->int
- return d_new TNode( IR_CAST,t,0 );
- }
- if( expr->sem_type==Type::int_type && sem_type==Type::float_type ){
- //int->float
- return d_new TNode( IR_FCAST,t,0 );
- }
- if( expr->sem_type==Type::string_type && sem_type==Type::int_type ){
- //str->int
- return call( "__bbStrToInt",t );
- }
- if( expr->sem_type==Type::int_type && sem_type==Type::string_type ){
- //int->str
- return call( "__bbStrFromInt",t );
- }
- if( expr->sem_type==Type::string_type && sem_type==Type::float_type ){
- //str->float
- return fcall( "__bbStrToFloat",t );
- }
- if( expr->sem_type==Type::float_type && sem_type==Type::string_type ){
- //float->str
- return call( "__bbStrFromFloat",t );
- }
- if( expr->sem_type->structType() && sem_type==Type::string_type ){
- //obj->str
- return call( "__bbObjToStr",t );
- }
- return t;
- }
- /////////////////////////////
- // Sequence of Expressions //
- /////////////////////////////
- void ExprSeqNode::semant( Environ *e ){
- for( int k=0;k<exprs.size();++k ){
- if( exprs[k] ) exprs[k]=exprs[k]->semant( e );
- }
- }
- TNode *ExprSeqNode::translate( Codegen *g,bool cfunc ){
- TNode *t=0,*l=0;
- for( int k=0;k<exprs.size();++k ){
- TNode *q=exprs[k]->translate(g);
- if( cfunc ){
- Type *ty=exprs[k]->sem_type;
- if( ty->stringType() ){
- q=call( "__bbStrToCStr",q );
- }else if( ty->structType() ){
- q=d_new TNode( IR_MEM,q );
- }else if( ty==Type::void_type ){
- q=d_new TNode( IR_MEM,add(q,iconst(4)) );
- }
- }
- TNode *p;
- p=d_new TNode( IR_ARG,0,0,k*4 );
- p=d_new TNode( IR_MEM,p,0 );
- p=d_new TNode( IR_MOVE,q,p );
- p=d_new TNode( IR_SEQ,p,0 );
- if( l ) l->r=p;
- else t=p;
- l=p;
- }
- return t;
- }
- void ExprSeqNode::castTo( DeclSeq *decls,Environ *e,bool cfunc ){
- if( exprs.size()>decls->size() ) ex( "Too many parameters" );
- for( int k=0;k<decls->size();++k ){
- Decl *d=decls->decls[k];
- if( k<exprs.size() && exprs[k] ){
- if( cfunc && d->type->structType() ){
- if( exprs[k]->sem_type->structType() ){
- }else if( exprs[k]->sem_type->intType() ){
- exprs[k]->sem_type=Type::void_type;
- }else{
- ex( "Illegal type conversion" );
- }
- continue;
- }
- exprs[k]=exprs[k]->castTo( d->type,e );
- }else{
- if( !d->defType ) ex( "Not enough parameters" );
- ExprNode *expr=constValue( d->defType );
- if( k<exprs.size() ) exprs[k]=expr;
- else exprs.push_back( expr );
- }
- }
- }
- void ExprSeqNode::castTo( Type *t,Environ *e ){
- for( int k=0;k<exprs.size();++k ){
- exprs[k]=exprs[k]->castTo( t,e );
- }
- }
- ///////////////////
- // Function call //
- ///////////////////
- ExprNode *CallNode::semant( Environ *e ){
- Type *t=e->findType( tag );
- sem_decl=e->findFunc( ident );
- if( !sem_decl || !(sem_decl->kind & DECL_FUNC) ) ex( "Function '"+ident+"' not found" );
- FuncType *f=sem_decl->type->funcType();
- if( t && f->returnType!=t ) ex( "incorrect function return type" );
- exprs->semant( e );
- exprs->castTo( f->params,e,f->cfunc );
- sem_type=f->returnType;
- return this;
- }
- TNode *CallNode::translate( Codegen *g ){
- FuncType *f=sem_decl->type->funcType();
- TNode *t;
- TNode *l=global( "_f"+ident );
- TNode *r=exprs->translate( g,f->cfunc );
- if( f->userlib ){
- l=d_new TNode( IR_MEM,l );
- usedfuncs.insert( ident );
- }
- if( sem_type==Type::float_type ){
- t=d_new TNode( IR_FCALL,l,r,exprs->size()*4 );
- }else{
- t=d_new TNode( IR_CALL,l,r,exprs->size()*4 );
- }
- if( f->returnType->stringType() ){
- if( f->cfunc ){
- t=call( "__bbCStrToStr",t );
- }
- }
- return t;
- }
- /////////////////////////
- // Variable expression //
- /////////////////////////
- ExprNode *VarExprNode::semant( Environ *e ){
- var->semant( e );
- sem_type=var->sem_type;
- ConstType *c=sem_type->constType();
- if( !c ) return this;
- ExprNode *expr=constValue( c );
- delete this;return expr;
- }
- TNode *VarExprNode::translate( Codegen *g ){
- return var->load( g );
- }
- //////////////////////
- // Integer constant //
- //////////////////////
- IntConstNode::IntConstNode( int n ):value(n){
- sem_type=Type::int_type;
- }
- TNode *IntConstNode::translate( Codegen *g ){
- return d_new TNode( IR_CONST,0,0,value );
- }
- int IntConstNode::intValue(){
- return value;
- }
- float IntConstNode::floatValue(){
- return value;
- }
- string IntConstNode::stringValue(){
- return itoa( value );
- }
- ////////////////////
- // Float constant //
- ////////////////////
- FloatConstNode::FloatConstNode( float f ):value(f){
- sem_type=Type::float_type;
- }
- TNode *FloatConstNode::translate( Codegen *g ){
- return d_new TNode( IR_CONST,0,0,*(int*)&value );
- }
- int FloatConstNode::intValue(){
- float flt=value;
- int temp;
- _control87( _RC_NEAR|_PC_24|_EM_INVALID|_EM_ZERODIVIDE|_EM_OVERFLOW|_EM_UNDERFLOW|_EM_INEXACT|_EM_DENORMAL,0xfffff );
- _asm{
- fld [flt];
- fistp [temp];
- }
- _control87( _CW_DEFAULT,0xfffff );
- return temp;
- }
- float FloatConstNode::floatValue(){
- return value;
- }
- string FloatConstNode::stringValue(){
- return ftoa( value );
- }
- /////////////////////
- // String constant //
- /////////////////////
- StringConstNode::StringConstNode( const string &s ):value(s){
- sem_type=Type::string_type;
- }
- TNode *StringConstNode::translate( Codegen *g ){
- string lab=genLabel();
- g->s_data( value,lab );
- return call( "__bbStrConst",global( lab ) );
- }
- int StringConstNode::intValue(){
- return atoi( value );
- }
- float StringConstNode::floatValue(){
- return (float)atof( value );
- }
- string StringConstNode::stringValue(){
- return value;
- }
- ////////////////////
- // Unary operator //
- ////////////////////
- ExprNode *UniExprNode::semant( Environ *e ){
- expr=expr->semant( e );
- sem_type=expr->sem_type;
- if( sem_type!=Type::int_type && sem_type!=Type::float_type ) ex( "Illegal operator for type" );
- if( ConstNode *c=expr->constNode() ){
- ExprNode *e;
- if( sem_type==Type::int_type ){
- switch( op ){
- case '+':e=d_new IntConstNode( +c->intValue() );break;
- case '-':e=d_new IntConstNode( -c->intValue() );break;
- case ABS:e=d_new IntConstNode( c->intValue()>=0 ? c->intValue() : -c->intValue() );break;
- case SGN:e=d_new IntConstNode( c->intValue()>0 ? 1 : (c->intValue()<0 ? -1 : 0) );break;
- }
- }else{
- switch( op ){
- case '+':e=d_new FloatConstNode( +c->floatValue() );break;
- case '-':e=d_new FloatConstNode( -c->floatValue() );break;
- case ABS:e=d_new FloatConstNode( c->floatValue()>=0 ? c->floatValue() : -c->floatValue() );break;
- case SGN:e=d_new FloatConstNode( c->floatValue()>0 ? 1 : (c->floatValue()<0 ? -1 : 0) );break;
- }
- }
- delete this;
- return e;
- }
- return this;
- }
- TNode *UniExprNode::translate( Codegen *g ){
- int n=0;
- TNode *l=expr->translate( g );
- if( sem_type==Type::int_type ){
- switch( op ){
- case '+':return l;
- case '-':n=IR_NEG;break;
- case ABS:return call( "__bbAbs",l );
- case SGN:return call( "__bbSgn",l );
- }
- }else{
- switch( op ){
- case '+':return l;
- case '-':n=IR_FNEG;break;
- case ABS:return fcall( "__bbFAbs",l );
- case SGN:return fcall( "__bbFSgn",l );
- }
- }
- return d_new TNode( n,l,0 );
- }
- /////////////////////////////////////////////////////
- // boolean expression - accepts ints, returns ints //
- /////////////////////////////////////////////////////
- ExprNode *BinExprNode::semant( Environ *e ){
- lhs=lhs->semant(e);lhs=lhs->castTo( Type::int_type,e );
- rhs=rhs->semant(e);rhs=rhs->castTo( Type::int_type,e );
- ConstNode *lc=lhs->constNode(),*rc=rhs->constNode();
- if( lc && rc ){
- ExprNode *expr;
- switch( op ){
- case AND:expr=d_new IntConstNode( lc->intValue() & rc->intValue() );break;
- case OR: expr=d_new IntConstNode( lc->intValue() | rc->intValue() );break;
- case XOR:expr=d_new IntConstNode( lc->intValue() ^ rc->intValue() );break;
- case SHL:expr=d_new IntConstNode( lc->intValue()<< rc->intValue() );break;
- case SHR:expr=d_new IntConstNode( (unsigned)lc->intValue()>>rc->intValue() );break;
- case SAR:expr=d_new IntConstNode( lc->intValue()>> rc->intValue() );break;
- }
- delete this;
- return expr;
- }
- sem_type=Type::int_type;
- return this;
- }
- TNode *BinExprNode::translate( Codegen *g ){
- TNode *l=lhs->translate( g );
- TNode *r=rhs->translate( g );
- int n=0;
- switch( op ){
- case AND:n=IR_AND;break;case OR:n=IR_OR;break;case XOR:n=IR_XOR;break;
- case SHL:n=IR_SHL;break;case SHR:n=IR_SHR;break;case SAR:n=IR_SAR;break;
- }
- return d_new TNode( n,l,r );
- }
- ///////////////////////////
- // arithmetic expression //
- ///////////////////////////
- ExprNode *ArithExprNode::semant( Environ *e ){
- lhs=lhs->semant(e);
- rhs=rhs->semant(e);
- if( lhs->sem_type->structType() || rhs->sem_type->structType() ){
- ex( "Arithmetic operator cannot be applied to custom type objects" );
- }
- if( lhs->sem_type==Type::string_type || rhs->sem_type==Type::string_type ){
- //one side is a string - only + operator...
- if( op!='+' ) ex( "Operator cannot be applied to strings" );
- sem_type=Type::string_type;
- }else if( op=='^' || lhs->sem_type==Type::float_type || rhs->sem_type==Type::float_type ){
- //It's ^, or one side is a float
- sem_type=Type::float_type;
- }else{
- //must be 2 ints
- sem_type=Type::int_type;
- }
- lhs=lhs->castTo( sem_type,e );
- rhs=rhs->castTo( sem_type,e );
- ConstNode *lc=lhs->constNode(),*rc=rhs->constNode();
- if( rc && (op=='/' || op==MOD) ){
- if( (sem_type==Type::int_type && !rc->intValue()) || (sem_type==Type::float_type && !rc->floatValue()) ){
- ex( "Division by zero" );
- }
- }
- if( lc && rc ){
- ExprNode *expr;
- if( sem_type==Type::string_type ){
- expr=d_new StringConstNode( lc->stringValue()+rc->stringValue() );
- }else if( sem_type==Type::int_type ){
- switch( op ){
- case '+':expr=d_new IntConstNode( lc->intValue()+rc->intValue() );break;
- case '-':expr=d_new IntConstNode( lc->intValue()-rc->intValue() );break;
- case '*':expr=d_new IntConstNode( lc->intValue()*rc->intValue() );break;
- case '/':expr=d_new IntConstNode( lc->intValue()/rc->intValue() );break;
- case MOD:expr=d_new IntConstNode( lc->intValue()%rc->intValue() );break;
- }
- }else{
- switch( op ){
- case '+':expr=d_new FloatConstNode( lc->floatValue()+rc->floatValue() );break;
- case '-':expr=d_new FloatConstNode( lc->floatValue()-rc->floatValue() );break;
- case '*':expr=d_new FloatConstNode( lc->floatValue()*rc->floatValue() );break;
- case '/':expr=d_new FloatConstNode( lc->floatValue()/rc->floatValue() );break;
- case MOD:expr=d_new FloatConstNode( fmod( lc->floatValue(),rc->floatValue() ) );break;
- case '^':expr=d_new FloatConstNode( pow( lc->floatValue(),rc->floatValue() ) );break;
- }
- }
- delete this;
- return expr;
- }
- return this;
- }
- TNode *ArithExprNode::translate( Codegen *g ){
- TNode *l=lhs->translate( g );
- TNode *r=rhs->translate( g );
- if( sem_type==Type::string_type ){
- return call( "__bbStrConcat",l,r );
- }
- int n=0;
- if( sem_type==Type::int_type ){
- switch( op ){
- case '+':n=IR_ADD;break;case '-':n=IR_SUB;break;
- case '*':n=IR_MUL;break;case '/':n=IR_DIV;break;
- case MOD:return call( "__bbMod",l,r );
- }
- }else{
- switch( op ){
- case '+':n=IR_FADD;break;case '-':n=IR_FSUB;break;
- case '*':n=IR_FMUL;break;case '/':n=IR_FDIV;break;
- case MOD:return fcall( "__bbFMod",l,r );
- case '^':return fcall( "__bbFPow",l,r );
- }
- }
- return d_new TNode( n,l,r );
- }
- /////////////////////////
- // relation expression //
- /////////////////////////
- ExprNode *RelExprNode::semant( Environ *e ){
- lhs=lhs->semant(e);
- rhs=rhs->semant(e);
- if( lhs->sem_type->structType() || rhs->sem_type->structType() ){
- if( op!='=' && op!=NE ) ex( "Illegal operator for custom type objects" );
- opType=lhs->sem_type!=Type::null_type ? lhs->sem_type : rhs->sem_type;
- }else if( lhs->sem_type==Type::string_type || rhs->sem_type==Type::string_type ){
- opType=Type::string_type;
- }else if( lhs->sem_type==Type::float_type || rhs->sem_type==Type::float_type ){
- opType=Type::float_type;
- }else{
- opType=Type::int_type;
- }
- sem_type=Type::int_type;
- lhs=lhs->castTo( opType,e );
- rhs=rhs->castTo( opType,e );
- ConstNode *lc=lhs->constNode(),*rc=rhs->constNode();
- if( lc && rc ){
- ExprNode *expr;
- if( opType==Type::string_type ){
- switch( op ){
- case '<':expr=d_new IntConstNode( lc->stringValue()< rc->stringValue() );break;
- case '=':expr=d_new IntConstNode( lc->stringValue()==rc->stringValue() );break;
- case '>':expr=d_new IntConstNode( lc->stringValue()> rc->stringValue() );break;
- case LE: expr=d_new IntConstNode( lc->stringValue()<=rc->stringValue() );break;
- case NE: expr=d_new IntConstNode( lc->stringValue()!=rc->stringValue() );break;
- case GE: expr=d_new IntConstNode( lc->stringValue()>=rc->stringValue() );break;
- }
- }else if( opType==Type::float_type ){
- switch( op ){
- case '<':expr=d_new IntConstNode( lc->floatValue()< rc->floatValue() );break;
- case '=':expr=d_new IntConstNode( lc->floatValue()==rc->floatValue() );break;
- case '>':expr=d_new IntConstNode( lc->floatValue()> rc->floatValue() );break;
- case LE: expr=d_new IntConstNode( lc->floatValue()<=rc->floatValue() );break;
- case NE: expr=d_new IntConstNode( lc->floatValue()!=rc->floatValue() );break;
- case GE: expr=d_new IntConstNode( lc->floatValue()>=rc->floatValue() );break;
- }
- }else{
- switch( op ){
- case '<':expr=d_new IntConstNode( lc->intValue()< rc->intValue() );break;
- case '=':expr=d_new IntConstNode( lc->intValue()==rc->intValue() );break;
- case '>':expr=d_new IntConstNode( lc->intValue()> rc->intValue() );break;
- case LE: expr=d_new IntConstNode( lc->intValue()<=rc->intValue() );break;
- case NE: expr=d_new IntConstNode( lc->intValue()!=rc->intValue() );break;
- case GE: expr=d_new IntConstNode( lc->intValue()>=rc->intValue() );break;
- }
- }
- delete this;
- return expr;
- }
- return this;
- }
- TNode *RelExprNode::translate( Codegen *g ){
- TNode *l=lhs->translate( g );
- TNode *r=rhs->translate( g );
- return compare( op,l,r,opType );
- }
- ////////////////////
- // New expression //
- ////////////////////
- ExprNode *NewNode::semant( Environ *e ){
- sem_type=e->findType( ident );
- if( !sem_type ) ex( "custom type name not found" );
- if( sem_type->structType()==0 ) ex( "type is not a custom type" );
- return this;
- }
- TNode *NewNode::translate( Codegen *g ){
- return call( "__bbObjNew",global( "_t"+ident ) );
- }
- ////////////////////
- // First of class //
- ////////////////////
- ExprNode *FirstNode::semant( Environ *e ){
- sem_type=e->findType( ident );
- if( !sem_type ) ex( "custom type name name not found" );
- return this;
- }
- TNode *FirstNode::translate( Codegen *g ){
- return call( "__bbObjFirst",global( "_t"+ident ) );
- }
- ///////////////////
- // Last of class //
- ///////////////////
- ExprNode *LastNode::semant( Environ *e ){
- sem_type=e->findType( ident );
- if( !sem_type ) ex( "custom type name not found" );
- return this;
- }
- TNode *LastNode::translate( Codegen *g ){
- return call( "__bbObjLast",global( "_t"+ident ) );
- }
- ////////////////////
- // Next of object //
- ////////////////////
- ExprNode *AfterNode::semant( Environ *e ){
- expr=expr->semant( e );
- if( expr->sem_type==Type::null_type ) ex( "'After' cannot be used on 'Null'" );
- if( expr->sem_type->structType()==0 ) ex( "'After' must be used with a custom type object" );
- sem_type=expr->sem_type;
- return this;
- }
- TNode *AfterNode::translate( Codegen *g ){
- TNode *t=expr->translate( g );
- if( g->debug ) t=jumpf( t,"__bbNullObjEx" );
- return call( "__bbObjNext",t );
- }
- ////////////////////
- // Prev of object //
- ////////////////////
- ExprNode *BeforeNode::semant( Environ *e ){
- expr=expr->semant( e );
- if( expr->sem_type==Type::null_type ) ex( "'Before' cannot be used with 'Null'" );
- if( expr->sem_type->structType()==0 ) ex( "'Before' must be used with a custom type object" );
- sem_type=expr->sem_type;
- return this;
- }
- TNode *BeforeNode::translate( Codegen *g ){
- TNode *t=expr->translate( g );
- if( g->debug ) t=jumpf( t,"__bbNullObjEx" );
- return call( "__bbObjPrev",t );
- }
- /////////////////
- // Null object //
- /////////////////
- ExprNode *NullNode::semant( Environ *e ){
- sem_type=Type::null_type;
- return this;
- }
- TNode *NullNode::translate( Codegen *g ){
- return d_new TNode( IR_CONST,0,0,0 );
- }
- /////////////////
- // Object cast //
- /////////////////
- ExprNode *ObjectCastNode::semant( Environ *e ){
- expr=expr->semant( e );
- expr=expr->castTo( Type::int_type,e );
- sem_type=e->findType( type_ident );
- if( !sem_type ) ex( "custom type name not found" );
- if( !sem_type->structType() ) ex( "type is not a custom type" );
- return this;
- }
- TNode *ObjectCastNode::translate( Codegen *g ){
- TNode *t=expr->translate( g );
- t=call( "__bbObjFromHandle",t,global( "_t"+sem_type->structType()->ident ) );
- return t;
- }
- ///////////////////
- // Object Handle //
- ///////////////////
- ExprNode *ObjectHandleNode::semant( Environ *e ){
- expr=expr->semant( e );
- if( !expr->sem_type->structType() ) ex( "'ObjectHandle' must be used with an object" );
- sem_type=Type::int_type;
- return this;
- }
- TNode *ObjectHandleNode::translate( Codegen *g ){
- TNode *t=expr->translate( g );
- return call( "__bbObjToHandle",t );
- }
|