module HJS.Interpreter.InterpMDecl where import Control.Monad.Identity import Control.Monad.Error import Control.Monad.State import Data.Map as M import HJS.Parser.JavaScript hiding (Object) data Ref = Ref String | RefObj ObjId String deriving (Eq,Show,Ord) data ObjId = ObjId Int | ObjIdNull deriving (Eq,Show,Ord) data Undefined = Undefined deriving (Eq,Show,Ord) data Null = Null deriving (Eq,Show,Ord) data RunFlag = Debug | Trace | ShowHeap deriving (Show,Eq) -- Either JS source from a function or a built in function data CallValue = CallJS [SourceElement] | CallBuiltIn (InterpM Value) data BreakContinue = Break | Continue deriving (Show,Eq,Ord) data ArgList = ArgList [String] | VarArgList -- Think I should be including Ref (ie what is returned by LeftExpr) into the Value type. type Value = Either Int -- Primitive values ( Either String ( Either Bool ( Either Undefined ( Either Null -- Internal values ( Either ObjId ( Either Ref -- Reference ( Either [ObjId] -- List of object ids ( Either CallValue -- Code, used 'Call' property of Function object. ( Either [String] -- List of argument names ( Either BreakContinue ())))))))))) type InterpM = ErrorT Throwable (StateT JSState IO) -- Identity) -- Execution Context = Scope chain, variable object, this object, current function type Ctx = ([ObjId],ObjId,ObjId,ObjId) data JSState = JSS { ctx :: [Ctx], oheap :: Map ObjId Object, pos :: (Int,Int), flags :: [ RunFlag ], debug :: [DebugAction] } deriving Show data Throwable = ThrowReturn Value | ThrowBreak (Maybe String) | ThrowContinue (Maybe String) | ThrowException Value | ThrowTypeError String | ThrowInternalError String deriving Show -- Section 8.6.2 data Object = Object { idd :: ObjId, prototype :: Maybe ObjId, klass :: String, value :: Maybe Value, properties :: M.Map String (Value,[Attribute]) } deriving Show data Attribute = ReadOnly | DontEnum | DontDelete | Internal deriving (Eq,Show) instance Show CallValue where show (CallJS x) = show x show (CallBuiltIn _) = show "" instance Ord CallValue where compare _ _ = EQ instance Eq CallValue where (==) _ _ = True data DebugAction = DBBreak Int -- Set a break point at a line | DBContinue -- Continue execution to next break point | StepOver -- Step over a statement | StepInto -- Step into a statement | PrintObj Int -- Print object with ID | PrintHeap -- Print the whole heap | PrintVar String -- Print variable | PrintLine -- Print current statement | PrintStack -- Print the stack | Eval String deriving (Show,Eq)