Holy fucking shit I don't want to work on this. Sibly, you son of a ...
This commit is contained in:
+348
-347
@@ -8,65 +8,66 @@
|
||||
//////////////////////////////////
|
||||
// Cast an expression to a type //
|
||||
//////////////////////////////////
|
||||
ExprNode *ExprNode::castTo( Type *ty,Environ *e ){
|
||||
if( !sem_type->canCastTo( ty ) ){
|
||||
ex( "Illegal type conversion" );
|
||||
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 *cast = d_new CastNode(this, ty);
|
||||
cast->semant(e);
|
||||
return cast;
|
||||
}
|
||||
|
||||
ExprNode *CastNode::semant( Environ *e ){
|
||||
if( !expr->sem_type ){
|
||||
expr=expr->semant( e );
|
||||
ExprNode *CastNode::semant(Environ *e) {
|
||||
if (!expr->sem_type) {
|
||||
expr = expr->semant(e);
|
||||
}
|
||||
|
||||
if( ConstNode *c=expr->constNode() ){
|
||||
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() );
|
||||
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;
|
||||
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 ){
|
||||
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 );
|
||||
return d_new TNode(IR_CAST, t, 0);
|
||||
}
|
||||
if( expr->sem_type==Type::int_type && sem_type==Type::float_type ){
|
||||
if (expr->sem_type == Type::int_type && sem_type == Type::float_type) {
|
||||
//int->float
|
||||
return d_new TNode( IR_FCAST,t,0 );
|
||||
return d_new TNode(IR_FCAST, t, 0);
|
||||
}
|
||||
if( expr->sem_type==Type::string_type && sem_type==Type::int_type ){
|
||||
if (expr->sem_type == Type::string_type && sem_type == Type::int_type) {
|
||||
//str->int
|
||||
return call( "__bbStrToInt",t );
|
||||
return call("__bbStrToInt", t);
|
||||
}
|
||||
if( expr->sem_type==Type::int_type && sem_type==Type::string_type ){
|
||||
if (expr->sem_type == Type::int_type && sem_type == Type::string_type) {
|
||||
//int->str
|
||||
return call( "__bbStrFromInt",t );
|
||||
return call("__bbStrFromInt", t);
|
||||
}
|
||||
if( expr->sem_type==Type::string_type && sem_type==Type::float_type ){
|
||||
if (expr->sem_type == Type::string_type && sem_type == Type::float_type) {
|
||||
//str->float
|
||||
return fcall( "__bbStrToFloat",t );
|
||||
return fcall("__bbStrToFloat", t);
|
||||
}
|
||||
if( expr->sem_type==Type::float_type && sem_type==Type::string_type ){
|
||||
if (expr->sem_type == Type::float_type && sem_type == Type::string_type) {
|
||||
//float->str
|
||||
return call( "__bbStrFromFloat",t );
|
||||
return call("__bbStrFromFloat", t);
|
||||
}
|
||||
if( expr->sem_type->structType() && sem_type==Type::string_type ){
|
||||
if (expr->sem_type->structType() && sem_type == Type::string_type) {
|
||||
//obj->str
|
||||
return call( "__bbObjToStr",t );
|
||||
return call("__bbObjToStr", t);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
@@ -74,111 +75,111 @@ TNode *CastNode::translate( Codegen *g ){
|
||||
/////////////////////////////
|
||||
// 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 );
|
||||
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 *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);
|
||||
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)) );
|
||||
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;
|
||||
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] ){
|
||||
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" );
|
||||
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 );
|
||||
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 );
|
||||
} 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 );
|
||||
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;
|
||||
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 ){
|
||||
TNode *CallNode::translate(Codegen *g) {
|
||||
|
||||
FuncType *f=sem_decl->type->funcType();
|
||||
FuncType *f = sem_decl->type->funcType();
|
||||
|
||||
TNode *t;
|
||||
TNode *l=global( "_f"+ident );
|
||||
TNode *r=exprs->translate( g,f->cfunc );
|
||||
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 (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 (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 );
|
||||
if (f->returnType->stringType()) {
|
||||
if (f->cfunc) {
|
||||
t = call("__bbCStrToStr", t);
|
||||
}
|
||||
}
|
||||
return t;
|
||||
@@ -187,232 +188,232 @@ TNode *CallNode::translate( Codegen *g ){
|
||||
/////////////////////////
|
||||
// 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;
|
||||
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 );
|
||||
TNode *VarExprNode::translate(Codegen *g) {
|
||||
return var->load(g);
|
||||
}
|
||||
|
||||
//////////////////////
|
||||
// Integer constant //
|
||||
//////////////////////
|
||||
IntConstNode::IntConstNode( int n ):value(n){
|
||||
sem_type=Type::int_type;
|
||||
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 );
|
||||
TNode *IntConstNode::translate(Codegen *g) {
|
||||
return d_new TNode(IR_CONST, 0, 0, value);
|
||||
}
|
||||
|
||||
int IntConstNode::intValue(){
|
||||
int IntConstNode::intValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
float IntConstNode::floatValue(){
|
||||
float IntConstNode::floatValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
string IntConstNode::stringValue(){
|
||||
return itoa( value );
|
||||
string IntConstNode::stringValue() {
|
||||
return itoa(value);
|
||||
}
|
||||
|
||||
////////////////////
|
||||
// Float constant //
|
||||
////////////////////
|
||||
FloatConstNode::FloatConstNode( float f ):value(f){
|
||||
sem_type=Type::float_type;
|
||||
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 );
|
||||
TNode *FloatConstNode::translate(Codegen *g) {
|
||||
return d_new TNode(IR_CONST, 0, 0, *(int*)&value);
|
||||
}
|
||||
|
||||
int FloatConstNode::intValue(){
|
||||
float flt=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(_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 );
|
||||
_control87(_CW_DEFAULT, 0xfffff);
|
||||
return temp;
|
||||
}
|
||||
|
||||
float FloatConstNode::floatValue(){
|
||||
float FloatConstNode::floatValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
string FloatConstNode::stringValue(){
|
||||
return ftoa( value );
|
||||
string FloatConstNode::stringValue() {
|
||||
return ftoa(value);
|
||||
}
|
||||
|
||||
/////////////////////
|
||||
// String constant //
|
||||
/////////////////////
|
||||
StringConstNode::StringConstNode( const string &s ):value(s){
|
||||
sem_type=Type::string_type;
|
||||
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 ) );
|
||||
TNode *StringConstNode::translate(Codegen *g) {
|
||||
string lab = genLabel();
|
||||
g->s_data(value, lab);
|
||||
return call("__bbStrConst", global(lab));
|
||||
}
|
||||
|
||||
int StringConstNode::intValue(){
|
||||
return atoi( value );
|
||||
int StringConstNode::intValue() {
|
||||
return atoi(value);
|
||||
}
|
||||
|
||||
float StringConstNode::floatValue(){
|
||||
return (float)atof( value );
|
||||
float StringConstNode::floatValue() {
|
||||
return (float)atof(value);
|
||||
}
|
||||
|
||||
string StringConstNode::stringValue(){
|
||||
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 *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;
|
||||
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;
|
||||
} 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 e = nullptr;
|
||||
}
|
||||
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 );
|
||||
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 );
|
||||
} 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 );
|
||||
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;
|
||||
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 = nullptr;
|
||||
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;
|
||||
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;
|
||||
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 );
|
||||
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" );
|
||||
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 ){
|
||||
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 ){
|
||||
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{
|
||||
sem_type = Type::float_type;
|
||||
} else {
|
||||
//must be 2 ints
|
||||
sem_type=Type::int_type;
|
||||
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" );
|
||||
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;
|
||||
if (lc && rc) {
|
||||
ExprNode *expr = nullptr;
|
||||
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;
|
||||
} 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;
|
||||
@@ -421,78 +422,78 @@ ExprNode *ArithExprNode::semant( Environ *e ){
|
||||
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 );
|
||||
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 );
|
||||
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 );
|
||||
} 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 );
|
||||
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;
|
||||
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;
|
||||
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 = nullptr;
|
||||
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 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;
|
||||
} 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;
|
||||
@@ -501,127 +502,127 @@ ExprNode *RelExprNode::semant( Environ *e ){
|
||||
return this;
|
||||
}
|
||||
|
||||
TNode *RelExprNode::translate( Codegen *g ){
|
||||
TNode *l=lhs->translate( g );
|
||||
TNode *r=rhs->translate( g );
|
||||
return compare( op,l,r,opType );
|
||||
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" );
|
||||
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 ) );
|
||||
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" );
|
||||
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 ) );
|
||||
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" );
|
||||
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 ) );
|
||||
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;
|
||||
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 );
|
||||
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;
|
||||
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 );
|
||||
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;
|
||||
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 );
|
||||
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" );
|
||||
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 ) );
|
||||
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;
|
||||
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 );
|
||||
TNode *ObjectHandleNode::translate(Codegen *g) {
|
||||
TNode *t = expr->translate(g);
|
||||
return call("__bbObjToHandle", t);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user