Changeset 8208
- Timestamp:
- 12/13/05 12:18:12 (3 years ago)
- Location:
- src
- Files:
-
- 1 added
- 9 modified
-
PIL.hs (modified) (3 diffs)
-
PIL/MM (added)
-
PIL/Native.hs (modified) (1 diff)
-
PIL/Native/Coerce.hs (modified) (7 diffs)
-
PIL/Native/Eval.hs (modified) (6 diffs)
-
PIL/Native/Objects.hs (modified) (2 diffs)
-
PIL/Native/Parser.hs (modified) (3 diffs)
-
PIL/Native/Pretty.hs (modified) (5 diffs)
-
PIL/Native/Prims.hs (modified) (2 diffs)
-
PIL/Native/Types.hs (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/PIL.hs
r8205 r8208 38 38 exps <- parseNativeLang src 39 39 banner "Parsed" 40 putStrLn =<< pretty exps40 putStrLn =<< prettyM exps 41 41 banner "Evaluated" 42 42 (val, objs) <- evalNativeLang exps 43 putStrLn =<< pretty val43 putStrLn =<< prettyM val 44 44 banner "Object Space" 45 45 dumpObjSpace objs … … 56 56 parse src = do 57 57 exps <- parseNativeLang src 58 putStrLn =<< pretty exps58 putStrLn =<< prettyM exps 59 59 return () 60 60 … … 63 63 exps <- parseNativeLang src 64 64 (val, objs) <- evalNativeLang exps 65 putStrLn =<< pretty val 65 putStrLn =<< prettyM val 66 banner "Object Space" 66 67 dumpObjSpace objs 67 68 -
src/PIL/Native.hs
r8205 r8208 5 5 parseNativeLang, 6 6 NativeLangExpression, 7 pretty, 7 pretty, prettyM, 8 8 dumpObjSpace, 9 9 ) where -
src/PIL/Native/Coerce.hs
r8205 r8208 28 28 nil = toNative mkNil 29 29 30 emptySeq :: Native 31 emptySeq = toNative (empty :: NativeSeq) 32 33 emptyMap :: Native 34 emptyMap = toNative (empty :: NativeMap) 35 30 36 mkNil :: NativeError 31 37 mkNil = NonTermination … … 59 65 isEmpty :: a -> NativeBit 60 66 size :: a -> NativeInt 67 exists :: a -> key -> Bool 61 68 empty :: a 62 69 indices :: a -> [key] … … 75 82 size = NStr.length 76 83 empty = NStr.empty 84 exists (NStr.PS _ _ l) n = (n >= 0) && (n < l) 77 85 indices = \x -> [0 .. (NStr.length x - 1)] 78 86 elems = NStr.elems … … 93 101 indices = NMap.keys 94 102 elems = NMap.elems 103 exists = flip NMap.member 95 104 append = NMap.union 96 105 push = error "It doesn't make sense to push into a hash" … … 102 111 103 112 instance IsPlural (SeqOf a) NativeInt a where 104 isEmpty = NSeq.null 105 size = NSeq.length 106 empty = NSeq.empty 107 indices = \x -> [0 .. size x - 1] 108 elems = NSeq.toList 109 append = (NSeq.><) 110 push = append 111 assocs = ([0..] `zip`) . elems 112 fromAssocs = NSeq.fromList . map snd -- XXX wrong 113 fetch x y = Just (NSeq.index x y) -- XXX wrong 114 insert = \x k v -> NSeq.update k v x 115 (!) = NSeq.index 113 isEmpty = NSeq.null 114 size = NSeq.length 115 empty = NSeq.empty 116 exists x n = (n >= 0) && (n < size x) 117 indices = \x -> [0 .. size x - 1] 118 elems = NSeq.toList 119 append = (NSeq.><) 120 push = append 121 assocs = ([0..] `zip`) . elems 122 fromAssocs = NSeq.fromList . map snd -- XXX wrong 123 fetch x y = Just (NSeq.index x y) -- XXX wrong 124 insert x k v | k == size x = (NSeq.|>) x v 125 insert x k v = NSeq.update k v x 126 (!) = NSeq.index 116 127 117 128 class Show a => IsNative a where … … 201 212 fromNative x = castFail x 202 213 214 instance IsNative NativeObj where 215 toNative = NObj 216 fromNative (NObj x) = x 217 fromNative x = castFail x 218 203 219 instance IsNative NativeError where 204 220 toNative = NError … … 243 259 castFail :: a -> b 244 260 castFail _ = error "cast fail" 261 262 failWith :: (Monad m, IsNative a) => String -> a -> m b 263 failWith msg s = fail $ msg ++ ": " ++ toString s -
src/PIL/Native/Eval.hs
r8205 r8208 1 1 {-# OPTIONS_GHC -fglasgow-exts -fno-warn-orphans -funbox-strict-fields #-} 2 2 3 module PIL.Native.Eval where3 module PIL.Native.Eval (evalNativeLang) where 4 4 import PIL.Native.Prims 5 5 import PIL.Native.Types 6 6 import PIL.Native.Coerce 7 7 import PIL.Native.Objects 8 import PIL.Native.Parser 8 9 import Data.FunctorM 9 10 import Control.Monad.State … … 24 25 -} 25 26 26 type Eval = StateT ObjectSpace (ReaderT Pad SIO)27 type Eval = StateT ObjectSpace (ReaderT Pad IO) 27 28 type Pad = NativeMap 28 29 … … 30 31 liftSTM = lift . lift . liftSTM 31 32 32 evalNativeLang :: MonadSTM m => [NativeLangExpression] -> m (Native, ObjectSpace) 33 evalNativeLang = runSIO . (`runReaderT` empty) . (`runStateT` empty) . evalMain 33 -- evalNativeLang :: MonadSTM m => [NativeLangExpression] -> m (Native, ObjectSpace) 34 evalNativeLang :: [NativeLangExpression] -> IO (Native, ObjectSpace) 35 evalNativeLang = (`runReaderT` empty) . (`runStateT` empty) . evalMain 34 36 35 37 evalMain :: [NativeLangExpression] -> Eval Native 36 evalMain exps = do37 -- bootstrap38 evalMain exps = bootstrapClass $ do 39 addClassMethods 38 40 evalExps exps 41 42 addClassMethods :: Eval Native 43 addClassMethods = do 44 add "has_method" "-> $name { self.get_attr('%methods').exists($name) }" 45 add "get_method" "-> $name { self.get_attr('%methods').fetch($name) }" 46 add "get_method_list" "-> $name { self.get_attr('%methods').keys() }" 47 add "new" "-> %prms { self.bless(nil, %prms) }" 48 add "bless" $ "-> $repr, %prms { \ 49 \ -> $obj { $obj.BUILDALL(%prms); $obj; } \ 50 \ .(self.CREATE($repr, %prms)) \ 51 \ }" 52 add "CREATE" $ "-> $repr, %prms {} " -- XXX - not finished yet 53 where 54 add name body = eval $ "::Class.add_method('" ++ name ++ "', " ++ body ++ ")" 55 56 eval :: String -> Eval Native 57 eval = evalExp . parseExp 58 59 bootstrapClass :: Eval a -> Eval a 60 bootstrapClass x = mdo 61 cls <- newObject cls 62 [ ("@MRO", emptySeq) 63 , ("@subclasses", emptySeq) 64 , ("@superclasses", emptySeq) 65 , ("%private_methods", emptyMap) 66 , ("%attributes", emptyMap) 67 , ("%methods", toNative $ mkMap [("add_method", addMethod)]) 68 ] 69 enterLex [("::Class", cls)] x 70 where 71 addMethod = parseSub 72 "-> $name, &method { self.set_attr_hash('%methods', $name, &method) }" 73 74 enterLex :: IsNative a => [(String, a)] -> Eval b -> Eval b 75 enterLex = local . append . mkMap . map (\(x, y) -> (x, toNative y)) 39 76 40 77 evalExps :: [NativeLangExpression] -> Eval Native … … 49 86 case pad `fetch` s of 50 87 Just v -> return v 51 Nothing -> fail $ "No such variable " ++ toStrings88 Nothing -> failWith "No such variable" s 52 89 evalExp (ECall { c_obj = objExp, c_meth = meth, c_args = argsExp }) = do 53 90 obj <- evalExp objExp … … 71 108 where 72 109 errMethodMissing :: Eval a 73 errMethodMissing = fail ("No such method: " ++ toString meth)110 errMethodMissing = failWith "No such method" meth 74 111 callMethod :: MapOf (a -> b -> Native) -> a -> b -> Eval Native 75 112 callMethod prims x args = case prims `fetch` meth of … … 91 128 callConditional x args = callSub (fromNative $ args ! fromEnum (not x)) empty 92 129 130 infixl ... 131 (...) :: IsNative a => NativeObj -> String -> Eval a 132 obj ... str = fmap fromNative $ getAttr obj (mkStr str) 133 93 134 callObject :: NativeObj -> NativeStr -> NativeSeq -> Eval Native 94 callObject obj meth args = do 95 mro <- getAttr obj (mkStr "@:MRO") 96 return mro 135 callObject obj meth args = enterLex lex $ do 136 meths <- cls ... "%methods" :: Eval NativeMap 137 case meths `fetch` meth of 138 Just x -> callSub (fromNative x) args 139 _ -> tryMRO =<< getMRO 97 140 where 141 lex = [("$?SELF", obj), ("$?CLASS", cls)] 98 142 cls = o_class obj 143 getMRO = do 144 mro <- cls ... "@MRO" :: Eval NativeSeq 145 if isEmpty mro 146 then cls ... "@superclasses" 147 else return (elems mro) 148 tryMRO [] | meth == mkStr "get_attr" = do 149 obj ... fromNative (args ! 0) 150 tryMRO [] | meth == mkStr "set_attr_hash" = do 151 let [attrVal, keyVal, val] = elems args 152 key :: NativeStr = fromNative keyVal 153 hash <- obj ... fromNative attrVal :: Eval NativeMap 154 setAttr obj (fromNative attrVal) (toNative $ insert hash key val) 155 return nil 156 tryMRO [] = failWith "No such method" meth 157 tryMRO (c:cs) = do 158 meths <- fromNative c ... "%methods" :: Eval NativeMap 159 case meths `fetch` meth of 160 Just x -> callSub (fromNative x) args 161 _ -> tryMRO cs -
src/PIL/Native/Objects.hs
r8206 r8208 1 1 {-# OPTIONS_GHC -fglasgow-exts #-} 2 2 3 module PIL.Native.Objects (ObjectSpace, dumpObjSpace, getAttr) where 3 module PIL.Native.Objects ( 4 ObjectSpace, 5 dumpObjSpace, 6 newObject, 7 getAttr, setAttr, addAttr, 8 ) where 4 9 import PIL.Native.Coerce 5 10 import PIL.Native.Types 6 11 import PIL.Native.Pretty 7 12 import System.Mem.Weak 8 import Control.Monad 13 import Control.Monad.State 9 14 10 15 type ObjectSpace = SeqOf (Weak NativeObj) 11 16 12 17 dumpObjSpace :: ObjectSpace -> IO () 13 dumpObjSpace ptrs = mapM_ dumpObj ( assocs ptrs)18 dumpObjSpace ptrs = mapM_ dumpObj (elems ptrs) 14 19 where 15 dumpObj (idx, ptr)= do20 dumpObj ptr = do 16 21 rv <- deRefWeak ptr 17 22 case rv of 18 Just obj -> do 19 putStr $ show idx ++ ": " 20 putStrLn =<< pretty obj 21 Nothing -> return () 23 Just obj -> putStrLn (pretty obj) 24 Nothing -> return () 22 25 23 26 getAttr :: MonadSTM m => NativeObj -> NativeStr -> m Native … … 26 29 case attrs `fetch` att of 27 30 Just val -> return val 28 Nothing -> fail "no such attribute" 31 Nothing -> failWith "no such attribute" att 32 33 setAttr :: MonadSTM m => NativeObj -> NativeStr -> Native -> m () 34 setAttr obj att val = do 35 let tvar = o_attrs obj 36 attrs <- liftSTM $ readTVar tvar 37 unless (exists attrs att) $ failWith "no such attribute" att 38 liftSTM $ writeTVar tvar (insert attrs att val) 39 40 addAttr :: MonadSTM m => NativeObj -> NativeStr -> m () 41 addAttr obj att = do 42 let tvar = o_attrs obj 43 attrs <- liftSTM $ readTVar tvar 44 when (exists attrs att) $ failWith "already got attribute" att 45 liftSTM $ writeTVar tvar (insert attrs att nil) 46 47 newObject :: (MonadState ObjectSpace m, MonadIO m, MonadSTM m) => 48 NativeObj -> [(String, Native)] -> m NativeObj 49 newObject cls pairs = do 50 attrs <- liftSTM $ newTVar (mkMap pairs) 51 objs <- get 52 let obj = MkObject oid cls attrs 53 oid = size objs 54 ptr <- liftIO $ mkWeak attrs obj Nothing 55 put (insert objs oid ptr) 56 return obj -
src/PIL/Native/Parser.hs
r8205 r8208 61 61 62 62 parseNativeLang :: Monad m => String -> m [NativeLangExpression] 63 parseNativeLang src = case ( runParser program () "-" src )of63 parseNativeLang src = case parse program "-" src of 64 64 Left err -> fail (show err) 65 65 Right exp -> return exp 66 66 where 67 67 program = between bof eof (semiColonSep expression) 68 bof = return () 68 69 parseWith :: Parser a -> String -> a 70 parseWith p src = case parse (between bof eof p) src src of 71 Left err -> error (show err) 72 Right exp -> exp 73 74 bof :: Parser () 75 bof = whiteSpace 76 77 parseSub :: String -> Native 78 parseSub = toNative . parseWith pointySub 79 80 parseExp :: String -> NativeLangExpression 81 parseExp = parseWith expression 69 82 70 83 expression :: Parser NativeLangExpression … … 72 85 obj <- choice 73 86 [ parens expression 87 , selfExpression 74 88 , arrayExpression 75 89 , fmap ELit literal … … 95 109 args <- option [] (parens $ commaSep expression) 96 110 return (name, args) 111 selfExpression = do 112 symbol "self" 113 return (EVar $ mkStr "$?SELF") 97 114 98 115 literal :: Parser Native -
src/PIL/Native/Pretty.hs
r8205 r8208 1 1 {-# OPTIONS_GHC -cpp -fglasgow-exts #-} 2 2 3 module PIL.Native.Pretty (Pretty(..), pretty ) where3 module PIL.Native.Pretty (Pretty(..), pretty, prettyM) where 4 4 import PIL.Native.Types 5 5 import PIL.Native.Coerce … … 19 19 -} 20 20 21 pretty :: (Functor m, MonadSTM m, Pretty a) => a -> m String 22 pretty a = fmap render $ formatM a 21 pretty :: (Pretty a) => a -> String 22 pretty = render . format 23 24 prettyM :: (MonadSTM m, Pretty a) => a -> m String 25 prettyM a = fmap render $ formatM a 26 27 defaultIndent :: Int 28 defaultIndent = 2 23 29 24 30 class (Show a) => Pretty a where … … 48 54 instance Pretty NativeSub where 49 55 format (MkSub params body) = hang 50 (text "->" <+> commaSep (elems params)) 256 (text "->" <+> commaSep (elems params)) defaultIndent 51 57 (braces . format . elems $ body) 52 58 … … 62 68 format (NSub x) = format x 63 69 format (NObj x) = format x 70 formatM (NObj x) = formatM x 71 formatM (NSeq x) = formatM x 72 formatM (NMap x) = formatM x 73 formatM x = return (format x) 64 74 65 75 instance Pretty NativeObj where 76 format o = text $ "<obj:#" ++ show (o_id o) ++ "|cls:#" ++ show (o_id (o_class o)) ++ ">" 77 formatM o = do 78 attrs <- liftSTM $ readTVar (o_attrs o) 79 formatM attrs 80 81 instance Pretty NativeSeq where 82 format x = brackets (nest defaultIndent (commaSep $ elems x)) 83 formatM x = do 84 items <- commaSepM $ elems x 85 return $ brackets (nest defaultIndent items) 86 87 instance Pretty NativeMap where 88 format x = braces (nest defaultIndent (commaSep $ assocs x)) 89 formatM x = do 90 pairs <- commaSepM $ assocs x 91 return $ braces (nest defaultIndent pairs) 92 93 instance Pretty Doc where 94 format = id 66 95 67 96 instance Pretty String where … … 74 103 sepBy x = sep . punctuate x . map format 75 104 105 sepByM :: (MonadSTM m, Pretty a) => Doc -> [a] -> m Doc 106 sepByM x = fmap (sep . punctuate x) . mapM formatM 107 76 108 commaSep :: Pretty a => [a] -> Doc 77 109 commaSep = sepBy comma 110 111 commaSepM :: (MonadSTM m, Pretty a) => [a] -> m Doc 112 commaSepM = sepByM comma 113 -
src/PIL/Native/Prims.hs
r8205 r8208 67 67 concat (Any) -> Nil 68 68 fetch (Any) -> Any 69 exists (Any) -> Any 69 70 store (Any, Any) -> Nil 70 71 push (Hash) -> Nil … … 148 149 , prim1 "concat" (append) 149 150 , prim1 "fetch" (fetch) 151 , prim1 "exists" (exists) 150 152 , prim2 "store" (insert) 151 153 , primX "push" (pushHash) -
src/PIL/Native/Types.hs
r8205 r8208 60 60 61 61 data NativeObj = MkObject 62 { o_ class :: NativeObj -- ::Class is self-recursive, so can't be strict here63 , o_ id :: !ObjectId62 { o_id :: !ObjectId 63 , o_class :: NativeObj -- ::Class is self-recursive, so can't be strict here 64 64 , o_attrs :: !ObjectAttrs 65 65 } … … 97 97 instance Ord NativeError where 98 98 compare x y = compare (show x) (show y) 99
