Changeset 12924

Show
Ignore:
Timestamp:
09/01/06 15:11:03 (2 years ago)
Author:
gaal
Message:

* Basic support for parsing Signatures with :().

Only named parameters are parsed, and optionals (incorrectly)
require a '?' even if they have a default value. No parameter
decoration (type constraints, access traits, etc.) is supported
yet. The following forms do work:

:($x:)
:($x)
:($x: $y, $z)
:($x: $y, $z? = 42)
:($x: $y?, $z) # correctly raises a parse error

Location:
src/Pugs
Files:
11 modified

Legend:

Unmodified
Added
Removed
  • src/Pugs/AST.hs

    r12721 r12924  
    3939import Pugs.AST.SIO 
    4040import Pugs.AST.Pad 
    41 import Pugs.Val (val, PureStr, PureInt, PureNum, Capt(..), ValCapt, Feed(..), ValFeed, emptyFeed) 
     41import Pugs.Val (val, PureStr, PureInt, PureNum, Capt(..), ValCapt, Feed(..), ValFeed, emptyFeed, Sig(..), SigParam(..), ParamAccess(..), ParamDefault(..)) 
    4242 
    4343{-| 
  • src/Pugs/AST/Internals.hs

    r12800 r12924  
    778778 
    779779These represent declared parameters; don't confuse them with actual parameter  
    780 values. 
    781 -} 
    782 data Param = MkParam 
     780values, which are henceforth termed "arguments". 
     781-} 
     782data Param = MkOldParam -- "Old" because Pugs.Val.Code defined a new one 
    783783    { isInvocant    :: !Bool        -- ^ Is it in invocant slot? 
    784784    , isOptional    :: !Bool        -- ^ Is it optional? 
     
    797797type Params     = [Param] 
    798798 
    799 paramToValParam :: Param -> Val.Param 
     799paramToValParam :: Param -> Val.SigParam 
    800800paramToValParam param = ret 
    801801    where  
     
    809809        , Val.p_slots       = Map.empty 
    810810        , Val.p_hasAccess   = case param of 
    811                                   MkParam { isLValue = True, isWritable = False } -> Val.AccessRO 
    812                                   MkParam { isLValue = True, isWritable = True }  -> Val.AccessRW 
    813                                   MkParam { isLValue = False }                    -> Val.AccessCopy 
     811                                  MkOldParam { isLValue = True, isWritable = False } -> Val.AccessRO 
     812                                  MkOldParam { isLValue = True, isWritable = True }  -> Val.AccessRW 
     813                                  MkOldParam { isLValue = False }                    -> Val.AccessCopy 
    814814        , Val.p_isRef       = Val.p_hasAccess ret == Val.AccessRW 
    815815        , Val.p_isLazy      = isLazy param 
     
    10871087           -> Exp    -- ^ Expression for the param's default value 
    10881088           -> Param 
    1089 buildParam typ sigil name e = MkParam 
     1089buildParam typ sigil name e = MkOldParam 
    10901090    { isInvocant    = False 
    10911091    , isOptional    = '?' `elem` sigil 
  • src/Pugs/AST/Internals/Instances.hs

    r12524 r12924  
    400400instance YAML Param where 
    401401    fromYAML MkNode{n_tag=Just t, n_elem=e} | 't':'a':'g':':':'h':'s':':':tag <- unpackBuf t = case tag of 
    402         "MkParam" -> do 
     402        "MkOldParam" -> do 
    403403            let liftM9 f m1 m2 m3 m4 m5 m6 m7 m8 m9 = do 
    404404                {x1 <- m1; x2 <- m2; x3 <- m3; x4 <- m4; x5 <- m5; x6 <- m6; x7 <- m7; x8 <- m8; x9 <- m9; return (f x1 x2 x3 x4 x5 x6 x7 x8 x9)} 
    405405            let ESeq [aa, ab, ac, ad, ae, af, ag, ah, ai] = e 
    406             liftM9 MkParam (fromYAML aa) (fromYAML ab) (fromYAML ac) (fromYAML ad) (fromYAML ae) (fromYAML af) (fromYAML ag) (fromYAML ah) (fromYAML ai) 
    407         _ -> fail $ "unhandled tag: " ++ show t ++ ", expecting " ++ show ["MkParam"] ++ " in node " ++ show e 
    408     fromYAML _ = fail "no tag found" 
    409     asYAML (MkParam aa ab ac ad ae af ag ah ai) = asYAMLseq "MkParam" 
     406            liftM9 MkOldParam (fromYAML aa) (fromYAML ab) (fromYAML ac) (fromYAML ad) (fromYAML ae) (fromYAML af) (fromYAML ag) (fromYAML ah) (fromYAML ai) 
     407        _ -> fail $ "unhandled tag: " ++ show t ++ ", expecting " ++ show ["MkOldParam"] ++ " in node " ++ show e 
     408    fromYAML _ = fail "no tag found" 
     409    asYAML (MkOldParam aa ab ac ad ae af ag ah ai) = 
     410           asYAMLseq "MkOldParam" 
    410411           [asYAML aa, asYAML ab, asYAML ac, asYAML ad, asYAML ae, asYAML af, 
    411412            asYAML ag, asYAML ah, asYAML ai] 
    412413 
    413414instance Perl5 Param where 
    414     showPerl5 (MkParam aa ab ac ad ae af ag ah ai) = 
    415               showP5HashObj "MkParam" 
     415    showPerl5 (MkOldParam aa ab ac ad ae af ag ah ai) = 
     416              showP5HashObj "MkOldParam" 
    416417              [("isInvocant", showPerl5 aa) , ("isOptional", showPerl5 ab) , 
    417418               ("isNamed", showPerl5 ac) , ("isLValue", showPerl5 ad) , 
     
    421422 
    422423instance JSON Param where 
    423     showJSON (MkParam aa ab ac ad ae af ag ah ai) = 
    424              showJSHashObj "MkParam" 
     424    showJSON (MkOldParam aa ab ac ad ae af ag ah ai) = 
     425             showJSHashObj "MkOldParam" 
    425426             [("isInvocant", showJSON aa), ("isOptional", showJSON ab), 
    426427              ("isNamed", showJSON ac), ("isLValue", showJSON ad), 
  • src/Pugs/CodeGen/PIR.hs

    r12324 r12924  
    1515module Pugs.CodeGen.PIR (genPIR, genPIR_YAML) where 
    1616import Pugs.Internals 
    17 import Pugs.AST 
     17import Pugs.AST hiding (Sig) 
    1818import Pugs.Types 
    1919import Pugs.PIL1 
  • src/Pugs/Eval.hs

    r12852 r12924  
    11481148        return (syms', ApplyArg var val coll:restArgs) 
    11491149    expToVal :: Param -> Exp -> Eval (Val, Bool) 
    1150     expToVal MkParam{ isLazy = thunk, isLValue = lv, paramContext = cxt, paramName = var, isWritable = rw } exp = do 
     1150    expToVal MkOldParam{ isLazy = thunk, isLValue = lv, paramContext = cxt, paramName = var, isWritable = rw } exp = do 
    11511151        env <- ask -- freeze environment at this point for thunks 
    11521152        let eval = local (const env{ envLValue = lv }) $ do 
  • src/Pugs/Monads.hs

    r12905 r12924  
    295295makeParams :: Env -> [Param] 
    296296makeParams MkEnv{ envContext = cxt, envLValue = lv } 
    297     = [ MkParam 
     297    = [ MkOldParam 
    298298        { isInvocant = False 
    299299        , isOptional = False 
  • src/Pugs/Parser.hs

    r12852 r12924  
    2929import Pugs.Internals 
    3030import Pugs.AST 
     31import qualified Pugs.Exp as Exp 
    3132import Pugs.Types 
    3233import Pugs.Version (versnum) 
     
    4243import Pugs.Parser.Util 
    4344import qualified Data.Map as Map 
     45import qualified Data.Set as Set 
    4446 
    4547-- Lexical units -------------------------------------------------- 
     
    12911293    term <- choice 
    12921294        [ ruleDereference 
     1295        , ruleSignatureVal  -- must come before ruleTypeVar 
    12931296        , ruleVarDecl 
    12941297        , ruleVar 
     
    13121315            fs <- many s_postTerm 
    13131316            return $! combine (reverse fs) term 
     1317 
     1318ruleSignatureVal :: RuleParser Exp 
     1319ruleSignatureVal = do 
     1320    between (symbol ":(") (symbol ")") ruleSignature 
     1321 
     1322data Paramdec = MkParamdec 
     1323    { p_param      :: SigParam 
     1324    , p_isNamed    :: Bool 
     1325    , p_isRequired :: Bool 
     1326    } 
     1327    deriving (Show) 
     1328 
     1329ruleSignature :: RuleParser Exp 
     1330ruleSignature = rule "Signature" $ do 
     1331    inv     <- option Nothing $ try $ fmap (Just . p_param) $ followedBy ruleParam (symbol ":") 
     1332    params  <- ruleParam `sepEndBy` (symbol ",") 
     1333    reqPosC <- validateRequired True params 
     1334    let reqNms   = Set.fromAscList $ sort $ map (p_label . p_param) $ filter p_isRequired params 
     1335        posLs    = map p_param $ filter (not . p_isNamed) params 
     1336        nmSt     = Map.fromList $ map (\p -> (p_label $ p_param p, p_param p)) $ filter p_isNamed params 
     1337        slpScLs  = [] 
     1338        slpArrLs = Nothing 
     1339        slpHsh   = Nothing 
     1340        slpCd    = Nothing 
     1341        slpCapt  = Nothing 
     1342    return $ Val $ VV $ val $ case inv of 
     1343        Nothing -> SigSubSingle    reqPosC reqNms posLs nmSt slpScLs slpArrLs slpHsh slpCd slpCapt 
     1344        Just i  -> SigMethSingle i reqPosC reqNms posLs nmSt slpScLs slpArrLs slpHsh slpCd slpCapt 
     1345    where 
     1346        validateRequired _     []     = return 0 
     1347        validateRequired False (x:_) 
     1348            | isReqPos x              = fail $ "Required parameter cannot come after optional ones: " ++ show x 
     1349        validateRequired _     (x:xs) = do 
     1350            next <- validateRequired (isReqPos x) xs 
     1351            return $ (fromEnum $ isReqPos x) + next 
     1352        isReqPos x = p_isRequired x && (not $ p_isNamed x) 
     1353 
     1354{- 
     1355        { s_requiredPositionalCount   :: Int 
     1356        , s_requiredNames             :: Set ID 
     1357        , s_positionalList            :: [Param] 
     1358        , s_namedSet                  :: Map.Map ID Param 
     1359        , s_slurpyScalarList          :: [Param] 
     1360        , s_slurpyArray               :: Maybe Param 
     1361        , s_slurpyHash                :: Maybe Param 
     1362        , s_slurpyCode                :: Maybe Param 
     1363        , s_slurpyCapture             :: Maybe Param 
     1364 
     1365data Param = MkParam 
     1366    { p_variable    :: ID            -- ^ E.g. $m above 
     1367    , p_types       :: [Types.Type]  -- ^ Static pieces of inferencer-food 
     1368                                     --   E.g. Elk above 
     1369    , p_constraints :: [Code]        -- ^ Dynamic pieces of runtime-mood 
     1370                                     --   E.g. where {...} above 
     1371    , p_unpacking   :: Maybe PureSig -- ^ E.g. BinTree $t (Left $l, Right $r) 
     1372    , p_default     :: ParamDefault  -- ^ E.g. $answer? = 42 
     1373    , p_label       :: ID            -- ^ The external name for the param ('m' above) 
     1374    , p_slots       :: Table         -- ^ Any additional attrib not 
     1375                                     --   explicitly mentioned below 
     1376    , p_hasAccess   :: ParamAccess   -- ^ is ro, is rw, is copy 
     1377    , p_isRef       :: Bool          -- ^ must be true if hasAccess = AccessRW 
     1378    , p_isLazy      :: Bool 
     1379    } 
     1380-} 
     1381 
     1382-- we start with basic param parsing only - this'll grow. 
     1383ruleParam :: RuleParser Paramdec 
     1384ruleParam = rule "paramater" $ do 
     1385    name@(s:lab) <- regularVarName 
     1386    def          <- option Nothing $ do 
     1387        symbol "?" 
     1388        fmap Just $ option DNil $ do 
     1389            symbol "=" 
     1390            fmap (DExp . Exp.EE . Exp.MkExpEmeritus) parseTerm 
     1391    access       <- option AccessRO $ try $ do -- XXX: expand this to do arbitrary traits, in any order 
     1392        traits   <- ruleTrait ["is"] 
     1393        case traits of 
     1394            ("is", "ro")   -> return AccessRO 
     1395            ("is", "rw")   -> return AccessRW 
     1396            ("is", "copy") -> return AccessCopy 
     1397            _              -> fail $ "unhandled trait: " ++ show traits 
     1398    let p = MkParam (cast name) [] [] Nothing (maybe DNil id def) (cast lab) Map.empty access False False 
     1399    return $ MkParamdec{ p_param = p, p_isRequired = isNothing def, p_isNamed = False } 
     1400 
     1401 
    13141402 
    13151403ruleTypeVar :: RuleParser Exp 
  • src/Pugs/Parser/Operator.hs

    r12794 r12924  
    275275matchUnary :: CurrentFunction -> Bool 
    276276matchUnary MkCurrentFunction 
    277     { f_assoc = ANil, f_params = [MkParam 
     277    { f_assoc = ANil, f_params = [MkOldParam 
    278278        { paramContext = CxtItem{}, isNamed = False }] } = True 
    279279matchUnary _ = False 
     
    288288    { f_params = (_:_:_) } = True 
    289289matchSlurpy MkCurrentFunction 
    290     { f_params = [MkParam 
     290    { f_params = [MkOldParam 
    291291        { paramContext = CxtSlurpy{}, paramName = MkVar{ v_sigil = sig } }] } 
    292292            = sig == SArray || sig == SArrayMulti 
  • src/Pugs/Parser/Util.hs

    r12777 r12924  
    115115 
    116116nameToParam :: Var -> Param 
    117 nameToParam name = MkParam 
     117nameToParam name = MkOldParam 
    118118    { isInvocant    = False 
    119119    , isOptional    = False 
     
    151151-- | A Param representing the default (unnamed) invocant of a method on the given type. 
    152152selfParam :: Type -> Param 
    153 selfParam typ = MkParam 
     153selfParam typ = MkOldParam 
    154154    { isInvocant    = True 
    155155    , isOptional    = False 
     
    223223    isBreakingSpace _       = False 
    224224 
    225 tryFollowedBy :: RuleParser a -> RuleParser b -> RuleParser a 
    226 tryFollowedBy rule after = try $ do 
     225followedBy, tryFollowedBy :: RuleParser a -> RuleParser b -> RuleParser a 
     226followedBy rule after = do 
    227227    rv <- rule 
    228228    after 
    229229    return rv 
    230230 
     231tryFollowedBy = (try .) . followedBy 
  • src/Pugs/Val.hs

    r12733 r12924  
    1818 
    1919    -- From Code 
    20         Sig(..), Param(..), ParamAccess(..), ParamDefault(..), 
     20        Sig(..), SigParam(..), ParamAccess(..), ParamDefault(..), 
    2121    Capt(..), Feed(..), emptyFeed, Code(..), 
    2222    ValCapt, ValFeed, 
  • src/Pugs/Val/Code.hs

    r12721 r12924  
    9797values. 
    9898-} 
    99 data Param = MkParam 
     99data SigParam = MkParam 
    100100    { p_variable    :: ID            -- ^ E.g. $m above 
    101101    , p_types       :: [Types.Type]  -- ^ Static pieces of inferencer-food 
     
    113113    } 
    114114    deriving (Show, Eq, Ord, Typeable) {-!derive: YAML_Pos, Perl6Class, MooseClass!-} 
     115 
     116type Param = SigParam -- to get around name clashes in Pugs.AST :( 
    115117 
    116118newtype CodeBody = MkCodeBody [Stmt]