module Berp.Base.SemanticTypes
( Procedure, ControlStack (..), EvalState (..), Object (..), Eval, ObjectRef
, HashTable, ListArray, Arity ) where
import Control.Monad.State.Strict (StateT)
import Control.Monad.Cont (ContT)
import Data.IntMap (IntMap)
import Data.IORef (IORef)
import Data.Array.IO (IOArray)
import Berp.Base.Identity (Identity)
data ControlStack
= EmptyStack
| ProcedureCall
{ procedure_return :: Object -> Eval Object
, control_stack_tail :: ControlStack
}
| ExceptionHandler
{ exception_handler :: Maybe (Object -> Eval Object)
, exception_finally :: Maybe (Eval Object)
, control_stack_tail :: ControlStack
}
| WhileLoop
{ loop_start :: Eval Object
, loop_end :: Eval Object
, control_stack_tail :: ControlStack
}
| GeneratorCall
{ generator_yield :: Object -> Eval Object
, generator_object :: Object
, control_stack_tail :: ControlStack
}
instance Show ControlStack where
show EmptyStack = "EmptyStack"
show (ProcedureCall {}) = "ProcedureCall"
show (ExceptionHandler {}) = "ExceptionHandler"
show (WhileLoop {}) = "WhileLoop"
show (GeneratorCall {}) = "GeneratorCall"
data EvalState = EvalState { control_stack :: !ControlStack }
type Eval a = StateT EvalState (ContT Object IO) a
type ObjectRef = IORef Object
type Procedure = [Object] -> Eval Object
type HashTable = IORef (IntMap [(Object, Object)])
type ListArray = IOArray Integer Object
type Arity = Int
data Object
= Object
{ object_identity :: !Identity
, object_type :: !Object
, object_dict :: !Object
}
| Type
{ object_identity :: !Identity
, object_type :: Object
, object_dict :: !Object
, object_bases :: !Object
, object_constructor :: !Procedure
, object_type_name :: !Object
, object_mro :: !Object
}
| Integer
{ object_identity :: !Identity
, object_integer :: !Integer
}
| Bool
{ object_identity :: !Identity
, object_bool :: !Bool
}
| Tuple
{ object_identity :: !Identity
, object_tuple :: ![Object]
, object_length :: !Int
}
| List
{ object_identity :: !Identity
, object_list_elements :: IORef ListArray
, object_list_num_elements :: Integer
}
| Function
{ object_identity :: !Identity
, object_procedure :: !Procedure
, object_arity :: !Arity
, object_dict :: !Object
}
| String
{ object_identity :: !Identity
, object_string :: !String
}
| Dictionary
{ object_identity :: !Identity
, object_hashTable :: !HashTable
}
| Generator
{ object_identity :: !Identity
, object_continuation :: !(IORef (Eval Object))
, object_stack_context :: !(IORef (ControlStack -> ControlStack))
}
| None
instance Show Object where
show obj@(Object {}) = "object of (" ++ show (object_type obj) ++ ")"
show obj@(Type {}) = "type(" ++ show (object_type_name obj) ++ ")"
show obj@(Integer {}) = "integer(" ++ show (object_integer obj) ++ ")"
show obj@(Bool {}) = "bool(" ++ show (object_bool obj) ++ ")"
show (Tuple {}) = "tuple"
show (List {}) = "list"
show (Function {}) = "function"
show obj@(String {}) = "string(" ++ show (object_string obj) ++ ")"
show (Dictionary {}) = "dictionary"
show (Generator {}) = "generator"
show (None {}) = "None"
instance Eq Object where
None {} == None {} = True
obj1 == obj2 = object_identity obj1 == object_identity obj2