Changeset 12317 for src/Pugs/AST.hs

Show
Ignore:
Timestamp:
08/16/06 19:28:24 (2 years ago)
Author:
audreyt
Message:

* Glorious refactoring of the Var type.

Previously, Var is type synonym to String, and all package

lookups, OUTER
handling, sigil and twigil parsing etc were done in an extremely adhoc way with String operations.

Now we split Var into several parts.
Take "&Moose::Elk::infix:<antler>" as an example:

v_sigil
VarSigil? -- SScalar
v_twigil
VarTwigil? -- TNone
v_package
Pkg -- ["Moose", "Elk"]
v_categ
VarCateg? -- C_infix
v_name
ID -- "antler"

The names are stored as interned ByteStrings? for fast comparison.

All involved types are changed from String to new types as well,

such as (envPackage
Pkg).
Files:
1 modified

Legend:

Unmodified
Added
Removed
  • src/Pugs/AST.hs

    r12176 r12317  
    3131import Pugs.Types 
    3232import qualified Data.Map as Map 
    33 import Pugs.AST.Internals.Instances 
     33import qualified Data.Set as Set 
     34import Pugs.AST.Internals.Instances () 
    3435import Pugs.AST.Internals 
    3536import Pugs.AST.Prag 
     
    100101(Is this correct?) 
    101102-} 
    102 genMultiSym :: MonadSTM m => String -> VRef -> m PadMutator 
     103genMultiSym :: MonadSTM m => Var -> VRef -> m PadMutator 
    103104genMultiSym name ref = do 
    104105    --trace ("installing multi: " ++ name) $ return () 
     
    114115(right?), shadowing any earlier or outer definition. 
    115116-} 
    116 genSym :: MonadSTM m => String -> VRef -> m PadMutator 
    117 genSym name ref = do 
     117genSym :: MonadSTM m => Var -> VRef -> m PadMutator 
     118genSym var ref = do 
    118119    --trace ("installing: " ++ name) $ return () 
    119120    tvar    <- liftSTM $ newTVar ref 
    120121    fresh   <- liftSTM $ newTVar True 
    121     return $ \(MkPad map) -> MkPad $ Map.insert name (MkEntry (fresh, tvar)) map 
     122    return $ \(MkPad map) -> MkPad $ Map.insert var (MkEntry (fresh, tvar)) map 
    122123 
    123124{-| 
     
    131132    Pad _ _ exp     -> isScalarLValue exp 
    132133    Sym _ _ exp     -> isScalarLValue exp 
    133     Var ('$':_)    -> True 
     134    Var var | SScalar <- v_sigil var -> True 
    134135    Syn "${}" _     -> True -- XXX - Change tp App("&prefix:<$>") later 
    135136    Syn "$::()" _   -> True 
     
    141142    where 
    142143    isSIMPLE x = case unwrap x of 
    143         App (Var ('&':'p':'r':'e':'f':'i':'x':':':op)) Nothing [y] 
    144             -> op `elem` coercePrefixOps || (op `elem` simplePrefixOps && isSIMPLE y) 
    145         App (Var ('&':'p':'r':'e':'f':'i':'x':':':op)) (Just y) [] 
    146             -> op `elem` coercePrefixOps || (op `elem` simplePrefixOps && isSIMPLE y) 
    147         App (Var ('&':'p':'o':'s':'t':'f':'i':'x':':':op)) Nothing [y] 
    148             -> op `elem` simplePostfixOps && isSIMPLE y 
    149         App (Var ('&':'p':'o':'s':'t':'f':'i':'x':':':op)) (Just y) [] 
    150             -> op `elem` simplePostfixOps && isSIMPLE y 
    151         App (Var ('&':'i':'n':'f':'i':'x':':':op)) Nothing [y, z] 
    152             -> op `elem` simpleInfixOps && isSIMPLE y && isSIMPLE z 
    153         App (Var ('&':'i':'n':'f':'i':'x':':':op)) (Just y) [z] 
    154             -> op `elem` simpleInfixOps && isSIMPLE y && isSIMPLE z 
     144        App (Var var) Nothing [y] 
     145            | C_prefix <- v_categ var 
     146            -> var `Set.member` coercePrefixOps 
     147                || (var `Set.member` simplePrefixOps && isSIMPLE y) 
     148            | C_postfix <- v_categ var 
     149            -> var `Set.member` simplePostfixOps && isSIMPLE y 
     150        App (Var var) (Just y) [] 
     151            | C_prefix <- v_categ var 
     152            -> var `Set.member` coercePrefixOps 
     153                || (var `Set.member` simplePrefixOps && isSIMPLE y) 
     154            | C_postfix <- v_categ var 
     155            -> var `Set.member` simplePostfixOps && isSIMPLE y 
     156        App (Var var) Nothing [x, y] 
     157            | C_infix <- v_categ var 
     158            -> var `Set.member` simpleInfixOps && isSIMPLE x && isSIMPLE y 
     159        App (Var var) (Just x) [y] 
     160            | C_infix <- v_categ var 
     161            -> var `Set.member` simpleInfixOps && isSIMPLE x && isSIMPLE y 
    155162        _               -> isScalarLValue x 
    156     coercePrefixOps = 
    157         [ "!","+","-","~","?","$" ] 
    158     simplePrefixOps = 
    159         [ "++","--" 
    160         , "$","&","+^","~^","?^","\\","^","=" 
    161         ] 
    162     simplePostfixOps = ["++", "--"] 
    163     simpleInfixOps = 
    164         [ "**" 
    165         , "**=" 
    166         , "*","/","%","x","+&","+<","+>","~&","~<","~>" 
    167         , "*=","/=","%=","x=","+&=","+<=","+>=","~&=","~<=","~>=" 
    168         , "+","-","~","+|","+^","~|","~^" 
    169         , "+=","-=","~=","+|=","+^=","~|=","~^=" 
    170         ] 
     163 
     164opSet :: VarCateg -> [String] -> Set Var 
     165opSet cat posts = Set.fromList $ map doMakeVar posts 
     166    where 
     167    doMakeVar name = MkVar 
     168        { v_sigil   = SCode 
     169        , v_twigil  = TNone 
     170        , v_package = emptyPkg 
     171        , v_categ   = cat 
     172        , v_name    = cast name 
     173        } 
     174 
     175coercePrefixOps, simplePrefixOps, simplePostfixOps, simpleInfixOps :: Set Var 
     176coercePrefixOps = opSet C_prefix [ "!","+","-","~","?","$" ] 
     177simplePrefixOps = opSet C_prefix 
     178    [ "++","--" 
     179    , "$","&","+^","~^","?^","\\","^","=" 
     180    ] 
     181simplePostfixOps = opSet C_postfix ["++", "--"] 
     182simpleInfixOps = opSet C_infix 
     183    [ "**" 
     184    , "**=" 
     185    , "*","/","%","x","+&","+<","+>","~&","~<","~>" 
     186    , "*=","/=","%=","x=","+&=","+<=","+>=","~&=","~<=","~>=" 
     187    , "+","-","~","+|","+^","~|","~^" 
     188    , "+=","-=","~=","+|=","+^=","~|=","~^=" 
     189    ] 
     190 
     191 
    171192 
    172193 
     
    181202    Syn "namespace" [kind, pkg, y] 
    182203mergeStmts x@(Ann ann (Syn syn _)) y | (syn ==) `any` words "subst match //"  = 
    183     mergeStmts (Ann ann (App (Var "&infix:~~") Nothing [Var "$_", x])) y 
     204    mergeStmts (Ann ann (App (_Var "&infix:~~") Nothing [_Var "$_", x])) y 
    184205mergeStmts x y@(Ann ann (Syn syn _)) | (syn ==) `any` words "subst match //"  = 
    185     mergeStmts x (Ann ann (App (Var "&infix:~~") Nothing [Var "$_", y])) 
     206    mergeStmts x (Ann ann (App (_Var "&infix:~~") Nothing [_Var "$_", y])) 
    186207mergeStmts (Ann ann (Syn "sub" [Val (VCode sub)])) y | subType sub == SubBlock = 
    187208    -- bare Block in statement level; annul all its parameters and run it! 
     
    196217isEmptyParams :: [Param] -> Bool 
    197218isEmptyParams [] = True 
    198 isEmptyParams [x] | [_, '_'] <- paramName x = True 
     219isEmptyParams [x] 
     220    | var <- paramName x 
     221    , _underscore == v_name var 
     222    , emptyPkg    == v_package var 
     223    , TNone       == v_twigil var 
     224    = True 
    199225isEmptyParams _ = False 
     226 
     227_underscore :: ID 
     228_underscore = cast "_"  
    200229 
    201230newPackage :: String -> String -> [String] -> [String] -> Exp 
    202231newPackage cls name classes roles = Stmts metaObj (newType name) 
    203232    where 
    204     metaObj = Sym SGlobal (':':'*':name) $! Syn ":=" 
    205         [ Var (':':'*':name) 
    206         , App (Var "&META::new") 
     233    metaObj = _Sym SGlobal (':':'*':name) $! Syn ":=" 
     234        [ _Var (':':'*':name) 
     235        , App (_Var "&META::new") 
    207236            (Just $ Val (VType $ mkType cls)) 
    208237            [ Syn "named" 
     
    222251 
    223252newType :: String -> Exp 
    224 newType name = Sym SGlobal ('&':'&':'*':name) $! Syn ":=" 
    225     [ Var ('&':'*':name) 
     253newType name = _Sym SGlobal ('&':'&':'*':name) $! Syn ":=" 
     254    [ _Var ('&':'*':name) 
    226255    , typeMacro name (Val . VType . mkType $ name) 
    227256    ] 
    228257 
    229258newMetaType :: String -> Exp 
    230 newMetaType name = Sym SGlobal ('&':'&':'*':name) $! Syn ":=" 
    231     [ Var ('&':'*':name) 
    232     , typeMacro name (Var (':':'*':name)) 
     259newMetaType name = _Sym SGlobal ('&':'&':'*':name) $! Syn ":=" 
     260    [ _Var ('&':'*':name) 
     261    , typeMacro name (_Var (':':'*':name)) 
    233262    ] 
    234263 
     
    236265typeMacro name exp = Syn "sub" . (:[]) . Val . VCode $ MkCode 
    237266    { isMulti       = True 
    238     , subName       = name 
     267    , subName       = cast ('&':name) 
    239268    , subEnv        = Nothing 
    240269    , subType       = SubMacro 
     
    259288    fmap (MkPad . Map.fromAscList . catMaybes) . mapM checkPrim $ Map.toAscList pad 
    260289 
    261 checkPrim :: (String, PadEntry) -> Eval (Maybe (String, PadEntry)) 
    262 checkPrim ((':':'*':_), _) = return Nothing 
    263 checkPrim e@((_, MkEntry (_, tv))) = do 
    264     rv <- isPrim tv 
    265     return $ if rv then Nothing else Just e 
    266 checkPrim (key, MkEntryMulti xs) = do 
    267     xs' <- filterM (fmap not . isPrim . snd) xs 
    268     return $ if null xs' then Nothing else Just (key, MkEntryMulti xs') 
     290checkPrim :: (Var, PadEntry) -> Eval (Maybe (Var, PadEntry)) 
     291checkPrim e@(var, entry) 
     292    | SType <- v_sigil var, isGlobalVar var = return Nothing 
     293    | MkEntry (_, tv) <- entry = do 
     294        rv <- isPrim tv 
     295        return $ if rv then Nothing else Just e 
     296    | otherwise = do 
     297        let MkEntryMulti xs = entry 
     298        xs' <- filterM (fmap not . isPrim . snd) xs 
     299        return $ if null xs' then Nothing else Just (var, MkEntryMulti xs') 
    269300 
    270301isPrim :: TVar VRef -> Eval Bool 
     
    282313filterUserDefinedPad (MkPad pad) = MkPad $ Map.filterWithKey doFilter pad 
    283314    where 
    284     doFilter key _ = not (key `elem` reserved) 
    285     reserved = words $ 
    286         "@*ARGS @*INC %*INC $*PUGS_HAS_HSPLUGINS $*EXECUTABLE_NAME " ++ 
    287         "$*PROGRAM_NAME $*PID $*UID $*EUID $*GID $*EGID @*CHECK @*INIT $*IN " ++ 
    288         "$*OUT $*ERR $*ARGS $/ %*ENV $*CWD @=POD $=POD $?PUGS_VERSION " ++ 
    289         "$*OS &?BLOCK_EXIT %?CONFIG $*_ $*AUTOLOAD" 
    290  
     315    doFilter key _ = key `Set.notMember` _reserved 
     316 
     317_reserved :: Set Var 
     318_reserved = Set.fromList . cast . words $ 
     319    "@*ARGS @*INC %*INC $*PUGS_HAS_HSPLUGINS $*EXECUTABLE_NAME " ++ 
     320    "$*PROGRAM_NAME $*PID $*UID $*EUID $*GID $*EGID @*CHECK @*INIT $*IN " ++ 
     321    "$*OUT $*ERR $*ARGS $/ %*ENV $*CWD @=POD $=POD $?PUGS_VERSION " ++ 
     322    "$*OS &?BLOCK_EXIT %?CONFIG $*_ $*AUTOLOAD"