Permalink
Browse files

Fixed automatic bolean-ification in boolean statements and expressions

  • Loading branch information...
1 parent b4b29e4 commit 3eee803b05308da230b92f96298b33a2dd9a3393 @jonnymind jonnymind committed Sep 22, 2011
View
@@ -349,7 +349,7 @@ void Class::op_setProperty( VMContext* , void*, const String& ) const
void Class::op_isTrue( VMContext* ctx, void* ) const
{
- ctx->stackResult(1, true);
+ ctx->topData().setBoolean(true);
}
View
@@ -350,9 +350,9 @@ void ClassString::op_toString( VMContext* ctx, void* data ) const
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 );
}
}
View
@@ -95,7 +95,7 @@ void generic_apply_( const PStep* DEBUG_ONLY(ps), VMContext* ctx )
op1.asClass()->op_compare( ctx, op1.asInst() );
// refetch, we may have gone deep
fassert( ctx->topData().isInteger() );
- ctx->topData().setBoolean( __CPR::cmpCheck( ctx->topData().asInteger() < 0 ) );
+ ctx->topData().setBoolean( __CPR::cmpCheck( ctx->topData().asInteger() ) );
break;
default:
View
@@ -219,11 +219,9 @@ bool ExprNot::simplify( Item& value ) const
void ExprNot::apply_( const PStep* DEBUG_ONLY(self), VMContext* ctx )
{
TRACE2( "Apply \"%s\"", ((ExprNot*)self)->describe().c_ize() );
-
- Item& operand = ctx->topData();
-
- //TODO: overload not
- operand.setBoolean( ! operand.isTrue() );
+ ctx->topData().setBoolean( ! ctx->boolTopData() );
+ //if the boolTopData goes deep, we'll be called again (and with a bool
+ // top data, next time).
}
void ExprNot::describeTo( String& str ) const
View
@@ -101,6 +101,7 @@ bool Item::isTrue() const
return false;
}
+
int64 Item::forceInteger() const
{
switch( type() ) {
View
@@ -92,16 +92,22 @@ void StmtWhile::apply_( const PStep* s1, VMContext* ctx )
const StmtWhile* self = static_cast<const StmtWhile*>(s1);
// 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() );
// redo.
ctx->pushCode( &self->m_pcCheck );
ctx->pushCode( self->m_stmts );
}
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
ctx->popCode();
}
@@ -274,7 +280,8 @@ void StmtIf::apply_( const PStep* s1, VMContext* ctx )
TRACE1( "Apply 'if' at line %d ", self->line() );
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
@@ -284,6 +291,12 @@ void StmtIf::apply_( const PStep* s1, VMContext* ctx )
}
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
// try next else-if
View
@@ -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 );
}
+
+
+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 */
@@ -54,12 +54,11 @@ class FALCON_DYN_CLASS ClassString: public Class
virtual void op_add( 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_compare( 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:
View
@@ -530,8 +530,9 @@ class FALCON_DYN_CLASS Item
return (type() == FLC_ITEM_USER && asClass()->typeID() == FLC_CLASS_ID_DICT);
}
+
bool isTrue() const;
-
+
/** Turns an item into its non-user class form.
\return True if the item can be de-usered.
@@ -1014,6 +1014,12 @@ class FALCON_DYN_CLASS VMContext
Error* thrownError() const { return m_thrown; }
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:
// Inner constructor to create subclasses

0 comments on commit 3eee803

Please sign in to comment.