content: -----------------------------------------------------------------------------
  -- |
  -- Module      : Berp.Base.Truth
  -- Copyright   : (c) 2010 Bernie Pope
  -- License     : BSD-style
  -- Maintainer  : florbitous@gmail.com
  -- Stability   : experimental
  -- Portability : ghc
  --
  -- Implementation of the truth predicate on Python objects.
  --
  -----------------------------------------------------------------------------
  
  module Berp.Base.Truth (truth) where
  
  import {-# SOURCE #-} Berp.Base.HashTable as HashTable (sizeIO)
  import {-# SOURCE #-} Berp.Base.HashSet as HashSet (sizeIO)
  import Berp.Base.SemanticTypes (Object (..))
  import Data.Complex (Complex (..))
  import System.IO.Unsafe (unsafePerformIO)
  import Data.IORef (readIORef)
  
  -- XXX incomplete
  truth :: Object -> Bool
  truth (Bool { object_bool = b }) = b
  truth (Integer { object_integer = i }) = i /= 0
  truth (Float { object_float = f }) = f /= 0
  truth (Complex { object_complex = c }) = c /= (0 :+ 0)
  truth None = False
  truth obj@(Tuple {}) = object_length obj /= 0
  truth obj@(String {}) = object_string obj /= []
  truth obj@(List {}) = unsafePerformIO $ do
     numElems <- readIORef $ object_list_num_elements obj
     return (numElems /= 0)
  truth obj@(Dictionary {}) = unsafePerformIO $ do
     numElems <- HashTable.sizeIO $ object_hashTable obj
     return (numElems /= 0)
  truth obj@(Set {}) = unsafePerformIO $ do
     numElems <- HashSet.sizeIO $ object_hashSet obj
     return (numElems /= 0)
  truth _other = True
  
  {-
     Python Language Reference, section 5.10 "Boolean operations":
  
     In the context of Boolean operations, and also when expressions 
     are used by control flow statements, the following values are 
     interpreted as false: False, None, numeric zero of all types, 
     and empty strings and containers (including strings, tuples, 
     lists, dictionaries, sets and frozensets). All other values 
     are interpreted as true. User-defined objects can customize their 
     truth value by providing a __bool__() method.
  -}
  