Changeset 8606

Show
Ignore:
Timestamp:
01/07/06 13:49:41 (3 years ago)
Author:
gaal
Message:

.yaml:

  • make YamlNode? resemble SyckNode? a little better in structure. This will come useful when eventually we need to serialize "undef but" etc.
  • golfage (I hope it's sane, or in the right form of insanity at least)
Location:
src
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • src/Data/Yaml/Syck.hsc

    r8604 r8606  
    55module Data.Yaml.Syck ( 
    66    parseYaml, emitYaml, 
    7     YamlNode(..), 
     7    YamlNode(..), YamlElem(..), emptyYamlNode, tagNode 
    88) where 
    99 
     
    2626import Control.Monad.Trans 
    2727 
    28 type YamlTag = Maybe String 
    29  
    30 -- XXX: add tags for other types except maps? 
    31 data YamlNode 
    32     = YamlMap YamlTag [(YamlNode, YamlNode)] 
     28type YamlTag    = Maybe String 
     29type YamlAnchor = Maybe String 
     30type SYMID = CULong 
     31 
     32data YamlNode = MkYamlNode 
     33    { nid    :: SYMID 
     34    , tag    :: YamlTag 
     35    , anchor :: YamlAnchor 
     36    , el     :: YamlElem 
     37    } 
     38    deriving (Show, Ord, Eq) 
     39 
     40data YamlElem 
     41    = YamlMap [(YamlNode, YamlNode)] 
    3342    | YamlSeq [YamlNode] 
    3443    | YamlStr String 
     
    3645    deriving (Show, Ord, Eq) 
    3746 
    38 type SYMID = CULong 
    3947type SyckNode = Ptr () 
    4048type SyckParser = Ptr () 
     
    4856data SyckKind = SyckMap | SyckSeq | SyckStr | SyckNil 
    4957    deriving (Show, Ord, Eq, Enum) 
     58 
     59emptyYamlNode :: YamlNode 
     60emptyYamlNode = MkYamlNode 0 Nothing Nothing YamlNil 
     61 
     62tagNode :: YamlTag -> YamlNode -> YamlNode 
     63tagNode _   MkYamlNode{tag=Just x} = error ("can't add tag: already tagged with" ++ x) 
     64tagNode tag node                   = node{tag = tag} 
    5065 
    5166-- the extra comma here is not a bug 
     
    93108     
    94109emitNode :: (?e :: SyckEmitter) -> YamlNode -> IO () 
    95 emitNode YamlNil = do 
    96     withCString "string" $ \stringLiteral ->        
     110emitNode n@(MkYamlNode{el = YamlNil}) = do 
     111    withTag n "string" $ \tag -> 
    97112        withCString "~" $ \cs ->        
    98             syck_emit_scalar ?e stringLiteral scalarNone 0 0 0 cs 1 
    99  
    100 emitNode (YamlStr str) = do 
    101     withCString "string" $ \stringLiteral ->        
     113            syck_emit_scalar ?e tag scalarNone 0 0 0 cs 1 
     114 
     115emitNode n@(MkYamlNode{el = YamlStr str}) = do 
     116    withTag n "string" $ \tag ->        
    102117        withCString str $ \cs ->        
    103             syck_emit_scalar ?e stringLiteral scalarNone 0 0 0 cs (toEnum $ length str) 
    104  
    105 emitNode (YamlSeq seq) = do 
    106     withCString "array" $ \arrayLiteral -> 
    107         syck_emit_seq ?e arrayLiteral seqNone 
     118            syck_emit_scalar ?e tag scalarNone 0 0 0 cs (toEnum $ length str) 
     119 
     120emitNode n@(MkYamlNode{el = YamlSeq seq}) = do 
     121    withTag n "array" $ \tag -> 
     122        syck_emit_seq ?e tag seqNone 
    108123    -- TODO: fix pesky warning about "integer from pointer without a cast" here 
    109124    mapM_ (syck_emit_item ?e) =<< (mapM freezeNode seq) 
    110125    syck_emit_end ?e 
    111126 
    112 emitNode (YamlMap tag m) = do 
     127emitNode n@(MkYamlNode{el = YamlMap m}) = do 
    113128    --trace ("hash<" ++ maybe "" id tag ++">: " ++ (show m)) $ return () 
    114     withCString (maybe "hash" id tag) $ \hashLiteral -> do 
    115         syck_emit_map ?e hashLiteral mapNone 
     129    withTag n "hash" $ \tag ->  
     130        syck_emit_map ?e tag mapNone 
    116131    flip mapM_ m (\(k,v) -> do 
    117132        syck_emit_item ?e =<< freezeNode k 
     
    119134    syck_emit_end ?e 
    120135 
     136withTag :: YamlNode -> String -> (CString -> IO a) -> IO a 
     137withTag node def f = withCString (maybe def id (tag node)) f 
    121138 
    122139parseYaml :: String -> IO (Either String (Maybe YamlNode)) 
     
    192209        val     <- readNode parser valId 
    193210        return (key, val) 
    194     return $ YamlMap Nothing pairs 
     211    return $ emptyYamlNode{ el = YamlMap pairs } 
    195212 
    196213parseNode SyckSeq parser syckNode len = do 
     
    198215        symId   <- syck_seq_read syckNode idx 
    199216        readNode parser symId 
    200     return $ YamlSeq nodes 
     217    return $ emptyYamlNode{ el = YamlSeq nodes } 
    201218 
    202219parseNode SyckStr _ syckNode len = do 
    203220    cstr    <- syck_str_read syckNode 
    204221    str     <- peekCStringLen (cstr, fromEnum len) 
    205     return $ YamlStr str 
     222    return $ emptyYamlNode{ el = YamlStr str } 
    206223 
    207224foreign import ccall "wrapper"   
  • src/Pugs/Prim/Yaml.hs

    r8604 r8606  
    2323 
    2424fromYaml :: YamlNode -> Eval Val 
    25 fromYaml YamlNil = return VUndef 
    26 fromYaml (YamlStr str) = return $ VStr (decodeUTF8 str) 
    27 fromYaml (YamlSeq nodes) = do 
     25fromYaml MkYamlNode{el=YamlNil}      = return VUndef 
     26fromYaml MkYamlNode{el=YamlStr str}  = return $ VStr (decodeUTF8 str) 
     27fromYaml MkYamlNode{el=YamlSeq nodes} = do 
    2828    vals    <- mapM fromYaml nodes 
    2929    av      <- liftSTM $ newTVar $ 
    3030        IntMap.fromAscList ([0..] `zip` map lazyScalar vals) 
    3131    return $ VRef (arrayRef av) 
    32 fromYaml (YamlMap _ nodes) = do 
     32fromYaml MkYamlNode{el=YamlMap nodes} = do 
    3333    vals    <- forM nodes $ \(keyNode, valNode) -> do 
    3434        key <- fromVal =<< fromYaml keyNode 
     
    4747 
    4848toYaml :: (?d :: Int) => Val -> Eval YamlNode 
    49 toYaml _ | ?d == 0  = return $ YamlStr "<deep recursion>" -- fail? make this configurable? 
    50 toYaml VUndef       = return YamlNil 
    51 toYaml (VStr str)   = return $ YamlStr (encodeUTF8 str) 
     49toYaml _ | ?d == 0  = return $ emptyYamlNode{el = YamlStr "<deep recursion>"} -- fail? make this configurable? 
     50toYaml VUndef       = return emptyYamlNode 
     51toYaml (VStr str)   = return $ emptyYamlNode{el = YamlStr (encodeUTF8 str)} 
    5252toYaml v@(VRef r)   = let ?d = pred ?d in do 
    5353    t  <- evalValType v 
     
    5757        ifValTypeIsa v "Array" (return nodes) $ case v' of 
    5858            VObject _   -> return nodes 
    59             _           -> return (YamlMap Nothing [(YamlStr "<ref>", nodes)]) 
     59            _           -> return emptyYamlNode{el = YamlMap [(emptyYamlNode{el=YamlStr "<ref>"}, nodes)]} 
    6060toYaml (VList nodes) = let ?d = pred ?d in do 
    61     fmap YamlSeq $ mapM toYaml nodes 
     61    n <- mapM toYaml nodes 
     62    return $ emptyYamlNode{el=YamlSeq n} -- golfme! 
     63    -- fmap YamlSeq$ mapM toYaml nodes 
    6264toYaml v@(VObject obj) = let ?d = pred ?d in do 
    6365    -- ... dump the objAttrs 
     
    6769    hash    <- fromVal v :: Eval VHash 
    6870    attrs   <- toYaml $ VRef (hashRef hash) 
    69     return $ addTag (Just $ "tag:pugs:object:" ++ showType (objType obj)) attrs 
    70     where 
    71     addTag _   (YamlMap (Just x) _) = error ("can't add tag: already tagged with" ++ x) 
    72     addTag tag (YamlMap _        m) = YamlMap tag m 
    73 toYaml v = (return . YamlStr . encodeUTF8 . pretty) v 
     71    return $ tagNode (Just $ "tag:pugs:object:" ++ showType (objType obj)) attrs 
     72toYaml v = return $ emptyYamlNode{el=YamlStr p} 
     73    where p = (encodeUTF8 . pretty) v 
     74 
    7475 
    7576hashToYaml :: (?d :: Int) => VRef -> Eval YamlNode 
     
    8182        va' <- toYaml va 
    8283        return (ka', va') 
    83     return $ YamlMap Nothing yamlmap 
     84    return $ emptyYamlNode{el=YamlMap yamlmap} 
    8485hashToYaml r = error ("unexpected node: " ++ show r) 
    85     
    86 {- 
    87 ifValTypeIsa v "Pair" 
    88     (case v' of 
    89         VList [ks, vs] -> do 
    90             kStr <- toYaml d ks 
    91             vStr <- toYaml d vs 
    92             return $ YamlMap [(kStr, vStr)] -- assume a pair is a one-element hash 
    93         _ -> toYaml d v'                    -- XXX: probably broken to blithingly ignore ref levels here 
    94     ) 
    95     (ifValTypeIsa v "Hash" 
    96         --fmap YamlMap $ mapM (\(k, v) -> do {k' <- toYaml k; v' <- toYaml v; return (k', v')}) Map.toList =<< hash_fetch v') 
    97         (do  
    98             case r of 
    99                 MkRef (IHash hv) -> do 
    100                     h <- hash_fetch hv 
    101                     let assocs = Map.toList h 
    102                     yamlmap <- mapM (\(k, v) -> do 
    103                         k' <- toYaml d (VStr k) 
    104                         v' <- toYaml d v 
    105                         return (k', v')) assocs 
    106                     return $ YamlMap yamlmap 
    107                 _ -> error ("can't process hash: " ++ show v') -- XXX 
    108         ) 
    109         (do nodes <- toYaml d v' 
    110             ifValTypeIsa v "Array" 
    111                 (return $ nodes) 
    112                 (return $ YamlMap [(YamlStr "<ref>", nodes)])) -- XXX 
    113     ) 
    114 -} 
     86