Changeset 15829 for src/Pugs/Parser
- Timestamp:
- 04/04/07 19:54:22 (20 months ago)
- Location:
- src/Pugs/Parser
- Files:
-
- 7 modified
-
Export.hs (modified) (1 diff)
-
Literal.hs (modified) (1 diff)
-
Operator.hs (modified) (1 diff)
-
Program.hs (modified) (3 diffs)
-
Types.hs (modified) (7 diffs)
-
Unsafe.hs (modified) (2 diffs)
-
Util.hs (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Pugs/Parser/Export.hs
r15828 r15829 16 16 17 17 exportSym :: Scope -> String -> Val -> RuleParser () 18 exportSym scope name@('&':_) ref = do 19 pad <- unsafeEvalLexDiff $ _Sym scope name mempty (Val ref) Noop 20 addBlockPad pad 18 exportSym scope ('&':subname) ref = do 19 rv <- unsafeEvalExp $ Syn "," [App (_Var "&values") (Just (Val ref)) []] 20 case rv of 21 Val (VList subs) -> do 22 exps <- forM (filter defined subs) $ \val -> do 23 let name = '&':subname 24 mkSym = _Sym scope name mempty (Val val) Noop 25 doExport scope mkSym 26 case scope of 27 SMy -> addBlockPad SState 28 (foldl' unionPads (mkPad []) [ pad | Pad SMy pad _ <- exps ]) 29 _ -> return () 30 _ -> fail $ "Invalid export list: " ++ show rv 21 31 exportSym scope subname@(sig:_) ref | isWordAlpha sig = do 22 32 exportSym scope ('&':subname) ref 23 33 exportSym _ _ _ = fail "Non-Code exports does not work yet" 24 34 --exportSym' scope name sym = other vars... 35 36 doExport :: Scope -> Exp -> RuleParser Exp 37 doExport SState sym = do 38 unsafeEvalExp sym 39 return emptyExp 40 doExport SMy sym = do 41 lexDiff <- unsafeEvalLexDiff sym 42 return $ Pad SMy lexDiff emptyExp 43 doExport _ _ = fail "notyet" -- XXX writeme. but do they all make sense at all? -
src/Pugs/Parser/Literal.hs
r15828 r15829 248 248 else mzero 249 249 closure = if qfInterpolateClosure flags 250 then r etInterpolatedBlock =<< ruleVerbatimBlock250 then ruleVerbatimBlock 251 251 else mzero 252 252 backslash = case qfInterpolateBackslash flags of -
src/Pugs/Parser/Operator.hs
r15828 r15829 138 138 forceParens (Ann x inner) = Ann x (forceParens inner) 139 139 forceParens (Sym x y flags init inner) = Sym x y flags init (forceParens inner) 140 forceParens (Pad x y inner) = Pad x y (forceParens inner) 140 141 forceParens exp = exp 141 142 -
src/Pugs/Parser/Program.hs
r15828 r15829 99 99 makeState :: Env -> RuleState 100 100 makeState env = MkState 101 { s_env = env 102 , s_parseProgram = parseProgram 103 , s_dynParsers = MkDynParsersEmpty 104 , s_bracketLevel = StatementBracket 105 -- , s_char = ' ' 106 -- , s_name = nullID 107 -- , s_pos = 0 108 , s_wsLine = 0 109 , s_wsColumn = 0 110 , s_closureTraits = [id] 111 , s_freeVars = Set.empty 112 , s_knownVars = Map.empty 113 , s_protoPad = emptyPad 101 { s_env = env 102 , s_parseProgram = parseProgram 103 , s_dynParsers = MkDynParsersEmpty 104 , s_bracketLevel = StatementBracket 105 -- , s_char = ' ' 106 -- , s_name = nullID 107 -- , s_pos = 0 108 , s_wsLine = 0 109 , s_wsColumn = 0 110 , s_blockPads = Map.empty 111 , s_closureTraits = [id] 112 , s_outerVars = Set.empty 114 113 } 115 116 -- XXX - Pending clarification about those 3 -- are they routine-implicit or block-implicit?117 {-118 protoPad :: Pad119 protoPad = mkPad120 [ (cast "$_", PELexical121 , (cast "$/",122 , (cast "$!",123 ]124 -}125 114 126 115 runRule :: Env -> RuleParser Env -> FilePath -> String -> Env … … 164 153 ruleProgram :: RuleParser Env 165 154 ruleProgram = rule "program" $ do 166 env <- getRuleEnv 167 168 topPad <- genParamEntries SubRoutine [defaultArrayParam] 169 modify $ \s -> s{ s_protoPad = topPad } 170 171 block <- ruleBlockBody 172 main <- retVerbatimBlock SubPointy Nothing False $ 173 block{ bi_body = mergeStmts emptyExp $ bi_body block } 174 155 env <- getRuleEnv 156 statements <- ruleBlockBody 175 157 -- error $ show statements 176 158 eof … … 190 172 env' <- getRuleEnv 191 173 return $ env' 192 { envBody = App main Nothing [] -- _Var "@*ARGS"]174 { envBody = mergeStmts emptyExp statements 193 175 , envPackage = envPackage env 194 176 } -
src/Pugs/Parser/Types.hs
r15828 r15829 3 3 module Pugs.Parser.Types ( 4 4 RuleParser, RuleState(..), CharClass(..), 5 DynParsers(..), ParensOption(..), FormalsOption(..), BracketLevel(..), OuterLevel, 6 BlockInfo(..), emptyBlockInfo, 7 5 DynParsers(..), ParensOption(..), FormalsOption(..), BracketLevel(..), 8 6 RuleOperator, RuleOperatorTable, 9 7 getRuleEnv, modifyRuleEnv, putRuleEnv, insertIntoPosition, 10 8 clearDynParsers, enterBracketLevel, getCurrCharClass, charClassOf, 11 addBlockPad, popClosureTrait, addClosureTrait, 9 addBlockPad, popClosureTrait, addClosureTrait, addOuterVar, 12 10 -- Alternate Char implementations that keeps track of s_charClass 13 11 satisfy, string, oneOf, noneOf, char, hexDigit, octDigit, … … 26 24 import qualified Data.Set as Set 27 25 28 data BlockInfo = MkBlockInfo29 { bi_pad :: !Pad30 , bi_traits :: !(TraitBlocks -> TraitBlocks)31 , bi_body :: !Exp32 }33 34 emptyBlockInfo :: BlockInfo35 emptyBlockInfo = MkBlockInfo emptyPad id emptyExp36 37 38 26 {-# INLINE satisfy #-} 39 27 satisfy :: (Char -> Bool) -> RuleParser Char … … 132 120 } 133 121 134 type OuterLevel = Int135 136 122 {-| 137 123 State object that gets passed around during the parsing process. … … 140 126 { s_env :: Env 141 127 , s_parseProgram :: (Env -> FilePath -> String -> Env) 142 , s_dynParsers :: DynParsers -- ^ Cache for dynamically-generated 143 -- parsers 144 , s_bracketLevel :: !BracketLevel -- ^ The kind of "bracket" we are in 145 -- part and has to suppress {..} literals 146 -- , s_char :: Char -- ^ What the previous character contains 147 -- , s_name :: !ID -- ^ Capture name 148 -- , s_pos :: !Int -- ^ Capture position 149 , s_wsLine :: !Line -- ^ Last whitespace position 150 , s_wsColumn :: !Column -- ^ Last whitespace position 151 -- , s_blockPads :: Map Scope Pad -- ^ Hoisted pad for this block 152 , s_knownVars :: !(Map Var MPad) -- ^ Map from variables to its associated scope 153 , s_freeVars :: !(Set (Var, LexPads)) -- ^ Set of free vars and the mpadlist to check with 154 , s_protoPad :: !Pad -- ^ Pad that's part of all scopes; used in param init 128 , s_dynParsers :: DynParsers -- ^ Cache for dynamically-generated 129 -- parsers 130 , s_bracketLevel :: !BracketLevel -- ^ The kind of "bracket" we are in 131 -- part and has to suppress {..} literals 132 -- , s_char :: Char -- ^ What the previous character contains 133 -- , s_name :: !ID -- ^ Capture name 134 -- , s_pos :: !Int -- ^ Capture position 135 , s_wsLine :: !Line -- ^ Last whitespace position 136 , s_wsColumn :: !Column -- ^ Last whitespace position 137 , s_blockPads :: Map Scope Pad -- ^ Hoisted pad for this block 138 , s_outerVars :: Set Var -- ^ OUTER symbols we remembers 139 155 140 , s_closureTraits :: [TraitBlocks -> TraitBlocks] 156 141 -- ^ Closure traits: head is this block, tail is all outer blocks … … 177 162 data FormalsOption = FormalsSimple | FormalsComplex 178 163 deriving (Show, Eq) 179 180 instance MonadSTM RuleParser where181 liftSTM x = return $! unsafePerformSTM x182 164 183 165 instance MonadReader Env RuleParser where … … 247 229 Update the 's_blockPads' in the parser's state by applying a transformation function. 248 230 -} 249 addBlockPad :: Pad -> RuleParser () 250 addBlockPad pad = do 251 -- To add a Pad to the COMPILING block, we do two things: 252 -- First, we check that our pad does not contain shadowed OUTER symbols. 253 -- XXX TODO: it should be fine for two identical padEntry to shadow each other, 254 -- as is the case with { our multi f () {}; { &f(); our multi f ($x) {} } }. 231 addBlockPad :: Scope -> Pad -> RuleParser () 232 addBlockPad scope pad = do 233 -- First we check that our pad does not contain shadows OUTER symbols. 255 234 state <- get 256 let myVars = padKeys pad 257 dupVars = myVars `Set.intersection` Map.keysSet outerKnownVars 258 outerKnownVars = Map.filter (/= compPad) (s_knownVars state) 259 Just compPad = envCompPad (s_env state) 260 261 unless (Set.null dupVars) $ do 235 let dupSyms = padKeys pad `Set.intersection` s_outerVars state 236 unless (Set.null dupSyms) $ do 262 237 fail $ "Redeclaration of " 263 ++ unwords (map show (Set.elems dup Vars))238 ++ unwords (map show (Set.elems dupSyms)) 264 239 ++ " conflicts with earlier OUTER references in the same scope" 265 266 -- Then we merge the Pad into COMPILING, and add those vars into s_knownVars. 267 () <- stm $ modifyTVar compPad (`unionPads` pad) 268 269 let myKnownVars = Map.fromDistinctAscList [ (var, compPad) | var <- Set.toAscList myVars ] 270 put state{ s_knownVars = s_knownVars state `Map.union` myKnownVars } 240 put state{ s_blockPads = Map.insertWith unionPads scope pad (s_blockPads state) } 271 241 272 242 popClosureTrait :: RuleParser () … … 310 280 "FIRST" -> block{ subFirstBlocks = subFirstBlocks block ++ [trait] } 311 281 _ -> trace ("Wrong closure trait name: "++name) block 282 {-| 283 Update the 's_outerVars' in the parser's state by applying a transformation function. 284 -} 285 addOuterVar :: Var -> RuleParser () 286 addOuterVar var = modify $ \state -> 287 state{ s_outerVars = Set.insert var (s_outerVars state) } 312 288 313 289 {-| -
src/Pugs/Parser/Unsafe.hs
r15828 r15829 83 83 -- The vcode is a macro! Apply it and substitute its return value. 84 84 ret <- unsafeEvalExp $! App (Val $ VCode vcode{ subType = SubRoutine }) invs args 85 -- local (maybe id const (subEnv vcode)) $ 86 substMacroResult ret 85 local (maybe id const (subEnv vcode)) $ substMacroResult ret 87 86 | otherwise 88 87 = return app … … 93 92 return $! fromObject o 94 93 -- A Str should be (re)parsed. 95 substMacroResult (Val (VStr code)) = fmap bi_body . localBlock$ do94 substMacroResult (Val (VStr code)) = localEnv $ do 96 95 parseProgram <- gets s_parseProgram 97 96 env <- ask -
src/Pugs/Parser/Util.hs
r15828 r15829 14 14 grammaticalCategories = ["prefix_circumfix_meta_operator:","infix_circumfix_meta_operator:","prefix_postfix_meta_operator:","postfix_prefix_meta_operator:","infix_postfix_meta_operator:","statement_modifier:","statement_control:","scope_declarator:","trait_auxiliary:","trait_verb:","regex_mod_external:","regex_mod_internal:","regex_assertion:","regex_backslash:","regex_metachar:","postcircumfix:","circumfix:","postfix:","infix:","prefix:","quote:","term:"] 15 15 16 17 retBlockWith :: (Exp -> Exp) -> BlockInfo -> RuleParser BlockInfo18 retBlockWith f bi = return bi{ bi_body = f (bi_body bi) }19 20 16 -- around a block body we save the package and the current lexical pad 21 17 -- at the start, so that they can be restored after parsing the body 22 local Block :: RuleParser Exp -> RuleParser BlockInfo23 local Blockm = do18 localEnv :: RuleParser Exp -> RuleParser Exp 19 localEnv m = do 24 20 state <- get 25 26 -- XXX - Perhaps clone the protopad right here, for $_ etc? 27 compPad <- stm $ newTVar (s_protoPad state) 28 29 let env = s_env state 30 lexPads = (PCompiling compPad:envLexPads env) 31 21 let env = s_env state 32 22 put state 33 { s_closureTraits = (id : s_closureTraits state) 34 , s_env = env 35 { envLexPads = lexPads -- enter the scope 36 , envCompPad = Just compPad 37 } 38 , s_protoPad = emptyPad 23 { s_blockPads = Map.empty 24 , s_closureTraits = (id : s_closureTraits state) 25 , s_outerVars = Set.empty 26 , s_env = env { envOuter = Just env } 39 27 } 40 41 body <- m 28 rv <- m 42 29 state' <- get 43 44 -- Remove from knownVars the bindings belonging to this scope .45 let outerKnownVars = Map.filter (/= compPad) (s_knownVars state')46 (traits, outerTraits) = case s_closureTraits state' of47 (t:ts) -> (t, ts)48 _ -> (id, [])49 50 30 put state 51 31 { s_env = (s_env state') 52 32 { envPackage = envPackage env 53 33 , envLexical = envLexical env 54 , envLexPads = envLexPads env 55 , envCompPad = envCompPad env 34 , envOuter = envOuter env 56 35 } 57 , s_closureTraits = outerTraits 58 , s_knownVars = outerKnownVars 36 , s_closureTraits = s_closureTraits state' 59 37 } 60 61 38 -- Re-read compile time refs into the new protos at end of scope. 62 newPad <- return $! unsafePerformSTM $! do 63 curPad <- readTVar compPad 64 entries <- forM (padToList curPad) $ \(var, entry) -> do 65 proto <- readPadEntry entry 66 let newEntry = entry{ pe_proto = proto } 67 return (newEntry `seq` (var, newEntry)) 68 let newPad = listToPad (length entries `seq` entries) 69 writeTVar compPad newPad 70 return newPad 71 return $ MkBlockInfo{ bi_pad = newPad, bi_body = body, bi_traits = traits } 39 newPads <- return $! unsafePerformSTM $! do 40 forM (Map.toList $ s_blockPads state') $ \(scope, pad) -> do 41 newPad <- forM (padToList pad) $ \(var, entry) -> do 42 proto <- readPadEntry entry 43 let newEntry = entry{ pe_proto = proto } 44 return (newEntry `seq` (var, newEntry)) 45 return (scope, listToPad (length newPad `seq` newPad)) 46 return $ Map.foldWithKey Pad rv (length newPads `seq` Map.fromList newPads) 72 47 73 48 ruleParamList :: ParensOption -> RuleParser a -> RuleParser (Maybe [[a]]) … … 119 94 120 95 defaultParamFor :: SubType -> [Param] 121 defaultParamFor SubBlock = [ ] --defaultScalarParam]96 defaultParamFor SubBlock = [defaultScalarParam] 122 97 defaultParamFor SubPointy = [] 123 98 defaultParamFor _ = [defaultArrayParam] 124 99 125 extractNamedPlaceholders:: SubType -> Maybe [Param] -> Exp -> (Exp, [Var], [Param])126 extractNamedPlaceholdersSubBlock formal body = (fun, names', params)100 doExtract :: SubType -> Maybe [Param] -> Exp -> (Exp, [Var], [Param]) 101 doExtract SubBlock formal body = (fun, names', params) 127 102 where 128 103 (fun, names) = extractPlaceholderVars body Set.empty … … 132 107 = sortNames names 133 108 params = map nameToParam names' ++ (maybe [] id formal) 134 extractNamedPlaceholdersSubPointy formal body = (body, [], maybe [] id formal)135 extractNamedPlaceholdersSubMethod formal body = (body, [], maybe [] id formal)136 extractNamedPlaceholders_ formal body = (body, names', params)109 doExtract SubPointy formal body = (body, [], maybe [] id formal) 110 doExtract SubMethod formal body = (body, [], maybe [] id formal) 111 doExtract _ formal body = (body, names', params) 137 112 where 138 113 (_, names) = extractPlaceholderVars body Set.empty … … 190 165 , isWritable = True 191 166 , isLazy = False 192 , paramName = cast " $__SELF__"167 , paramName = cast "&self" 193 168 , paramContext = CxtItem typ 194 169 , paramDefault = Noop 195 170 } 196 171 197 hashComposerCheck :: Exp -> RuleParser Bool 198 hashComposerCheck exp 199 | Ann (Prag [MkPrag "eol-block" _]) _ <- exp = do 200 when isHash $ 201 fail "Closing hash curly may not terminate a line;\nplease add a comma or a semicolon to disambiguate" 202 return False 203 | otherwise = return isHash 204 where 205 isHash = doCheck (possiblyUnwrap exp) 172 extractHash :: Exp -> RuleParser (Maybe Exp) 173 extractHash exp 174 | Ann (Prag [MkPrag "eol-block" _]) _ <- exp = case result of 175 Just{} -> fail "Closing hash curly may not terminate a line;\nplease add a comma or a semicolon to disambiguate" 176 _ -> return Nothing 177 | otherwise = return result 178 where 179 result = extractHash' (possiblyUnwrap exp) 206 180 207 181 possiblyUnwrap (Ann _ exp) = possiblyUnwrap exp … … 210 184 possiblyUnwrap x = x 211 185 212 isHashOrPair (Ann _ exp) = isHashOrPair exp213 isHashOrPair (App (Var var) _ _) = (var == cast "&pair") || (var == cast "&infix:=>")214 isHashOrPair (Syn "%{}" _) = True215 isHashOrPair (Var var) = v_sigil var == SHash216 isHashOrPair _ = False186 isHashOrPair (Ann _ exp) = isHashOrPair exp 187 isHashOrPair (App (Var var) _ _) = (var == cast "&pair") || (var == cast "&infix:=>") 188 isHashOrPair (Syn "%{}" _) = True 189 isHashOrPair (Var var) = v_sigil var == SHash 190 isHashOrPair _ = False 217 191 218 doCheck Noop = True 219 doCheck (Syn "," (subexp:_)) = isHashOrPair subexp 220 doCheck exp = isHashOrPair exp 192 extractHash' exp | isHashOrPair exp = Just exp 193 extractHash' exp@(Syn "," (subexp:_)) | isHashOrPair subexp = Just exp 194 extractHash' exp@Noop = Just exp 195 extractHash' _ = Nothing 221 196 222 197 tryLookAhead :: RuleParser a -> RuleParser b -> RuleParser a
