Skip to content

Commit

Permalink
Fixed automatic bolean-ification in boolean statements and expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
Giancarlo Niccolai committed Sep 22, 2011
1 parent b4b29e4 commit 3eee803
Show file tree
Hide file tree
Showing 10 changed files with 63 additions and 15 deletions.
2 changes: 1 addition & 1 deletion engine/class.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ void Class::op_setProperty( VMContext* , void*, const String& ) const


void Class::op_isTrue( VMContext* ctx, void* ) const void Class::op_isTrue( VMContext* ctx, void* ) const
{ {
ctx->stackResult(1, true); ctx->topData().setBoolean(true);
} }




Expand Down
4 changes: 2 additions & 2 deletions engine/classstring.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -350,9 +350,9 @@ void ClassString::op_toString( VMContext* ctx, void* data ) const
ctx->topData().setUser( this, data, true ); ctx->topData().setUser( this, data, true );
} }


void ClassString::op_true( VMContext* ctx, void* str) const void ClassString::op_isTrue( VMContext* ctx, void* str ) const
{ {
ctx->topData() = static_cast<String*>(str)->size() != 0; ctx->topData().setBoolean( static_cast<String*>(str)->size() != 0 );
} }


} }
Expand Down
2 changes: 1 addition & 1 deletion engine/exprcompare.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ void generic_apply_( const PStep* DEBUG_ONLY(ps), VMContext* ctx )
op1.asClass()->op_compare( ctx, op1.asInst() ); op1.asClass()->op_compare( ctx, op1.asInst() );
// refetch, we may have gone deep // refetch, we may have gone deep
fassert( ctx->topData().isInteger() ); fassert( ctx->topData().isInteger() );
ctx->topData().setBoolean( __CPR::cmpCheck( ctx->topData().asInteger() < 0 ) ); ctx->topData().setBoolean( __CPR::cmpCheck( ctx->topData().asInteger() ) );
break; break;


default: default:
Expand Down
8 changes: 3 additions & 5 deletions engine/expression.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -219,11 +219,9 @@ bool ExprNot::simplify( Item& value ) const
void ExprNot::apply_( const PStep* DEBUG_ONLY(self), VMContext* ctx ) void ExprNot::apply_( const PStep* DEBUG_ONLY(self), VMContext* ctx )
{ {
TRACE2( "Apply \"%s\"", ((ExprNot*)self)->describe().c_ize() ); TRACE2( "Apply \"%s\"", ((ExprNot*)self)->describe().c_ize() );

ctx->topData().setBoolean( ! ctx->boolTopData() );
Item& operand = ctx->topData(); //if the boolTopData goes deep, we'll be called again (and with a bool

// top data, next time).
//TODO: overload not
operand.setBoolean( ! operand.isTrue() );
} }


void ExprNot::describeTo( String& str ) const void ExprNot::describeTo( String& str ) const
Expand Down
1 change: 1 addition & 0 deletions engine/item.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ bool Item::isTrue() const
return false; return false;
} }



int64 Item::forceInteger() const int64 Item::forceInteger() const
{ {
switch( type() ) { switch( type() ) {
Expand Down
19 changes: 16 additions & 3 deletions engine/statement.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -92,16 +92,22 @@ void StmtWhile::apply_( const PStep* s1, VMContext* ctx )
const StmtWhile* self = static_cast<const StmtWhile*>(s1); const StmtWhile* self = static_cast<const StmtWhile*>(s1);


// break items are always nil, and so, false. // break items are always nil, and so, false.
if ( ctx->topData().isTrue() ) CodeFrame& ctxTop = ctx->currentCode();
if ( ctx->boolTopData() )
{ {
TRACE1( "Apply 'while' at line %d -- redo ", self->line() ); TRACE1( "Apply 'while' at line %d -- redo ", self->line() );
// redo. // redo.
ctx->pushCode( &self->m_pcCheck ); ctx->pushCode( &self->m_pcCheck );
ctx->pushCode( self->m_stmts ); ctx->pushCode( self->m_stmts );
} }
else { else {
TRACE1( "Apply 'while' at line %d -- leave ", self->line() ); if( &ctxTop != &ctx->currentCode() )
{
TRACE1( "Apply 'while' at line %d -- going deep on boolean check ", self->line() );
return;
}


TRACE1( "Apply 'while' at line %d -- leave ", self->line() );
//we're done //we're done
ctx->popCode(); ctx->popCode();
} }
Expand Down Expand Up @@ -274,7 +280,8 @@ void StmtIf::apply_( const PStep* s1, VMContext* ctx )
TRACE1( "Apply 'if' at line %d ", self->line() ); TRACE1( "Apply 'if' at line %d ", self->line() );


int sid = ctx->currentCode().m_seqId; int sid = ctx->currentCode().m_seqId;
if ( ctx->topData().isTrue() ) CodeFrame& ctxTop = ctx->currentCode();
if ( ctx->boolTopData() )
{ {
ctx->popData(); // anyhow, we have consumed the data ctx->popData(); // anyhow, we have consumed the data


Expand All @@ -284,6 +291,12 @@ void StmtIf::apply_( const PStep* s1, VMContext* ctx )
} }
else else
{ {
if( &ctxTop != &ctx->currentCode() )
{
TRACE1( "Apply 'if' at line %d -- going deep on boolean check ", self->line() );
return;
}

ctx->popData(); // anyhow, we have consumed the data ctx->popData(); // anyhow, we have consumed the data


// try next else-if // try next else-if
Expand Down
30 changes: 30 additions & 0 deletions engine/vmcontext.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -783,6 +783,36 @@ void VMContext::returnFrame( const Item& value )
TRACE( "Return frame code:%p, data:%p, call:%p", m_topCode, m_topData, m_topCall ); TRACE( "Return frame code:%p, data:%p, call:%p", m_topCode, m_topData, m_topCall );
} }




bool VMContext::boolTopData()
{

switch( topData().type() )
{
case FLC_ITEM_NIL:
return false;

case FLC_ITEM_BOOL:
return topData().asBoolean();

case FLC_ITEM_INT:
return topData().asInteger() != 0;

case FLC_ITEM_NUM:
return topData().asNumeric() != 0.0;

case FLC_ITEM_USER:
topData().asClass()->op_isTrue( this, topData().asInst() );
if(topData().isBoolean() )
{
return topData().asBoolean();
}
}

return false;
}

} }


/* end of vmcontext.cpp */ /* end of vmcontext.cpp */
3 changes: 1 addition & 2 deletions include/falcon/classstring.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -54,12 +54,11 @@ class FALCON_DYN_CLASS ClassString: public Class
virtual void op_add( VMContext* ctx, void* self ) const; virtual void op_add( VMContext* ctx, void* self ) const;
virtual void op_aadd( VMContext* ctx, void* self ) const; virtual void op_aadd( VMContext* ctx, void* self ) const;


// THIS IS A TODO!
virtual void op_getIndex( VMContext* ctx, void* self ) const; virtual void op_getIndex( VMContext* ctx, void* self ) const;


virtual void op_compare( VMContext* ctx, void* self ) const; virtual void op_compare( VMContext* ctx, void* self ) const;
virtual void op_toString( VMContext* ctx, void* self ) const; virtual void op_toString( VMContext* ctx, void* self ) const;
virtual void op_true( VMContext* ctx, void* self ) const; virtual void op_isTrue( VMContext* ctx, void* self ) const;


private: private:


Expand Down
3 changes: 2 additions & 1 deletion include/falcon/item.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -530,8 +530,9 @@ class FALCON_DYN_CLASS Item
return (type() == FLC_ITEM_USER && asClass()->typeID() == FLC_CLASS_ID_DICT); return (type() == FLC_ITEM_USER && asClass()->typeID() == FLC_CLASS_ID_DICT);
} }



bool isTrue() const; bool isTrue() const;

/** Turns an item into its non-user class form. /** Turns an item into its non-user class form.
\return True if the item can be de-usered. \return True if the item can be de-usered.
Expand Down
6 changes: 6 additions & 0 deletions include/falcon/vmcontext.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -1014,6 +1014,12 @@ class FALCON_DYN_CLASS VMContext


Error* thrownError() const { return m_thrown; } Error* thrownError() const { return m_thrown; }
Error* detachThrownError() { Error* e = m_thrown; m_thrown =0; return e; } Error* detachThrownError() { Error* e = m_thrown; m_thrown =0; return e; }

/** Check the boolean true-ness of the topmost data item, possibly going deep.
If
*/
bool boolTopData();

protected: protected:


// Inner constructor to create subclasses // Inner constructor to create subclasses
Expand Down

0 comments on commit 3eee803

Please sign in to comment.