packages feed

WebBits 0.11.0 → 0.14.0

raw patch · 37 files changed

+2482/−3008 lines, 37 filessetup-changedPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- WebBits.Common: class PrettyPrintable a
- WebBits.Common: data SourcePos :: *
- WebBits.Common: instance (PrettyPrintable a) => PrettyPrintable (Maybe a)
- WebBits.Common: instance Data SourcePos
- WebBits.Common: instance Typeable SourcePos
- WebBits.Common: isPrefixOf :: (Eq a) => [a] -> [a] -> Bool
- WebBits.Common: pp :: (PrettyPrintable a) => a -> Doc
- WebBits.Common: sourceName :: SourcePos -> SourceName
- WebBits.Data.Zipper: Node :: a -> Forest a -> Tree a
- WebBits.Data.Zipper: canGoDown :: Location a -> Bool
- WebBits.Data.Zipper: canGoLeft :: Location a -> Bool
- WebBits.Data.Zipper: canGoRight :: Location a -> Bool
- WebBits.Data.Zipper: canGoUp :: Location a -> Bool
- WebBits.Data.Zipper: change :: Location a -> a -> Location a
- WebBits.Data.Zipper: data Location a
- WebBits.Data.Zipper: data Tree a :: * -> *
- WebBits.Data.Zipper: dfsFold :: (w -> v -> w) -> w -> Tree v -> Tree w
- WebBits.Data.Zipper: dfsFoldM :: (Monad m) => (w -> v -> m w) -> w -> Tree v -> m (Tree w)
- WebBits.Data.Zipper: down :: Location a -> Location a
- WebBits.Data.Zipper: empty :: a -> Tree a
- WebBits.Data.Zipper: evalZipperT :: (Monad m) => ZipperT v m a -> Location v -> m a
- WebBits.Data.Zipper: execZipperT :: (Monad m) => ZipperT v m a -> Location v -> m (Tree v)
- WebBits.Data.Zipper: fromLocation :: Location a -> Tree a
- WebBits.Data.Zipper: getNode :: (Monad m) => ZipperT v m v
- WebBits.Data.Zipper: getValue :: Location a -> a
- WebBits.Data.Zipper: insertDown :: Location a -> Tree a -> Location a
- WebBits.Data.Zipper: insertLeft :: Location a -> Tree a -> Location a
- WebBits.Data.Zipper: insertRight :: Location a -> Tree a -> Location a
- WebBits.Data.Zipper: isChild :: Location a -> Bool
- WebBits.Data.Zipper: isTop :: Location a -> Bool
- WebBits.Data.Zipper: left :: Location a -> Location a
- WebBits.Data.Zipper: nest :: (Monad m) => v -> ZipperT v m a -> ZipperT v m a
- WebBits.Data.Zipper: replace :: Location a -> Tree a -> Location a
- WebBits.Data.Zipper: right :: Location a -> Location a
- WebBits.Data.Zipper: rootLabel :: Tree a -> a
- WebBits.Data.Zipper: runZipperT :: (Monad m) => ZipperT v m a -> Location v -> m (a, Tree v)
- WebBits.Data.Zipper: setNode :: (Monad m) => v -> ZipperT v m ()
- WebBits.Data.Zipper: shiftLeft :: (Monad m) => ZipperT v m ()
- WebBits.Data.Zipper: shiftLeft' :: (Monad m) => ZipperT v m ()
- WebBits.Data.Zipper: shiftRight :: (Monad m) => ZipperT v m ()
- WebBits.Data.Zipper: shiftRight' :: (Monad m) => ZipperT v m ()
- WebBits.Data.Zipper: showTree :: (Show a) => Tree a -> String
- WebBits.Data.Zipper: subForest :: Tree a -> Forest a
- WebBits.Data.Zipper: subTree :: Location a -> Tree a
- WebBits.Data.Zipper: toLocation :: Tree a -> Location a
- WebBits.Data.Zipper: top :: Location a -> Location a
- WebBits.Data.Zipper: type ZipperT v m a = StateT (Location v) m a
- WebBits.Data.Zipper: up :: Location a -> Location a
- WebBits.Data.Zipper: withCurrentChild :: (Monad m) => ZipperT v m a -> ZipperT v m a
- WebBits.Html.Html: html :: (Script s) => CharParser [Warning] (Html SourcePos s)
- WebBits.Html.Html: parseHtmlFromFile :: (Script s) => String -> IO (Either ParseError (Html SourcePos s, [Warning]))
- WebBits.Html.Html: parseHtmlFromString :: (Script s) => String -> String -> Either ParseError (Html SourcePos s, [Warning])
- WebBits.Html.Instances: instance Foldable (Attribute a)
- WebBits.Html.Instances: instance Foldable (Html a)
- WebBits.Html.Instances: instance Functor (Attribute a)
- WebBits.Html.Instances: instance Functor (Html a)
- WebBits.Html.Instances: instance Traversable (Attribute a)
- WebBits.Html.Instances: instance Traversable (Html a)
- WebBits.Html.PermissiveParser: data (Script s) => Token s
- WebBits.Html.PermissiveParser: html :: (Script s) => CharParser [Warning] (Html SourcePos s)
- WebBits.Html.PermissiveParser: instance (Script s) => Show (Token s)
- WebBits.Html.PermissiveParser: instance Show Warning
- WebBits.Html.PermissiveParser: parseHtmlFromFile :: (Script s) => String -> IO (Either ParseError (Html SourcePos s, [Warning]))
- WebBits.Html.PermissiveParser: parseHtmlFromString :: (Script s) => String -> String -> Either ParseError (Html SourcePos s, [Warning])
- WebBits.Html.PermissiveParser: tokens :: (Script s) => CharParser [Warning] [Token s]
- WebBits.Html.PrettyPrint: instance (PrettyPrintable s) => PrettyPrintable (Attribute a s)
- WebBits.Html.PrettyPrint: instance (PrettyPrintable s) => PrettyPrintable (Html a s)
- WebBits.Html.RawScript: RawScript :: String -> RawScript
- WebBits.Html.RawScript: data RawScript
- WebBits.Html.RawScript: instance Data RawScript
- WebBits.Html.RawScript: instance Eq RawScript
- WebBits.Html.RawScript: instance PrettyPrintable RawScript
- WebBits.Html.RawScript: instance Script RawScript
- WebBits.Html.RawScript: instance Show RawScript
- WebBits.Html.RawScript: instance Typeable RawScript
- WebBits.Html.RawScript: parseFromFile :: Parser a -> SourceName -> IO (Either ParseError a)
- WebBits.Html.RawScript: parseFromString :: String -> RawHtml
- WebBits.Html.RawScript: type RawHtml = Html SourcePos RawScript
- WebBits.Html.Syntax: Attribute :: HtmlId -> AttributeValue -> a -> Attribute a s
- WebBits.Html.Syntax: AttributeExpr :: a -> HtmlId -> s -> String -> Attribute a s
- WebBits.Html.Syntax: Comment :: String -> a -> Html a sc
- WebBits.Html.Syntax: Element :: HtmlId -> [Attribute a sc] -> [Html a sc] -> a -> Html a sc
- WebBits.Html.Syntax: HtmlSeq :: [Html a sc] -> Html a sc
- WebBits.Html.Syntax: InlineScript :: sc -> a -> String -> Html a sc
- WebBits.Html.Syntax: ProcessingInstruction :: String -> a -> Html a sc
- WebBits.Html.Syntax: Script :: sc -> a -> Html a sc
- WebBits.Html.Syntax: Text :: String -> a -> Html a sc
- WebBits.Html.Syntax: attributeSet :: HtmlId -> String -> [Attribute a s] -> [Attribute a s]
- WebBits.Html.Syntax: attributeUpdate :: HtmlId -> (String -> String) -> [Attribute a s] -> [Attribute a s]
- WebBits.Html.Syntax: attributeValue :: HtmlId -> [Attribute a s] -> Maybe String
- WebBits.Html.Syntax: class Script t
- WebBits.Html.Syntax: data Attribute a s
- WebBits.Html.Syntax: data Html a sc
- WebBits.Html.Syntax: instance (Data a, Data s) => Data (Attribute a s)
- WebBits.Html.Syntax: instance (Data a, Data sc) => Data (Html a sc)
- WebBits.Html.Syntax: instance (Eq a, Eq s) => Eq (Attribute a s)
- WebBits.Html.Syntax: instance (Eq a, Eq sc) => Eq (Html a sc)
- WebBits.Html.Syntax: instance (Show a, Show s) => Show (Attribute a s)
- WebBits.Html.Syntax: instance (Show a, Show sc) => Show (Html a sc)
- WebBits.Html.Syntax: instance Typeable2 Attribute
- WebBits.Html.Syntax: instance Typeable2 Html
- WebBits.Html.Syntax: isAttributeExpr :: Attribute t t1 -> Bool
- WebBits.Html.Syntax: parseAttributeScript :: (Script t) => Maybe (CharParser a t)
- WebBits.Html.Syntax: parseInlineScript :: (Script t) => Maybe (CharParser a t)
- WebBits.Html.Syntax: parseScriptBlock :: (Script t) => [Attribute SourcePos t] -> CharParser a t
- WebBits.Html.Syntax: type AttributeValue = String
- WebBits.Html.Syntax: type HtmlId = String
- WebBits.JavaScript.Combinators: expressionsAt :: (Data a, Typeable a) => SourcePos -> a -> [Expression SourcePos]
- WebBits.JavaScript.Combinators: isParenExpr :: Expression t -> Bool
- WebBits.JavaScript.Combinators: scriptStatements :: JavaScript a -> [Statement a]
- WebBits.JavaScript.Combinators: statementsAt :: (Data a, Typeable a) => SourcePos -> a -> [Statement SourcePos]
- WebBits.JavaScript.Combinators: syntaxAt :: (Data a, Typeable a, Data (t SourcePos), Typeable (t SourcePos), Foldable t) => SourcePos -> a -> [t SourcePos]
- WebBits.JavaScript.Crawl: getPageJavaScript :: ParsedJsHtml -> IO [ParsedStatement]
- WebBits.JavaScript.Environment: staticEnvironment :: [Statement SourcePos] -> ([Statement Ann], Env, Env, Int)
- WebBits.JavaScript.Environment: type Ann = (Env, Int, SourcePos)
- WebBits.JavaScript.Environment: type Env = Map String Int
- WebBits.JavaScript.Environment: type LabelledExpression = Expression Ann
- WebBits.JavaScript.Environment: type LabelledStatement = Statement Ann
- WebBits.JavaScript.HtmlEmbedding: instance Script ParsedJavaScript
- WebBits.JavaScript.HtmlEmbedding: type JsHtml a = Html SourcePos (JavaScript a)
- WebBits.JavaScript.HtmlEmbedding: type ParsedJavaScript = JavaScript SourcePos
- WebBits.JavaScript.HtmlEmbedding: type ParsedJsHtml = JsHtml SourcePos
- WebBits.JavaScript.Instances: instance Foldable CaseClause
- WebBits.JavaScript.Instances: instance Foldable CatchClause
- WebBits.JavaScript.Instances: instance Foldable Expression
- WebBits.JavaScript.Instances: instance Foldable ForInInit
- WebBits.JavaScript.Instances: instance Foldable ForInit
- WebBits.JavaScript.Instances: instance Foldable Id
- WebBits.JavaScript.Instances: instance Foldable Prop
- WebBits.JavaScript.Instances: instance Foldable Statement
- WebBits.JavaScript.Instances: instance Foldable VarDecl
- WebBits.JavaScript.Instances: instance Functor CaseClause
- WebBits.JavaScript.Instances: instance Functor CatchClause
- WebBits.JavaScript.Instances: instance Functor Expression
- WebBits.JavaScript.Instances: instance Functor ForInInit
- WebBits.JavaScript.Instances: instance Functor ForInit
- WebBits.JavaScript.Instances: instance Functor Id
- WebBits.JavaScript.Instances: instance Functor JavaScript
- WebBits.JavaScript.Instances: instance Functor Prop
- WebBits.JavaScript.Instances: instance Functor Statement
- WebBits.JavaScript.Instances: instance Functor VarDecl
- WebBits.JavaScript.Instances: instance Traversable CaseClause
- WebBits.JavaScript.Instances: instance Traversable CatchClause
- WebBits.JavaScript.Instances: instance Traversable Expression
- WebBits.JavaScript.Instances: instance Traversable ForInInit
- WebBits.JavaScript.Instances: instance Traversable ForInit
- WebBits.JavaScript.Instances: instance Traversable Id
- WebBits.JavaScript.Instances: instance Traversable Prop
- WebBits.JavaScript.Instances: instance Traversable Statement
- WebBits.JavaScript.Instances: instance Traversable VarDecl
- WebBits.JavaScript.Lexer: braces :: CharParser st a -> CharParser st a
- WebBits.JavaScript.Lexer: brackets :: CharParser st a -> CharParser st a
- WebBits.JavaScript.Lexer: charLiteral :: CharParser st Char
- WebBits.JavaScript.Lexer: colon :: CharParser st String
- WebBits.JavaScript.Lexer: comma :: CharParser st String
- WebBits.JavaScript.Lexer: decimal :: CharParser st Integer
- WebBits.JavaScript.Lexer: dot :: CharParser st String
- WebBits.JavaScript.Lexer: float :: CharParser st Double
- WebBits.JavaScript.Lexer: hexadecimal :: CharParser st Integer
- WebBits.JavaScript.Lexer: identifier :: CharParser st String
- WebBits.JavaScript.Lexer: identifierStart :: GenParser Char st Char
- WebBits.JavaScript.Lexer: integer :: CharParser st Integer
- WebBits.JavaScript.Lexer: lexeme :: CharParser st a -> CharParser st a
- WebBits.JavaScript.Lexer: natural :: CharParser st Integer
- WebBits.JavaScript.Lexer: naturalOrFloat :: CharParser st (Either Integer Double)
- WebBits.JavaScript.Lexer: octal :: CharParser st Integer
- WebBits.JavaScript.Lexer: operator :: CharParser st String
- WebBits.JavaScript.Lexer: parens :: CharParser st a -> CharParser st a
- WebBits.JavaScript.Lexer: reserved :: String -> CharParser st ()
- WebBits.JavaScript.Lexer: reservedOp :: String -> CharParser st ()
- WebBits.JavaScript.Lexer: semi :: CharParser st String
- WebBits.JavaScript.Lexer: squares :: CharParser st a -> CharParser st a
- WebBits.JavaScript.Lexer: stringLiteral :: CharParser st String
- WebBits.JavaScript.Lexer: symbol :: String -> CharParser st String
- WebBits.JavaScript.Lexer: whiteSpace :: CharParser st ()
- WebBits.JavaScript.Parser: emptyParsedJavaScript :: JavaScript a
- WebBits.JavaScript.Parser: parseAssignExpr :: ExpressionParser st
- WebBits.JavaScript.Parser: parseBlockStmt :: StatementParser st
- WebBits.JavaScript.Parser: parseExpression :: ExpressionParser st
- WebBits.JavaScript.Parser: parseJavaScriptFromFile :: (MonadIO m) => String -> m [Statement SourcePos]
- WebBits.JavaScript.Parser: parseScript :: CharParser state (JavaScript SourcePos)
- WebBits.JavaScript.Parser: parseScriptFromString :: String -> String -> Either ParseError (JavaScript SourcePos)
- WebBits.JavaScript.Parser: parseSimpleExpr' :: GenParser Char st ParsedExpression
- WebBits.JavaScript.Parser: parseStatement :: StatementParser st
- WebBits.JavaScript.Parser: parseString :: String -> [Statement SourcePos]
- WebBits.JavaScript.Parser: type ExpressionParser state = CharParser state ParsedExpression
- WebBits.JavaScript.Parser: type ParsedExpression = Expression SourcePos
- WebBits.JavaScript.Parser: type ParsedStatement = Statement SourcePos
- WebBits.JavaScript.Parser: type StatementParser state = CharParser state ParsedStatement
- WebBits.JavaScript.PrettyPrint: instance PrettyPrintable (CaseClause a)
- WebBits.JavaScript.PrettyPrint: instance PrettyPrintable (CatchClause a)
- WebBits.JavaScript.PrettyPrint: instance PrettyPrintable (Expression a)
- WebBits.JavaScript.PrettyPrint: instance PrettyPrintable (ForInInit a)
- WebBits.JavaScript.PrettyPrint: instance PrettyPrintable (ForInit a)
- WebBits.JavaScript.PrettyPrint: instance PrettyPrintable (Id a)
- WebBits.JavaScript.PrettyPrint: instance PrettyPrintable (JavaScript a)
- WebBits.JavaScript.PrettyPrint: instance PrettyPrintable (Prop a)
- WebBits.JavaScript.PrettyPrint: instance PrettyPrintable (Statement a)
- WebBits.JavaScript.PrettyPrint: instance PrettyPrintable (VarDecl a)
- WebBits.JavaScript.PrettyPrint: instance PrettyPrintable AssignOp
- WebBits.JavaScript.PrettyPrint: instance PrettyPrintable InfixOp
- WebBits.JavaScript.PrettyPrint: instance PrettyPrintable PostfixOp
- WebBits.JavaScript.PrettyPrint: instance PrettyPrintable PrefixOp
- WebBits.JavaScript.Syntax: ArrayLit :: a -> [Expression a] -> Expression a
- WebBits.JavaScript.Syntax: AssignExpr :: a -> AssignOp -> (Expression a) -> (Expression a) -> Expression a
- WebBits.JavaScript.Syntax: BlockStmt :: a -> [Statement a] -> Statement a
- WebBits.JavaScript.Syntax: BoolLit :: a -> Bool -> Expression a
- WebBits.JavaScript.Syntax: BracketRef :: a -> (Expression a) -> (Expression a) -> Expression a
- WebBits.JavaScript.Syntax: BreakStmt :: a -> (Maybe (Id a)) -> Statement a
- WebBits.JavaScript.Syntax: CallExpr :: a -> (Expression a) -> [Expression a] -> Expression a
- WebBits.JavaScript.Syntax: CaseClause :: a -> (Expression a) -> [Statement a] -> CaseClause a
- WebBits.JavaScript.Syntax: CaseDefault :: a -> [Statement a] -> CaseClause a
- WebBits.JavaScript.Syntax: CatchClause :: a -> (Id a) -> (Statement a) -> CatchClause a
- WebBits.JavaScript.Syntax: CondExpr :: a -> (Expression a) -> (Expression a) -> (Expression a) -> Expression a
- WebBits.JavaScript.Syntax: ContinueStmt :: a -> (Maybe (Id a)) -> Statement a
- WebBits.JavaScript.Syntax: DoWhileStmt :: a -> (Statement a) -> (Expression a) -> Statement a
- WebBits.JavaScript.Syntax: DotRef :: a -> (Expression a) -> (Id a) -> Expression a
- WebBits.JavaScript.Syntax: EmptyStmt :: a -> Statement a
- WebBits.JavaScript.Syntax: ExprInit :: (Expression a) -> ForInit a
- WebBits.JavaScript.Syntax: ExprStmt :: a -> (Expression a) -> Statement a
- WebBits.JavaScript.Syntax: ForInNoVar :: (Id a) -> ForInInit a
- WebBits.JavaScript.Syntax: ForInStmt :: a -> (ForInInit a) -> (Expression a) -> (Statement a) -> Statement a
- WebBits.JavaScript.Syntax: ForInVar :: (Id a) -> ForInInit a
- WebBits.JavaScript.Syntax: ForStmt :: a -> (ForInit a) -> (Maybe (Expression a)) -> (Maybe (Expression a)) -> (Statement a) -> Statement a
- WebBits.JavaScript.Syntax: FuncExpr :: a -> [(Id a)] -> (Statement a) -> Expression a
- WebBits.JavaScript.Syntax: FunctionStmt :: a -> (Id a) -> [(Id a)] -> (Statement a) -> Statement a
- WebBits.JavaScript.Syntax: Id :: a -> String -> Id a
- WebBits.JavaScript.Syntax: IfSingleStmt :: a -> (Expression a) -> (Statement a) -> Statement a
- WebBits.JavaScript.Syntax: IfStmt :: a -> (Expression a) -> (Statement a) -> (Statement a) -> Statement a
- WebBits.JavaScript.Syntax: InfixExpr :: a -> InfixOp -> (Expression a) -> (Expression a) -> Expression a
- WebBits.JavaScript.Syntax: LabelledStmt :: a -> (Id a) -> (Statement a) -> Statement a
- WebBits.JavaScript.Syntax: ListExpr :: a -> [Expression a] -> Expression a
- WebBits.JavaScript.Syntax: NewExpr :: a -> (Expression a) -> [Expression a] -> Expression a
- WebBits.JavaScript.Syntax: NoInit :: ForInit a
- WebBits.JavaScript.Syntax: NullLit :: a -> Expression a
- WebBits.JavaScript.Syntax: NumLit :: a -> Double -> Expression a
- WebBits.JavaScript.Syntax: ObjectLit :: a -> [(Prop a, Expression a)] -> Expression a
- WebBits.JavaScript.Syntax: OpAdd :: InfixOp
- WebBits.JavaScript.Syntax: OpAssign :: AssignOp
- WebBits.JavaScript.Syntax: OpAssignAdd :: AssignOp
- WebBits.JavaScript.Syntax: OpAssignBAnd :: AssignOp
- WebBits.JavaScript.Syntax: OpAssignBOr :: AssignOp
- WebBits.JavaScript.Syntax: OpAssignBXor :: AssignOp
- WebBits.JavaScript.Syntax: OpAssignDiv :: AssignOp
- WebBits.JavaScript.Syntax: OpAssignLShift :: AssignOp
- WebBits.JavaScript.Syntax: OpAssignMod :: AssignOp
- WebBits.JavaScript.Syntax: OpAssignMul :: AssignOp
- WebBits.JavaScript.Syntax: OpAssignSpRShift :: AssignOp
- WebBits.JavaScript.Syntax: OpAssignSub :: AssignOp
- WebBits.JavaScript.Syntax: OpAssignZfRShift :: AssignOp
- WebBits.JavaScript.Syntax: OpBAnd :: InfixOp
- WebBits.JavaScript.Syntax: OpBOr :: InfixOp
- WebBits.JavaScript.Syntax: OpBXor :: InfixOp
- WebBits.JavaScript.Syntax: OpDiv :: InfixOp
- WebBits.JavaScript.Syntax: OpEq :: InfixOp
- WebBits.JavaScript.Syntax: OpGEq :: InfixOp
- WebBits.JavaScript.Syntax: OpGT :: InfixOp
- WebBits.JavaScript.Syntax: OpIn :: InfixOp
- WebBits.JavaScript.Syntax: OpInstanceof :: InfixOp
- WebBits.JavaScript.Syntax: OpLAnd :: InfixOp
- WebBits.JavaScript.Syntax: OpLEq :: InfixOp
- WebBits.JavaScript.Syntax: OpLOr :: InfixOp
- WebBits.JavaScript.Syntax: OpLShift :: InfixOp
- WebBits.JavaScript.Syntax: OpLT :: InfixOp
- WebBits.JavaScript.Syntax: OpMod :: InfixOp
- WebBits.JavaScript.Syntax: OpMul :: InfixOp
- WebBits.JavaScript.Syntax: OpNEq :: InfixOp
- WebBits.JavaScript.Syntax: OpSpRShift :: InfixOp
- WebBits.JavaScript.Syntax: OpStrictEq :: InfixOp
- WebBits.JavaScript.Syntax: OpStrictNEq :: InfixOp
- WebBits.JavaScript.Syntax: OpSub :: InfixOp
- WebBits.JavaScript.Syntax: OpZfRShift :: InfixOp
- WebBits.JavaScript.Syntax: ParenExpr :: a -> (Expression a) -> Expression a
- WebBits.JavaScript.Syntax: PostfixDec :: PostfixOp
- WebBits.JavaScript.Syntax: PostfixExpr :: a -> PostfixOp -> (Expression a) -> Expression a
- WebBits.JavaScript.Syntax: PostfixInc :: PostfixOp
- WebBits.JavaScript.Syntax: PrefixBNot :: PrefixOp
- WebBits.JavaScript.Syntax: PrefixDec :: PrefixOp
- WebBits.JavaScript.Syntax: PrefixDelete :: PrefixOp
- WebBits.JavaScript.Syntax: PrefixExpr :: a -> PrefixOp -> (Expression a) -> Expression a
- WebBits.JavaScript.Syntax: PrefixInc :: PrefixOp
- WebBits.JavaScript.Syntax: PrefixLNot :: PrefixOp
- WebBits.JavaScript.Syntax: PrefixMinus :: PrefixOp
- WebBits.JavaScript.Syntax: PrefixPlus :: PrefixOp
- WebBits.JavaScript.Syntax: PrefixTypeof :: PrefixOp
- WebBits.JavaScript.Syntax: PrefixVoid :: PrefixOp
- WebBits.JavaScript.Syntax: PropId :: a -> (Id a) -> Prop a
- WebBits.JavaScript.Syntax: PropNum :: a -> Integer -> Prop a
- WebBits.JavaScript.Syntax: PropString :: a -> String -> Prop a
- WebBits.JavaScript.Syntax: RegexpLit :: a -> String -> Bool -> Bool -> Expression a
- WebBits.JavaScript.Syntax: ReturnStmt :: a -> (Maybe (Expression a)) -> Statement a
- WebBits.JavaScript.Syntax: Script :: a -> [Statement a] -> JavaScript a
- WebBits.JavaScript.Syntax: StringLit :: a -> String -> Expression a
- WebBits.JavaScript.Syntax: SwitchStmt :: a -> (Expression a) -> [CaseClause a] -> Statement a
- WebBits.JavaScript.Syntax: ThisRef :: a -> Expression a
- WebBits.JavaScript.Syntax: ThrowStmt :: a -> (Expression a) -> Statement a
- WebBits.JavaScript.Syntax: TryStmt :: a -> (Statement a) -> [CatchClause a] -> (Maybe (Statement a)) -> Statement a
- WebBits.JavaScript.Syntax: VarDecl :: a -> (Id a) -> (Maybe (Expression a)) -> VarDecl a
- WebBits.JavaScript.Syntax: VarDeclStmt :: a -> [VarDecl a] -> Statement a
- WebBits.JavaScript.Syntax: VarInit :: [VarDecl a] -> ForInit a
- WebBits.JavaScript.Syntax: VarRef :: a -> (Id a) -> Expression a
- WebBits.JavaScript.Syntax: WhileStmt :: a -> (Expression a) -> (Statement a) -> Statement a
- WebBits.JavaScript.Syntax: WithStmt :: a -> (Expression a) -> (Statement a) -> Statement a
- WebBits.JavaScript.Syntax: data AssignOp
- WebBits.JavaScript.Syntax: data CaseClause a
- WebBits.JavaScript.Syntax: data CatchClause a
- WebBits.JavaScript.Syntax: data Expression a
- WebBits.JavaScript.Syntax: data ForInInit a
- WebBits.JavaScript.Syntax: data ForInit a
- WebBits.JavaScript.Syntax: data Id a
- WebBits.JavaScript.Syntax: data InfixOp
- WebBits.JavaScript.Syntax: data JavaScript a
- WebBits.JavaScript.Syntax: data PostfixOp
- WebBits.JavaScript.Syntax: data PrefixOp
- WebBits.JavaScript.Syntax: data Prop a
- WebBits.JavaScript.Syntax: data Statement a
- WebBits.JavaScript.Syntax: data VarDecl a
- WebBits.JavaScript.Syntax: instance (Data a) => Data (CaseClause a)
- WebBits.JavaScript.Syntax: instance (Data a) => Data (CatchClause a)
- WebBits.JavaScript.Syntax: instance (Data a) => Data (Expression a)
- WebBits.JavaScript.Syntax: instance (Data a) => Data (ForInInit a)
- WebBits.JavaScript.Syntax: instance (Data a) => Data (ForInit a)
- WebBits.JavaScript.Syntax: instance (Data a) => Data (Id a)
- WebBits.JavaScript.Syntax: instance (Data a) => Data (JavaScript a)
- WebBits.JavaScript.Syntax: instance (Data a) => Data (Prop a)
- WebBits.JavaScript.Syntax: instance (Data a) => Data (Statement a)
- WebBits.JavaScript.Syntax: instance (Data a) => Data (VarDecl a)
- WebBits.JavaScript.Syntax: instance (Eq a) => Eq (CaseClause a)
- WebBits.JavaScript.Syntax: instance (Eq a) => Eq (CatchClause a)
- WebBits.JavaScript.Syntax: instance (Eq a) => Eq (Expression a)
- WebBits.JavaScript.Syntax: instance (Eq a) => Eq (ForInInit a)
- WebBits.JavaScript.Syntax: instance (Eq a) => Eq (ForInit a)
- WebBits.JavaScript.Syntax: instance (Eq a) => Eq (Id a)
- WebBits.JavaScript.Syntax: instance (Eq a) => Eq (JavaScript a)
- WebBits.JavaScript.Syntax: instance (Eq a) => Eq (Prop a)
- WebBits.JavaScript.Syntax: instance (Eq a) => Eq (Statement a)
- WebBits.JavaScript.Syntax: instance (Eq a) => Eq (VarDecl a)
- WebBits.JavaScript.Syntax: instance (Ord a) => Ord (CaseClause a)
- WebBits.JavaScript.Syntax: instance (Ord a) => Ord (CatchClause a)
- WebBits.JavaScript.Syntax: instance (Ord a) => Ord (Expression a)
- WebBits.JavaScript.Syntax: instance (Ord a) => Ord (ForInInit a)
- WebBits.JavaScript.Syntax: instance (Ord a) => Ord (ForInit a)
- WebBits.JavaScript.Syntax: instance (Ord a) => Ord (Id a)
- WebBits.JavaScript.Syntax: instance (Ord a) => Ord (JavaScript a)
- WebBits.JavaScript.Syntax: instance (Ord a) => Ord (Prop a)
- WebBits.JavaScript.Syntax: instance (Ord a) => Ord (Statement a)
- WebBits.JavaScript.Syntax: instance (Ord a) => Ord (VarDecl a)
- WebBits.JavaScript.Syntax: instance (Show a) => Show (CaseClause a)
- WebBits.JavaScript.Syntax: instance (Show a) => Show (CatchClause a)
- WebBits.JavaScript.Syntax: instance (Show a) => Show (Expression a)
- WebBits.JavaScript.Syntax: instance (Show a) => Show (ForInInit a)
- WebBits.JavaScript.Syntax: instance (Show a) => Show (ForInit a)
- WebBits.JavaScript.Syntax: instance (Show a) => Show (Id a)
- WebBits.JavaScript.Syntax: instance (Show a) => Show (JavaScript a)
- WebBits.JavaScript.Syntax: instance (Show a) => Show (Prop a)
- WebBits.JavaScript.Syntax: instance (Show a) => Show (Statement a)
- WebBits.JavaScript.Syntax: instance (Show a) => Show (VarDecl a)
- WebBits.JavaScript.Syntax: instance Data AssignOp
- WebBits.JavaScript.Syntax: instance Data InfixOp
- WebBits.JavaScript.Syntax: instance Data PostfixOp
- WebBits.JavaScript.Syntax: instance Data PrefixOp
- WebBits.JavaScript.Syntax: instance Enum InfixOp
- WebBits.JavaScript.Syntax: instance Eq AssignOp
- WebBits.JavaScript.Syntax: instance Eq InfixOp
- WebBits.JavaScript.Syntax: instance Eq PostfixOp
- WebBits.JavaScript.Syntax: instance Eq PrefixOp
- WebBits.JavaScript.Syntax: instance Ord AssignOp
- WebBits.JavaScript.Syntax: instance Ord InfixOp
- WebBits.JavaScript.Syntax: instance Ord PostfixOp
- WebBits.JavaScript.Syntax: instance Ord PrefixOp
- WebBits.JavaScript.Syntax: instance Show AssignOp
- WebBits.JavaScript.Syntax: instance Show InfixOp
- WebBits.JavaScript.Syntax: instance Show PostfixOp
- WebBits.JavaScript.Syntax: instance Show PrefixOp
- WebBits.JavaScript.Syntax: instance Typeable AssignOp
- WebBits.JavaScript.Syntax: instance Typeable InfixOp
- WebBits.JavaScript.Syntax: instance Typeable PostfixOp
- WebBits.JavaScript.Syntax: instance Typeable PrefixOp
- WebBits.JavaScript.Syntax: instance Typeable1 CaseClause
- WebBits.JavaScript.Syntax: instance Typeable1 CatchClause
- WebBits.JavaScript.Syntax: instance Typeable1 Expression
- WebBits.JavaScript.Syntax: instance Typeable1 ForInInit
- WebBits.JavaScript.Syntax: instance Typeable1 ForInit
- WebBits.JavaScript.Syntax: instance Typeable1 Id
- WebBits.JavaScript.Syntax: instance Typeable1 JavaScript
- WebBits.JavaScript.Syntax: instance Typeable1 Prop
- WebBits.JavaScript.Syntax: instance Typeable1 Statement
- WebBits.JavaScript.Syntax: instance Typeable1 VarDecl
+ BrownPLT.Html: parseHtmlFromFile :: (Script s) => String -> IO (Either ParseError (Html SourcePos s, [Warning]))
+ BrownPLT.Html: parseHtmlFromString :: (Script s) => String -> String -> Either ParseError (Html SourcePos s, [Warning])
+ BrownPLT.Html: renderHtml :: (Script s) => Html a s -> String
+ BrownPLT.Html.Instances: instance Foldable (Attribute a)
+ BrownPLT.Html.Instances: instance Foldable (Html a)
+ BrownPLT.Html.Instances: instance Functor (Attribute a)
+ BrownPLT.Html.Instances: instance Functor (Html a)
+ BrownPLT.Html.Instances: instance Traversable (Attribute a)
+ BrownPLT.Html.Instances: instance Traversable (Html a)
+ BrownPLT.Html.PermissiveParser: data (Script s) => Token s
+ BrownPLT.Html.PermissiveParser: html :: (Script s) => CharParser [Warning] (Html SourcePos s)
+ BrownPLT.Html.PermissiveParser: instance (Script s) => Show (Token s)
+ BrownPLT.Html.PermissiveParser: instance Show Warning
+ BrownPLT.Html.PermissiveParser: parseHtmlFromFile :: (Script s) => String -> IO (Either ParseError (Html SourcePos s, [Warning]))
+ BrownPLT.Html.PermissiveParser: parseHtmlFromString :: (Script s) => String -> String -> Either ParseError (Html SourcePos s, [Warning])
+ BrownPLT.Html.PermissiveParser: tokens :: (Script s) => CharParser [Warning] [Token s]
+ BrownPLT.Html.PrettyPrint: html :: (Script s) => Html a s -> Doc
+ BrownPLT.Html.PrettyPrint: renderHtml :: (Script s) => Html a s -> String
+ BrownPLT.Html.RawScript: RawScript :: String -> RawScript
+ BrownPLT.Html.RawScript: data RawScript
+ BrownPLT.Html.RawScript: instance Data RawScript
+ BrownPLT.Html.RawScript: instance Eq RawScript
+ BrownPLT.Html.RawScript: instance Script RawScript
+ BrownPLT.Html.RawScript: instance Show RawScript
+ BrownPLT.Html.RawScript: instance Typeable RawScript
+ BrownPLT.Html.RawScript: parseFromFile :: Parser a -> SourceName -> IO (Either ParseError a)
+ BrownPLT.Html.RawScript: parseFromString :: String -> RawHtml
+ BrownPLT.Html.RawScript: type RawHtml = Html SourcePos RawScript
+ BrownPLT.Html.Syntax: Attribute :: HtmlId -> AttributeValue -> a -> Attribute a s
+ BrownPLT.Html.Syntax: AttributeExpr :: a -> HtmlId -> s -> String -> Attribute a s
+ BrownPLT.Html.Syntax: Comment :: String -> a -> Html a sc
+ BrownPLT.Html.Syntax: Element :: HtmlId -> [Attribute a sc] -> [Html a sc] -> a -> Html a sc
+ BrownPLT.Html.Syntax: HtmlSeq :: [Html a sc] -> Html a sc
+ BrownPLT.Html.Syntax: InlineScript :: sc -> a -> String -> Html a sc
+ BrownPLT.Html.Syntax: ProcessingInstruction :: String -> a -> Html a sc
+ BrownPLT.Html.Syntax: Script :: sc -> a -> Html a sc
+ BrownPLT.Html.Syntax: Text :: String -> a -> Html a sc
+ BrownPLT.Html.Syntax: attributeSet :: HtmlId -> String -> [Attribute a s] -> [Attribute a s]
+ BrownPLT.Html.Syntax: attributeUpdate :: HtmlId -> (String -> String) -> [Attribute a s] -> [Attribute a s]
+ BrownPLT.Html.Syntax: attributeValue :: HtmlId -> [Attribute a s] -> Maybe String
+ BrownPLT.Html.Syntax: class Script t
+ BrownPLT.Html.Syntax: data Attribute a s
+ BrownPLT.Html.Syntax: data Html a sc
+ BrownPLT.Html.Syntax: instance (Data a, Data s) => Data (Attribute a s)
+ BrownPLT.Html.Syntax: instance (Data a, Data sc) => Data (Html a sc)
+ BrownPLT.Html.Syntax: instance (Eq a, Eq s) => Eq (Attribute a s)
+ BrownPLT.Html.Syntax: instance (Eq a, Eq sc) => Eq (Html a sc)
+ BrownPLT.Html.Syntax: instance (Show a, Show s) => Show (Attribute a s)
+ BrownPLT.Html.Syntax: instance (Show a, Show sc) => Show (Html a sc)
+ BrownPLT.Html.Syntax: instance Typeable2 Attribute
+ BrownPLT.Html.Syntax: instance Typeable2 Html
+ BrownPLT.Html.Syntax: isAttributeExpr :: Attribute t t1 -> Bool
+ BrownPLT.Html.Syntax: parseAttributeScript :: (Script t) => Maybe (CharParser a t)
+ BrownPLT.Html.Syntax: parseInlineScript :: (Script t) => Maybe (CharParser a t)
+ BrownPLT.Html.Syntax: parseScriptBlock :: (Script t) => [Attribute SourcePos t] -> CharParser a t
+ BrownPLT.Html.Syntax: prettyPrintScript :: (Script t) => t -> Doc
+ BrownPLT.Html.Syntax: type AttributeValue = String
+ BrownPLT.Html.Syntax: type HtmlId = String
+ BrownPLT.JavaScript: renderExpression :: Expression a -> String
+ BrownPLT.JavaScript: renderStatements :: [Statement a] -> String
+ BrownPLT.JavaScript.Crawl: getPageJavaScript :: ParsedJsHtml -> IO [ParsedStatement]
+ BrownPLT.JavaScript.Crawl: instance Data SourcePos
+ BrownPLT.JavaScript.Crawl: instance Typeable SourcePos
+ BrownPLT.JavaScript.Environment: EnvTree :: (Map String SourcePos) -> [EnvTree] -> EnvTree
+ BrownPLT.JavaScript.Environment: data EnvTree
+ BrownPLT.JavaScript.Environment: env :: Map String SourcePos -> [Statement SourcePos] -> (EnvTree, Map String SourcePos)
+ BrownPLT.JavaScript.Environment: localVars :: [Statement SourcePos] -> Set String
+ BrownPLT.JavaScript.HtmlEmbedding: instance Script ParsedJavaScript
+ BrownPLT.JavaScript.HtmlEmbedding: type JsHtml a = Html SourcePos (JavaScript a)
+ BrownPLT.JavaScript.HtmlEmbedding: type ParsedJavaScript = JavaScript SourcePos
+ BrownPLT.JavaScript.HtmlEmbedding: type ParsedJsHtml = JsHtml SourcePos
+ BrownPLT.JavaScript.Instances: instance Foldable CaseClause
+ BrownPLT.JavaScript.Instances: instance Foldable CatchClause
+ BrownPLT.JavaScript.Instances: instance Foldable Expression
+ BrownPLT.JavaScript.Instances: instance Foldable ForInInit
+ BrownPLT.JavaScript.Instances: instance Foldable ForInit
+ BrownPLT.JavaScript.Instances: instance Foldable Id
+ BrownPLT.JavaScript.Instances: instance Foldable Prop
+ BrownPLT.JavaScript.Instances: instance Foldable Statement
+ BrownPLT.JavaScript.Instances: instance Foldable VarDecl
+ BrownPLT.JavaScript.Instances: instance Functor CaseClause
+ BrownPLT.JavaScript.Instances: instance Functor CatchClause
+ BrownPLT.JavaScript.Instances: instance Functor Expression
+ BrownPLT.JavaScript.Instances: instance Functor ForInInit
+ BrownPLT.JavaScript.Instances: instance Functor ForInit
+ BrownPLT.JavaScript.Instances: instance Functor Id
+ BrownPLT.JavaScript.Instances: instance Functor JavaScript
+ BrownPLT.JavaScript.Instances: instance Functor Prop
+ BrownPLT.JavaScript.Instances: instance Functor Statement
+ BrownPLT.JavaScript.Instances: instance Functor VarDecl
+ BrownPLT.JavaScript.Instances: instance Traversable CaseClause
+ BrownPLT.JavaScript.Instances: instance Traversable CatchClause
+ BrownPLT.JavaScript.Instances: instance Traversable Expression
+ BrownPLT.JavaScript.Instances: instance Traversable ForInInit
+ BrownPLT.JavaScript.Instances: instance Traversable ForInit
+ BrownPLT.JavaScript.Instances: instance Traversable Id
+ BrownPLT.JavaScript.Instances: instance Traversable Prop
+ BrownPLT.JavaScript.Instances: instance Traversable Statement
+ BrownPLT.JavaScript.Instances: instance Traversable VarDecl
+ BrownPLT.JavaScript.Lexer: braces :: CharParser st a -> CharParser st a
+ BrownPLT.JavaScript.Lexer: brackets :: CharParser st a -> CharParser st a
+ BrownPLT.JavaScript.Lexer: charLiteral :: CharParser st Char
+ BrownPLT.JavaScript.Lexer: colon :: CharParser st String
+ BrownPLT.JavaScript.Lexer: comma :: CharParser st String
+ BrownPLT.JavaScript.Lexer: decimal :: CharParser st Integer
+ BrownPLT.JavaScript.Lexer: dot :: CharParser st String
+ BrownPLT.JavaScript.Lexer: float :: CharParser st Double
+ BrownPLT.JavaScript.Lexer: hexadecimal :: CharParser st Integer
+ BrownPLT.JavaScript.Lexer: identifier :: CharParser st String
+ BrownPLT.JavaScript.Lexer: identifierStart :: GenParser Char st Char
+ BrownPLT.JavaScript.Lexer: integer :: CharParser st Integer
+ BrownPLT.JavaScript.Lexer: lexeme :: CharParser st a -> CharParser st a
+ BrownPLT.JavaScript.Lexer: natural :: CharParser st Integer
+ BrownPLT.JavaScript.Lexer: naturalOrFloat :: CharParser st (Either Integer Double)
+ BrownPLT.JavaScript.Lexer: octal :: CharParser st Integer
+ BrownPLT.JavaScript.Lexer: operator :: CharParser st String
+ BrownPLT.JavaScript.Lexer: parens :: CharParser st a -> CharParser st a
+ BrownPLT.JavaScript.Lexer: reserved :: String -> CharParser st ()
+ BrownPLT.JavaScript.Lexer: reservedOp :: String -> CharParser st ()
+ BrownPLT.JavaScript.Lexer: semi :: CharParser st String
+ BrownPLT.JavaScript.Lexer: squares :: CharParser st a -> CharParser st a
+ BrownPLT.JavaScript.Lexer: stringLiteral :: CharParser st String
+ BrownPLT.JavaScript.Lexer: symbol :: String -> CharParser st String
+ BrownPLT.JavaScript.Lexer: whiteSpace :: CharParser st ()
+ BrownPLT.JavaScript.Parser: emptyParsedJavaScript :: JavaScript a
+ BrownPLT.JavaScript.Parser: parseAssignExpr :: ExpressionParser st
+ BrownPLT.JavaScript.Parser: parseBlockStmt :: StatementParser st
+ BrownPLT.JavaScript.Parser: parseExpression :: ExpressionParser st
+ BrownPLT.JavaScript.Parser: parseJavaScriptFromFile :: (MonadIO m) => String -> m [Statement SourcePos]
+ BrownPLT.JavaScript.Parser: parseScript :: CharParser state (JavaScript SourcePos)
+ BrownPLT.JavaScript.Parser: parseScriptFromString :: String -> String -> Either ParseError (JavaScript SourcePos)
+ BrownPLT.JavaScript.Parser: parseSimpleExpr' :: GenParser Char st2 (Expression SourcePos)
+ BrownPLT.JavaScript.Parser: parseStatement :: StatementParser st
+ BrownPLT.JavaScript.Parser: parseString :: String -> [Statement SourcePos]
+ BrownPLT.JavaScript.Parser: type ExpressionParser state = CharParser state ParsedExpression
+ BrownPLT.JavaScript.Parser: type ParsedExpression = Expression SourcePos
+ BrownPLT.JavaScript.Parser: type ParsedStatement = Statement SourcePos
+ BrownPLT.JavaScript.Parser: type StatementParser state = CharParser state ParsedStatement
+ BrownPLT.JavaScript.PrettyPrint: expr :: Expression a -> Doc
+ BrownPLT.JavaScript.PrettyPrint: javaScript :: JavaScript a -> Doc
+ BrownPLT.JavaScript.PrettyPrint: renderExpression :: Expression a -> String
+ BrownPLT.JavaScript.PrettyPrint: renderStatements :: [Statement a] -> String
+ BrownPLT.JavaScript.PrettyPrint: stmt :: Statement a -> Doc
+ BrownPLT.JavaScript.Syntax: ArrayLit :: a -> [Expression a] -> Expression a
+ BrownPLT.JavaScript.Syntax: AssignExpr :: a -> AssignOp -> (Expression a) -> (Expression a) -> Expression a
+ BrownPLT.JavaScript.Syntax: BlockStmt :: a -> [Statement a] -> Statement a
+ BrownPLT.JavaScript.Syntax: BoolLit :: a -> Bool -> Expression a
+ BrownPLT.JavaScript.Syntax: BracketRef :: a -> (Expression a) -> (Expression a) -> Expression a
+ BrownPLT.JavaScript.Syntax: BreakStmt :: a -> (Maybe (Id a)) -> Statement a
+ BrownPLT.JavaScript.Syntax: CallExpr :: a -> (Expression a) -> [Expression a] -> Expression a
+ BrownPLT.JavaScript.Syntax: CaseClause :: a -> (Expression a) -> [Statement a] -> CaseClause a
+ BrownPLT.JavaScript.Syntax: CaseDefault :: a -> [Statement a] -> CaseClause a
+ BrownPLT.JavaScript.Syntax: CatchClause :: a -> (Id a) -> (Statement a) -> CatchClause a
+ BrownPLT.JavaScript.Syntax: CondExpr :: a -> (Expression a) -> (Expression a) -> (Expression a) -> Expression a
+ BrownPLT.JavaScript.Syntax: ContinueStmt :: a -> (Maybe (Id a)) -> Statement a
+ BrownPLT.JavaScript.Syntax: DoWhileStmt :: a -> (Statement a) -> (Expression a) -> Statement a
+ BrownPLT.JavaScript.Syntax: DotRef :: a -> (Expression a) -> (Id a) -> Expression a
+ BrownPLT.JavaScript.Syntax: EmptyStmt :: a -> Statement a
+ BrownPLT.JavaScript.Syntax: ExprInit :: (Expression a) -> ForInit a
+ BrownPLT.JavaScript.Syntax: ExprStmt :: a -> (Expression a) -> Statement a
+ BrownPLT.JavaScript.Syntax: ForInNoVar :: (Id a) -> ForInInit a
+ BrownPLT.JavaScript.Syntax: ForInStmt :: a -> (ForInInit a) -> (Expression a) -> (Statement a) -> Statement a
+ BrownPLT.JavaScript.Syntax: ForInVar :: (Id a) -> ForInInit a
+ BrownPLT.JavaScript.Syntax: ForStmt :: a -> (ForInit a) -> (Maybe (Expression a)) -> (Maybe (Expression a)) -> (Statement a) -> Statement a
+ BrownPLT.JavaScript.Syntax: FuncExpr :: a -> [(Id a)] -> (Statement a) -> Expression a
+ BrownPLT.JavaScript.Syntax: FunctionStmt :: a -> (Id a) -> [(Id a)] -> (Statement a) -> Statement a
+ BrownPLT.JavaScript.Syntax: Id :: a -> String -> Id a
+ BrownPLT.JavaScript.Syntax: IfSingleStmt :: a -> (Expression a) -> (Statement a) -> Statement a
+ BrownPLT.JavaScript.Syntax: IfStmt :: a -> (Expression a) -> (Statement a) -> (Statement a) -> Statement a
+ BrownPLT.JavaScript.Syntax: InfixExpr :: a -> InfixOp -> (Expression a) -> (Expression a) -> Expression a
+ BrownPLT.JavaScript.Syntax: IntLit :: a -> Int -> Expression a
+ BrownPLT.JavaScript.Syntax: LabelledStmt :: a -> (Id a) -> (Statement a) -> Statement a
+ BrownPLT.JavaScript.Syntax: ListExpr :: a -> [Expression a] -> Expression a
+ BrownPLT.JavaScript.Syntax: NewExpr :: a -> (Expression a) -> [Expression a] -> Expression a
+ BrownPLT.JavaScript.Syntax: NoInit :: ForInit a
+ BrownPLT.JavaScript.Syntax: NullLit :: a -> Expression a
+ BrownPLT.JavaScript.Syntax: NumLit :: a -> Double -> Expression a
+ BrownPLT.JavaScript.Syntax: ObjectLit :: a -> [(Prop a, Expression a)] -> Expression a
+ BrownPLT.JavaScript.Syntax: OpAdd :: InfixOp
+ BrownPLT.JavaScript.Syntax: OpAssign :: AssignOp
+ BrownPLT.JavaScript.Syntax: OpAssignAdd :: AssignOp
+ BrownPLT.JavaScript.Syntax: OpAssignBAnd :: AssignOp
+ BrownPLT.JavaScript.Syntax: OpAssignBOr :: AssignOp
+ BrownPLT.JavaScript.Syntax: OpAssignBXor :: AssignOp
+ BrownPLT.JavaScript.Syntax: OpAssignDiv :: AssignOp
+ BrownPLT.JavaScript.Syntax: OpAssignLShift :: AssignOp
+ BrownPLT.JavaScript.Syntax: OpAssignMod :: AssignOp
+ BrownPLT.JavaScript.Syntax: OpAssignMul :: AssignOp
+ BrownPLT.JavaScript.Syntax: OpAssignSpRShift :: AssignOp
+ BrownPLT.JavaScript.Syntax: OpAssignSub :: AssignOp
+ BrownPLT.JavaScript.Syntax: OpAssignZfRShift :: AssignOp
+ BrownPLT.JavaScript.Syntax: OpBAnd :: InfixOp
+ BrownPLT.JavaScript.Syntax: OpBOr :: InfixOp
+ BrownPLT.JavaScript.Syntax: OpBXor :: InfixOp
+ BrownPLT.JavaScript.Syntax: OpDiv :: InfixOp
+ BrownPLT.JavaScript.Syntax: OpEq :: InfixOp
+ BrownPLT.JavaScript.Syntax: OpGEq :: InfixOp
+ BrownPLT.JavaScript.Syntax: OpGT :: InfixOp
+ BrownPLT.JavaScript.Syntax: OpIn :: InfixOp
+ BrownPLT.JavaScript.Syntax: OpInstanceof :: InfixOp
+ BrownPLT.JavaScript.Syntax: OpLAnd :: InfixOp
+ BrownPLT.JavaScript.Syntax: OpLEq :: InfixOp
+ BrownPLT.JavaScript.Syntax: OpLOr :: InfixOp
+ BrownPLT.JavaScript.Syntax: OpLShift :: InfixOp
+ BrownPLT.JavaScript.Syntax: OpLT :: InfixOp
+ BrownPLT.JavaScript.Syntax: OpMod :: InfixOp
+ BrownPLT.JavaScript.Syntax: OpMul :: InfixOp
+ BrownPLT.JavaScript.Syntax: OpNEq :: InfixOp
+ BrownPLT.JavaScript.Syntax: OpSpRShift :: InfixOp
+ BrownPLT.JavaScript.Syntax: OpStrictEq :: InfixOp
+ BrownPLT.JavaScript.Syntax: OpStrictNEq :: InfixOp
+ BrownPLT.JavaScript.Syntax: OpSub :: InfixOp
+ BrownPLT.JavaScript.Syntax: OpZfRShift :: InfixOp
+ BrownPLT.JavaScript.Syntax: ParenExpr :: a -> (Expression a) -> Expression a
+ BrownPLT.JavaScript.Syntax: PostfixDec :: PostfixOp
+ BrownPLT.JavaScript.Syntax: PostfixExpr :: a -> PostfixOp -> (Expression a) -> Expression a
+ BrownPLT.JavaScript.Syntax: PostfixInc :: PostfixOp
+ BrownPLT.JavaScript.Syntax: PrefixBNot :: PrefixOp
+ BrownPLT.JavaScript.Syntax: PrefixDec :: PrefixOp
+ BrownPLT.JavaScript.Syntax: PrefixDelete :: PrefixOp
+ BrownPLT.JavaScript.Syntax: PrefixExpr :: a -> PrefixOp -> (Expression a) -> Expression a
+ BrownPLT.JavaScript.Syntax: PrefixInc :: PrefixOp
+ BrownPLT.JavaScript.Syntax: PrefixLNot :: PrefixOp
+ BrownPLT.JavaScript.Syntax: PrefixMinus :: PrefixOp
+ BrownPLT.JavaScript.Syntax: PrefixPlus :: PrefixOp
+ BrownPLT.JavaScript.Syntax: PrefixTypeof :: PrefixOp
+ BrownPLT.JavaScript.Syntax: PrefixVoid :: PrefixOp
+ BrownPLT.JavaScript.Syntax: PropId :: a -> (Id a) -> Prop a
+ BrownPLT.JavaScript.Syntax: PropNum :: a -> Integer -> Prop a
+ BrownPLT.JavaScript.Syntax: PropString :: a -> String -> Prop a
+ BrownPLT.JavaScript.Syntax: RegexpLit :: a -> String -> Bool -> Bool -> Expression a
+ BrownPLT.JavaScript.Syntax: ReturnStmt :: a -> (Maybe (Expression a)) -> Statement a
+ BrownPLT.JavaScript.Syntax: Script :: a -> [Statement a] -> JavaScript a
+ BrownPLT.JavaScript.Syntax: StringLit :: a -> String -> Expression a
+ BrownPLT.JavaScript.Syntax: SwitchStmt :: a -> (Expression a) -> [CaseClause a] -> Statement a
+ BrownPLT.JavaScript.Syntax: ThisRef :: a -> Expression a
+ BrownPLT.JavaScript.Syntax: ThrowStmt :: a -> (Expression a) -> Statement a
+ BrownPLT.JavaScript.Syntax: TryStmt :: a -> (Statement a) -> [CatchClause a] -> (Maybe (Statement a)) -> Statement a
+ BrownPLT.JavaScript.Syntax: VarDecl :: a -> (Id a) -> (Maybe (Expression a)) -> VarDecl a
+ BrownPLT.JavaScript.Syntax: VarDeclStmt :: a -> [VarDecl a] -> Statement a
+ BrownPLT.JavaScript.Syntax: VarInit :: [VarDecl a] -> ForInit a
+ BrownPLT.JavaScript.Syntax: VarRef :: a -> (Id a) -> Expression a
+ BrownPLT.JavaScript.Syntax: WhileStmt :: a -> (Expression a) -> (Statement a) -> Statement a
+ BrownPLT.JavaScript.Syntax: WithStmt :: a -> (Expression a) -> (Statement a) -> Statement a
+ BrownPLT.JavaScript.Syntax: data AssignOp
+ BrownPLT.JavaScript.Syntax: data CaseClause a
+ BrownPLT.JavaScript.Syntax: data CatchClause a
+ BrownPLT.JavaScript.Syntax: data Expression a
+ BrownPLT.JavaScript.Syntax: data ForInInit a
+ BrownPLT.JavaScript.Syntax: data ForInit a
+ BrownPLT.JavaScript.Syntax: data Id a
+ BrownPLT.JavaScript.Syntax: data InfixOp
+ BrownPLT.JavaScript.Syntax: data JavaScript a
+ BrownPLT.JavaScript.Syntax: data PostfixOp
+ BrownPLT.JavaScript.Syntax: data PrefixOp
+ BrownPLT.JavaScript.Syntax: data Prop a
+ BrownPLT.JavaScript.Syntax: data Statement a
+ BrownPLT.JavaScript.Syntax: data VarDecl a
+ BrownPLT.JavaScript.Syntax: instance (Data a) => Data (CaseClause a)
+ BrownPLT.JavaScript.Syntax: instance (Data a) => Data (CatchClause a)
+ BrownPLT.JavaScript.Syntax: instance (Data a) => Data (Expression a)
+ BrownPLT.JavaScript.Syntax: instance (Data a) => Data (ForInInit a)
+ BrownPLT.JavaScript.Syntax: instance (Data a) => Data (ForInit a)
+ BrownPLT.JavaScript.Syntax: instance (Data a) => Data (Id a)
+ BrownPLT.JavaScript.Syntax: instance (Data a) => Data (JavaScript a)
+ BrownPLT.JavaScript.Syntax: instance (Data a) => Data (Prop a)
+ BrownPLT.JavaScript.Syntax: instance (Data a) => Data (Statement a)
+ BrownPLT.JavaScript.Syntax: instance (Data a) => Data (VarDecl a)
+ BrownPLT.JavaScript.Syntax: instance (Eq a) => Eq (CaseClause a)
+ BrownPLT.JavaScript.Syntax: instance (Eq a) => Eq (CatchClause a)
+ BrownPLT.JavaScript.Syntax: instance (Eq a) => Eq (Expression a)
+ BrownPLT.JavaScript.Syntax: instance (Eq a) => Eq (ForInInit a)
+ BrownPLT.JavaScript.Syntax: instance (Eq a) => Eq (ForInit a)
+ BrownPLT.JavaScript.Syntax: instance (Eq a) => Eq (Id a)
+ BrownPLT.JavaScript.Syntax: instance (Eq a) => Eq (JavaScript a)
+ BrownPLT.JavaScript.Syntax: instance (Eq a) => Eq (Prop a)
+ BrownPLT.JavaScript.Syntax: instance (Eq a) => Eq (Statement a)
+ BrownPLT.JavaScript.Syntax: instance (Eq a) => Eq (VarDecl a)
+ BrownPLT.JavaScript.Syntax: instance (Ord a) => Ord (CaseClause a)
+ BrownPLT.JavaScript.Syntax: instance (Ord a) => Ord (CatchClause a)
+ BrownPLT.JavaScript.Syntax: instance (Ord a) => Ord (Expression a)
+ BrownPLT.JavaScript.Syntax: instance (Ord a) => Ord (ForInInit a)
+ BrownPLT.JavaScript.Syntax: instance (Ord a) => Ord (ForInit a)
+ BrownPLT.JavaScript.Syntax: instance (Ord a) => Ord (Id a)
+ BrownPLT.JavaScript.Syntax: instance (Ord a) => Ord (JavaScript a)
+ BrownPLT.JavaScript.Syntax: instance (Ord a) => Ord (Prop a)
+ BrownPLT.JavaScript.Syntax: instance (Ord a) => Ord (Statement a)
+ BrownPLT.JavaScript.Syntax: instance (Ord a) => Ord (VarDecl a)
+ BrownPLT.JavaScript.Syntax: instance (Show a) => Show (CaseClause a)
+ BrownPLT.JavaScript.Syntax: instance (Show a) => Show (CatchClause a)
+ BrownPLT.JavaScript.Syntax: instance (Show a) => Show (Expression a)
+ BrownPLT.JavaScript.Syntax: instance (Show a) => Show (ForInInit a)
+ BrownPLT.JavaScript.Syntax: instance (Show a) => Show (ForInit a)
+ BrownPLT.JavaScript.Syntax: instance (Show a) => Show (Id a)
+ BrownPLT.JavaScript.Syntax: instance (Show a) => Show (JavaScript a)
+ BrownPLT.JavaScript.Syntax: instance (Show a) => Show (Prop a)
+ BrownPLT.JavaScript.Syntax: instance (Show a) => Show (Statement a)
+ BrownPLT.JavaScript.Syntax: instance (Show a) => Show (VarDecl a)
+ BrownPLT.JavaScript.Syntax: instance Data AssignOp
+ BrownPLT.JavaScript.Syntax: instance Data InfixOp
+ BrownPLT.JavaScript.Syntax: instance Data PostfixOp
+ BrownPLT.JavaScript.Syntax: instance Data PrefixOp
+ BrownPLT.JavaScript.Syntax: instance Enum InfixOp
+ BrownPLT.JavaScript.Syntax: instance Eq AssignOp
+ BrownPLT.JavaScript.Syntax: instance Eq InfixOp
+ BrownPLT.JavaScript.Syntax: instance Eq PostfixOp
+ BrownPLT.JavaScript.Syntax: instance Eq PrefixOp
+ BrownPLT.JavaScript.Syntax: instance Ord AssignOp
+ BrownPLT.JavaScript.Syntax: instance Ord InfixOp
+ BrownPLT.JavaScript.Syntax: instance Ord PostfixOp
+ BrownPLT.JavaScript.Syntax: instance Ord PrefixOp
+ BrownPLT.JavaScript.Syntax: instance Show AssignOp
+ BrownPLT.JavaScript.Syntax: instance Show InfixOp
+ BrownPLT.JavaScript.Syntax: instance Show PostfixOp
+ BrownPLT.JavaScript.Syntax: instance Show PrefixOp
+ BrownPLT.JavaScript.Syntax: instance Typeable AssignOp
+ BrownPLT.JavaScript.Syntax: instance Typeable InfixOp
+ BrownPLT.JavaScript.Syntax: instance Typeable PostfixOp
+ BrownPLT.JavaScript.Syntax: instance Typeable PrefixOp
+ BrownPLT.JavaScript.Syntax: instance Typeable1 CaseClause
+ BrownPLT.JavaScript.Syntax: instance Typeable1 CatchClause
+ BrownPLT.JavaScript.Syntax: instance Typeable1 Expression
+ BrownPLT.JavaScript.Syntax: instance Typeable1 ForInInit
+ BrownPLT.JavaScript.Syntax: instance Typeable1 ForInit
+ BrownPLT.JavaScript.Syntax: instance Typeable1 Id
+ BrownPLT.JavaScript.Syntax: instance Typeable1 JavaScript
+ BrownPLT.JavaScript.Syntax: instance Typeable1 Prop
+ BrownPLT.JavaScript.Syntax: instance Typeable1 Statement
+ BrownPLT.JavaScript.Syntax: instance Typeable1 VarDecl
+ BrownPLT.JavaScript.Syntax: unId :: Id a -> String

Files

+ Setup.hs view
@@ -0,0 +1,37 @@+#!/usr/bin/env runhaskell+import Distribution.Simple+import qualified Data.List as L+import System.Directory+import qualified Data.Char as Ch+import System.Process (runCommand,waitForProcess)++isHaskellFile file = ".lhs" `L.isSuffixOf` file || ".hs" `L.isSuffixOf` file++moduleName file = L.takeWhile  (/= '.') file++isRequested :: [String] -> String -> Bool+isRequested requestedTests test = +  (map Ch.toLower test) `elem` (map (map Ch.toLower) requestedTests)++testMain args _ _ _ = do+  files <- getDirectoryContents "tests"+  let testFiles = filter isHaskellFile files+  let testModules = if null args+                      then map moduleName testFiles+                      else filter (isRequested args) (map moduleName testFiles)+  let testFuncs = map (++ ".main") testModules+  let testExpr = "sequence [ " ++ concat (L.intersperse "," testFuncs) ++ +                 " ] >>= \\cases -> runTestTT (TestList cases)"+  let moduleLine = concat (L.intersperse " " testModules)+  let cmd = "cd tests && ghc  -XNoMonomorphismRestriction -fglasgow-exts " +++            "-package HUnit -package parsec-2.1.0.1 -i:../src -e \"" ++ +            testExpr ++ " >> return ()\" " ++ moduleLine+  putStrLn "Testing command is:"+  putStrLn cmd+  putStrLn "\nLoading tests..."+  handle <- runCommand cmd+  waitForProcess handle+  putStrLn "Testing complete.  Errors reported above (if any)."+++main = defaultMainWithHooks (simpleUserHooks { runTests = testMain })
− Setup.lhs
@@ -1,29 +0,0 @@-#!/usr/bin/env runhaskell-> import Distribution.Simple-> import qualified Data.List as L-> import System.Directory-> import System.Process (runCommand,waitForProcess)--> isHaskellFile file = ".lhs" `L.isSuffixOf` file || ".hs" `L.isSuffixOf` file--> moduleName file = L.takeWhile  (/= '.') file--> testMain _ _ _ _ = do->   files <- getDirectoryContents "tests"->   let testModules = [moduleName f | f <- files, isHaskellFile f]->   let testFuncs = map (++ ".main") testModules->   let testExpr = "sequence [ " ++ concat (L.intersperse "," testFuncs) ++ ->                  " ] >>= \\cases -> runTestTT (TestList cases)"->   let moduleLine = concat (L.intersperse " " testModules)->   let cmd = "cd tests && ghc  -XNoMonomorphismRestriction -fglasgow-exts " ++->             "-package HUnit -i:../src -e \"" ++ testExpr ++ ->             " >> return ()\" " ++ moduleLine->   putStrLn "Testing command is:"->   putStrLn cmd->   putStrLn "\nLoading tests..."->   handle <- runCommand cmd->   waitForProcess handle->   putStrLn "Testing complete.  Errors reported above (if any)."- --> main = defaultMainWithHooks (simpleUserHooks { runTests = testMain })
WebBits.cabal view
@@ -1,7 +1,7 @@ Name:           WebBits-Version:        0.11.0+Version:        0.14.0 Cabal-Version:	>= 1.2.3-Copyright:      Copyright (c) 2007-2008 Arjun Guha and Spiridon Eliopoulos+Copyright:      Copyright (c) 2007-2009 Arjun Guha and Spiridon Eliopoulos License:        LGPL License-file:   LICENSE Author:         Arjun Guha, Spiridon Eliopoulos@@ -16,16 +16,16 @@ 	WebBits is a collection of libraries for working with JavaScript embeded in   HTML files.  Highlights include:   .-	* @WebBits.JavaScript.Crawl@ returns all JavaScript in an HTML page, including+	* @BrownPLT.JavaScript.Crawl@ returns all JavaScript in an HTML page, including      JavaScript from imported script files (@\<script src=...\>@).   .-  * @WebBits.JavaScript.Environment@ annotates JavaScript syntax with its static-    environment and returns a list of free identifiers.+  * @BrownPLT.JavaScript.Environment@ annotates JavaScript syntax with its +    static environment and returns a list of free identifiers.   .-  * @WebBits.JavaScript.Parser@ is a JavaScript parser that is largely based on+  * @BrownPLT.JavaScript.Parser@ is a JavaScript parser that is largely based on     JavaScript 1.5.   .-  * @WebBits.Html.Parser@ is a permissive HTML parser.+  * @BrownPLT.Html.Parser@ is a permissive HTML parser.   Library   Hs-Source-Dirs:@@ -35,16 +35,20 @@   ghc-options:     -fwarn-incomplete-patterns   Extensions:     -    Generics Rank2Types MultiParamTypeClasses FunctionalDependencies-    TypeSynonymInstances FlexibleInstances FlexibleContexts-    DeriveDataTypeable NoMonomorphismRestriction RelaxedPolyRec+    Generics TypeSynonymInstances DeriveDataTypeable   Exposed-Modules:-    WebBits.Data.Zipper-    WebBits.Html.Html WebBits.Html.Syntax WebBits.Html.PermissiveParser-    WebBits.Html.PrettyPrint WebBits.Html.Instances WebBits.Common-    WebBits.Html.RawScript WebBits.JavaScript.Combinators-    WebBits.JavaScript.HtmlEmbedding WebBits.JavaScript.Instances-    WebBits.JavaScript.JavaScript WebBits.JavaScript.Lexer -    WebBits.JavaScript.Parser WebBits.JavaScript.PrettyPrint-    WebBits.JavaScript.Syntax WebBits.JavaScript.Environment-    WebBits.JavaScript.Crawl WebBits.JavaScript+    BrownPLT.Html+    BrownPLT.Html.Syntax+    BrownPLT.Html.PermissiveParser+    BrownPLT.Html.PrettyPrint +    BrownPLT.Html.Instances+    BrownPLT.Html.RawScript+    BrownPLT.JavaScript +    BrownPLT.JavaScript.HtmlEmbedding +    BrownPLT.JavaScript.Instances+    BrownPLT.JavaScript.Lexer +    BrownPLT.JavaScript.Parser+    BrownPLT.JavaScript.PrettyPrint+    BrownPLT.JavaScript.Syntax +    BrownPLT.JavaScript.Crawl+    BrownPLT.JavaScript.Environment
+ src/BrownPLT/Html.hs view
@@ -0,0 +1,14 @@+-- |Rexports various modules of the HTML library.  It's best to use this in lieu+-- of selectively importing the following libraries.+module BrownPLT.Html+  ( module BrownPLT.Html.Syntax+  -- PermissiveParser+  , renderHtml+  , parseHtmlFromFile+  , parseHtmlFromString+  ) where+  +import BrownPLT.Html.Syntax+import BrownPLT.Html.PermissiveParser+import BrownPLT.Html.PrettyPrint -- no names, only instances+import BrownPLT.Html.Instances -- no names, only instances
+ src/BrownPLT/Html/Instances.hs view
@@ -0,0 +1,66 @@+module BrownPLT.Html.Instances() where++import qualified Prelude as Prelude+import Prelude (Functor,map,fmap)+import qualified Data.List as List+import qualified Data.Char as Char+import Data.Foldable+import Data.Traversable+import Control.Applicative++import BrownPLT.Html.Syntax++ltraverse:: (Traversable t, Applicative f) => (a -> f b) -> [t a] -> f [t b]+ltraverse f [] = pure []+ltraverse f (x:xs) = pure (:) <*> (traverse f x) <*> ltraverse f xs++instance Functor (Attribute a) where+  fmap f (Attribute id val a)            = Attribute id val a+  fmap f (AttributeExpr a id script def) = AttributeExpr a id (f script) def++instance Functor (Html a) where+  fmap f (Element id attrs children a) = +    Element id (map (fmap f) attrs) (map (fmap f) children) a+  fmap f (Text str a)                  = Text str a+  fmap f (Comment str a)               = Comment str a+  fmap f (HtmlSeq xs)                  = HtmlSeq (map (fmap f) xs)+  fmap f (ProcessingInstruction str a) = ProcessingInstruction str a+  fmap f (InlineScript script a def)   = InlineScript (f script) a def+  fmap f (Script script a)             = Script (f script) a++instance Foldable (Attribute a) where+  foldr f x (Attribute id val a)          = x+  foldr f x (AttributeExpr a id script def) = f script x++instance Foldable (Html a) where+  foldr f x (Element id attrs children a) =+    Prelude.foldr  (\child x' -> foldr f x' child) x children  +  foldr f x (Text str a)                  = x+  foldr f x (Comment str a)               = x+  foldr f x (HtmlSeq ys)                  = +    Prelude.foldr (\child x' -> foldr f x' child) x ys+  foldr f x (ProcessingInstruction str a) = x+  foldr f x (InlineScript script a def)   = f script x+  foldr f x (Script script a)             = f script x++instance Traversable (Attribute a) where+  traverse f (Attribute id val a)            =+    pure (Attribute id val a)+  traverse f (AttributeExpr a id script def) =+    (AttributeExpr a id) <$> (f script) <*> pure def++instance Traversable (Html a) where+  traverse f (Element id attrs children a) = +    (Element id) <$> ltraverse f attrs  <*> ltraverse f children <*> pure a+  traverse f (Text str a)                  = +    pure (Text str a)+  traverse f (Comment str a)               = +    pure (Comment str a)+  traverse f (HtmlSeq xs)                  = +    HtmlSeq <$> ltraverse f xs+  traverse f (ProcessingInstruction str a) = +    pure (ProcessingInstruction str a)+  traverse f (InlineScript script a def)   =+    InlineScript <$> (f script) <*> pure a <*> pure def+  traverse f (Script script a)             = +    Script <$> (f script) <*> pure a
+ src/BrownPLT/Html/PermissiveParser.hs view
@@ -0,0 +1,492 @@+-- |A structure-recovering parser for malformed documents.+--+-- Copyright 2007-2008 Arjun Guha.+-- Based on HtmlPrag 0.16 Copyright (C) 2003 - 2005 Neil W. Van Dyke.  +--+-- This program is Free Software; you can redistribute it and/or modify it under+-- the terms of the GNU Lesser General Public License as published by the Free+-- Software Foundation; either version 2.1 of the License, or (at your option)+-- any later version.  This program is distributed in the hope that it will be+-- useful, but without any warranty; without even the implied warranty of+-- merchantability or fitness for a particular purpose.  See +-- <http://www.gnu.org/copyleft/lesser.html> for details.  For other license+-- options and consulting, contact the author.+module BrownPLT.Html.PermissiveParser+  ( html+  , parseHtmlFromFile+  , parseHtmlFromString+  -- tokenizer is exported primarily for testing+  , tokens+  , Token+  ) where++import Control.Monad+import Text.ParserCombinators.Parsec hiding (token,tokens)+import qualified Text.ParserCombinators.Parsec as Parsec+import Data.Char (toLower)+import Data.List (intersperse)++import qualified BrownPLT.Html.Syntax as Html+import BrownPLT.Html.Syntax (HtmlId,Attribute,Script(..))++type ParsedHtml s = Html.Html SourcePos s+type ParsedAttribute s = Html.Attribute SourcePos s++--------------------------------------------------------------------------------+-- Parsers generate warnings++data Warning = StringWarning SourcePos String++instance Show Warning where+  show (StringWarning p s) = "Warning parsing HTML: " ++ s+  showList [] s = s+  showList (x:xs) s = show x ++ ('\n':showList xs s)++warn:: String -> GenParser tok [Warning] ()+warn s = do+  p <- getPosition+  updateState ((StringWarning p s):)++noWarnings:: [Warning]+noWarnings = []+  ++-- A structure-recovering parser for malformed documents, derived from+-- Neil W. Van Dyke's htmlprag library for PLT Scheme++-- The elements in the list can legally enclose the 1st element of the pair.+parentConstraints:: [(HtmlId,[HtmlId])]+parentConstraints =+  [("area",["map"]),+   ("body",["html"]),+   ("caption", ["table"]),+   ("colgroup", ["table"]),+   ("dd", ["dl"]),+   ("dt", ["dl"]),+   ("frame", ["frameset"]),+   ("head", ["html"]),+   ("isindex", ["head"]),+   ("li", ["dir", "menu", "ol", "ul"]),+   ("meta", ["head"]),+   ("noframes", ["frameset"]),+   ("option", ["select"]),+   ("p", ["body", "td", "th"]),+   ("param", ["applet"]),+   ("tbody", ["table"]),+   ("td", ["tr"]),+   ("th", ["tr"]),+   ("thead", ["table"]),+   ("title", ["head"]),+   ("tr", ["table", "tbody", "thead"])]++-- |List of HTML elements that are empty.+emptyElements:: [HtmlId]+emptyElements = +  ["area", "base", "br", "frame", "hr", "img", "input", "isindex", "keygen", +   "link", "meta", "object", "param", "spacer", "wbr"]++isLegalChildOf:: HtmlId -> HtmlId -> Bool+isLegalChildOf child parent =+  case lookup child parentConstraints of+    Nothing             -> True+    (Just legalParents) -> parent `elem` legalParents+    +isEmptyElement:: HtmlId -> Bool+isEmptyElement element = element `elem` emptyElements++--}}}++--------------------------------------------------------------------------------+-- Parses an HTML file into a stream of tokens.++-- The auxillary parsing functions return values of this type.+data Script s  => Token s+  = Text SourcePos String+  | EntityToken SourcePos String+  | EntityInt SourcePos Int+  | Tag SourcePos HtmlId [Attribute SourcePos s] Bool {-closed?-}+  | Script SourcePos s+  | Inline SourcePos s String+  | EndTag SourcePos HtmlId+  | Comment SourcePos String+  | DoctypeToken SourcePos String String String (Maybe String)+++token:: Script s => Bool -> [Attribute SourcePos s] +     -> CharParser [Warning] (Token s)+token expectedScript prevAttrs = case expectedScript of+  True  -> (liftM2 Script getPosition (parseScriptBlock prevAttrs)) +             <?> "expected a script after a <script> tag"+  False -> doctype <|> comment <|> tag <|> endTag <|> inlineScript <|> entity +             <|> text++tokens:: Script s => CharParser [Warning] [Token s]+tokens = (eof >> return []) <|> tokens' where+  tokens' = do +    t <- token False []+    case t of+      (Tag _ "script" attrs False) -> do s <- token True attrs+                                         ts <- tokens+                                         return (t:s:ts)+      _ -> tokens >>= return.(t:)++--------------------------------------------------------------------------------+-- Parsers for various components of HTML++qname:: CharParser st String+qname = do+  x <- letter+  xs <- many (noneOf "/*=<>\"\'  \v\f\t\r\n")+  return (x:xs)++-- |We do not permit spaces between the hyphens and the right-angle in the+-- terminating '-->'.+comment:: Script s => CharParser st (Token s) +comment =+  let notDoubleHyphen = try (char '-' >> notFollowedBy (char '-') >> return '-')+      notHyphen = noneOf "-"+    in do try (string "<!--")+          pos <- getPosition+          msg <- many (notHyphen <|> notDoubleHyphen)+          string "-->"+          return (Comment pos msg)++endTag:: Script s => CharParser [Warning] (Token s)+endTag  = do+  pos <- getPosition+  string "</"+  name <- qname <?> "closing tag\'s name"+  junk <- manyTill anyChar (char '>') -- permits junk between tag name and '>'+  unless (null junk) (warn $ "extra characters: " ++ junk ++ +                             "; assuming tag name is " ++ name)+  return (EndTag pos name)+  +doctype:: Script s => CharParser [Warning] (Token s)+doctype = do+  p <- getPosition+  try (string "<!DOCTYPE")+  spaces+  top <- qname <?> "top-element name"+  spaces+  avail <- qname <?> "availability"+  spaces+  regEtc <- quotedString <?> "registration, etc."+  spaces+  uri <- optionMaybe quotedString+  spaces+  string ">"+  return (DoctypeToken p top avail regEtc uri)+  +entity:: Script s => CharParser [Warning] (Token s)+entity = do+  char '&'+  pos <- getPosition+  name <- many alphaNum <|> (char '#' >> many1 digit)+  when (null name) (warn "no identifer or number after &")+  (char ';' >> return ()) <|> (warn "expected semi-colon after entity") +  return (EntityToken pos name)+  +notScript:: CharParser a Char+notScript = try (char '{' >> notFollowedBy (char '!') >> return '{')++-- Parses raw text, upto an opening angle-bracket ('<').+text:: Script s => CharParser st (Token s)+text = do+  pos  <- getPosition+  cs <- many1 (noneOf "<{" <|> notScript) -- Doesn't consume the terminating angle bracket.+  return (Text pos cs)++-- Strings that are either double-quoted or single-quoted.  Note that HTML+-- strings contain no escape sequences.+quotedString:: CharParser a String+quotedString =+  (char '"' >> manyTill anyChar (char '"')) <|>+  (char '\'' >> manyTill anyChar (char '\'')) <?>+  "quoted string (double-quotes or single quotes)"++-- Parses text to the right of a triple-stick in an inline expression.  We have+-- to ensure that if we read a `!,' it isn't immediately followed by `}.'+initText =+  let notEnd = try (char '!' >> notFollowedBy (char '}') >> return '!')+    in many1 (notEnd <|> noneOf "!")++scriptValue:: Script s => CharParser a (s,String)+scriptValue =+  case parseAttributeScript of+    Nothing -> fail "attribute-script parser not defined"+    (Just parser) -> do string "{!"+                        script <- parser+                        init <- (string "!}" >> return "")  <|> +                                (string "|||" >> initText >>= +                                 (\s -> string "!}" >> return s))+                        return (script,init)++number:: CharParser a String+number = many1 digit++-- +nonquotedAttribute:: CharParser [Warning]  String+nonquotedAttribute = do+  x <- alphaNum <|> oneOf "_"+  xs <- many (noneOf "/*=<>\"\'  \v\f\t\r\n")+  warn $ "non-quoted attribute value: " ++ (x:xs)+  return (x:xs)+++attribute:: Script s => CharParser [Warning] (Html.Attribute SourcePos s)+attribute = do+  pos  <- getPosition+  name <- qname <?> "attribute name"+  spaces+  value <- (do char '='+               spaces+               (liftM Right scriptValue)+                 <|> (liftM Left (quotedString <|> nonquotedAttribute)) +                 <?> "attribute value")+           <|> (return $ Left "") -- Unspecified values are empty values.+  case value of+    (Left v)      -> return $ Html.Attribute name v pos+    (Right (s,d)) -> return $ Html.AttributeExpr pos name s d++-- Takes the name of the immediately-enclosing parent tag as an argument.+tag:: Script s => CharParser [Warning] (Token s)+tag = do+  try (char '<' >> notFollowedBy (char '/'))+  pos <- getPosition+  name <- qname <?>  "opening tag\'s name"+  spaces+  attributes <- (attribute `sepEndBy` spaces)+  (char '>' >> return (Tag pos name attributes False))+    <|> (string "/>" >> return (Tag pos name attributes True))+    <?> "end of tag (i.e. \">\")"+++-- Parses an inline (curly-banged) script, if an inline-script parser has been+-- specified (i.e. not Nothing).  Two-character lookahead for the ``{!,'' after+-- which control is passed to the inline script parser.  Once control returns,+-- the parser expects to see the closing ``!}.''+inlineScript:: Script s => CharParser a (Token s)+inlineScript =+  case parseInlineScript of+    Nothing -> fail "no inline script parser specified." -- TODO: appropriate?+    (Just parser) -> do string "{!" <?> "{! script !}"+                        pos <- getPosition+                        script <- parser+                        spaces+                        init <- (string "!}" >> return "") <|>+                                (string "|||" >> initText >>= +                                 (\s -> string "!}" >> return s))+                        return $ Inline pos script init+++-- Parses a stream of tokens, with a script parser, s and returns values of +-- type a.+type TokenParser s a = GenParser (Token s) [Warning] a++instance Script s => Show (Token s) where+  show = tokenShow++tokenShow token = case token of+  (Text _ s)        -> s+  (EntityToken _ s) -> "&" ++ s ++ ";"+  (EntityInt _ n)   -> "&#" ++ show n ++ ";"+  (Tag _ id attrs closed) -> +    "<" ++ id ++ " ... " ++ closing where+      closing = if closed then "/>" else ">"+  (Script _ s)  -> "/* script body omitted */"+  (Inline _ s _)-> "{! /* script */ !}"+  (EndTag _ id) -> "</" ++ show id ++ ">"+  (Comment _ s) -> "<!-- " ++ show s ++ " -->"+  (DoctypeToken _ top avail desc Nothing) ->+    "<!DOCTYPE " ++ top ++ " " ++ avail ++ " " ++ show desc ++ ">"+  (DoctypeToken _ top avail desc (Just uri)) ->+    "<!DOCTYPE " ++ top ++ " " ++ avail ++ " " ++ show desc ++ " " +      ++ show uri ++ ">" ++tokenPos tok = case tok of+  (Text p _) -> p+  (EntityToken p _) -> p+  (EntityInt p _) -> p+  (Tag p _ _ _) -> p+  (Script p _) -> p+  (Inline p _ _) -> p+  (EndTag p _) -> p+  (Comment p _) -> p+  (DoctypeToken p _ _ _ _) -> p+    +textToken :: Script s => TokenParser s (ParsedHtml s)+textToken = Parsec.token tokenShow tokenPos $ \t -> case t of+  Text _ s -> Just (Html.Text s (tokenPos t))+  otherwise -> Nothing+             +entityToken :: Script s => TokenParser s (ParsedHtml s)+entityToken =+  Parsec.token tokenShow tokenPos+    (\t -> case t of+             (EntityToken p s) -> Just (Html.Text ("&" ++ s ++ ";") p)+             (EntityInt p n) -> Just (Html.Text ("&#" ++ show n ++ ";") p)+             otherwise -> Nothing)+           +commentToken :: Script s => TokenParser s (ParsedHtml s)+commentToken = +  Parsec.token tokenShow tokenPos+    (\t -> case t of+             (Comment _ s) -> Just (Html.Comment s (tokenPos t))+             otherwise -> Nothing)++scriptToken :: Script s => TokenParser s (ParsedHtml s) +scriptToken = +  Parsec.token tokenShow tokenPos+    (\t -> case t of+             (Script p s) -> Just (Html.Script s p)+             otherwise    -> Nothing)++inlineToken :: Script s => TokenParser s (ParsedHtml s)+inlineToken = +  Parsec.token tokenShow tokenPos+    (\t -> case t of+             (Inline p s d) -> Just (Html.InlineScript s p d)+             otherwise    -> Nothing)+             +endToken :: Script s => TokenParser s HtmlId+endToken = +  Parsec.token tokenShow tokenPos+    (\t -> case t of+             (EndTag p s) -> Just s+             otherwise    -> Nothing)++tagToken :: Script s => TokenParser s (Token s)+tagToken = +  Parsec.token tokenShow tokenPos+  (\t -> case t of+           (Tag p id attrs closed) -> Just t+           otherwise               -> Nothing)++doctypeToken :: Script s => TokenParser s (Token s)+doctypeToken = Parsec.token tokenShow tokenPos $ \t -> case t of+  DoctypeToken _ _ _ _ _ -> Just t+  otherwise -> Nothing++--------------------------------------------------------------------------------+-- HTML fragments++-- |An HTML fragment represents an HTML element with a sequence of children.+data HtmlFragment s = Fragment {+  fragmentPosition   :: SourcePos,+  fragmentName       :: HtmlId,+  fragmentAttributes :: [ParsedAttribute s],+  fragmentChildren   :: [ParsedHtml s]+}++closeFragment:: HtmlFragment s -> ParsedHtml s+closeFragment (Fragment p htmlId attrs children) =  +  Html.Element htmlId attrs (reverse children) p++appendChildToFragment child fragment =+  fragment { fragmentChildren = child : (fragmentChildren fragment) }+             +atomic :: Script s => TokenParser s (ParsedHtml s)+atomic =+  textToken <|> commentToken <|> scriptToken <|> inlineToken <|> entityToken+++maybeClose :: Script s => [HtmlFragment s] -> TokenParser s [HtmlFragment s] +maybeClose es = do+  htmlId <- endToken+  let close [] = do +        warn $ "unmatched closing tag \"" ++ htmlId ++ "\"; ignoring"+        return es+      close (e:e2:es) | fragmentName e == htmlId = do+        return $ (appendChildToFragment (closeFragment e) e2) : es+      close (e:e2:es) | otherwise = +        let e2' = appendChildToFragment (closeFragment e) e2+          in close (e2':es)+      close [e] | fragmentName e == htmlId = do+        return [e]+      close [e] | otherwise = do+        warn $ "unmatched closing tag \"" ++ htmlId ++ "\"; ignoring"+        return [e]+    in close es++open :: Script s => [HtmlFragment s] -> TokenParser s [HtmlFragment s]+open [] = fail "PermissiveParser.open: invalid state (1)"+open (e:es) = do+  (Tag p id attrs isClosed) <- tagToken+  case isClosed of+    True -> return $ (appendChildToFragment (Html.Element id attrs [] p) e) : es+    False ->+      case isEmptyElement id of+        True -> do warn $ "empty-element, \"" ++ id +                            ++ "\" was not immediately closed"+                   return $ (appendChildToFragment (Html.Element id attrs [] p)+                               e) : es+        False -> do+          let fragment = Fragment p id attrs []+              -- If we reach the root, simply make 'fragment' a child.+          let insert [root] = [fragment,root]+              -- The <html> element is the only child of the root.  This+              -- catches all other elements and makes them children of <html>.+              insert [html,root] = [fragment,html,root]+              insert (e1:e2:es) | id `isLegalChildOf` (fragmentName e1) =+                fragment:e1:e2:es+              insert (e1:e2:es) | otherwise =+                insert $ (appendChildToFragment (closeFragment e1) e2):es +              insert [] = fail "PermissiveParser.open: invalid state (2)"+          return $ insert (e:es)++structured es = do+  maybeClose es <|> open es++html' :: Script s => [HtmlFragment s] -> TokenParser s [HtmlFragment s]+html' [] = fail "PermissiveParser.html': invalid state (1)"+html' (e:es) =+  (do a <- atomic+      html' $ (appendChildToFragment a e):es) <|>+  (structured (e:es) >>= html') <|>+  (return (e:es))++parseRoot = Fragment (error "parseRoot: position is meaningless") +                     "DOCROOT"  (error "parseRoot: attributes are meaningless")+                     []++html :: Script s => CharParser [Warning] (Html.Html SourcePos s)+html = do+  let parser = do+        -- optional doctypeToken -- ignored+        fragments <- html' [parseRoot]+        case fragments of+          [fragment] -> case closeFragment fragment of +                          Html.Element _ _ (c:_) _ -> do+                            ws <- getState+                            return (ws,head [c])+                          otherwise -> fail "root element not found"+          otherwise -> fail "no root / multiple roots"+  toks <- tokens -- a stream of HTML entities+  pos <- Parsec.getPosition+  warnings <- Parsec.getState+  case Parsec.runParser parser warnings (Parsec.sourceName pos) toks of+    Left e -> fail  $ "unparsable HTML: " ++ (show e)+    Right (ws,html) -> Parsec.setState ws >> return html ++htmlWithWarnings :: Script s +                 => CharParser [Warning] (Html.Html SourcePos s,[Warning])+htmlWithWarnings = do+  h <- html+  ws <- getState+  return (h,ws)++parseHtmlFromString :: Script s => String -> String -> Either Parsec.ParseError (Html.Html SourcePos s,[Warning])+parseHtmlFromString sourceName sourceText = +  case Parsec.runParser htmlWithWarnings noWarnings sourceName sourceText of+    Left err -> Left err+    Right (html,ws) -> Right (html,ws) ++parseHtmlFromFile :: Script s +                  => String +                  -> IO (Either Parsec.ParseError +                                (Html.Html SourcePos s,[Warning]))+parseHtmlFromFile filename = do+  chars <- readFile filename+  case Parsec.runParser htmlWithWarnings noWarnings filename chars of+    Left err -> return (Left err)+    Right (html,ws) -> return $ Right (html,ws)
+ src/BrownPLT/Html/PrettyPrint.hs view
@@ -0,0 +1,53 @@+-- |Pretty-printer for HTML.  This modules exports no names.  It only defines+-- instances of 'PrettyPrintable' for HTML. +module BrownPLT.Html.PrettyPrint+  ( html+  , renderHtml+  ) where++import qualified Data.List as List+import qualified Data.Char as Char+import Text.PrettyPrint.HughesPJ++import BrownPLT.Html.Syntax++renderHtml :: Script s => Html a s -> String+renderHtml = render.html++vert [] = empty+vert [doc] = doc+vert (doc:docs) = doc <> text "<!--" $+$+                  text "-->" <> vert docs++attr :: Script s => Attribute a s -> Doc+attr a = case a of+  Attribute name value _ ->+    text name <> equals <> doubleQuotes (text value)+  AttributeExpr _ n v "" ->+    text n <> equals <> text "{!" <+> prettyPrintScript v <+> text "!}"+  AttributeExpr _ n v d ->+    text n <> equals <> text "{!" <+> prettyPrintScript v <+> text "|||" <+> +    text d <+> text "!}"++html :: Script s => Html a s -> Doc+html x = case x of+  -- The <script> tag must be terminated by </script>.+  -- <script lang= src= /> doesn't work.+  Element name attrs children _ ->+    -- WARNING: Spacing is very sensitive+    text "<" <> text name <+> hsep (map attr attrs) <> text ">"  -- opening+      $$ (nest 2 (vcat (map html children)))                     -- body+      $$ text "</" <> text name <> text ">"                    -- closing+  -- Horizontally aligned material that is vertically represented in source.+  HtmlSeq xs -> vert (map html xs)+  Text str _ -> text (skipWs str) where+    skipWs str = List.dropWhile Char.isSpace str+  Comment str _ -> text "<!--" <+> text str <+> text "-->"+  ProcessingInstruction str _ -> text "<?" <> text str <> text ">"+  Script s _ -> prettyPrintScript s+  InlineScript script _ "" ->+    text "{!" <+> prettyPrintScript script <+> text "!}"+  InlineScript script _ init -> +    text "{!" <+> prettyPrintScript script <+> text "|||" <+> +    text init <+> text "!}"+
+ src/BrownPLT/Html/RawScript.hs view
@@ -0,0 +1,35 @@+module BrownPLT.Html.RawScript+  ( RawScript (..)+  , parseFromFile+  , parseFromString+  , RawHtml+  ) where++import Data.Generics (Data, Typeable)+import Text.PrettyPrint.HughesPJ (text)+import Text.ParserCombinators.Parsec+import BrownPLT.Html.Syntax+import BrownPLT.Html.PermissiveParser++type RawHtml = Html SourcePos RawScript+++data RawScript = RawScript String deriving (Show,Eq,Typeable,Data)+++instance Script RawScript where++  prettyPrintScript (RawScript s) = text s+  parseInlineScript = Nothing+  +  parseAttributeScript = Nothing+  +  parseScriptBlock _ = do+    s <- manyTill anyChar (string "</script>")+    return (RawScript s)+    ++parseFromString :: String -> RawHtml+parseFromString s = case parseHtmlFromString "" s of+  Left e -> error (show e)+  Right (html,_) -> html
+ src/BrownPLT/Html/Syntax.hs view
@@ -0,0 +1,86 @@+-- |Datatypes for HTML parameterized over an annotation type and a script type.+module BrownPLT.Html.Syntax +  (+  -- * HTML Data Structures+    HtmlId,AttributeValue, Attribute (..), Html (..)+  -- * The Script class+  , Script (..)+  -- * Miscellaneous Functions+  , attributeValue, attributeUpdate, attributeSet, isAttributeExpr+  ) where++import Text.ParserCombinators.Parsec (CharParser, SourcePos)+import Text.PrettyPrint.HughesPJ (Doc)+import Data.Generics (Data, Typeable)++--------------------------------------------------------------------------------+-- Types++type HtmlId = String+type AttributeValue = String++data Attribute a s+  = Attribute HtmlId AttributeValue a+  | AttributeExpr a HtmlId s String+  deriving (Show,Eq,Typeable,Data)++data Html a sc+  = Element HtmlId [Attribute a sc] [Html a sc] a+  | Text String a+  | Comment String a+  | HtmlSeq [Html a sc] -- ^must be a non-empty list+  | ProcessingInstruction String a+  | InlineScript sc a String+  | Script sc a+  deriving (Show,Eq,Typeable,Data)+  +--------------------------------------------------------------------------------+-- The Script class++-- |A type 't' of the 'Script' class can be parsed using 'Parsec'.  't' is of+-- kind '* -> *', as the parsed AST should be annotated with souce locations+-- (see 'Text.ParserCombinators.Parsec.SourcePos').+--+-- The big deal here is that we can embed a parser for some scripting language,+-- (e.g. Javascript) into this HTML parser with ease, while preserving source+-- locations.  The Html datatype is parameterized over a script parser (an+-- instance of Script).+class Script t where+  prettyPrintScript :: t -> Doc+  parseScriptBlock:: [Attribute SourcePos t] -> CharParser a t+  -- An inline script parser, which may be Nothing if the scripting language+  -- does not support inline scripts.+  parseInlineScript:: Maybe (CharParser a t)+  -- A parser for script-expressions defined inline as attribute values.+  parseAttributeScript:: Maybe (CharParser a t)+  +--------------------------------------------------------------------------------+-- HTML navigation++isAttributeExpr (AttributeExpr _ _ _ _) = True+isAttributeExpr _                       = False++-- |Returns the value of the attribute in the list, or 'Nothing' if it doesn't+-- exist of the value is an inline-expression.+attributeValue:: HtmlId -> [Attribute a s] -> Maybe String+attributeValue name [] = Nothing+attributeValue name ((AttributeExpr pos name' expr init):rest) =+  if name == name' then Nothing+                   else attributeValue name rest+attributeValue name ((Attribute name' value _):rest) =+  if name == name' then Just value+                   else attributeValue name rest++attributeSet:: HtmlId -> String -> [Attribute a s]  -> [Attribute a s]+attributeSet n v attrs = attributeUpdate n (\_ -> v) attrs++attributeUpdate:: HtmlId -> (String -> String) -> [Attribute a s] +               -> [Attribute a s]+attributeUpdate n f [] = +  [Attribute n (f "") (error "attributeUpdate--no value")] -- TODO: undefined?!+attributeUpdate n _ ((AttributeExpr _ _ _ _):_) =+  error $ "attributeUpdate: " ++ n ++ " is an expression-attribute."+attributeUpdate n f ((Attribute n' v p):attrs) =+  if n' == n then (Attribute n (f v) p):attrs+             else (Attribute n' v p):(attributeUpdate n f attrs)+
+ src/BrownPLT/JavaScript.hs view
@@ -0,0 +1,17 @@+-- |Re-exports commonly used modules.+module BrownPLT.JavaScript+  ( module BrownPLT.JavaScript.Syntax+  , module BrownPLT.JavaScript.HtmlEmbedding+  , module BrownPLT.JavaScript.Parser+  -- JavaScript.Instances exports nothing+  , renderStatements+  , renderExpression+  ) where+++import BrownPLT.JavaScript.Syntax+import BrownPLT.JavaScript.Parser+import BrownPLT.JavaScript.PrettyPrint+import BrownPLT.JavaScript.HtmlEmbedding++import BrownPLT.JavaScript.Instances
+ src/BrownPLT/JavaScript/Crawl.hs view
@@ -0,0 +1,102 @@+-- |Crawls an HTML page for JavaScript+module BrownPLT.JavaScript.Crawl +  ( getPageJavaScript+  ) where++import Control.Monad+import Data.List+import Data.Char (toLower)+import Data.Generics+import System.IO+import Text.ParserCombinators.Parsec.Pos (SourcePos, sourceName)+import Text.ParserCombinators.Parsec(parse,setPosition,incSourceColumn,Column,sourceLine,sourceColumn)++import BrownPLT.Html.Syntax+import qualified BrownPLT.JavaScript as Js+++instance Typeable SourcePos where+  typeOf _  = +    mkTyConApp (mkTyCon "Text.ParserCombinators.Parsec.Pos.SourcePos") []++ +-- Complete guesswork.  It seems to work.+-- This definition is incomplete.+instance Data SourcePos where+  -- We treat source locations as opaque.  After all, we don't have access to+  -- the constructor.+  gfoldl k z pos = z pos+  toConstr _ = sourcePosConstr1 where+    sourcePosConstr1 = mkConstr sourcePosDatatype "SourcePos" [] Prefix+    sourcePosDatatype = mkDataType "SourcePos" [sourcePosConstr1]+  gunfold   = error "gunfold is not defined for SourcePos"+  dataTypeOf = error "dataTypeOf is not defined for SourcePos"+++-- |Returns the source of the script.+scriptSrc:: Js.ParsedJsHtml -> [String]+scriptSrc (Element tag attrs _ _) | (map toLower tag) == "script" =+  case attributeValue "src" attrs of -- TODO: Check for type="javascript"?+    Just ""  -> []+    Just url -> [url]+    Nothing  -> []+scriptSrc _ =+  []+++-- |Returns a list of URIs for external Javascript files referenced in the page.+importedScripts:: Js.ParsedJsHtml -> [String]+importedScripts = everything (++) (mkQ [] scriptSrc)++-- |Returns the top-level statements of a script.+scriptText :: Js.ParsedJsHtml -> [Js.ParsedStatement]+scriptText (Script (Js.Script _ stmts) _) = stmts+scriptText _ = []++eventHandlers :: [String]+eventHandlers = ["onload","onclick"]; +-- ,"onmousemove","onmouseover","onmousedown","onmouseout","onmouseup","onselectstart", "onkeypress"]++attrScript :: Attribute SourcePos Js.ParsedJavaScript +           -> IO [Js.ParsedStatement]+attrScript (Attribute id val loc) | id `elem` eventHandlers = do+  let eventId = drop 2 id -- drop the "on" prefix+  let scriptText = if "javascript:" `isPrefixOf` val then drop 11 val else val+  let eventListenerPrefix = "addEventListener('" ++ eventId ++ "', function(event) { "+  let prefixLen = length eventListenerPrefix+  let eventListenerText = eventListenerPrefix ++ scriptText ++ " });"+  let parser = do+        setPosition (incSourceColumn loc (-prefixLen))+        Js.parseExpression+  case parse parser (sourceName loc) eventListenerText of+    Left err -> do+      fail $ "Error parsiing JavaScript in an attribute at " ++ show loc +++             "\nThe script was:\n\n" ++ eventListenerText+    Right e -> return [Js.ExprStmt loc e]+attrScript _ = return []++inpageAttrScripts :: Js.ParsedJsHtml -> IO [Js.ParsedStatement]+inpageAttrScripts = everything (liftM2 (++)) (mkQ (return []) attrScript)++inpageScripts :: Js.ParsedJsHtml -> [Js.ParsedStatement]+inpageScripts = everything (++) (mkQ [] scriptText)++parseJsFile path = do+  text <- readFile path+  case Js.parseScriptFromString path text of+    Left err -> fail (show err)+    Right js -> hPutStrLn stderr ("Read file " ++ path) >> return js++-- |Given an HTML page, crawls all external Javascript files and returns a list+-- of statements, concatenated from all files.+getPageJavascript:: Js.ParsedJsHtml -> IO [Js.ParsedStatement]+getPageJavascript page = do+  let importURIs = importedScripts page+  let inpageJs   = inpageScripts page+  attrScripts <- inpageAttrScripts page+  importedScripts <- mapM parseJsFile importURIs+  let unScript (Js.Script _ ss) = ss+  return $ (concatMap unScript importedScripts ++ attrScripts) ++ inpageJs++getPageJavaScript:: Js.ParsedJsHtml -> IO [Js.ParsedStatement] -- monomorphism+getPageJavaScript = getPageJavascript
+ src/BrownPLT/JavaScript/Environment.hs view
@@ -0,0 +1,146 @@+module BrownPLT.JavaScript.Environment+  ( env+  , localVars+  , EnvTree (..)+  ) where++import Data.List+import Data.Maybe+import qualified Data.Map as M+import Data.Map (Map)+import qualified Data.Set as S+import Data.Set (Set)+import Text.ParserCombinators.Parsec.Pos (SourcePos)++import BrownPLT.JavaScript.Syntax++-- Intermediate data structure that contains locally declared names and+-- all references to identifers.+data Partial = Partial {+  partialLocals :: M.Map String SourcePos,+  partialReferences :: M.Map String SourcePos,+  partialNested :: [Partial]+}++empty :: Partial+empty = Partial M.empty M.empty []++ref :: Id SourcePos -> Partial+ref (Id p v) = Partial M.empty (M.singleton v p) []++decl :: Id SourcePos -> Partial+decl (Id p v) = Partial (M.singleton v p) M.empty []++nest :: Partial -> Partial+nest partial = Partial M.empty M.empty [partial]++-- Combine partial results from the same lexical scope.+unions :: [Partial] -> Partial+unions ps = Partial (M.unions (map partialLocals ps))+                    (M.unions (map partialReferences ps))+                    (concatMap partialNested ps)++javascript :: JavaScript SourcePos -> Partial+javascript (Script _ ss) = unions (map stmt ss)++expr :: Expression SourcePos -> Partial+expr e = case e of+  StringLit _ _ -> empty+  RegexpLit _ _ _ _ -> empty+  NumLit _ _ -> empty+  IntLit _ _ -> empty+  BoolLit _ _ -> empty+  NullLit _ -> empty+  ArrayLit _ es -> unions (map expr es)+  ObjectLit _ props -> unions (map (expr.snd) props)+  ThisRef _ -> empty+  VarRef _ id -> empty+  DotRef _ e _ -> expr e+  BracketRef _ e1 e2 -> unions [expr e1, expr e2]+  NewExpr _ e1 es -> unions [expr e1, unions $ map expr es]+  PostfixExpr _ _ e -> expr e+  PrefixExpr _ _ e -> expr e+  InfixExpr _ _ e1 e2 -> unions [expr e1, expr e2]+  CondExpr _ e1 e2 e3 -> unions [expr e1, expr e2, expr e3]+  AssignExpr _ _ (VarRef _ id) e -> unions [ref id, expr e]+  AssignExpr _ _ e1 e2 -> unions [expr e1, expr e2]+  ParenExpr _ e -> expr e+  ListExpr _ es -> unions (map expr es)+  CallExpr _ e es -> unions [expr e, unions $ map expr es]+  FuncExpr _ args s -> nest $ unions [unions $ map decl args, stmt s]++caseClause :: CaseClause SourcePos -> Partial+caseClause cc = case cc of+  CaseClause _ e ss -> unions [expr e, unions $ map stmt ss]+  CaseDefault _ ss -> unions $ map stmt ss++-- TODO: Verify that this is a declaration and not a reference.+catchClause :: CatchClause SourcePos -> Partial+catchClause (CatchClause _ id s) = unions [decl id, stmt s]++varDecl :: VarDecl SourcePos -> Partial+varDecl (VarDecl _ id Nothing) = decl id+varDecl (VarDecl _ id (Just e)) = unions [decl id, expr e]+ +forInit :: ForInit SourcePos -> Partial+forInit fi = case fi of+  NoInit -> empty+  VarInit ds -> unions $ map varDecl ds+  ExprInit e -> expr e ++forInInit :: ForInInit SourcePos -> Partial+forInInit (ForInVar id) = decl id+forInInit (ForInNoVar id) = ref id+  +stmt :: Statement SourcePos -> Partial+stmt s = case s of+  BlockStmt _ ss -> unions $ map stmt ss+  EmptyStmt _ -> empty+  ExprStmt _ e -> expr e+  IfStmt _ e s1 s2 -> unions [expr e, stmt s1, stmt s2]+  IfSingleStmt _ e s -> unions [expr e, stmt s]+  SwitchStmt _ e cases -> unions [expr e, unions $ map caseClause cases]+  WhileStmt _ e s -> unions [expr e, stmt s]+  DoWhileStmt _ s e -> unions [stmt s, expr e]+  BreakStmt _ _ -> empty+  ContinueStmt _ _ -> empty+  LabelledStmt _ _ s -> stmt s+  ForInStmt _ fii e s -> unions [forInInit fii, expr e, stmt s]+  ForStmt _ fi  me1 me2 s -> +    unions [forInit fi, maybe empty expr me1, maybe empty expr me2, stmt s]+  TryStmt _ s catches ms ->+    unions [stmt s, unions $ map catchClause catches, maybe empty stmt ms]+  ThrowStmt _ e -> expr e+  ReturnStmt _ me -> maybe empty expr me+  WithStmt _ e s -> unions [expr e, stmt s]+  VarDeclStmt _ decls -> unions $ map varDecl decls+  FunctionStmt _ fnId args s ->+    unions [decl fnId, nest $ unions [unions $ map decl args, stmt s]]++-- |The statically-determinate lexical structure of a JavaScript program.+data EnvTree = EnvTree (M.Map String SourcePos) [EnvTree]++-- A 'Partial' specifies identifier references in addition to identifier+-- declarations.  We descend into a 'Partial', pushing enclosing declarations+-- in to remove references to identifiers declared in the enclosing scope.+-- Any referencs to identifiers not declared in either the current or the+-- enclosing scope are local definitions of global variables.+makeEnvTree :: Map String SourcePos -- ^enclosing environment+            -> Partial -- ^local environment and references+            -> (EnvTree,Map String SourcePos) +            -- ^environment and global definitions+makeEnvTree enclosing (Partial locals references nested) = (tree,globals) where+  nestedResults = map (makeEnvTree (locals `M.union` enclosing)) nested+  tree = EnvTree locals (map fst nestedResults)+  globals' = (references `M.difference` locals) `M.difference` enclosing+  globals = M.unions (globals':(map snd nestedResults))++env :: Map String SourcePos -- ^browser/testing environment+    -> [Statement SourcePos] +    -> (EnvTree,Map String SourcePos)+env globals program = makeEnvTree globals (unions $ map stmt program)++localVars :: [Statement SourcePos]+          -> Set String+localVars body = S.fromList (M.keys locals) where+  Partial locals _ _ = unions $ map stmt body
+ src/BrownPLT/JavaScript/HtmlEmbedding.hs view
@@ -0,0 +1,25 @@+module BrownPLT.JavaScript.HtmlEmbedding+  ( JsHtml+  , ParsedJavaScript+  , ParsedJsHtml+  ) where++import BrownPLT.Html.Syntax+import BrownPLT.JavaScript.Parser (parseScript)+import BrownPLT.JavaScript.Syntax (JavaScript)+import BrownPLT.JavaScript.PrettyPrint (javaScript)+import Text.ParserCombinators.Parsec (SourcePos)++type JsHtml a = Html SourcePos (JavaScript a)++type ParsedJavaScript = JavaScript SourcePos++type ParsedJsHtml = JsHtml SourcePos++instance Script ParsedJavaScript where+  prettyPrintScript s = javaScript s+  parseScriptBlock attrs = parseScript+  parseInlineScript = Nothing+  parseAttributeScript = Nothing+    +  
+ src/BrownPLT/JavaScript/Instances.hs view
@@ -0,0 +1,294 @@+-- |Instances of 'Foldable' and 'Traversable' for JavaScript's syntax.+module BrownPLT.JavaScript.Instances+  ( -- This module does not export any names.+  ) where++import Prelude hiding (foldr,sequence,mapM)+import qualified Prelude as Prelude++import Data.Foldable (Foldable(..))+import Data.Traversable(Traversable(..))+import Control.Applicative++import BrownPLT.JavaScript.Syntax++yfoldr:: Foldable t => (a -> b -> b) -> b -> Maybe (t a) -> b+yfoldr _ b Nothing = b+yfoldr f b (Just t) = foldr f b t++lfoldr:: Foldable t => (a -> b -> b) -> b -> [t a] -> b+lfoldr f = Prelude.foldr (flip $ foldr f)++ltraverse:: (Traversable t, Applicative f) => (a -> f b) -> [t a] -> f [t b]+ltraverse _ [] = pure []+ltraverse f (a:as) = (:) <$> traverse f a <*> ltraverse f as++ytraverse:: (Traversable t, Applicative f) +         => (a -> f b) -> Maybe (t a) -> f (Maybe (t b))+ytraverse _ Nothing = pure Nothing+ytraverse f (Just t) = Just <$> traverse f t++instance Functor Id where+  fmap f (Id a v) = Id (f a) v++instance Functor JavaScript where+  fmap f (Script a stmts) = Script (f a) (map (fmap f) stmts)+  +instance Functor Prop where+  fmap f (PropId a id) = PropId (f a) (fmap f id)+  fmap f (PropString a s) = PropString (f a) s+  fmap f (PropNum a n) = PropNum (f a) n++instance Functor Expression where+  fmap f expression = +    case expression of+      StringLit a s -> StringLit (f a) s+      RegexpLit a s g ci -> RegexpLit (f a) s g ci+      NumLit a n -> NumLit (f a) n+      IntLit a n -> IntLit (f a) n+      BoolLit a b -> BoolLit (f a) b+      NullLit a -> NullLit (f a)+      ArrayLit a es -> ArrayLit (f a) (map (fmap f) es)+      ObjectLit a pes -> ObjectLit (f a) (map f' pes) where+        f' (p,e) = (fmap f p, fmap f e)+      ThisRef a -> ThisRef (f a)+      VarRef a id -> VarRef (f a) (fmap f id)+      DotRef a e id -> DotRef (f a) (fmap f e) (fmap f id)+      BracketRef a e1 e2 -> BracketRef (f a) (fmap f e1) (fmap f e2)+      NewExpr a e es -> NewExpr (f a) (fmap f e) (map (fmap f) es)+      PostfixExpr a op e -> PostfixExpr (f a) op (fmap f e)+      PrefixExpr a op e -> PrefixExpr (f a) op (fmap f e)+      InfixExpr a op e1 e2 -> InfixExpr (f a) op (fmap f e1) (fmap f e2)+      CondExpr a e1 e2 e3 -> CondExpr (f a) (fmap f e1) (fmap f e2) (fmap f e3)+      AssignExpr a op e1 e2 -> AssignExpr (f a) op (fmap f e1) (fmap f e2)+      ParenExpr a e -> ParenExpr (f a) (fmap f e)+      ListExpr a es -> ListExpr (f a) (map (fmap f) es)+      CallExpr a e es -> CallExpr (f a) (fmap f e) (map (fmap f) es)+      FuncExpr a args s -> FuncExpr (f a) (map (fmap f) args) (fmap f s)++instance Functor CaseClause where+  fmap f (CaseClause a e ss) = CaseClause (f a) (fmap f e) (map (fmap f) ss)+  fmap f (CaseDefault a ss) = CaseDefault (f a) (map (fmap f) ss)+  +instance Functor CatchClause where+  fmap f (CatchClause a id s) = CatchClause (f a) (fmap f id) (fmap f s)++instance Functor VarDecl where+  fmap f (VarDecl a id Nothing) = VarDecl (f a) (fmap f id) Nothing+  fmap f (VarDecl a id (Just e)) = VarDecl (f a) (fmap f id) (Just $ fmap f e)+  +instance Functor ForInit where+  fmap f NoInit = NoInit+  fmap f (VarInit decls) = VarInit (map (fmap f) decls)+  fmap f (ExprInit e) = ExprInit (fmap f e)++instance Functor ForInInit where+  fmap f (ForInVar id) = ForInVar (fmap f id)+  fmap f (ForInNoVar id) = ForInNoVar (fmap f id)+  +instance Functor Statement where+  fmap f s = +    case s of+      BlockStmt a ss -> BlockStmt (f a) (map (fmap f) ss)+      EmptyStmt a -> EmptyStmt (f a)+      ExprStmt a e -> ExprStmt (f a) (fmap f e)+      IfStmt a e s1 s2 -> IfStmt (f a) (fmap f e) (fmap f s1) (fmap f s2)+      IfSingleStmt a e s -> IfSingleStmt (f a) (fmap f e) (fmap f s)+      SwitchStmt a e cs -> SwitchStmt (f a) (fmap f e) (map (fmap f) cs)+      WhileStmt a e s -> WhileStmt (f a) (fmap f e) (fmap f s)+      DoWhileStmt a s e -> DoWhileStmt (f a) (fmap f s) (fmap f e)+      BreakStmt a Nothing -> BreakStmt (f a) Nothing+      BreakStmt a (Just id) -> BreakStmt (f a) (Just (fmap f id))+      ContinueStmt a yid -> ContinueStmt (f a) (yid >>= return.(fmap f))+      LabelledStmt a id s -> LabelledStmt (f a) (fmap f id) (fmap f s)+      ForInStmt a init e s -> ForInStmt (f a) (fmap f init) (fmap f e)+                                (fmap f s)+      ForStmt a init yinc ytest body -> +        ForStmt (f a) (fmap f init) (yinc >>= return.(fmap f))+          (ytest >>= return.(fmap f)) (fmap f body)+      TryStmt a s cs ys -> +        TryStmt (f a) (fmap f s) (map (fmap f) cs) (ys >>= return.(fmap f))+      ThrowStmt a e -> ThrowStmt (f a) (fmap f e)+      ReturnStmt a ye -> ReturnStmt (f a) (ye >>= return.(fmap f))+      WithStmt a e s -> WithStmt (f a) (fmap f e) (fmap f s)+      VarDeclStmt a ds -> VarDeclStmt (f a) (map (fmap f) ds)+      FunctionStmt a id args s -> +        FunctionStmt (f a) (fmap f id) (map (fmap f) args) (fmap f s)++instance Foldable Id where+  foldr f b (Id a _) = f a b++instance Foldable Prop where+  foldr f b (PropId a id) = f a (foldr f b id)+  foldr f b (PropString a _) = f a b+  foldr f b (PropNum a _) = f a b+        +instance Foldable Expression where+  -- foldr:: (a -> b -> b) -> b -> Expression a -> b+  foldr f b e =+    case e of+      StringLit a _ -> f a b+      RegexpLit a _ _ _ -> f a b+      NumLit a _ -> f a b+      IntLit a _ -> f a b+      BoolLit a _ -> f a b+      NullLit a -> f a b+      ArrayLit a es -> f a (Prelude.foldr (flip $ foldr f) b es)+      ObjectLit a pes -> f a (Prelude.foldr f' b pes) where+        f' (p,e) b = foldr f (foldr f b e) p+      ThisRef a -> f a b+      VarRef a id -> f a (foldr f b id)+      DotRef a e id -> f a (foldr f (foldr f b id) e)+      BracketRef a e1 e2 -> f a (foldr f (foldr f b e2) e1)+      NewExpr a e es -> f a (foldr f (Prelude.foldr (flip $ foldr f) b es) e)+      PostfixExpr a _ e -> f a $ foldr f b e+      PrefixExpr a _ e -> f a $ foldr f b e+      InfixExpr a _ e1 e2 -> f a $ foldr f (foldr f b e2) e1+      CondExpr a e1 e2 e3 -> f a $ foldr f (foldr f (foldr f b e3) e2) e1+      AssignExpr a _ e1 e2 -> f a $ foldr f (foldr f b e2) e1+      ParenExpr a e -> f a $ foldr f b e+      ListExpr a es -> f a $ Prelude.foldr (flip $ foldr f) b es+      CallExpr a e es -> f a $ foldr f (Prelude.foldr (flip $ foldr f) b es) e+      FuncExpr a args s -> +        f a $ Prelude.foldr (flip $ foldr f) (foldr f b s) args++instance Foldable CaseClause where+  foldr f b (CaseClause a e ss) = +    f a $ foldr f (Prelude.foldr (flip $ foldr f) b ss) e+  foldr f b (CaseDefault a ss) = f a $ Prelude.foldr (flip $ foldr f) b ss+  +instance Foldable CatchClause where+  foldr f b (CatchClause a id s) = f a $ foldr f (foldr f b s) id++instance Foldable VarDecl where+  foldr f b (VarDecl a id ye) = f a $ foldr f (yfoldr f b ye) id++instance Foldable ForInit where+  foldr f b NoInit = b+  foldr f b (VarInit ds) = Prelude.foldr (flip $ foldr f) b ds+  foldr f b (ExprInit e) = foldr f b e++instance Foldable ForInInit where+ foldr f b (ForInVar id) = foldr f b id+ foldr f b (ForInNoVar id) = foldr f b id++instance Foldable Statement where+  foldr f b statement =+    case statement of+      BlockStmt a ss -> f a $ lfoldr f b ss+      EmptyStmt a -> f a b+      ExprStmt a e -> f a $ foldr f b e+      IfStmt a e s1 s2 -> f a $ foldr f (foldr f (foldr f b s2) s1) e+      IfSingleStmt a e s -> f a $ foldr f (foldr f b s) e+      SwitchStmt a e cs -> f a $ foldr f (lfoldr f b cs) e+      WhileStmt a e s -> f a $ foldr f (foldr f b s) e+      DoWhileStmt a s e -> f a $ foldr f (foldr f b e) s+      BreakStmt a yid -> f a $ yfoldr f b yid+      ContinueStmt a yid -> f a $ yfoldr f b yid+      LabelledStmt a id s -> f a $ foldr f (foldr f b s) id+      ForInStmt a init e s -> f a $ foldr f (foldr f (foldr f b s) e) init+      ForStmt a init ye1 ye2 s ->+        f a $ foldr f (yfoldr f (yfoldr f (foldr f b s) ye2) ye1) init+      TryStmt a s cs ys -> f a $ foldr f (lfoldr f (yfoldr f b ys) cs) s+      ThrowStmt a e -> f a $ foldr f b e+      ReturnStmt a ys -> f a $ yfoldr f b ys+      WithStmt a e s -> f a $ foldr f (foldr f b s) e+      VarDeclStmt a ds -> f a $ lfoldr f b ds+      FunctionStmt a id args s ->+        f a $ lfoldr f (foldr f b s) (id:args)++instance Traversable Id where+  traverse f (Id a v) = Id <$> f a <*> pure v++instance Traversable Prop where+  traverse f (PropId a id) = PropId <$> f a <*> traverse f id+  traverse f (PropString a s) = PropString <$> f a <*> pure s+  traverse f (PropNum a n) = PropNum <$> f a <*> pure n+  +instance Traversable Expression where+  traverse f expression =+    case expression of+      StringLit a s -> StringLit <$> f a <*> pure s+      RegexpLit a s g ci -> RegexpLit <$> f a <*> pure s <*> pure g <*> pure ci+      NumLit a n -> NumLit <$> f a <*> pure n+      IntLit a n -> IntLit <$> f a <*> pure n+      BoolLit a b -> BoolLit <$> f a <*> pure b+      NullLit a -> NullLit <$> f a+      ArrayLit a es -> ArrayLit <$> f a <*> ltraverse f es+      ObjectLit a ps -> ObjectLit <$> f a <*>  (zip <$> props' <*> es') where+        (props,es) = unzip ps+        props' = ltraverse f props+        es' = ltraverse f es+      ThisRef a -> ThisRef <$> f a+      VarRef a id -> VarRef <$> f a <*> traverse f id+      DotRef a e id -> DotRef <$> f a <*> traverse f e <*> traverse f id+      BracketRef a e es -> BracketRef <$> f a <*> traverse f e <*> traverse f es+      NewExpr a e es -> NewExpr <$> f a <*> traverse f e <*> ltraverse f es+      PostfixExpr a op e -> PostfixExpr <$> f a <*> pure op <*> traverse f e+      PrefixExpr a op e -> PrefixExpr <$> f a <*> pure op <*> traverse f e+      InfixExpr a op e1 e2 -> InfixExpr <$> f a <*> pure op <*> traverse f e1+                                <*> traverse f e2+      CondExpr a e1 e2 e3 ->+        CondExpr <$> f a <*> traverse f e1 <*> traverse f e2 <*> traverse f e3+      AssignExpr a op e1 e2 -> AssignExpr <$> f a <*> pure op <*> traverse f e1+        <*> traverse f e2+      ParenExpr a e -> ParenExpr <$> f a <*> traverse f e+      ListExpr a es -> ListExpr <$> f a <*> ltraverse f es+      CallExpr a e es -> CallExpr <$> f a <*> traverse f e <*> ltraverse f es+      FuncExpr a ids s -> FuncExpr <$> f a <*> ltraverse f ids <*> traverse f s++instance Traversable CaseClause where+  traverse f (CaseClause a e ss) =+    CaseClause <$> f a <*> traverse f e <*> ltraverse f ss+  traverse f (CaseDefault a ss) = +    CaseDefault <$> f a <*> ltraverse f ss++instance Traversable CatchClause where+  traverse f (CatchClause a id s) = +    CatchClause <$> f a <*> traverse f id <*> traverse f s+    +instance Traversable VarDecl where+  traverse f (VarDecl a id ye) =+    VarDecl <$> f a <*> traverse f id <*> ytraverse f ye++instance Traversable ForInit where+  traverse f NoInit = pure NoInit+  traverse f (VarInit ds) = VarInit <$> ltraverse f ds+  traverse f (ExprInit e) = ExprInit <$> traverse f e++instance Traversable ForInInit where+ traverse f (ForInVar id) = ForInVar <$> traverse f id+ traverse f (ForInNoVar id) = ForInNoVar <$> traverse f id++instance Traversable Statement where+  traverse f statement =+    case statement of+      BlockStmt a ss -> BlockStmt <$> f a <*> ltraverse f ss+      EmptyStmt a -> EmptyStmt <$> f a+      ExprStmt a e -> ExprStmt <$> f a <*> traverse f e+      IfStmt a e s1 s2 ->+        IfStmt <$> f a <*> traverse f e <*> traverse f s1 <*> traverse f s2+      IfSingleStmt a e s ->+        IfSingleStmt <$> f a <*> traverse f e <*> traverse f s+      SwitchStmt a e cs ->+        SwitchStmt <$> f a <*> traverse f e <*> ltraverse f cs+      WhileStmt a e s -> WhileStmt <$> f a <*> traverse f e <*> traverse f s+      DoWhileStmt a s e -> DoWhileStmt <$> f a <*> traverse f s <*> traverse f e+      BreakStmt a yid -> BreakStmt <$> f a <*> ytraverse f yid+      ContinueStmt a yid -> ContinueStmt <$> f a <*> ytraverse f yid+      LabelledStmt a id s -> +        LabelledStmt <$> f a <*> traverse f id <*> traverse f s+      ForInStmt a init e s ->+        ForInStmt <$> f a <*> traverse f init <*> traverse f e <*> traverse f s+      ForStmt a init yinc ytest s ->+        ForStmt <$> f a <*> traverse f init <*> ytraverse f yinc +          <*> ytraverse f ytest <*> traverse f s+      TryStmt a s cs ys ->+        TryStmt <$> f a <*> traverse f s <*> ltraverse f cs <*> ytraverse f ys+      ThrowStmt a e -> ThrowStmt <$> f a <*> traverse f e+      ReturnStmt a ys -> ReturnStmt <$> f a <*> ytraverse f ys+      WithStmt a e s -> WithStmt <$> f a <*> traverse f e <*> traverse f s+      VarDeclStmt a ds -> VarDeclStmt <$> f a <*> ltraverse f ds+      FunctionStmt a id args s ->+        FunctionStmt <$> f a <*> traverse f id <*> ltraverse f args +          <*> traverse f s 
+ src/BrownPLT/JavaScript/Lexer.hs view
@@ -0,0 +1,64 @@+{- This isn't a lexer in the sense that it provides a JavaScript token-stream.+ - This module provides character-parsers for various JavaScript tokens.+ -}+module BrownPLT.JavaScript.Lexer(lexeme,identifier,reserved,operator,reservedOp,charLiteral,+                        stringLiteral,natural,integer,float,naturalOrFloat,+                        decimal,hexadecimal,octal,symbol,whiteSpace,parens,+                        braces,brackets,squares,semi,comma,colon,dot,+                        identifierStart) where++import Prelude hiding (lex)+import Text.ParserCombinators.Parsec+import qualified Text.ParserCombinators.Parsec.Token as T++identifierStart = (letter <|> oneOf "$_")++javascriptDef =+  T.LanguageDef "/*"+                "*/"+                "//"+                False -- no nested comments+                {- Adapted from syntax/regexps.ss in Dave's code. -}+                identifierStart+                (alphaNum <|> oneOf "$_") -- identifier rest+                (oneOf "{}<>()~.,?:|&^=!+-*/%!") -- operator start+                (oneOf "=<>|&+") -- operator rest+                ["break", "case", "catch", "const", "continue", "debugger", +                 "default", "delete", "do", "else", "enum", "false", "finally",+                 "for", "function", "if", "instanceof", "in", "let", "new", +                 "null", "return", "switch", "this", "throw", "true", "try", +                 "typeof", "var", "void", "while", "with"]+                ["|=", "^=", "&=", "<<=", ">>=", ">>>=", "+=", "-=", "*=", "/=", +                 "%=", "=", ";", ",", "?", ":", "||", "&&", "|", "^", "&", +                 "===", "==", "=", "!==", "!=", "<<", "<=", "<", ">>>", ">>", +                 ">=", ">", "++", "--", "+", "-", "*", "/", "%", "!", "~", ".", +                 "[", "]", "{", "}", "(", ")","</","instanceof"]+                 True -- case-sensitive+            +lex = T.makeTokenParser javascriptDef++-- everything but commaSep and semiSep+identifier = T.identifier	 lex+reserved = T.reserved	 lex+operator = T.operator	 lex+reservedOp = T.reservedOp lex	+charLiteral = T.charLiteral lex	+stringLiteral = T.stringLiteral lex	+natural = T.natural lex	+integer = T.integer lex	+float = T.float lex	+naturalOrFloat = T.naturalOrFloat lex	+decimal = T.decimal lex	+hexadecimal = T.hexadecimal lex	+octal = T.octal lex	+symbol = T.symbol lex	+whiteSpace = T.whiteSpace lex	+parens = T.parens	 lex+braces = T.braces	 lex+squares = T.squares lex	+semi = T.semi	 lex+comma = T.comma	 lex+colon = T.colon lex	+dot = T.dot lex+brackets = T.brackets lex+lexeme = T.lexeme lex
+ src/BrownPLT/JavaScript/Parser.hs view
@@ -0,0 +1,668 @@+module BrownPLT.JavaScript.Parser+  (parseScript+  , parseExpression+  , parseString+  , parseScriptFromString+  , emptyParsedJavaScript+  , ParsedStatement+  , ParsedExpression+  , parseJavaScriptFromFile+  , parseSimpleExpr'+  , parseBlockStmt+  , parseStatement+  , StatementParser+  , ExpressionParser+  , parseAssignExpr+  ) where++import BrownPLT.JavaScript.Lexer hiding (identifier)+import qualified BrownPLT.JavaScript.Lexer as Lexer+import BrownPLT.JavaScript.Syntax+import Text.ParserCombinators.Parsec+import Text.ParserCombinators.Parsec.Expr+import Control.Monad(liftM,liftM2)+import Control.Monad.Trans (MonadIO,liftIO)+import Numeric(readDec,readOct,readHex)+import Data.Char(chr)+import Data.Char++-- We parameterize the parse tree over source-locations.+type ParsedStatement = Statement SourcePos+type ParsedExpression = Expression SourcePos+++-- These parsers can store some arbitrary state+type StatementParser state = CharParser state ParsedStatement+type ExpressionParser state = CharParser state ParsedExpression++identifier =+  liftM2 Id getPosition Lexer.identifier++--{{{ Statements++-- Keep in mind that Token.reserved parsers (exported from the lexer) do not+-- consume any input on failure.  Note that all statements (expect for labelled+-- and expression statements) begin with a reserved-word.  If we fail to parse+-- this reserved-word, no input is consumed.  Hence, we can have the massive or+-- block that is parseExpression.  Note that if the reserved-word is parsed, it +-- must be whatever statement the reserved-word indicates.  If we fail after the+-- reserved-word, we truly have a syntax error.  Since input has been consumed,+-- <|> will not try its alternate in parseExpression, and we will fail.++parseIfStmt:: StatementParser st  +parseIfStmt = do+  pos <- getPosition+  reserved "if"+  test <- parseParenExpr <?> "parenthesized test-expression in if statement"+  consequent <- parseStatement <?> "true-branch of if statement"+  optional semi -- TODO: in spec?+  ((do reserved "else"+       alternate <- parseStatement+       return (IfStmt pos test consequent alternate))+    <|> return (IfSingleStmt pos test consequent))++parseSwitchStmt:: StatementParser st+parseSwitchStmt =+  let parseDefault = do+        pos <- getPosition+        reserved "default"+        colon+        statements <- many parseStatement+        return (CaseDefault pos statements)+      parseCase = do+         pos <- getPosition+         reserved "case"+         condition <- parseListExpr+         colon+         actions <- many parseStatement+         return (CaseClause pos condition actions)+    in do pos <- getPosition+          reserved "switch"+          test <- parseParenExpr+          clauses <- braces $ many $ parseDefault <|> parseCase+          return (SwitchStmt pos test clauses)++parseWhileStmt:: StatementParser st+parseWhileStmt = do+  pos <- getPosition+  reserved "while"+  test <- parseParenExpr <?> "parenthesized test-expression in while loop"+  body <- parseStatement+  return (WhileStmt pos test body)++parseDoWhileStmt:: StatementParser st+parseDoWhileStmt = do+  pos <- getPosition+  reserved "do"+  body <- parseBlockStmt+  reserved "while" <?> "while at the end of a do block"+  test <- parseParenExpr <?> "parenthesized test-expression in do loop"+  optional semi+  return (DoWhileStmt pos body test)++parseContinueStmt:: StatementParser st+parseContinueStmt = do+  pos <- getPosition+  reserved "continue"+  pos' <- getPosition+  -- Ensure that the identifier is on the same line as 'continue.'+  id <- (if (sourceLine pos == sourceLine pos')+           then (liftM Just identifier) <|> (return Nothing)+           else return Nothing)+  return (ContinueStmt pos id)++parseBreakStmt:: StatementParser st+parseBreakStmt = do+  pos <- getPosition+  reserved "break"+  pos' <- getPosition+  -- Ensure that the identifier is on the same line as 'break.'+  id <- (if (sourceLine pos == sourceLine pos')+           then (liftM Just identifier) <|> (return Nothing)+           else return Nothing)+  optional semi           +  return (BreakStmt pos id)++parseBlockStmt:: StatementParser st+parseBlockStmt = do+  pos <- getPosition+  statements <- braces (many parseStatement)+  return (BlockStmt pos statements)++parseEmptyStmt:: StatementParser st +parseEmptyStmt = do+  pos <- getPosition+  semi+  return (EmptyStmt pos)++parseLabelledStmt:: StatementParser st+parseLabelledStmt = do+  pos <- getPosition+  -- Lookahead for the colon.  If we don't see it, we are parsing an identifier+  -- for an expression statement.+  label <- try (do label <- identifier+                   colon+                   return label)+  statement <- parseStatement+  return (LabelledStmt pos label statement)++parseExpressionStmt:: StatementParser st+parseExpressionStmt = do+  pos <- getPosition+  expr <- parseListExpr -- TODO: spec 12.4?+  optional semi+  return (ExprStmt pos expr)+++parseForInStmt:: StatementParser st+parseForInStmt =+  let parseInit = (reserved "var" >> liftM ForInVar identifier)+                  <|> (liftM ForInNoVar identifier)+    in do pos <- getPosition+          -- Lookahead, so that we don't clash with parseForStmt+          (init,expr) <- try (do reserved "for"+                                 parens (do init <- parseInit+                                            reserved "in"+                                            expr <- parseExpression+                                            return (init,expr)))+          body <- parseStatement+          return (ForInStmt pos init expr body) ++parseForStmt:: StatementParser st+parseForStmt =+  let parseInit =+        (reserved "var" >> liftM VarInit (parseVarDecl `sepBy` comma)) <|>+        (liftM ExprInit parseListExpr) <|>+        (return NoInit)+    in do pos <- getPosition+          reserved "for"+          reservedOp "("+          init <- parseInit+          semi+          test <- (liftM Just parseExpression) <|> (return Nothing)+          semi+          iter <- (liftM Just parseListExpr) <|> (return Nothing)+          reservedOp ")" <?> "closing paren"+          stmt <- parseStatement+          return (ForStmt pos init test iter stmt)++parseTryStmt:: StatementParser st+parseTryStmt =+  let parseCatchClause = do+        pos <- getPosition+        reserved "catch"+        id <- parens identifier+        stmt <- parseStatement+        return (CatchClause pos id stmt)+    in do reserved "try"+          pos <- getPosition+          guarded <- parseStatement+          catches <- many parseCatchClause+          finally <- (reserved "finally" >> liftM Just parseStatement) +                      <|> (return Nothing)+          return (TryStmt pos guarded catches finally)++parseThrowStmt:: StatementParser st+parseThrowStmt = do+  pos <- getPosition+  reserved "throw"+  expr <- parseExpression+  optional semi+  return (ThrowStmt pos expr)++parseReturnStmt:: StatementParser st+parseReturnStmt = do+  pos <- getPosition+  reserved "return"+  expr <- (liftM Just parseListExpr) <|> (return Nothing)+  optional semi+  return (ReturnStmt pos expr)++parseWithStmt:: StatementParser st+parseWithStmt = do+  pos <- getPosition+  reserved "with"+  context <- parseParenExpr+  stmt <- parseStatement+  return (WithStmt pos context stmt)++parseVarDecl = do+  pos <- getPosition+  id <- identifier+  init <- (reservedOp "=" >> liftM Just parseExpression) <|> (return Nothing)+  return (VarDecl pos id init)++parseVarDeclStmt:: StatementParser st+parseVarDeclStmt = do +  pos <- getPosition+  reserved "var"+  decls <- parseVarDecl `sepBy` comma+  optional semi+  return (VarDeclStmt pos decls)++parseFunctionStmt:: StatementParser st+parseFunctionStmt = do+  pos <- getPosition+  name <- try (reserved "function" >> identifier) -- ambiguity with FuncExpr+  args <- parens (identifier `sepBy` comma)+  body <- parseBlockStmt <?> "function body in { ... }"+  return (FunctionStmt pos name args body)++parseStatement:: StatementParser st+parseStatement = parseIfStmt <|> parseSwitchStmt <|> parseWhileStmt +  <|> parseDoWhileStmt <|> parseContinueStmt <|> parseBreakStmt +  <|> parseBlockStmt <|> parseEmptyStmt <|> parseForInStmt <|> parseForStmt+  <|> parseTryStmt <|> parseThrowStmt <|> parseReturnStmt <|> parseWithStmt +  <|> parseVarDeclStmt  <|> parseFunctionStmt+  -- labelled, expression and the error message always go last, in this order+  <|> parseLabelledStmt <|> parseExpressionStmt <?> "statement"++--}}}++--{{{ Expressions++-- References used to construct this stuff:+-- + http://developer.mozilla.org/en/docs/+--     Core_JavaScript_1.5_Reference:Operators:Operator_Precedence+-- + http://www.mozilla.org/js/language/grammar14.html+--+-- Aren't expression tables nice?  Well, we can't quite use them, because of +-- JavaScript's ternary (?:) operator.  We have to use two expression tables.+-- We use one expression table for the assignment operators that bind looser +-- than ?: (assignTable).  The terms of assignTable are ternary expressions +-- (parseTernaryExpr).  parseTernaryExpr left-factors the left-recursive+-- production for ?:, and is defined over the second expression table, +-- exprTable, which consists of operators that bind tighter than ?:.  The terms+-- of exprTable are atomic expressions, parenthesized expressions, functions and+-- array references.++--{{{ Primary expressions++parseThisRef:: ExpressionParser st+parseThisRef = do+  pos <- getPosition+  reserved "this"+  return (ThisRef pos)++parseNullLit:: ExpressionParser st+parseNullLit = do+  pos <- getPosition+  reserved "null"+  return (NullLit pos)+++parseBoolLit:: ExpressionParser st+parseBoolLit = do+    pos <- getPosition+    let parseTrueLit  = reserved "true"  >> return (BoolLit pos True)+        parseFalseLit = reserved "false" >> return (BoolLit pos False)+    parseTrueLit <|> parseFalseLit++parseVarRef:: ExpressionParser st+parseVarRef = liftM2 VarRef getPosition identifier++parseArrayLit:: ExpressionParser st+parseArrayLit = liftM2 ArrayLit getPosition (squares (parseExpression `sepBy` comma))+  +parseFuncExpr = do+  pos <- getPosition+  reserved "function"+  args <- parens (identifier `sepBy` comma)+  body <- parseBlockStmt+  return $ FuncExpr pos args body++--{{{ parsing strings++escapeChars =+ [('\'','\''),('\"','\"'),('\\','\\'),('b','\b'),('f','\f'),('n','\n'),+  ('r','\r'),('t','\t'),('v','\v'),('/','/'),(' ',' ')]++allEscapes:: String+allEscapes = map fst escapeChars++parseEscapeChar = do+  c <- oneOf allEscapes+  let (Just c') = lookup c escapeChars -- will succeed due to line above+  return c' ++parseAsciiHexChar = do+  char 'x'+  d1 <- hexDigit+  d2 <- hexDigit+  return ((chr.fst.head.readHex) (d1:d2:""))++parseUnicodeHexChar = do+  char 'u'+  liftM (chr.fst.head.readHex) +        (sequence [hexDigit,hexDigit,hexDigit,hexDigit])+        +isWhitespace ch = ch `elem` " \t"+++-- The endWith argument is either single-quote or double-quote, depending on how+-- we opened the string.+parseStringLit' endWith =+  (char endWith >> return "") <|>+  (do try (string "\\'")+      cs <- parseStringLit' endWith+      return $ "'" ++ cs) <|>+  (do char '\\'+      c <- parseEscapeChar <|> parseAsciiHexChar <|> parseUnicodeHexChar <|> +           char '\r' <|> char '\n'+      cs <- parseStringLit' endWith+      if c == '\r' || c == '\n' +        then return (c:(dropWhile isWhitespace cs)) +        else return (c:cs)) <|>+   (liftM2 (:) anyChar (parseStringLit' endWith))++parseStringLit:: ExpressionParser st+parseStringLit = do+  pos <- getPosition+  -- parseStringLit' takes as an argument the quote-character that opened the+  -- string.+  str <- lexeme $ (char '\'' >>= parseStringLit') <|> (char '\"' >>= parseStringLit')+  -- CRUCIAL: Parsec.Token parsers expect to find their token on the first+  -- character, and read whitespaces beyond their tokens.  Without 'lexeme'+  -- above, expressions like:+  --   var s = "string"   ;+  -- do not parse.+  return $ StringLit pos str++--}}}++parseRegexpLit:: ExpressionParser st+parseRegexpLit = do+  let parseFlags = do+        flags <- many (oneOf "mgi")+        return $ \f -> f ('g' `elem` flags) ('i' `elem` flags) +  let parseEscape = char '\\' >> anyChar+  let parseChar = noneOf "/"+  let parseRe = (char '/' >> return "") <|> +                (do char '\\'+                    ch <- anyChar -- TOOD: too lenient+                    rest <- parseRe+                    return ('\\':ch:rest)) <|> +                (liftM2 (:) anyChar parseRe)+  pos <- getPosition+  char '/'+  pat <- parseRe --many1 parseChar+  flags <- parseFlags+  spaces -- crucial for Parsec.Token parsers+  return $ flags (RegexpLit pos pat)+          +parseObjectLit:: ExpressionParser st+parseObjectLit =+  let parseProp = do+        -- Parses a string, identifier or integer as the property name.  I+        -- apologize for the abstruse style, but it really does make the code+        -- much shorter.+        name <- (liftM (uncurry PropString) +                       (liftM (\(StringLit p s) -> (p,s)) parseStringLit))+                <|> (liftM2 PropId getPosition identifier)+                <|> (liftM2 PropNum getPosition decimal)+        colon+        val <- parseAssignExpr+        return (name,val)+    in do pos <- getPosition+          props <- braces (parseProp `sepEndBy` comma) <?> "object literal"+          return $ ObjectLit pos props++--{{{ Parsing numbers.  From pg. 17-18 of ECMA-262.++hexLit = do+  try (string "0x")+  digits <- many1 (oneOf "0123456789abcdefABCDEF")+  [(hex,"")] <- return $ Numeric.readHex digits+  return (True, hex)++-- Creates a decimal value from a whole, fractional and exponent part.+mkDecimal:: Double -> Double -> Int -> Double+mkDecimal w f e =+  if (f >= 1.0)+    then mkDecimal w (f / 10.0) e+    else (w + f) * (10.0 ^^ e)++exponentPart = do+  oneOf "eE"+  (char '+' >> decimal) <|> (char '-' >> negate `fmap` decimal) <|> decimal++--wrap a parser's result in a Just:+jparser p = p >>= (return . Just) ++decLit = +  (do whole <- decimal+      mfrac <- option Nothing (jparser (char '.' >> decimal))+      mexp <-  option Nothing (jparser exponentPart)+      if (mfrac == Nothing && mexp == Nothing)+        then return (True, fromIntegral whole)+        else return (False, mkDecimal (fromIntegral whole) +                                      (fromIntegral (maybe 0 id mfrac))+                                      (fromIntegral (maybe 0 id mexp)))) <|>+  (do frac <- char '.' >> decimal+      exp <- option 0 exponentPart+      return (False, mkDecimal 0.0 (fromIntegral frac) (fromIntegral exp)))++parseNumLit:: ExpressionParser st+parseNumLit = do+    pos <- getPosition+    (isint, num) <- lexeme $ hexLit <|> decLit+    notFollowedBy identifierStart <?> "whitespace"+    if isint+      then return $ IntLit pos (round num) +      else return $ NumLit pos num+++------------------------------------------------------------------------------+-- Position Helper+------------------------------------------------------------------------------++withPos cstr p = do { pos <- getPosition; e <- p; return $ cstr pos e }++-------------------------------------------------------------------------------+-- Compound Expression Parsers+-------------------------------------------------------------------------------++dotRef e = (reservedOp "." >> withPos cstr identifier) <?> "property.ref"+    where cstr pos key = DotRef pos e key++funcApp e = (parens $ withPos cstr (parseExpression `sepBy` comma)) <?> "(function application)"+    where cstr pos args = CallExpr pos e args++bracketRef e = (brackets $ withPos cstr parseExpression) <?> "[property-ref]"+    where cstr pos key = BracketRef pos e key++-------------------------------------------------------------------------------+-- Expression Parsers+-------------------------------------------------------------------------------++parseParenExpr:: ExpressionParser st+parseParenExpr = withPos ParenExpr (parens parseListExpr)++-- everything above expect functions+parseExprForNew = parseThisRef <|> parseNullLit <|> parseBoolLit <|> parseStringLit +  <|> parseArrayLit <|> parseParenExpr <|> parseNewExpr <|> parseNumLit +  <|> parseRegexpLit <|> parseObjectLit <|> parseVarRef++-- all the expression parsers defined above+parseSimpleExpr' = parseThisRef <|> parseNullLit <|> parseBoolLit +  <|> parseStringLit <|> parseArrayLit <|> parseParenExpr+  <|> parseFuncExpr <|> parseNumLit <|> parseRegexpLit <|> parseObjectLit+  <|> parseVarRef++parseNewExpr =+  (do pos <- getPosition+      reserved "new"+      constructor <- parseSimpleExprForNew Nothing -- right-associativity+      arguments <- (try (parens (parseExpression `sepBy` comma))) <|> (return [])+      return (NewExpr pos constructor arguments)) <|>+  parseSimpleExpr'++parseSimpleExpr (Just e) = (do+    e' <- dotRef e <|> funcApp e <|> bracketRef e+    parseSimpleExpr $ Just e') <|> (return e)+parseSimpleExpr Nothing = do+  e <- parseNewExpr <?> "expression (3)"+  parseSimpleExpr (Just e)++parseSimpleExprForNew (Just e) = (do+    e' <- dotRef e <|> bracketRef e+    parseSimpleExprForNew $ Just e') <|> (return e)+parseSimpleExprForNew Nothing = do+  e <- parseNewExpr <?> "expression (3)"+  parseSimpleExprForNew (Just e)+    +--}}}++makeInfixExpr str constr = Infix parser AssocLeft where+  parser:: CharParser st (Expression SourcePos -> Expression SourcePos -> Expression SourcePos)+  parser = do+    pos <- getPosition+    reservedOp str+    return (InfixExpr pos constr)  -- points-free, returns a function++makePrefixExpr str constr = Prefix parser where+  parser = do+    pos <- getPosition+    (reservedOp str <|> reserved str)+    return (PrefixExpr pos constr) -- points-free, returns a function+    +mkPrefix operator constr = Prefix $ do+  pos <- getPosition+  operator+  return (\operand -> PrefixExpr pos constr operand)++makePostfixExpr str constr = Postfix parser where+  parser = do+    pos <- getPosition+    (reservedOp str <|> reserved str)+    return (PostfixExpr pos constr) -- points-free, returns a function++prefixIncDecExpr = do+  pos <- getPosition+  op <- optionMaybe $ (reservedOp "++" >> return PrefixInc) <|>+                      (reservedOp "--" >> return PrefixDec)+  case op of+    Nothing -> parseSimpleExpr Nothing+    Just op -> do+      innerExpr <- parseSimpleExpr Nothing -- TODO: must be an l-val, I think+      return (PrefixExpr pos op innerExpr)++-- apparently, expression tables can't handle immediately-nested prefixes++parsePrefixedExpr = do+  pos <- getPosition+  op <- optionMaybe $ (reservedOp "!" >> return PrefixLNot) <|> +                      (reservedOp "~" >> return PrefixBNot) <|>+                      (try (lexeme $ char '-' >> notFollowedBy (char '-')) >>+                       return PrefixMinus) <|>+                      (try (lexeme $ char '+' >> notFollowedBy (char '+')) >>+                       return PrefixPlus) <|>+                      (reserved "typeof" >> return PrefixTypeof) <|>+                      (reserved "void" >> return PrefixVoid) <|>+                      (reserved "delete" >> return PrefixDelete)+  case op of+    Nothing -> prefixIncDecExpr  -- new is treated as a simple expr+    Just op -> do+      innerExpr <- parsePrefixedExpr+      return (PrefixExpr pos op innerExpr)++exprTable:: [[Operator Char st ParsedExpression]]+exprTable = +  [+   [makePrefixExpr "++" PrefixInc,+    makePostfixExpr "++" PostfixInc],+   [makePrefixExpr "--" PrefixDec,+    makePostfixExpr "--" PostfixDec],+   [makeInfixExpr "*" OpMul, makeInfixExpr "/" OpDiv, makeInfixExpr "%" OpMod],+   [makeInfixExpr "+" OpAdd, makeInfixExpr "-" OpSub],+   [makeInfixExpr "<<" OpLShift, makeInfixExpr ">>" OpSpRShift,+    makeInfixExpr ">>>" OpZfRShift],+   [makeInfixExpr "<" OpLT, makeInfixExpr "<=" OpLEq, makeInfixExpr ">" OpGT,+    makeInfixExpr ">=" OpGEq, +    makeInfixExpr "instanceof" OpInstanceof, makeInfixExpr "in" OpIn],+   [makeInfixExpr "&" OpBAnd], +   [makeInfixExpr "^" OpBXor], +   [makeInfixExpr "|" OpBOr],+   [makeInfixExpr "&&" OpLAnd],+   [makeInfixExpr "||" OpLOr],  +   [makeInfixExpr "==" OpEq, makeInfixExpr "!=" OpNEq,+    makeInfixExpr "===" OpStrictEq, makeInfixExpr "!==" OpStrictNEq]+    ]+  +parseExpression' = +  buildExpressionParser exprTable parsePrefixedExpr <?> "simple expression"++--{{{ Parsing ternary operators: left factored++parseTernaryExpr':: CharParser st (ParsedExpression,ParsedExpression)+parseTernaryExpr' = do+    reservedOp "?"+    l <- parseAssignExpr+    colon+    r <- parseAssignExpr+    return $(l,r)++parseTernaryExpr:: ExpressionParser st+parseTernaryExpr = do+  e <- parseExpression'+  e' <- optionMaybe parseTernaryExpr'+  case e' of+    Nothing -> return e+    Just (l,r) -> do p <- getPosition+                     return $ CondExpr p e l r+--}}}++-- Parsing assignment operations.+makeAssignExpr str constr = Infix parser AssocRight where+  parser:: CharParser st (ParsedExpression -> ParsedExpression -> ParsedExpression)+  parser = do+    pos <- getPosition+    reservedOp str+    return (AssignExpr pos constr)++assignTable:: [[Operator Char st ParsedExpression]]+assignTable = [+  [makeAssignExpr "=" OpAssign, makeAssignExpr "+=" OpAssignAdd, +    makeAssignExpr "-=" OpAssignSub, makeAssignExpr "*=" OpAssignMul,+    makeAssignExpr "/=" OpAssignDiv, makeAssignExpr "%=" OpAssignMod,+    makeAssignExpr "<<=" OpAssignLShift, makeAssignExpr ">>=" OpAssignSpRShift,+    makeAssignExpr ">>>=" OpAssignZfRShift, makeAssignExpr "&=" OpAssignBAnd,+    makeAssignExpr "^=" OpAssignBXor, makeAssignExpr "|=" OpAssignBOr+  ]]+++parseAssignExpr:: ExpressionParser st+parseAssignExpr = buildExpressionParser assignTable parseTernaryExpr  ++parseExpression:: ExpressionParser st+parseExpression = parseAssignExpr++parseListExpr =+  liftM2 ListExpr getPosition (parseAssignExpr `sepBy1` comma)++--}}}++parseScript:: CharParser state (JavaScript SourcePos)+parseScript = do+  whiteSpace+  liftM2 Script getPosition (parseStatement `sepBy` whiteSpace)+  +parseJavaScriptFromFile :: MonadIO m => String -> m [Statement SourcePos]+parseJavaScriptFromFile filename = do+  chars <- liftIO $ readFile filename+  case parse parseScript filename chars of+    Left err               -> fail (show err)+    Right (Script _ stmts) -> return stmts+++parseScriptFromString :: String -> String +                      -> Either ParseError (JavaScript SourcePos)+parseScriptFromString src script = parse parseScript src script++emptyParsedJavaScript = +  Script (error "Parser.emptyParsedJavaScript--no annotation") []++parseString :: String -> [Statement SourcePos]+parseString str = case parse parseScript "" str of+  Left err -> error (show err)+  Right (Script _ stmts) -> stmts
+ src/BrownPLT/JavaScript/PrettyPrint.hs view
@@ -0,0 +1,239 @@+-- |Pretty-printing JavaScript.+module BrownPLT.JavaScript.PrettyPrint+  ( stmt+  , expr+  , javaScript+  , renderStatements+  , renderExpression+  ) where++import Text.PrettyPrint.HughesPJ+import BrownPLT.JavaScript.Syntax+++renderStatements :: [Statement a] -> String+renderStatements ss = render (semiSep ss)+++renderExpression :: Expression a -> String+renderExpression e = render (expr e)+++-- Displays the statement in { ... }, unless it already is in a block.+inBlock:: (Statement a) -> Doc+inBlock s@(BlockStmt _ ss) = stmt s+inBlock s                 = lbrace $+$ nest 2 (stmt s) $+$ rbrace+++-- Displays the expression in ( ... ), unless it already is in parens.+inParens:: (Expression a) -> Doc+inParens e@(ParenExpr _ _) = expr e+inParens e                 = parens (expr e)++semiSep :: [Statement a] -> Doc+semiSep ss = vcat $ map (\s -> stmt s <> semi) ss+++pp (Id _ str) = text str+++forInit :: ForInit a -> Doc+forInit t = case t of+  NoInit     -> empty+  VarInit vs -> text "var" <+> (cat $ punctuate comma $ (map varDecl vs))+  ExprInit e -> expr e+  ++forInInit :: ForInInit a -> Doc  +forInInit t = case t of+  ForInVar id   -> text "var" <+> pp id+  ForInNoVar id -> pp id+++caseClause :: CaseClause a -> Doc+caseClause (CaseClause _ e ss) =+  text "case" $+$ expr e <+> colon $$ (nest 2 (semiSep ss))+caseClause (CaseDefault _ ss) =+  text "default:" $$ (nest 2 (semiSep ss))+++catchClause :: CatchClause a -> Doc+catchClause (CatchClause _ id s) = text "catch" <+> (parens.pp) id <+> inBlock s+++varDecl :: VarDecl a -> Doc+varDecl (VarDecl _ id Nothing) = pp id+varDecl (VarDecl _ id (Just e)) = pp id <+> equals <+> expr e+++stmt :: Statement a -> Doc+stmt s = case s of+  BlockStmt _ ss -> lbrace $+$ (nest 2 (semiSep ss)) $$ rbrace+  EmptyStmt _ -> semi+  ExprStmt _ e -> expr e+  IfSingleStmt _ test cons -> text "if" <+> inParens test $$ stmt cons+  IfStmt _ test cons alt ->+    text "if" <+> inParens test $$ stmt cons $$ text "else" <+> stmt alt+  SwitchStmt _ e cases ->+    text "switch" <+> inParens e $$ +    braces (nest 2 (vcat (map caseClause cases)))+  WhileStmt _ test body -> text "while" <+> inParens test $$ (stmt body)+  ReturnStmt _ Nothing -> text "return"+  ReturnStmt _ (Just e) -> text "return" <+> expr e+  DoWhileStmt _ s e -> text "do" $$ (stmt s <+> text "while" <+> inParens e)+  BreakStmt _ Nothing ->  text "break"+  BreakStmt _ (Just label) -> text "break" <+> pp label+  ContinueStmt _ Nothing -> text "continue"+  ContinueStmt _ (Just label) -> text"continue" <+> pp label+  LabelledStmt _ label s -> pp label <> colon $$ stmt s+  ForInStmt p init e body -> +    text "for" <+> +    parens (forInInit init <+> text "in" <+> expr e) $+$ stmt body+  ForStmt _ init incr test body ->+    text "for" <+> +    parens (forInit init <> semi <+> mexpr incr <> semi <+> mexpr test) $$ +    stmt body+  TryStmt _ stmt catches finally ->+    text "try" $$ inBlock stmt $$ (vcat (map catchClause catches)) $$+    ppFinally where +       ppFinally = case finally of+        Nothing -> empty+        Just stmt -> text "finally" <> inBlock stmt+  ThrowStmt _ e -> text "throw" <+> expr e+  WithStmt _ expr s ->  text "with" <+> inParens expr $$ stmt s+  VarDeclStmt _ decls ->+    text "var" <+> (cat $ punctuate comma (map varDecl decls))+  FunctionStmt _ name args s ->+    text "function" <+> pp name <> +    (parens $ cat $ punctuate comma (map pp args)) $$ +    inBlock s+++prop :: Prop a -> Doc+prop p = case p of+  PropId _ id -> pp id+  PropString _ str -> doubleQuotes (text (jsEscape str))+  PropNum _ n -> text (show n)+++infixOp op = text $ case op of+  OpMul -> "*"+  OpDiv -> "/"+  OpMod -> "%" +  OpAdd -> "+" +  OpSub -> "-"+  OpLShift -> "<<"+  OpSpRShift -> ">>"+  OpZfRShift -> ">>>"+  OpLT -> "<"+  OpLEq -> "<="+  OpGT -> ">"+  OpGEq -> ">="+  OpIn -> "in"+  OpInstanceof -> "instanceof"+  OpEq -> "=="+  OpNEq -> "!="+  OpStrictEq -> "==="+  OpStrictNEq -> "!=="+  OpBAnd -> "&"+  OpBXor -> "^"+  OpBOr -> "|"+  OpLAnd -> "&&"+  OpLOr -> "||"+++prefixOp op = text $ case op of+  PrefixInc -> "++"+  PrefixDec -> "--"+  PrefixLNot -> "!"+  PrefixBNot -> "~"+  PrefixPlus -> "+"+  PrefixMinus -> "-"+  PrefixTypeof -> "typeof"+  PrefixVoid -> "void"+  PrefixDelete -> "delete"+++postfixOp op = text $ case op of+  PostfixInc -> "++"+  PostfixDec ->  "--"+++assignOp op = text $ case op of+  OpAssign -> "="+  OpAssignAdd -> "+="+  OpAssignSub -> "-="+  OpAssignMul -> "*="+  OpAssignDiv -> "/="+  OpAssignMod -> "%="+  OpAssignLShift -> "<<="+  OpAssignSpRShift -> ">>="+  OpAssignZfRShift -> ">>>="+  OpAssignBAnd -> "&="+  OpAssignBXor -> "^="+  OpAssignBOr -> "|="+++-- Based on:+--   http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Guide:Literals+jsEscape:: String -> String+jsEscape "" = ""+jsEscape (ch:chs) = (sel ch) ++ jsEscape chs where+    sel '\b' = "\\b"+    sel '\f' = "\\f"+    sel '\n' = "\\n"+    sel '\r' = "\\r"+    sel '\t' = "\\t"+    sel '\v' = "\\v"+    sel '\'' = "\\'"+    sel '\"' = "\\\""+    sel '\\' = "\\\\"+    sel x    = [x]+    -- We don't have to do anything about \X, \x and \u escape sequences.++ +expr :: Expression a -> Doc+expr e = case e of +  StringLit _ str ->  doubleQuotes (text (jsEscape str))+  RegexpLit _ re global ci -> +    text "/" <> text re <> text "/" <> g <> i where+      g = if global then text "g" else empty+      i = if ci then text "i" else empty+  NumLit _ n ->  text (show n)+  IntLit _ n ->  text (show n)+  BoolLit _ True ->  text "true"+  BoolLit _ False ->  text "false"+  NullLit _ ->  text "null"+  ArrayLit _ es ->  brackets $ cat $ punctuate comma (map expr es)+  ObjectLit _ xs ->  +    braces (hsep (punctuate comma (map pp' xs))) where+      pp' (n,v) =  prop n <> colon <+> expr v+  ThisRef _ ->  text "this"+  VarRef _ id ->  pp id+  DotRef _ e' id -> expr e' <> text "." <> pp id+  BracketRef _ container key -> expr container <> brackets (expr key)+  NewExpr _ constr args -> +    text "new" <+> expr constr <> +    (parens $ cat $ punctuate comma (map expr args))+  PrefixExpr _ op e' -> prefixOp op <+> expr e'+  PostfixExpr _ op e' -> expr e' <+> postfixOp op+  InfixExpr _ op left right -> expr left <+> infixOp op <+> expr right+  CondExpr _ test cons alt -> +    expr test <+> text "?" <+> expr cons <+> colon <+> expr alt+  AssignExpr _ op l r ->  expr l <+> assignOp op <+> expr r+  ParenExpr _ e' ->  parens (expr e')+  ListExpr _ es ->  cat $ punctuate comma (map expr es)+  CallExpr _ f args -> +    expr f <> (parens $ cat $ punctuate comma (map expr args))+  FuncExpr _ args body -> +    text "function" <+> +    (parens $ cat $ punctuate comma (map pp args)) $$ +    inBlock body+++mexpr :: Maybe (Expression a) -> Doc+mexpr Nothing = empty+mexpr (Just e) = expr e++javaScript :: JavaScript a -> Doc+javaScript (Script _ ss) = semiSep ss
+ src/BrownPLT/JavaScript/Syntax.hs view
@@ -0,0 +1,121 @@+-- |JavaScript's syntax.+module BrownPLT.JavaScript.Syntax(Expression(..),CaseClause(..),Statement(..),+         InfixOp(..),CatchClause(..),VarDecl(..),JavaScript(..),+         AssignOp(..),Id(..),PrefixOp(..),PostfixOp(..),Prop(..),+         ForInit(..),ForInInit(..),unId) where++import Text.ParserCombinators.Parsec(SourcePos) -- used by data JavaScript+import Data.Generics(Data,Typeable)++data JavaScript a+  -- |A script in <script> ... </script> tags.  This may seem a little silly,+  -- but the Flapjax analogue has an inline variant and attribute-inline +  -- variant.+  = Script a [Statement a] +  deriving (Show,Data,Typeable,Eq,Ord)++data Id a = Id a String deriving (Show,Eq,Ord,Data,Typeable)++unId :: Id a -> String+unId (Id _ s) = s++-- http://developer.mozilla.org/en/docs/+--   Core_JavaScript_1.5_Reference:Operators:Operator_Precedence+data InfixOp = OpLT | OpLEq | OpGT | OpGEq  | OpIn  | OpInstanceof | OpEq | OpNEq+             | OpStrictEq | OpStrictNEq | OpLAnd | OpLOr +             | OpMul | OpDiv | OpMod  | OpSub | OpLShift | OpSpRShift+             | OpZfRShift | OpBAnd | OpBXor | OpBOr | OpAdd+    deriving (Show,Data,Typeable,Eq,Ord,Enum)++data AssignOp = OpAssign | OpAssignAdd | OpAssignSub | OpAssignMul | OpAssignDiv+  | OpAssignMod | OpAssignLShift | OpAssignSpRShift | OpAssignZfRShift+  | OpAssignBAnd | OpAssignBXor | OpAssignBOr+  deriving (Show,Data,Typeable,Eq,Ord)++data PrefixOp = PrefixInc | PrefixDec | PrefixLNot | PrefixBNot | PrefixPlus+  | PrefixMinus | PrefixTypeof | PrefixVoid | PrefixDelete+  deriving (Show,Data,Typeable,Eq,Ord)+  +data PostfixOp +  = PostfixInc | PostfixDec+  deriving (Show,Data,Typeable,Eq,Ord)+  +data Prop a +  = PropId a (Id a) | PropString a String | PropNum a Integer+  deriving (Show,Data,Typeable,Eq,Ord)++data Expression a+  = StringLit a String+  | RegexpLit a String Bool {- global? -} Bool {- case-insensitive? -}+  | NumLit a Double+  | IntLit a Int+  | BoolLit a Bool+  | NullLit a+  | ArrayLit a [Expression a]+  | ObjectLit a [(Prop a, Expression a)]+  | ThisRef a+  | VarRef a (Id a)+  | DotRef a (Expression a) (Id a)+  | BracketRef a (Expression a) {- container -} (Expression a) {- key -}+  | NewExpr a (Expression a) {- constructor -} [Expression a]+  | PostfixExpr a PostfixOp (Expression a)+  | PrefixExpr a PrefixOp (Expression a)+  | InfixExpr a InfixOp (Expression a) (Expression a)+  | CondExpr a (Expression a) (Expression a) (Expression a)+  | AssignExpr a AssignOp (Expression a) (Expression a)+  | ParenExpr a (Expression a)+  | ListExpr a [Expression a]+  | CallExpr a (Expression a) [Expression a]+  | FuncExpr a [(Id a)] (Statement a)+  deriving (Show,Data,Typeable,Eq,Ord)++data CaseClause a +  = CaseClause a (Expression a) [Statement a]+  | CaseDefault a [Statement a]+  deriving (Show,Data,Typeable,Eq,Ord)+  +data CatchClause a +  = CatchClause a (Id a) (Statement a) +  deriving (Show,Data,Typeable,Eq,Ord)++data VarDecl a +  = VarDecl a (Id a) (Maybe (Expression a)) +  deriving (Show,Data,Typeable,Eq,Ord)+  +data ForInit a+  = NoInit+  | VarInit [VarDecl a]+  | ExprInit (Expression a)+  deriving (Show,Data,Typeable,Eq,Ord)++data ForInInit a+ = ForInVar (Id a)+ | ForInNoVar (Id a)+ deriving (Show,Data,Typeable,Eq,Ord)+  +  +data Statement a+  = BlockStmt a [Statement a]+  | EmptyStmt a+  | ExprStmt a (Expression a)+  | IfStmt a (Expression a) (Statement a) (Statement a)+  | IfSingleStmt a (Expression a) (Statement a)+  | SwitchStmt a (Expression a) [CaseClause a]+  | WhileStmt a (Expression a) (Statement a)+  | DoWhileStmt a (Statement a) (Expression a)+  | BreakStmt a (Maybe (Id a))+  | ContinueStmt a (Maybe (Id a))+  | LabelledStmt a (Id a) (Statement a)+  | ForInStmt a (ForInInit a) (Expression a) (Statement a)+  | ForStmt a (ForInit a)        +              (Maybe (Expression a)) -- increment+              (Maybe (Expression a)) -- test+              (Statement a)          -- body+  | TryStmt a (Statement a) {-body-} [CatchClause a] {-catches-}+      (Maybe (Statement a)) {-finally-}+  | ThrowStmt a (Expression a)+  | ReturnStmt a (Maybe (Expression a))+  | WithStmt a (Expression a) (Statement a)+  | VarDeclStmt a [VarDecl a]+  | FunctionStmt a (Id a) {-name-} [(Id a)] {-args-} (Statement a) {-body-}+  deriving (Show,Data,Typeable,Eq,Ord)  
− src/WebBits/Common.hs
@@ -1,63 +0,0 @@--- | Defines commonly used datatypes and functions.-module WebBits.Common-  ( PrettyPrintable(..)-  , L.isPrefixOf-  , SourcePos-  , sourceName-  ) where--import Data.Map (Map)-import Data.Maybe (catMaybes)-import Data.Char (toLower)-import Control.Applicative-import qualified System.IO as IO-import Control.Monad.State.Strict-import Control.Monad.Identity-import qualified Data.List as L-import Data.Generics hiding (GT)-import qualified Data.Foldable as Foldable-import Data.Foldable (Foldable)-import qualified Data.Traversable as Traversable-import Data.Traversable (Traversable, traverse)-import qualified Text.PrettyPrint.HughesPJ as Pp-import Text.ParserCombinators.Parsec.Pos (SourcePos, initialPos, sourceName)--lowercase = map toLower---- | 'PrettyPrintable' makes writing pretty-printing code for large, recursive--- data structures shorter.-class PrettyPrintable a where-  pp:: a -> Pp.Doc-  -instance PrettyPrintable a => PrettyPrintable (Maybe a) where-  pp (Just a) = pp a-  pp Nothing  = Pp.empty------------------------------------------------------------------------------------- Generics for SourcePos---- | These definitions allow us to use data structures containing 'SourcePos'--- values with generics.---- |We make 'SourcePos' an instance of 'Typeable' so that we can use it with--- generics.-instance Typeable SourcePos where-  typeOf _  = -    mkTyConApp (mkTyCon "Text.ParserCombinators.Parsec.Pos.SourcePos") []-    --- Complete guesswork.  It seems to work.-sourcePosDatatype = mkDataType "SourcePos" [sourcePosConstr1]-sourcePosConstr1 = mkConstr sourcePosDatatype "SourcePos" [] Prefix---- |We make 'SourcePos' an instance of 'Typeable' so that we can use it with--- generics.------ This definition is incomplete.-instance Data SourcePos where-  -- We treat source locations as opaque.  After all, we don't have access to-  -- the constructor.-  gfoldl k z pos = z pos-  toConstr _ = sourcePosConstr1-  gunfold   = error "gunfold is not defined for SourcePos"-  dataTypeOf = error "dataTypeOf is not defined for SourcePos"-
− src/WebBits/Data/Zipper.hs
@@ -1,274 +0,0 @@--- |A zipper for "Data.Tree".-module WebBits.Data.Zipper-  ( -  -- * Functional zipper-  -  -- $functionalZipper-  -    Tree(..)-  , Location-  , toLocation, fromLocation  -  , dfsFold -  , dfsFoldM-  , showTree--  , empty-  , up, down, left, right -- Location a -> Location a-  , replace-  , change-  , insertDown, insertLeft, insertRight-  , isTop, isChild-  , getValue-  , subTree-  , top-  , canGoLeft, canGoRight, canGoUp, canGoDown -- Location a -> Bool-  -  -- * Imperative tree construction-  -  -- $treeBuilder-  -  , ZipperT--  , nest                  -- Monad m => v -> ZipperT v m a -> ZipperT v m a-  , getNode               -- Monad m => ZipperT v m v-  , setNode               -- Monad m => v -> ZipperT v m ()-  , runZipperT-  , evalZipperT-  , execZipperT-  , shiftLeft, shiftRight   -- Monad m => ZipperT v m ()-  , shiftLeft', shiftRight' -- Monad m => ZipperT v m ()-  , withCurrentChild        -- Monad m => Zipper T v m a -> ZipperT v m a-  -  ) where--import Control.Monad-import Control.Monad.State-import Data.Tree (Tree (..), drawTree)------------------------------------------------------------------------------------ Data types!-----data Path a-  = Top-  | Split a [Tree a] (Path a) [Tree a]--data Location a = Location (Tree a) (Path a)---dfsFold :: (w -> v -> w) -- ^transforms a node 'v' using the accumulated-                         -- value 'w' from the root of the tree to 'v'-        -> w             -- ^the initial value of the accumulator at the root-        -> Tree v -        -> Tree w-dfsFold f w (Node v ts) = Node w' (map (dfsFold f w') ts)-  where w' = f w v---- |Similar to 'dfsFold', but the transformation is done in the monad 'm'.  The--- sequence of operations is depth-first, left-to-right.-dfsFoldM :: Monad m => (w -> v -> m w) -> w -> Tree v -> m (Tree w)-dfsFoldM f w (Node v ts) = do-  w'  <- f w v-  ts' <- mapM (dfsFoldM f w') ts-  return $ Node w' ts'---- Uses 'Data.Tree.drawShow'.-showTree :: Show a => Tree a -> String-showTree tree =  drawTree (fmap show tree)-  ------------------------------------------------------------------------------------ Combinators!------- $functionalZipper--- These are the core zipper functions.--empty :: a -> Tree a-empty a = Node a []--up :: Location a -> Location a-up (Location _ Top)               = error " up of Top"-up (Location t (Split v ls p rs)) = Location (Node v (reverse ls ++ (t:rs))) p--down :: Location a -> Location a-down (Location (Node v []) _)     = error "down of empty"-down (Location (Node v (t:ts)) p) = Location t (Split v [] p ts)--left :: Location a -> Location a-left (Location t Top)                   = error "left of top"-left (Location t (Split v [] p rs))     = error "left on leftmost"-left (Location t (Split v (l:ls) p rs)) = Location l (Split v ls p (t:rs))--right :: Location a -> Location a-right (Location t Top) = -  error "Data.Zipper.right : at the top"-right (Location t (Split v ls p []))     = error "right on rightmost"-right (Location t (Split v ls p (r:rs))) = Location r (Split v (t:ls) p rs)--replace :: Location a -> Tree a ->  Location a-replace (Location _ p) t = Location t p--change :: Location a -> a -> Location a-change (Location (Node _ cs) p) t = Location (Node t cs) p--insertDown :: Location a -> Tree a -> Location a-insertDown (Location (Node v ts) p) t = Location (Node v (t:ts)) p--insertDownRight :: Location a -> Tree a -> Location a-insertDownRight (Location (Node v ts) p) t = -  Location t (Split v (reverse ts) p [])--insertLeft :: Location a -> Tree a -> Location a-insertLeft (Location _ Top) _                = error "insert on top"-insertLeft (Location t (Split v ls p rs)) t' =-  Location t (Split v (t':ls) p rs)--insertRight :: Location a -> Tree a -> Location a-insertRight (Location _ Top) _                = error "insert on top"-insertRight (Location t (Split v ls p rs)) t' = -  Location t (Split v ls p (t':rs))--isTop :: Location a -> Bool-isTop (Location _ Top) = True-isTop _                = False--isChild :: Location a -> Bool-isChild = not . isTop--canGoRight :: Location a -> Bool-canGoRight (Location _ (Split _ _ _ [])) = False-canGoRight (Location _ Top) = False-canGoRight _ = True--canGoDown :: Location a -> Bool-canGoDown (Location (Node _ []) _) = False-canGoDown _                        = True--canGoLeft :: Location a -> Bool-canGoLeft (Location _ Top)              = False-canGoLeft (Location _ (Split _ [] _ _)) = False-canGoLeft _                             = True--canGoUp :: Location a -> Bool-canGoUp (Location _ Top) = False-canGoUp _                = True--getValue :: Location a -> a-getValue (Location (Node v _) _) = v--subTree :: Location a -> Tree a-subTree (Location node _) = node---- |Traverses to the top of the tree.------ @--- up.top = undefined--- top.top = top--- @-top :: Location a -> Location a-top loc@(Location _ Top) = loc-top loc@(Location _ _) = top (up loc)--toLocation :: Tree a -> Location a-toLocation t = Location t Top--fromLocation :: Location a -> Tree a-fromLocation (Location t _) = t----- $treeBuilder--- A state monad that carries a zipper.  It provides convenient methods to--- imperatively create and update a tree.------ The state monad's set method may be used to arbitrarily update the current--- location.  However, such updates can break the behavior of nest and--- withCurrentChild.  We recommend avoiding StateT.set.--type ZipperT v m a = StateT (Location v) m a---runZipperT :: Monad m => ZipperT v m a -> Location v -> m (a, Tree v)-runZipperT m l = do-  (a, Location t Top) <- runStateT m l-  return (a,t)--evalZipperT :: Monad m => ZipperT v m a -> Location v -> m a-evalZipperT m l = do-  ~(a, _) <- runStateT m l-  return a--execZipperT :: Monad m => ZipperT v m a -> Location v -> m (Tree v)-execZipperT m l = do-  ~(_, Location t Top) <- runStateT m l-  return t---- |Creates a new node as the right-most child of the current node.-nest :: Monad m -     => v -- ^value of the new right-most child -     -> ZipperT v m a -- ^computation applied to the new child -     -> ZipperT v m a -- ^returns the result of the nested computation-nest v m = do-  z <- get -  put $ insertDownRight z (empty v)-  a <- m-  z' <- get -- z' is the child of z -  put (up z')-  return a-  -getNode :: Monad m => ZipperT v m v-getNode = do-  (Location (Node v _) _)  <- get-  return v-  -setNode :: Monad m => v -> ZipperT v m ()-setNode v = do-  (Location (Node _ cs) path) <- get-  put $ Location (Node v cs) path--withCurrentChild :: Monad m -                 => ZipperT v m a -- ^computation to apply to the current child -                 -> ZipperT v m a -- ^returns the result of the nested -                                  -- computation-withCurrentChild m = do-  z <- get-  put (down z)-  a <- m-  z' <- get-  put (up z')-  return a--shiftRight :: Monad m => ZipperT v m ()-shiftRight = do-  z <- get-  put (right z)--  -shiftLeft :: Monad m => ZipperT v m ()-shiftLeft = do-  z <- get-  put (left z)---- |Silently fails to shift right if there is no right-child.-shiftRight' :: Monad m => ZipperT v m ()-shiftRight' = do-  z <- get-  when (hasRight z)-       (put (right z))---- |Silently fails to shift left if there is no left-child.-shiftLeft' :: Monad m => ZipperT v m ()-shiftLeft' = do-  z <- get-  when (hasLeft z)-       (put (left z))--hasLeft :: Location a -> Bool-hasLeft (Location _ (Split _ (_:_) _ _)) = True-hasLeft _                                = False--hasRight :: Location a -> Bool-hasRight (Location _ (Split _ _ _ (_:_))) = True-hasRight _                                = False--
− src/WebBits/Html/Html.hs
@@ -1,14 +0,0 @@--- |Rexports various modules of the HTML library.  It's best to use this in lieu--- of selectively importing the following libraries.-module WebBits.Html.Html-  ( module WebBits.Html.Syntax-  -- PermissiveParser-  , html-  , parseHtmlFromFile-  , parseHtmlFromString-  ) where-  -import WebBits.Html.Syntax-import WebBits.Html.PermissiveParser-import WebBits.Html.PrettyPrint -- no names, only instances-import WebBits.Html.Instances -- no names, only instances
− src/WebBits/Html/Instances.hs
@@ -1,66 +0,0 @@-module WebBits.Html.Instances() where--import qualified Prelude as Prelude-import Prelude (Functor,map,fmap)-import qualified Data.List as List-import qualified Data.Char as Char-import Data.Foldable-import Data.Traversable-import Control.Applicative--import WebBits.Html.Syntax--ltraverse:: (Traversable t, Applicative f) => (a -> f b) -> [t a] -> f [t b]-ltraverse f [] = pure []-ltraverse f (x:xs) = pure (:) <*> (traverse f x) <*> ltraverse f xs--instance Functor (Attribute a) where-  fmap f (Attribute id val a)            = Attribute id val a-  fmap f (AttributeExpr a id script def) = AttributeExpr a id (f script) def--instance Functor (Html a) where-  fmap f (Element id attrs children a) = -    Element id (map (fmap f) attrs) (map (fmap f) children) a-  fmap f (Text str a)                  = Text str a-  fmap f (Comment str a)               = Comment str a-  fmap f (HtmlSeq xs)                  = HtmlSeq (map (fmap f) xs)-  fmap f (ProcessingInstruction str a) = ProcessingInstruction str a-  fmap f (InlineScript script a def)   = InlineScript (f script) a def-  fmap f (Script script a)             = Script (f script) a--instance Foldable (Attribute a) where-  foldr f x (Attribute id val a)          = x-  foldr f x (AttributeExpr a id script def) = f script x--instance Foldable (Html a) where-  foldr f x (Element id attrs children a) =-    Prelude.foldr  (\child x' -> foldr f x' child) x children  -  foldr f x (Text str a)                  = x-  foldr f x (Comment str a)               = x-  foldr f x (HtmlSeq ys)                  = -    Prelude.foldr (\child x' -> foldr f x' child) x ys-  foldr f x (ProcessingInstruction str a) = x-  foldr f x (InlineScript script a def)   = f script x-  foldr f x (Script script a)             = f script x--instance Traversable (Attribute a) where-  traverse f (Attribute id val a)            =-    pure (Attribute id val a)-  traverse f (AttributeExpr a id script def) =-    (AttributeExpr a id) <$> (f script) <*> pure def--instance Traversable (Html a) where-  traverse f (Element id attrs children a) = -    (Element id) <$> ltraverse f attrs  <*> ltraverse f children <*> pure a-  traverse f (Text str a)                  = -    pure (Text str a)-  traverse f (Comment str a)               = -    pure (Comment str a)-  traverse f (HtmlSeq xs)                  = -    HtmlSeq <$> ltraverse f xs-  traverse f (ProcessingInstruction str a) = -    pure (ProcessingInstruction str a)-  traverse f (InlineScript script a def)   =-    InlineScript <$> (f script) <*> pure a <*> pure def-  traverse f (Script script a)             = -    Script <$> (f script) <*> pure a
− src/WebBits/Html/PermissiveParser.hs
@@ -1,492 +0,0 @@--- |A structure-recovering parser for malformed documents.------ Copyright 2007-2008 Arjun Guha.--- Based on HtmlPrag 0.16 Copyright (C) 2003 - 2005 Neil W. Van Dyke.  ------ This program is Free Software; you can redistribute it and/or modify it under--- the terms of the GNU Lesser General Public License as published by the Free--- Software Foundation; either version 2.1 of the License, or (at your option)--- any later version.  This program is distributed in the hope that it will be--- useful, but without any warranty; without even the implied warranty of--- merchantability or fitness for a particular purpose.  See --- <http://www.gnu.org/copyleft/lesser.html> for details.  For other license--- options and consulting, contact the author.-module WebBits.Html.PermissiveParser-  ( html-  , parseHtmlFromFile-  , parseHtmlFromString-  -- tokenizer is exported primarily for testing-  , tokens-  , Token-  ) where--import Control.Monad-import Text.ParserCombinators.Parsec hiding (token,tokens)-import qualified Text.ParserCombinators.Parsec as Parsec-import Data.Char (toLower)-import Data.List (intersperse)--import qualified WebBits.Html.Syntax as Html-import WebBits.Html.Syntax (HtmlId,Attribute,Script(..))--type ParsedHtml s = Html.Html SourcePos s-type ParsedAttribute s = Html.Attribute SourcePos s------------------------------------------------------------------------------------- Parsers generate warnings--data Warning = StringWarning SourcePos String--instance Show Warning where-  show (StringWarning p s) = "Warning parsing HTML: " ++ s-  showList [] s = s-  showList (x:xs) s = show x ++ ('\n':showList xs s)--warn:: String -> GenParser tok [Warning] ()-warn s = do-  p <- getPosition-  updateState ((StringWarning p s):)--noWarnings:: [Warning]-noWarnings = []-  ---- A structure-recovering parser for malformed documents, derived from--- Neil W. Van Dyke's htmlprag library for PLT Scheme---- The elements in the list can legally enclose the 1st element of the pair.-parentConstraints:: [(HtmlId,[HtmlId])]-parentConstraints =-  [("area",["map"]),-   ("body",["html"]),-   ("caption", ["table"]),-   ("colgroup", ["table"]),-   ("dd", ["dl"]),-   ("dt", ["dl"]),-   ("frame", ["frameset"]),-   ("head", ["html"]),-   ("isindex", ["head"]),-   ("li", ["dir", "menu", "ol", "ul"]),-   ("meta", ["head"]),-   ("noframes", ["frameset"]),-   ("option", ["select"]),-   ("p", ["body", "td", "th"]),-   ("param", ["applet"]),-   ("tbody", ["table"]),-   ("td", ["tr"]),-   ("th", ["tr"]),-   ("thead", ["table"]),-   ("title", ["head"]),-   ("tr", ["table", "tbody", "thead"])]---- |List of HTML elements that are empty.-emptyElements:: [HtmlId]-emptyElements = -  ["area", "base", "br", "frame", "hr", "img", "input", "isindex", "keygen", -   "link", "meta", "object", "param", "spacer", "wbr"]--isLegalChildOf:: HtmlId -> HtmlId -> Bool-isLegalChildOf child parent =-  case lookup child parentConstraints of-    Nothing             -> True-    (Just legalParents) -> parent `elem` legalParents-    -isEmptyElement:: HtmlId -> Bool-isEmptyElement element = element `elem` emptyElements----}}}------------------------------------------------------------------------------------- Parses an HTML file into a stream of tokens.---- The auxillary parsing functions return values of this type.-data Script s  => Token s-  = Text SourcePos String-  | EntityToken SourcePos String-  | EntityInt SourcePos Int-  | Tag SourcePos HtmlId [Attribute SourcePos s] Bool {-closed?-}-  | Script SourcePos s-  | Inline SourcePos s String-  | EndTag SourcePos HtmlId-  | Comment SourcePos String-  | DoctypeToken SourcePos String String String (Maybe String)---token:: Script s => Bool -> [Attribute SourcePos s] -     -> CharParser [Warning] (Token s)-token expectedScript prevAttrs = case expectedScript of-  True  -> (liftM2 Script getPosition (parseScriptBlock prevAttrs)) -             <?> "expected a script after a <script> tag"-  False -> doctype <|> comment <|> tag <|> endTag <|> inlineScript <|> entity -             <|> text--tokens:: Script s => CharParser [Warning] [Token s]-tokens = (eof >> return []) <|> tokens' where-  tokens' = do -    t <- token False []-    case t of-      (Tag _ "script" attrs False) -> do s <- token True attrs-                                         ts <- tokens-                                         return (t:s:ts)-      _ -> tokens >>= return.(t:)------------------------------------------------------------------------------------- Parsers for various components of HTML--qname:: CharParser st String-qname = do-  x <- letter-  xs <- many (noneOf "/*=<>\"\'  \v\f\t\r\n")-  return (x:xs)---- |We do not permit spaces between the hyphens and the right-angle in the--- terminating '-->'.-comment:: Script s => CharParser st (Token s) -comment =-  let notDoubleHyphen = try (char '-' >> notFollowedBy (char '-') >> return '-')-      notHyphen = noneOf "-"-    in do try (string "<!--")-          pos <- getPosition-          msg <- many (notHyphen <|> notDoubleHyphen)-          string "-->"-          return (Comment pos msg)--endTag:: Script s => CharParser [Warning] (Token s)-endTag  = do-  pos <- getPosition-  string "</"-  name <- qname <?> "closing tag\'s name"-  junk <- manyTill anyChar (char '>') -- permits junk between tag name and '>'-  unless (null junk) (warn $ "extra characters: " ++ junk ++ -                             "; assuming tag name is " ++ name)-  return (EndTag pos name)-  -doctype:: Script s => CharParser [Warning] (Token s)-doctype = do-  p <- getPosition-  try (string "<!DOCTYPE")-  spaces-  top <- qname <?> "top-element name"-  spaces-  avail <- qname <?> "availability"-  spaces-  regEtc <- quotedString <?> "registration, etc."-  spaces-  uri <- optionMaybe quotedString-  spaces-  string ">"-  return (DoctypeToken p top avail regEtc uri)-  -entity:: Script s => CharParser [Warning] (Token s)-entity = do-  char '&'-  pos <- getPosition-  name <- many alphaNum <|> (char '#' >> many1 digit)-  when (null name) (warn "no identifer or number after &")-  (char ';' >> return ()) <|> (warn "expected semi-colon after entity") -  return (EntityToken pos name)-  -notScript:: CharParser a Char-notScript = try (char '{' >> notFollowedBy (char '!') >> return '{')---- Parses raw text, upto an opening angle-bracket ('<').-text:: Script s => CharParser st (Token s)-text = do-  pos  <- getPosition-  cs <- many1 (noneOf "<{" <|> notScript) -- Doesn't consume the terminating angle bracket.-  return (Text pos cs)---- Strings that are either double-quoted or single-quoted.  Note that HTML--- strings contain no escape sequences.-quotedString:: CharParser a String-quotedString =-  (char '"' >> manyTill anyChar (char '"')) <|>-  (char '\'' >> manyTill anyChar (char '\'')) <?>-  "quoted string (double-quotes or single quotes)"---- Parses text to the right of a triple-stick in an inline expression.  We have--- to ensure that if we read a `!,' it isn't immediately followed by `}.'-initText =-  let notEnd = try (char '!' >> notFollowedBy (char '}') >> return '!')-    in many1 (notEnd <|> noneOf "!")--scriptValue:: Script s => CharParser a (s,String)-scriptValue =-  case parseAttributeScript of-    Nothing -> fail "attribute-script parser not defined"-    (Just parser) -> do string "{!"-                        script <- parser-                        init <- (string "!}" >> return "")  <|> -                                (string "|||" >> initText >>= -                                 (\s -> string "!}" >> return s))-                        return (script,init)--number:: CharParser a String-number = many1 digit---- -nonquotedAttribute:: CharParser [Warning]  String-nonquotedAttribute = do-  x <- alphaNum <|> oneOf "_"-  xs <- many (noneOf "/*=<>\"\'  \v\f\t\r\n")-  warn $ "non-quoted attribute value: " ++ (x:xs)-  return (x:xs)---attribute:: Script s => CharParser [Warning] (Html.Attribute SourcePos s)-attribute = do-  pos  <- getPosition-  name <- qname <?> "attribute name"-  spaces-  value <- (do char '='-               spaces-               (liftM Right scriptValue)-                 <|> (liftM Left (quotedString <|> nonquotedAttribute)) -                 <?> "attribute value")-           <|> (return $ Left "") -- Unspecified values are empty values.-  case value of-    (Left v)      -> return $ Html.Attribute name v pos-    (Right (s,d)) -> return $ Html.AttributeExpr pos name s d---- Takes the name of the immediately-enclosing parent tag as an argument.-tag:: Script s => CharParser [Warning] (Token s)-tag = do-  try (char '<' >> notFollowedBy (char '/'))-  pos <- getPosition-  name <- qname <?>  "opening tag\'s name"-  spaces-  attributes <- (attribute `sepEndBy` spaces)-  (char '>' >> return (Tag pos name attributes False))-    <|> (string "/>" >> return (Tag pos name attributes True))-    <?> "end of tag (i.e. \">\")"----- Parses an inline (curly-banged) script, if an inline-script parser has been--- specified (i.e. not Nothing).  Two-character lookahead for the ``{!,'' after--- which control is passed to the inline script parser.  Once control returns,--- the parser expects to see the closing ``!}.''-inlineScript:: Script s => CharParser a (Token s)-inlineScript =-  case parseInlineScript of-    Nothing -> fail "no inline script parser specified." -- TODO: appropriate?-    (Just parser) -> do string "{!" <?> "{! script !}"-                        pos <- getPosition-                        script <- parser-                        spaces-                        init <- (string "!}" >> return "") <|>-                                (string "|||" >> initText >>= -                                 (\s -> string "!}" >> return s))-                        return $ Inline pos script init----- Parses a stream of tokens, with a script parser, s and returns values of --- type a.-type TokenParser s a = GenParser (Token s) [Warning] a--instance Script s => Show (Token s) where-  show = tokenShow--tokenShow token = case token of-  (Text _ s)        -> s-  (EntityToken _ s) -> "&" ++ s ++ ";"-  (EntityInt _ n)   -> "&#" ++ show n ++ ";"-  (Tag _ id attrs closed) -> -    "<" ++ id ++ " ... " ++ closing where-      closing = if closed then "/>" else ">"-  (Script _ s)  -> "/* script body omitted */"-  (Inline _ s _)-> "{! /* script */ !}"-  (EndTag _ id) -> "</" ++ show id ++ ">"-  (Comment _ s) -> "<!-- " ++ show s ++ " -->"-  (DoctypeToken _ top avail desc Nothing) ->-    "<!DOCTYPE " ++ top ++ " " ++ avail ++ " " ++ show desc ++ ">"-  (DoctypeToken _ top avail desc (Just uri)) ->-    "<!DOCTYPE " ++ top ++ " " ++ avail ++ " " ++ show desc ++ " " -      ++ show uri ++ ">" --tokenPos tok = case tok of-  (Text p _) -> p-  (EntityToken p _) -> p-  (EntityInt p _) -> p-  (Tag p _ _ _) -> p-  (Script p _) -> p-  (Inline p _ _) -> p-  (EndTag p _) -> p-  (Comment p _) -> p-  (DoctypeToken p _ _ _ _) -> p-    -textToken :: Script s => TokenParser s (ParsedHtml s)-textToken = Parsec.token tokenShow tokenPos $ \t -> case t of-  Text _ s -> Just (Html.Text s (tokenPos t))-  otherwise -> Nothing-             -entityToken :: Script s => TokenParser s (ParsedHtml s)-entityToken =-  Parsec.token tokenShow tokenPos-    (\t -> case t of-             (EntityToken p s) -> Just (Html.Text ("&" ++ s ++ ";") p)-             (EntityInt p n) -> Just (Html.Text ("&#" ++ show n ++ ";") p)-             otherwise -> Nothing)-           -commentToken :: Script s => TokenParser s (ParsedHtml s)-commentToken = -  Parsec.token tokenShow tokenPos-    (\t -> case t of-             (Comment _ s) -> Just (Html.Comment s (tokenPos t))-             otherwise -> Nothing)--scriptToken :: Script s => TokenParser s (ParsedHtml s) -scriptToken = -  Parsec.token tokenShow tokenPos-    (\t -> case t of-             (Script p s) -> Just (Html.Script s p)-             otherwise    -> Nothing)--inlineToken :: Script s => TokenParser s (ParsedHtml s)-inlineToken = -  Parsec.token tokenShow tokenPos-    (\t -> case t of-             (Inline p s d) -> Just (Html.InlineScript s p d)-             otherwise    -> Nothing)-             -endToken :: Script s => TokenParser s HtmlId-endToken = -  Parsec.token tokenShow tokenPos-    (\t -> case t of-             (EndTag p s) -> Just s-             otherwise    -> Nothing)--tagToken :: Script s => TokenParser s (Token s)-tagToken = -  Parsec.token tokenShow tokenPos-  (\t -> case t of-           (Tag p id attrs closed) -> Just t-           otherwise               -> Nothing)--doctypeToken :: Script s => TokenParser s (Token s)-doctypeToken = Parsec.token tokenShow tokenPos $ \t -> case t of-  DoctypeToken _ _ _ _ _ -> Just t-  otherwise -> Nothing------------------------------------------------------------------------------------- HTML fragments---- |An HTML fragment represents an HTML element with a sequence of children.-data HtmlFragment s = Fragment {-  fragmentPosition   :: SourcePos,-  fragmentName       :: HtmlId,-  fragmentAttributes :: [ParsedAttribute s],-  fragmentChildren   :: [ParsedHtml s]-}--closeFragment:: HtmlFragment s -> ParsedHtml s-closeFragment (Fragment p htmlId attrs children) =  -  Html.Element htmlId attrs (reverse children) p--appendChildToFragment child fragment =-  fragment { fragmentChildren = child : (fragmentChildren fragment) }-             -atomic :: Script s => TokenParser s (ParsedHtml s)-atomic =-  textToken <|> commentToken <|> scriptToken <|> inlineToken <|> entityToken---maybeClose :: Script s => [HtmlFragment s] -> TokenParser s [HtmlFragment s] -maybeClose es = do-  htmlId <- endToken-  let close [] = do -        warn $ "unmatched closing tag \"" ++ htmlId ++ "\"; ignoring"-        return es-      close (e:e2:es) | fragmentName e == htmlId = do-        return $ (appendChildToFragment (closeFragment e) e2) : es-      close (e:e2:es) | otherwise = -        let e2' = appendChildToFragment (closeFragment e) e2-          in close (e2':es)-      close [e] | fragmentName e == htmlId = do-        return [e]-      close [e] | otherwise = do-        warn $ "unmatched closing tag \"" ++ htmlId ++ "\"; ignoring"-        return [e]-    in close es--open :: Script s => [HtmlFragment s] -> TokenParser s [HtmlFragment s]-open [] = fail "PermissiveParser.open: invalid state (1)"-open (e:es) = do-  (Tag p id attrs isClosed) <- tagToken-  case isClosed of-    True -> return $ (appendChildToFragment (Html.Element id attrs [] p) e) : es-    False ->-      case isEmptyElement id of-        True -> do warn $ "empty-element, \"" ++ id -                            ++ "\" was not immediately closed"-                   return $ (appendChildToFragment (Html.Element id attrs [] p)-                               e) : es-        False -> do-          let fragment = Fragment p id attrs []-              -- If we reach the root, simply make 'fragment' a child.-          let insert [root] = [fragment,root]-              -- The <html> element is the only child of the root.  This-              -- catches all other elements and makes them children of <html>.-              insert [html,root] = [fragment,html,root]-              insert (e1:e2:es) | id `isLegalChildOf` (fragmentName e1) =-                fragment:e1:e2:es-              insert (e1:e2:es) | otherwise =-                insert $ (appendChildToFragment (closeFragment e1) e2):es -              insert [] = fail "PermissiveParser.open: invalid state (2)"-          return $ insert (e:es)--structured es = do-  maybeClose es <|> open es--html' :: Script s => [HtmlFragment s] -> TokenParser s [HtmlFragment s]-html' [] = fail "PermissiveParser.html': invalid state (1)"-html' (e:es) =-  (do a <- atomic-      html' $ (appendChildToFragment a e):es) <|>-  (structured (e:es) >>= html') <|>-  (return (e:es))--parseRoot = Fragment (error "parseRoot: position is meaningless") -                     "DOCROOT"  (error "parseRoot: attributes are meaningless")-                     []--html :: Script s => CharParser [Warning] (Html.Html SourcePos s)-html = do-  let parser = do-        -- optional doctypeToken -- ignored-        fragments <- html' [parseRoot]-        case fragments of-          [fragment] -> case closeFragment fragment of -                          Html.Element _ _ (c:_) _ -> do-                            ws <- getState-                            return (ws,head [c])-                          otherwise -> fail "root element not found"-          otherwise -> fail "no root / multiple roots"-  toks <- tokens -- a stream of HTML entities-  pos <- Parsec.getPosition-  warnings <- Parsec.getState-  case Parsec.runParser parser warnings (Parsec.sourceName pos) toks of-    Left e -> fail  $ "unparsable HTML: " ++ (show e)-    Right (ws,html) -> Parsec.setState ws >> return html --htmlWithWarnings :: Script s -                 => CharParser [Warning] (Html.Html SourcePos s,[Warning])-htmlWithWarnings = do-  h <- html-  ws <- getState-  return (h,ws)--parseHtmlFromString :: Script s => String -> String -> Either Parsec.ParseError (Html.Html SourcePos s,[Warning])-parseHtmlFromString sourceName sourceText = -  case Parsec.runParser htmlWithWarnings noWarnings sourceName sourceText of-    Left err -> Left err-    Right (html,ws) -> Right (html,ws) --parseHtmlFromFile :: Script s -                  => String -                  -> IO (Either Parsec.ParseError -                                (Html.Html SourcePos s,[Warning]))-parseHtmlFromFile filename = do-  chars <- readFile filename-  case Parsec.runParser htmlWithWarnings noWarnings filename chars of-    Left err -> return (Left err)-    Right (html,ws) -> return $ Right (html,ws)
− src/WebBits/Html/PrettyPrint.hs
@@ -1,54 +0,0 @@--- |Pretty-printer for HTML.  This modules exports no names.  It only defines--- instances of 'PrettyPrintable' for HTML. -module WebBits.Html.PrettyPrint-  ( -- this module exports no names-  ) where--import qualified Data.List as List-import qualified Data.Char as Char-import Text.PrettyPrint.HughesPJ--import WebBits.Common (PrettyPrintable(..))--import WebBits.Html.Syntax--vert [] = empty-vert [doc] = doc-vert (doc:docs) = doc <> text "<!--" $+$-                  text "-->" <> vert docs--instance PrettyPrintable s => PrettyPrintable (Attribute a s) where-  pp (Attribute name value _) =-    text name <> equals <> doubleQuotes (text value)-  pp (AttributeExpr _ n v "") =-    text n <> equals <> text "{!" <+> pp v <+> text "!}"-  pp (AttributeExpr _ n v d) =-    text n <> equals <> text "{!" <+> pp v <+> text "|||" <+> text d -      <+> text "!}"--instance PrettyPrintable s => PrettyPrintable (Html a s) where-  -- The <script> tag must be terminated by </script>.-  -- <script lang= src= /> doesn't work.-  -- pp (Element name attrs [] _) =-  --   text "<" <> text name <+> hsep (map pp attrs) <+> text "/>"-  pp (Element name attrs children _) =-    -- WARNING: Spacing is very sensitive-    text "<" <> text name <+> hsep (map pp attrs) <> text ">"  -- opening-      $$ (nest 2 (vcat (map pp children)))                     -- body-      $$ text "</" <> text name <> text ">"                    -- closing-  -- Horizontally aligned material that is vertically represented in source.-  pp (HtmlSeq xs) = vert (map pp xs)-  pp (Text str _) =-    text (skipWs str) where-      skipWs str = List.dropWhile Char.isSpace str-  pp (Comment str _) =-    text "<!--" <+> text str <+> text "-->"-  pp (ProcessingInstruction str _) =-    text "<?" <> text str <> text ">"-  pp (Script script _) =-    pp script-  pp (InlineScript script _ "") =-    text "{!" <+> pp script <+> text "!}"-  pp (InlineScript script _ init) =-    text "{!" <+> pp script <+> text "|||" <+> text init <+> text "!}"-
− src/WebBits/Html/RawScript.hs
@@ -1,34 +0,0 @@-module WebBits.Html.RawScript-  ( RawScript (..)-  , parseFromFile-  , parseFromString-  , RawHtml-  ) where--import Data.Generics (Data)-import Data.Generics (Typeable)-import Text.PrettyPrint.HughesPJ (text)-import Text.ParserCombinators.Parsec-import WebBits.Common-import WebBits.Html.Html--type RawHtml = Html SourcePos RawScript--data RawScript = RawScript String deriving (Show,Eq,Typeable,Data)--instance Script RawScript where-  parseInlineScript = Nothing-  -  parseAttributeScript = Nothing-  -  parseScriptBlock _ = do-    s <- manyTill anyChar (string "</script>")-    return (RawScript s)-    -instance PrettyPrintable RawScript where-  pp (RawScript s) = text s--parseFromString :: String -> RawHtml-parseFromString s = case parseHtmlFromString "" s of-  Left e -> error (show e)-  Right (html,_) -> html
− src/WebBits/Html/Syntax.hs
@@ -1,84 +0,0 @@--- |Datatypes for HTML parameterized over an annotation type and a script type.
-module WebBits.Html.Syntax (
-  -- * HTML Data Structures
-    HtmlId,AttributeValue,Attribute(..),Html(..)
-  -- * The Script class
-  , Script(..)
-  -- * Miscellaneous Functions
-  , attributeValue,attributeUpdate,attributeSet,isAttributeExpr
-  ) where
-
-import Text.ParserCombinators.Parsec(CharParser,SourcePos)
-import Data.Generics(Data)
-import Data.Typeable(Typeable)
-
---------------------------------------------------------------------------------
--- Types
-
-type HtmlId = String
-type AttributeValue = String
-
-data Attribute a s
-  = Attribute HtmlId AttributeValue a
-  | AttributeExpr a HtmlId s String
-  deriving (Show,Eq,Typeable,Data)
-
-data Html a sc
-  = Element HtmlId [Attribute a sc] [Html a sc] a
-  | Text String a
-  | Comment String a
-  | HtmlSeq [Html a sc] -- ^must be a non-empty list
-  | ProcessingInstruction String a
-  | InlineScript sc a String
-  | Script sc a
-  deriving (Show,Eq,Typeable,Data)
-  
---------------------------------------------------------------------------------
--- The Script class
-
--- |A type 't' of the 'Script' class can be parsed using 'Parsec'.  't' is of
--- kind '* -> *', as the parsed AST should be annotated with souce locations
--- (see 'Text.ParserCombinators.Parsec.SourcePos').
---
--- The big deal here is that we can embed a parser for some scripting language,
--- (e.g. Javascript) into this HTML parser with ease, while preserving source
--- locations.  The Html datatype is parameterized over a script parser (an
--- instance of Script).
-class Script t where
-  parseScriptBlock:: [Attribute SourcePos t] -> CharParser a t
-  -- An inline script parser, which may be Nothing if the scripting language
-  -- does not support inline scripts.
-  parseInlineScript:: Maybe (CharParser a t)
-  -- A parser for script-expressions defined inline as attribute values.
-  parseAttributeScript:: Maybe (CharParser a t)
-  
---------------------------------------------------------------------------------
--- HTML navigation
-
-isAttributeExpr (AttributeExpr _ _ _ _) = True
-isAttributeExpr _                       = False
-
--- |Returns the value of the attribute in the list, or 'Nothing' if it doesn't
--- exist of the value is an inline-expression.
-attributeValue:: HtmlId -> [Attribute a s] -> Maybe String
-attributeValue name [] = Nothing
-attributeValue name ((AttributeExpr pos name' expr init):rest) =
-  if name == name' then Nothing
-                   else attributeValue name rest
-attributeValue name ((Attribute name' value _):rest) =
-  if name == name' then Just value
-                   else attributeValue name rest
-
-attributeSet:: HtmlId -> String -> [Attribute a s]  -> [Attribute a s]
-attributeSet n v attrs = attributeUpdate n (\_ -> v) attrs
-
-attributeUpdate:: HtmlId -> (String -> String) -> [Attribute a s] 
-               -> [Attribute a s]
-attributeUpdate n f [] = 
-  [Attribute n (f "") (error "attributeUpdate--no value")] -- TODO: undefined?!
-attributeUpdate n _ ((AttributeExpr _ _ _ _):_) =
-  error $ "attributeUpdate: " ++ n ++ " is an expression-attribute."
-attributeUpdate n f ((Attribute n' v p):attrs) =
-  if n' == n then (Attribute n (f v) p):attrs
-             else (Attribute n' v p):(attributeUpdate n f attrs)
-
− src/WebBits/JavaScript.hs
@@ -1,21 +0,0 @@--- |Re-exports commonly used modules.-module WebBits.JavaScript-  ( module WebBits.JavaScript.Syntax-  , module WebBits.JavaScript.HtmlEmbedding-  , module WebBits.JavaScript.Parser-  , module WebBits.JavaScript.Combinators-  , module WebBits.Common-  , module WebBits.JavaScript.Environment-  -- JavaScript.Instances exports nothing-  ) where--import WebBits.Common--import WebBits.JavaScript.Syntax-import WebBits.JavaScript.Parser-import WebBits.JavaScript.PrettyPrint-import WebBits.JavaScript.HtmlEmbedding-import WebBits.JavaScript.Combinators-import WebBits.JavaScript.Environment--import WebBits.JavaScript.Instances
− src/WebBits/JavaScript/Combinators.hs
@@ -1,39 +0,0 @@-module WebBits.JavaScript.Combinators -  ( scriptStatements-  , isParenExpr-  , syntaxAt-  , expressionsAt-  , statementsAt-  ) where--import Data.Generics (Data,Typeable, everything, mkQ)-import Text.ParserCombinators.Parsec (SourcePos)-import qualified Data.Foldable as F-import Data.Foldable (Foldable)-import WebBits.JavaScript.Syntax-import WebBits.JavaScript.Instances ()-import WebBits.Common () --scriptStatements:: JavaScript a -> [Statement a]-scriptStatements (Script _ ss) = ss--isParenExpr (ParenExpr _ _) = True-isParenExpr _               = False--syntaxAt :: (Data a, Typeable a, Data (t SourcePos), -             Typeable (t SourcePos), Foldable t)-         => SourcePos -> a -> [t SourcePos]-syntaxAt pos a = everything (++) (mkQ [] isMatch) a where-  isMatch stx = case F.find (const True) stx of-    Nothing -> []-    Just pos' | pos == pos' -> [stx]-              | otherwise   -> []--expressionsAt :: (Data a, Typeable a) -              => SourcePos -> a -> [Expression SourcePos]-expressionsAt = syntaxAt--statementsAt :: (Data a, Typeable a) -              => SourcePos -> a -> [Statement SourcePos]-statementsAt = syntaxAt-
− src/WebBits/JavaScript/Crawl.hs
@@ -1,80 +0,0 @@--- |Crawls an HTML page for JavaScript-module WebBits.JavaScript.Crawl -  ( getPageJavaScript-  ) where--import WebBits.Common-import Control.Monad-import Data.Char (toLower)-import Data.Generics-import System.IO-import Text.ParserCombinators.Parsec(parse,setPosition,incSourceColumn,Column,sourceLine,sourceColumn)--import WebBits.Html.Syntax-import qualified WebBits.JavaScript.JavaScript as Js---- |Returns the source of the script.-scriptSrc:: Js.ParsedJsHtml -> [String]-scriptSrc (Element tag attrs _ _) | (map toLower tag) == "script" =-  case attributeValue "src" attrs of -- TODO: Check for type="javascript"?-    Just ""  -> []-    Just url -> [url]-    Nothing  -> []-scriptSrc _ =-  []---- |Returns a list of URIs for external Javascript files referenced in the page.-importedScripts:: Js.ParsedJsHtml -> [String]-importedScripts = everything (++) (mkQ [] scriptSrc)---- |Returns the top-level statements of a script.-scriptText :: Js.ParsedJsHtml -> [Js.ParsedStatement]-scriptText (Script (Js.Script _ stmts) _) = stmts-scriptText _ = []--eventHandlers :: [String]-eventHandlers = ["onload","onclick"]; --- ,"onmousemove","onmouseover","onmousedown","onmouseout","onmouseup","onselectstart", "onkeypress"]--attrScript :: Attribute SourcePos Js.ParsedJavaScript -           -> IO [Js.ParsedStatement]-attrScript (Attribute id val loc) | id `elem` eventHandlers = do-  let eventId = drop 2 id -- drop the "on" prefix-  let scriptText = if "javascript:" `isPrefixOf` val then drop 11 val else val-  let eventListenerPrefix = "addEventListener('" ++ eventId ++ "', function(event) { "-  let prefixLen = length eventListenerPrefix-  let eventListenerText = eventListenerPrefix ++ scriptText ++ " });"-  let parser = do-        setPosition (incSourceColumn loc (-prefixLen))-        Js.parseExpression-  case parse parser (sourceName loc) eventListenerText of-    Left err -> do-      fail $ "Error parsiing JavaScript in an attribute at " ++ show loc ++-             "\nThe script was:\n\n" ++ eventListenerText-    Right e -> return [Js.ExprStmt loc e]-attrScript _ = return []--inpageAttrScripts :: Js.ParsedJsHtml -> IO [Js.ParsedStatement]-inpageAttrScripts = everything (liftM2 (++)) (mkQ (return []) attrScript)--inpageScripts :: Js.ParsedJsHtml -> [Js.ParsedStatement]-inpageScripts = everything (++) (mkQ [] scriptText)--parseJsFile path = do-  text <- readFile path-  case Js.parseScriptFromString path text of-    Left err -> fail (show err)-    Right js -> hPutStrLn stderr ("Read file " ++ path) >> return js---- |Given an HTML page, crawls all external Javascript files and returns a list--- of statements, concatenated from all files.-getPageJavascript:: Js.ParsedJsHtml -> IO [Js.ParsedStatement]-getPageJavascript page = do-  let importURIs = importedScripts page-  let inpageJs   = inpageScripts page-  attrScripts <- inpageAttrScripts page-  importedScripts <- mapM parseJsFile importURIs-  return $ (concatMap Js.scriptStatements importedScripts ++ attrScripts) ++ inpageJs--getPageJavaScript:: Js.ParsedJsHtml -> IO [Js.ParsedStatement] -- monomorphism-getPageJavaScript = getPageJavascript
− src/WebBits/JavaScript/Environment.hs
@@ -1,304 +0,0 @@-module WebBits.JavaScript.Environment -  ( staticEnvironment-  , Ann-  , LabelledStatement-  , LabelledExpression-  , Env-  ) where--import Data.Generics hiding (GT)-import Data.Maybe (fromJust)-import qualified Data.Set as S-import WebBits.Data.Zipper (ZipperT,ZipperT)-import qualified Data.Map as M-import qualified WebBits.Data.Zipper as Z-import Control.Monad.State-import qualified Data.Foldable as F-import qualified Data.List as L-import WebBits.JavaScript.JavaScript-import Text.ParserCombinators.Parsec.Pos (SourcePos,initialPos)-------- Add `this' and `arguments' to the formal parameters of all --- functions ------ TODO: Does a local var x shadow a formal argument x?  What about 'arguments'?--thisStmt :: Statement SourcePos -> Statement SourcePos-thisStmt (FunctionStmt loc id args body) = -  FunctionStmt loc id ((Id loc "this"):(Id loc "arguments"):args) body-thisStmt s = s--thisExpr :: Expression SourcePos -> Expression SourcePos-thisExpr (FuncExpr l args s) = -  FuncExpr l ((Id l "this"):(Id l "arguments"):args) s-thisExpr e = e--removeParens :: Expression SourcePos -> Expression SourcePos-removeParens (ParenExpr _ e) = e-removeParens e = e--removeSingletons :: Expression SourcePos -> Expression SourcePos-removeSingletons (ListExpr _ [e]) = e-removeSingletons e = e--explicitThis :: [Statement SourcePos] -> [Statement SourcePos]-explicitThis = everywhere $ (mkT removeSingletons) . (mkT removeParens) -  . (mkT thisExpr) . (mkT thisStmt)---- JavaScript has a global and function scopes.  Globals do not need to be--- declared.  Any "unbound identifier" in a function is treated as a reference--- to a global.---- For each FunctionExpr and FunctionStmt, we create a list of locally defined--- identifiers (var x = ...) and free identifiers.---- We build a tree of "partial environments."  Since a variable may be used--- before it is declared locally, we maintain a set of free identifiers and--- narrow the set when appropriate.-type PartialEnv = (Env,S.Set String)--type Env = M.Map String Int--emptyPartialEnv :: PartialEnv-emptyPartialEnv = (M.empty,S.empty)--type RefM a = Z.ZipperT PartialEnv (State Int) a--nextLabel :: (MonadTrans t, Monad (t (State Int))) => t (State Int) Int-nextLabel = do-  l <- lift get-  lift $ modify (+1)-  return l -  -bind :: Id SourcePos -> RefM ()-bind (Id _ s) = do-  lbl <- nextLabel-  (env,freeIds) <- Z.getNode-  Z.setNode (M.insert s lbl env, S.delete s freeIds)-  -use :: Id SourcePos -> RefM ()-use (Id _ s) = do-  (env,freeIds) <- Z.getNode-  case M.lookup s env of-    Just _ -> return ()-    Nothing -> Z.setNode (env, S.insert s freeIds)-  --buildExpr :: Expression SourcePos -> RefM (Expression SourcePos)-buildExpr (FuncExpr loc args stmt) = do-  stmt' <- Z.nest emptyPartialEnv (mapM_ bind args >> buildStmt stmt)-  return (FuncExpr loc args stmt')-buildExpr e@(VarRef _ id) = do-  use id-  return e-buildExpr (AssignExpr loc op (VarRef loc' id) e) = do-  use id-  e' <- buildExpr e-  return (AssignExpr loc op (VarRef loc' id) e')-buildExpr e =-  gmapM buildAny e--buildCatchClause :: CatchClause SourcePos -> RefM (CatchClause SourcePos)-buildCatchClause (CatchClause loc id stmt) = do-  bind id-  stmt' <- buildStmt stmt-  return (CatchClause loc id stmt')-  -buildVarDecl :: VarDecl SourcePos -> RefM (VarDecl SourcePos)-buildVarDecl (VarDecl loc id ye) = do-  bind id-  ye' <- gmapM buildAny ye-  return (VarDecl loc id ye')--buildForInInit :: ForInInit SourcePos -> RefM (ForInInit SourcePos)-buildForInInit e@(ForInVar id) = do-  bind id-  return e-buildForInInit e@(ForInNoVar id) = do-  use id-  return e-  -buildStmt :: Statement SourcePos -> RefM (Statement SourcePos)-buildStmt (FunctionStmt loc id args stmt) = do-  stmt' <- Z.nest emptyPartialEnv (mapM_ bind args >> buildStmt stmt)-  return (FunctionStmt loc id args stmt')-buildStmt s = gmapM buildAny s--buildAny' :: (Data a, Typeable a) => a -> RefM a-buildAny' v = gmapM buildAny v--buildAny :: GenericM RefM-buildAny =-  buildAny' `extM` buildExpr `extM` buildCatchClause `extM`-    buildVarDecl `extM` buildForInInit `extM` buildStmt------- buildAny creates a tree of partial environments.  We now walk the tree and--- attempt to associate free identifiers with their bindings in enclosing--- scopes.  Any remaining free identifiers are globals.-----resolveFreeId :: Env -> String -> StateT Env (State Int) Env-resolveFreeId env freeId = case M.lookup freeId env of-  Just lbl -> return env -- the free identifier was bound in an enclosing env-  Nothing  -> do -- this is a global -    globals <- get-    case M.lookup freeId globals of-      Just lbl -> return (M.insert freeId lbl env) -- global already bound-      Nothing -> do -- new global-        lbl <- nextLabel-        put (M.insert freeId lbl globals)-        return (M.insert freeId lbl env)---completeEnvM' :: Z.Tree PartialEnv -> StateT Env (State Int) (Z.Tree Env)-completeEnvM' pt = Z.dfsFoldM f M.empty pt where-  -- the union is left-biased; bindings in env shadow bindings in enclosingEnv-  f enclosingEnv (env,freeIds) = -    foldM resolveFreeId (M.union env enclosingEnv) (S.elems freeIds) --completeEnvM :: Z.Tree PartialEnv -> StateT Env (State Int) (Z.Tree Env)-completeEnvM pt = do-  tree <- completeEnvM' pt-  globals <- get-  -- left-biased union: lexicals shadow globals-  return (fmap (\lexicals -> M.union lexicals globals) tree)------- completeEnvM creates a tree of environments whose structure is identical to--- the function-nesting structure of the JavaScript source.  We walk the tree--- and the code in step and annotate the code with environments.-----type Ann = (Env,Int,SourcePos)--type LabelledStatement = Statement Ann-type LabelledExpression = Expression Ann---- Necessary for type-checking.  gmapM won't let us transform the type of the--- annotation.  So, we first inject SourcePos into a trivial Ann.-insertEmptyAnn :: (Functor f) => f SourcePos -> f Ann-insertEmptyAnn = fmap (\loc -> (M.empty,0,loc))---locOf :: F.Foldable t => t SourcePos -> SourcePos-locOf = fromJust . (F.find $ const True)--labelEnv :: Env -> Z.ZipperT Env (State Int) Env-labelEnv env = Z.getNode--labelId :: Id Ann -> Z.ZipperT Env (State Int) (Id Ann)-labelId id@(Id (_,_,loc) s) = do-  env <- Z.getNode-  case M.lookup s env of-    Nothing -> fail $ "BUG: unbound identifier while labelling" ++ show id-    Just lbl -> return (Id (env,lbl,loc) s)-    -labelIdNoVar :: Id Ann -> Z.ZipperT Env (State Int) (Id Ann)-labelIdNoVar (Id (_,_,loc) s) = do-  env <- Z.getNode-  lbl <- nextLabel-  return (Id (env,lbl,loc) s)--labelProp :: Prop Ann -> Z.ZipperT Env (State Int) (Prop Ann)-labelProp (PropId (_,_,loc) id) = do-  env <- Z.getNode-  lbl <- nextLabel-  id' <- labelIdNoVar id-  return (PropId (env,lbl,loc) id')-labelProp e = gmapM labelAny e---labelVarDecl :: VarDecl Ann-             -> Z.ZipperT Env (State Int) (VarDecl Ann)-labelVarDecl (VarDecl (_,_,loc) id@(Id _ name) rhs) = do-  env <- Z.getNode-  case M.lookup name env of-    Nothing -> fail $ "WebBits bug: unbound id in labelVarDecl (" ++ name ++ ")"-    Just lbl' -> case rhs of-      Nothing -> return (VarDecl (env,lbl',loc) id Nothing)-      Just expr -> do-        expr' <- labelExpr expr-        return (VarDecl (env,lbl',loc) id (Just expr'))--labelExpr :: Expression Ann -          -> Z.ZipperT Env (State Int) (Expression Ann)-labelExpr (ThisRef (_,_,loc)) = do-  env <- Z.getNode-  case M.lookup "this" env of-    Just lbl -> return $ ThisRef (env,lbl,loc)-    Nothing -> fail "BUG: expected to find this in the environment"-labelExpr (DotRef (_,_,loc) expr id) = do-  env <- Z.getNode-  lbl <- nextLabel-  id' <- labelIdNoVar id-  expr' <- labelExpr expr-  return (DotRef (env,lbl,loc) expr' id')-labelExpr (VarRef (_,_,loc) id@(Id _ name)) = do-  env <- Z.getNode-  case M.lookup name env of-    Nothing -> fail $ "WebBits bug : unbound identifer " ++ name-    Just lbl' -> return (VarRef (env,lbl',loc) id)-labelExpr (FuncExpr (_,_,loc) args stmt) = do-  env <- Z.getNode-  lbl <- nextLabel-  args' <- Z.withCurrentChild (mapM labelId args)-  stmt' <- Z.withCurrentChild (labelStmt stmt)-  Z.shiftRight'-  return (FuncExpr (env,lbl,loc) args' stmt')-labelExpr e = gmapM labelAny e-  -labelStmt :: Statement Ann-          -> Z.ZipperT Env (State Int) (Statement Ann)-labelStmt (BreakStmt (_,_,loc) (Just id)) = do-  env <- Z.getNode-  lbl <- nextLabel-  id' <- labelIdNoVar id-  return (BreakStmt (env,lbl,loc) (Just id'))-labelStmt (ContinueStmt (_,_,loc) (Just id)) = do-  env <- Z.getNode-  lbl <- nextLabel-  id' <- labelIdNoVar id-  return (ContinueStmt (env,lbl,loc) (Just id'))-labelStmt (LabelledStmt (_,_,loc) id stmt) = do-  env <- Z.getNode-  lbl <- nextLabel-  id' <- labelIdNoVar id-  stmt' <- labelStmt stmt-  return (LabelledStmt (env,lbl,loc) id' stmt')  -labelStmt (FunctionStmt (_,_,loc) id args stmt) = do-  env <- Z.getNode-  lbl <- nextLabel-  args' <- Z.withCurrentChild (mapM labelId args)-  stmt' <- Z.withCurrentChild (labelStmt stmt)-  Z.shiftRight'-  return (FunctionStmt (env,lbl,loc) id args' stmt')-labelStmt e = gmapM labelAny e--labelAny' :: (Data a, Typeable a) => a -> Z.ZipperT Env (State Int) a-labelAny' a = gmapM labelAny a--labelAny :: GenericM (Z.ZipperT Env (State Int)) -labelAny a = (labelAny' `extM` labelEnv `extM` labelId `extM` labelProp `extM`-  labelExpr `extM` labelStmt `extM` labelVarDecl) a--topLevelPartialEnv = (M.empty,S.singleton "this")---- |Annotates each expression with its static environment.  In addition,--- a map of free identifiers is returned, along with the next valid label.-staticEnvironment :: [Statement SourcePos] -                  -> ([Statement Ann],Env,Env,Int)-staticEnvironment stmts =-  let stmts' = explicitThis stmts-      labelM = do-        partialEnvTree <- Z.execZipperT (mapM buildStmt stmts')-                            (Z.toLocation (Z.Node topLevelPartialEnv []))-        (envTree,freeEnv) <- runStateT (completeEnvM partialEnvTree) M.empty-        let globals = M.union freeEnv (Z.rootLabel envTree)-        let stmts'' = map insertEmptyAnn stmts' -        labelledStmts <- Z.evalZipperT (mapM labelStmt stmts'') -                                       (Z.toLocation envTree)-        return (labelledStmts,freeEnv,globals)-      ((labelledStmts,freeEnv,globals),nextLabel) = runState labelM 1-    in (labelledStmts,freeEnv,globals,nextLabel)
− src/WebBits/JavaScript/HtmlEmbedding.hs
@@ -1,26 +0,0 @@-module WebBits.JavaScript.HtmlEmbedding-  ( JsHtml-  , ParsedJavaScript-  , ParsedJsHtml-  ) where--import WebBits.Html.Syntax(Html,Script,parseScriptBlock,parseInlineScript,-                   parseAttributeScript)-import WebBits.JavaScript.Parser(parseScript)-import WebBits.JavaScript.Syntax(JavaScript)---import JavaScript.PrettyPrint -- for the instance declaration-import Text.ParserCombinators.Parsec (SourcePos)--type JsHtml a = Html SourcePos (JavaScript a)--type ParsedJavaScript = JavaScript SourcePos--type ParsedJsHtml = JsHtml SourcePos--instance Script ParsedJavaScript where-  parseScriptBlock attrs = do-    parseScript-  parseInlineScript = Nothing-  parseAttributeScript = Nothing-    -  
− src/WebBits/JavaScript/Instances.hs
@@ -1,291 +0,0 @@--- |Instances of 'Foldable' and 'Traversable' for JavaScript's syntax.-module WebBits.JavaScript.Instances-  ( -- This module does not export any names.-  ) where--import Prelude hiding (foldr,sequence,mapM)-import qualified Prelude as Prelude--import Data.Foldable (Foldable(..))-import Data.Traversable(Traversable(..))-import Control.Applicative--import WebBits.JavaScript.Syntax--yfoldr:: Foldable t => (a -> b -> b) -> b -> Maybe (t a) -> b-yfoldr _ b Nothing = b-yfoldr f b (Just t) = foldr f b t--lfoldr:: Foldable t => (a -> b -> b) -> b -> [t a] -> b-lfoldr f = Prelude.foldr (flip $ foldr f)--ltraverse:: (Traversable t, Applicative f) => (a -> f b) -> [t a] -> f [t b]-ltraverse _ [] = pure []-ltraverse f (a:as) = (:) <$> traverse f a <*> ltraverse f as--ytraverse:: (Traversable t, Applicative f) -         => (a -> f b) -> Maybe (t a) -> f (Maybe (t b))-ytraverse _ Nothing = pure Nothing-ytraverse f (Just t) = Just <$> traverse f t--instance Functor Id where-  fmap f (Id a v) = Id (f a) v--instance Functor JavaScript where-  fmap f (Script a stmts) = Script (f a) (map (fmap f) stmts)-  -instance Functor Prop where-  fmap f (PropId a id) = PropId (f a) (fmap f id)-  fmap f (PropString a s) = PropString (f a) s-  fmap f (PropNum a n) = PropNum (f a) n--instance Functor Expression where-  fmap f expression = -    case expression of-      StringLit a s -> StringLit (f a) s-      RegexpLit a s g ci -> RegexpLit (f a) s g ci-      NumLit a n -> NumLit (f a) n-      BoolLit a b -> BoolLit (f a) b-      NullLit a -> NullLit (f a)-      ArrayLit a es -> ArrayLit (f a) (map (fmap f) es)-      ObjectLit a pes -> ObjectLit (f a) (map f' pes) where-        f' (p,e) = (fmap f p, fmap f e)-      ThisRef a -> ThisRef (f a)-      VarRef a id -> VarRef (f a) (fmap f id)-      DotRef a e id -> DotRef (f a) (fmap f e) (fmap f id)-      BracketRef a e1 e2 -> BracketRef (f a) (fmap f e1) (fmap f e2)-      NewExpr a e es -> NewExpr (f a) (fmap f e) (map (fmap f) es)-      PostfixExpr a op e -> PostfixExpr (f a) op (fmap f e)-      PrefixExpr a op e -> PrefixExpr (f a) op (fmap f e)-      InfixExpr a op e1 e2 -> InfixExpr (f a) op (fmap f e1) (fmap f e2)-      CondExpr a e1 e2 e3 -> CondExpr (f a) (fmap f e1) (fmap f e2) (fmap f e3)-      AssignExpr a op e1 e2 -> AssignExpr (f a) op (fmap f e1) (fmap f e2)-      ParenExpr a e -> ParenExpr (f a) (fmap f e)-      ListExpr a es -> ListExpr (f a) (map (fmap f) es)-      CallExpr a e es -> CallExpr (f a) (fmap f e) (map (fmap f) es)-      FuncExpr a args s -> FuncExpr (f a) (map (fmap f) args) (fmap f s)--instance Functor CaseClause where-  fmap f (CaseClause a e ss) = CaseClause (f a) (fmap f e) (map (fmap f) ss)-  fmap f (CaseDefault a ss) = CaseDefault (f a) (map (fmap f) ss)-  -instance Functor CatchClause where-  fmap f (CatchClause a id s) = CatchClause (f a) (fmap f id) (fmap f s)--instance Functor VarDecl where-  fmap f (VarDecl a id Nothing) = VarDecl (f a) (fmap f id) Nothing-  fmap f (VarDecl a id (Just e)) = VarDecl (f a) (fmap f id) (Just $ fmap f e)-  -instance Functor ForInit where-  fmap f NoInit = NoInit-  fmap f (VarInit decls) = VarInit (map (fmap f) decls)-  fmap f (ExprInit e) = ExprInit (fmap f e)--instance Functor ForInInit where-  fmap f (ForInVar id) = ForInVar (fmap f id)-  fmap f (ForInNoVar id) = ForInNoVar (fmap f id)-  -instance Functor Statement where-  fmap f s = -    case s of-      BlockStmt a ss -> BlockStmt (f a) (map (fmap f) ss)-      EmptyStmt a -> EmptyStmt (f a)-      ExprStmt a e -> ExprStmt (f a) (fmap f e)-      IfStmt a e s1 s2 -> IfStmt (f a) (fmap f e) (fmap f s1) (fmap f s2)-      IfSingleStmt a e s -> IfSingleStmt (f a) (fmap f e) (fmap f s)-      SwitchStmt a e cs -> SwitchStmt (f a) (fmap f e) (map (fmap f) cs)-      WhileStmt a e s -> WhileStmt (f a) (fmap f e) (fmap f s)-      DoWhileStmt a s e -> DoWhileStmt (f a) (fmap f s) (fmap f e)-      BreakStmt a Nothing -> BreakStmt (f a) Nothing-      BreakStmt a (Just id) -> BreakStmt (f a) (Just (fmap f id))-      ContinueStmt a yid -> ContinueStmt (f a) (yid >>= return.(fmap f))-      LabelledStmt a id s -> LabelledStmt (f a) (fmap f id) (fmap f s)-      ForInStmt a init e s -> ForInStmt (f a) (fmap f init) (fmap f e)-                                (fmap f s)-      ForStmt a init yinc ytest body -> -        ForStmt (f a) (fmap f init) (yinc >>= return.(fmap f))-          (ytest >>= return.(fmap f)) (fmap f body)-      TryStmt a s cs ys -> -        TryStmt (f a) (fmap f s) (map (fmap f) cs) (ys >>= return.(fmap f))-      ThrowStmt a e -> ThrowStmt (f a) (fmap f e)-      ReturnStmt a ye -> ReturnStmt (f a) (ye >>= return.(fmap f))-      WithStmt a e s -> WithStmt (f a) (fmap f e) (fmap f s)-      VarDeclStmt a ds -> VarDeclStmt (f a) (map (fmap f) ds)-      FunctionStmt a id args s -> -        FunctionStmt (f a) (fmap f id) (map (fmap f) args) (fmap f s)--instance Foldable Id where-  foldr f b (Id a _) = f a b--instance Foldable Prop where-  foldr f b (PropId a id) = f a (foldr f b id)-  foldr f b (PropString a _) = f a b-  foldr f b (PropNum a _) = f a b-        -instance Foldable Expression where-  -- foldr:: (a -> b -> b) -> b -> Expression a -> b-  foldr f b e =-    case e of-      StringLit a _ -> f a b-      RegexpLit a _ _ _ -> f a b-      NumLit a _ -> f a b-      BoolLit a _ -> f a b-      NullLit a -> f a b-      ArrayLit a es -> f a (Prelude.foldr (flip $ foldr f) b es)-      ObjectLit a pes -> f a (Prelude.foldr f' b pes) where-        f' (p,e) b = foldr f (foldr f b e) p-      ThisRef a -> f a b-      VarRef a id -> f a (foldr f b id)-      DotRef a e id -> f a (foldr f (foldr f b id) e)-      BracketRef a e1 e2 -> f a (foldr f (foldr f b e2) e1)-      NewExpr a e es -> f a (foldr f (Prelude.foldr (flip $ foldr f) b es) e)-      PostfixExpr a _ e -> f a $ foldr f b e-      PrefixExpr a _ e -> f a $ foldr f b e-      InfixExpr a _ e1 e2 -> f a $ foldr f (foldr f b e2) e1-      CondExpr a e1 e2 e3 -> f a $ foldr f (foldr f (foldr f b e3) e2) e1-      AssignExpr a _ e1 e2 -> f a $ foldr f (foldr f b e2) e1-      ParenExpr a e -> f a $ foldr f b e-      ListExpr a es -> f a $ Prelude.foldr (flip $ foldr f) b es-      CallExpr a e es -> f a $ foldr f (Prelude.foldr (flip $ foldr f) b es) e-      FuncExpr a args s -> -        f a $ Prelude.foldr (flip $ foldr f) (foldr f b s) args--instance Foldable CaseClause where-  foldr f b (CaseClause a e ss) = -    f a $ foldr f (Prelude.foldr (flip $ foldr f) b ss) e-  foldr f b (CaseDefault a ss) = f a $ Prelude.foldr (flip $ foldr f) b ss-  -instance Foldable CatchClause where-  foldr f b (CatchClause a id s) = f a $ foldr f (foldr f b s) id--instance Foldable VarDecl where-  foldr f b (VarDecl a id ye) = f a $ foldr f (yfoldr f b ye) id--instance Foldable ForInit where-  foldr f b NoInit = b-  foldr f b (VarInit ds) = Prelude.foldr (flip $ foldr f) b ds-  foldr f b (ExprInit e) = foldr f b e--instance Foldable ForInInit where- foldr f b (ForInVar id) = foldr f b id- foldr f b (ForInNoVar id) = foldr f b id--instance Foldable Statement where-  foldr f b statement =-    case statement of-      BlockStmt a ss -> f a $ lfoldr f b ss-      EmptyStmt a -> f a b-      ExprStmt a e -> f a $ foldr f b e-      IfStmt a e s1 s2 -> f a $ foldr f (foldr f (foldr f b s2) s1) e-      IfSingleStmt a e s -> f a $ foldr f (foldr f b s) e-      SwitchStmt a e cs -> f a $ foldr f (lfoldr f b cs) e-      WhileStmt a e s -> f a $ foldr f (foldr f b s) e-      DoWhileStmt a s e -> f a $ foldr f (foldr f b e) s-      BreakStmt a yid -> f a $ yfoldr f b yid-      ContinueStmt a yid -> f a $ yfoldr f b yid-      LabelledStmt a id s -> f a $ foldr f (foldr f b s) id-      ForInStmt a init e s -> f a $ foldr f (foldr f (foldr f b s) e) init-      ForStmt a init ye1 ye2 s ->-        f a $ foldr f (yfoldr f (yfoldr f (foldr f b s) ye2) ye1) init-      TryStmt a s cs ys -> f a $ foldr f (lfoldr f (yfoldr f b ys) cs) s-      ThrowStmt a e -> f a $ foldr f b e-      ReturnStmt a ys -> f a $ yfoldr f b ys-      WithStmt a e s -> f a $ foldr f (foldr f b s) e-      VarDeclStmt a ds -> f a $ lfoldr f b ds-      FunctionStmt a id args s ->-        f a $ lfoldr f (foldr f b s) (id:args)--instance Traversable Id where-  traverse f (Id a v) = Id <$> f a <*> pure v--instance Traversable Prop where-  traverse f (PropId a id) = PropId <$> f a <*> traverse f id-  traverse f (PropString a s) = PropString <$> f a <*> pure s-  traverse f (PropNum a n) = PropNum <$> f a <*> pure n-  -instance Traversable Expression where-  traverse f expression =-    case expression of-      StringLit a s -> StringLit <$> f a <*> pure s-      RegexpLit a s g ci -> RegexpLit <$> f a <*> pure s <*> pure g <*> pure ci-      NumLit a n -> NumLit <$> f a <*> pure n-      BoolLit a b -> BoolLit <$> f a <*> pure b-      NullLit a -> NullLit <$> f a-      ArrayLit a es -> ArrayLit <$> f a <*> ltraverse f es-      ObjectLit a ps -> ObjectLit <$> f a <*>  (zip <$> props' <*> es') where-        (props,es) = unzip ps-        props' = ltraverse f props-        es' = ltraverse f es-      ThisRef a -> ThisRef <$> f a-      VarRef a id -> VarRef <$> f a <*> traverse f id-      DotRef a e id -> DotRef <$> f a <*> traverse f e <*> traverse f id-      BracketRef a e es -> BracketRef <$> f a <*> traverse f e <*> traverse f es-      NewExpr a e es -> NewExpr <$> f a <*> traverse f e <*> ltraverse f es-      PostfixExpr a op e -> PostfixExpr <$> f a <*> pure op <*> traverse f e-      PrefixExpr a op e -> PrefixExpr <$> f a <*> pure op <*> traverse f e-      InfixExpr a op e1 e2 -> InfixExpr <$> f a <*> pure op <*> traverse f e1-                                <*> traverse f e2-      CondExpr a e1 e2 e3 ->-        CondExpr <$> f a <*> traverse f e1 <*> traverse f e2 <*> traverse f e3-      AssignExpr a op e1 e2 -> AssignExpr <$> f a <*> pure op <*> traverse f e1-        <*> traverse f e2-      ParenExpr a e -> ParenExpr <$> f a <*> traverse f e-      ListExpr a es -> ListExpr <$> f a <*> ltraverse f es-      CallExpr a e es -> CallExpr <$> f a <*> traverse f e <*> ltraverse f es-      FuncExpr a ids s -> FuncExpr <$> f a <*> ltraverse f ids <*> traverse f s--instance Traversable CaseClause where-  traverse f (CaseClause a e ss) =-    CaseClause <$> f a <*> traverse f e <*> ltraverse f ss-  traverse f (CaseDefault a ss) = -    CaseDefault <$> f a <*> ltraverse f ss--instance Traversable CatchClause where-  traverse f (CatchClause a id s) = -    CatchClause <$> f a <*> traverse f id <*> traverse f s-    -instance Traversable VarDecl where-  traverse f (VarDecl a id ye) =-    VarDecl <$> f a <*> traverse f id <*> ytraverse f ye--instance Traversable ForInit where-  traverse f NoInit = pure NoInit-  traverse f (VarInit ds) = VarInit <$> ltraverse f ds-  traverse f (ExprInit e) = ExprInit <$> traverse f e--instance Traversable ForInInit where- traverse f (ForInVar id) = ForInVar <$> traverse f id- traverse f (ForInNoVar id) = ForInNoVar <$> traverse f id--instance Traversable Statement where-  traverse f statement =-    case statement of-      BlockStmt a ss -> BlockStmt <$> f a <*> ltraverse f ss-      EmptyStmt a -> EmptyStmt <$> f a-      ExprStmt a e -> ExprStmt <$> f a <*> traverse f e-      IfStmt a e s1 s2 ->-        IfStmt <$> f a <*> traverse f e <*> traverse f s1 <*> traverse f s2-      IfSingleStmt a e s ->-        IfSingleStmt <$> f a <*> traverse f e <*> traverse f s-      SwitchStmt a e cs ->-        SwitchStmt <$> f a <*> traverse f e <*> ltraverse f cs-      WhileStmt a e s -> WhileStmt <$> f a <*> traverse f e <*> traverse f s-      DoWhileStmt a s e -> DoWhileStmt <$> f a <*> traverse f s <*> traverse f e-      BreakStmt a yid -> BreakStmt <$> f a <*> ytraverse f yid-      ContinueStmt a yid -> ContinueStmt <$> f a <*> ytraverse f yid-      LabelledStmt a id s -> -        LabelledStmt <$> f a <*> traverse f id <*> traverse f s-      ForInStmt a init e s ->-        ForInStmt <$> f a <*> traverse f init <*> traverse f e <*> traverse f s-      ForStmt a init yinc ytest s ->-        ForStmt <$> f a <*> traverse f init <*> ytraverse f yinc -          <*> ytraverse f ytest <*> traverse f s-      TryStmt a s cs ys ->-        TryStmt <$> f a <*> traverse f s <*> ltraverse f cs <*> ytraverse f ys-      ThrowStmt a e -> ThrowStmt <$> f a <*> traverse f e-      ReturnStmt a ys -> ReturnStmt <$> f a <*> ytraverse f ys-      WithStmt a e s -> WithStmt <$> f a <*> traverse f e <*> traverse f s-      VarDeclStmt a ds -> VarDeclStmt <$> f a <*> ltraverse f ds-      FunctionStmt a id args s ->-        FunctionStmt <$> f a <*> traverse f id <*> ltraverse f args -          <*> traverse f s 
− src/WebBits/JavaScript/JavaScript.hs
@@ -1,19 +0,0 @@--- |Re-exports commonly used modules.-module WebBits.JavaScript.JavaScript-  ( module WebBits.JavaScript.Syntax-  , module WebBits.JavaScript.HtmlEmbedding-  , module WebBits.JavaScript.Parser-  , module WebBits.JavaScript.Combinators-  , module WebBits.Common-  -- JavaScript.Instances exports nothing-  ) where--import WebBits.Common--import WebBits.JavaScript.Syntax-import WebBits.JavaScript.Parser-import WebBits.JavaScript.PrettyPrint-import WebBits.JavaScript.HtmlEmbedding-import WebBits.JavaScript.Combinators--import WebBits.JavaScript.Instances
− src/WebBits/JavaScript/Lexer.hs
@@ -1,64 +0,0 @@-{- This isn't a lexer in the sense that it provides a JavaScript token-stream.
- - This module provides character-parsers for various JavaScript tokens.
- -}
-module WebBits.JavaScript.Lexer(lexeme,identifier,reserved,operator,reservedOp,charLiteral,
-                        stringLiteral,natural,integer,float,naturalOrFloat,
-                        decimal,hexadecimal,octal,symbol,whiteSpace,parens,
-                        braces,brackets,squares,semi,comma,colon,dot,
-                        identifierStart) where
-
-import Prelude hiding (lex)
-import Text.ParserCombinators.Parsec
-import qualified Text.ParserCombinators.Parsec.Token as T
-
-identifierStart = (letter <|> oneOf "$_")
-
-javascriptDef =
-  T.LanguageDef "/*"
-                "*/"
-                "//"
-                False -- no nested comments
-                {- Adapted from syntax/regexps.ss in Dave's code. -}
-                identifierStart
-                (alphaNum <|> oneOf "$_") -- identifier rest
-                (oneOf "{}<>()~.,?:|&^=!+-*/%!") -- operator start
-                (oneOf "=<>|&+") -- operator rest
-                ["break", "case", "catch", "const", "continue", "debugger", 
-                 "default", "delete", "do", "else", "enum", "false", "finally",
-                 "for", "function", "if", "instanceof", "in", "let", "new", 
-                 "null", "return", "switch", "this", "throw", "true", "try", 
-                 "typeof", "var", "void", "while", "with"]
-                ["|=", "^=", "&=", "<<=", ">>=", ">>>=", "+=", "-=", "*=", "/=", 
-                 "%=", "=", ";", ",", "?", ":", "||", "&&", "|", "^", "&", 
-                 "===", "==", "=", "!==", "!=", "<<", "<=", "<", ">>>", ">>", 
-                 ">=", ">", "++", "--", "+", "-", "*", "/", "%", "!", "~", ".", 
-                 "[", "]", "{", "}", "(", ")","</","instanceof"]
-                 True -- case-sensitive
-            
-lex = T.makeTokenParser javascriptDef
-
--- everything but commaSep and semiSep
-identifier = T.identifier	 lex
-reserved = T.reserved	 lex
-operator = T.operator	 lex
-reservedOp = T.reservedOp lex	
-charLiteral = T.charLiteral lex	
-stringLiteral = T.stringLiteral lex	
-natural = T.natural lex	
-integer = T.integer lex	
-float = T.float lex	
-naturalOrFloat = T.naturalOrFloat lex	
-decimal = T.decimal lex	
-hexadecimal = T.hexadecimal lex	
-octal = T.octal lex	
-symbol = T.symbol lex	
-whiteSpace = T.whiteSpace lex	
-parens = T.parens	 lex
-braces = T.braces	 lex
-squares = T.squares lex	
-semi = T.semi	 lex
-comma = T.comma	 lex
-colon = T.colon lex	
-dot = T.dot lex
-brackets = T.brackets lex
-lexeme = T.lexeme lex
− src/WebBits/JavaScript/Parser.hs
@@ -1,657 +0,0 @@-module WebBits.JavaScript.Parser(parseScript,parseExpression
-   , parseString
-   , parseScriptFromString
-   , emptyParsedJavaScript
-   , ParsedStatement
-   , ParsedExpression
-   , parseJavaScriptFromFile
-   , parseSimpleExpr'
-   , parseBlockStmt
-   , parseStatement
-   , StatementParser
-   , ExpressionParser
-   , parseAssignExpr
-   ) where
-
-import WebBits.JavaScript.Lexer hiding (identifier)
-import qualified WebBits.JavaScript.Lexer as Lexer
-import WebBits.JavaScript.Syntax
-import Text.ParserCombinators.Parsec
-import Text.ParserCombinators.Parsec.Expr
-import Control.Monad(liftM,liftM2)
-import Control.Monad.Trans (MonadIO,liftIO)
-import Numeric(readDec,readOct,readHex)
-import Data.Char(chr)
-import Data.Char
-
--- We parameterize the parse tree over source-locations.
-type ParsedStatement = Statement SourcePos
-type ParsedExpression = Expression SourcePos
-
-
--- These parsers can store some arbitrary state
-type StatementParser state = CharParser state ParsedStatement
-type ExpressionParser state = CharParser state ParsedExpression
-
-identifier =
-  liftM2 Id getPosition Lexer.identifier
-
---{{{ Statements
-
--- Keep in mind that Token.reserved parsers (exported from the lexer) do not
--- consume any input on failure.  Note that all statements (expect for labelled
--- and expression statements) begin with a reserved-word.  If we fail to parse
--- this reserved-word, no input is consumed.  Hence, we can have the massive or
--- block that is parseExpression.  Note that if the reserved-word is parsed, it 
--- must be whatever statement the reserved-word indicates.  If we fail after the
--- reserved-word, we truly have a syntax error.  Since input has been consumed,
--- <|> will not try its alternate in parseExpression, and we will fail.
-
-parseIfStmt:: StatementParser st  
-parseIfStmt = do
-  pos <- getPosition
-  reserved "if"
-  test <- parseParenExpr <?> "parenthesized test-expression in if statement"
-  consequent <- parseStatement <?> "true-branch of if statement"
-  optional semi -- TODO: in spec?
-  ((do reserved "else"
-       alternate <- parseStatement
-       return (IfStmt pos test consequent alternate))
-    <|> return (IfSingleStmt pos test consequent))
-
-parseSwitchStmt:: StatementParser st
-parseSwitchStmt =
-  let parseDefault = do
-        pos <- getPosition
-        reserved "default"
-        colon
-        statements <- many parseStatement
-        return (CaseDefault pos statements)
-      parseCase = do
-         pos <- getPosition
-         reserved "case"
-         condition <- parseListExpr
-         colon
-         actions <- many parseStatement
-         return (CaseClause pos condition actions)
-    in do pos <- getPosition
-          reserved "switch"
-          test <- parseParenExpr
-          clauses <- braces $ many $ parseDefault <|> parseCase
-          return (SwitchStmt pos test clauses)
-
-parseWhileStmt:: StatementParser st
-parseWhileStmt = do
-  pos <- getPosition
-  reserved "while"
-  test <- parseParenExpr <?> "parenthesized test-expression in while loop"
-  body <- parseStatement
-  return (WhileStmt pos test body)
-
-parseDoWhileStmt:: StatementParser st
-parseDoWhileStmt = do
-  pos <- getPosition
-  reserved "do"
-  body <- parseBlockStmt
-  reserved "while" <?> "while at the end of a do block"
-  test <- parseParenExpr <?> "parenthesized test-expression in do loop"
-  optional semi
-  return (DoWhileStmt pos body test)
-
-parseContinueStmt:: StatementParser st
-parseContinueStmt = do
-  pos <- getPosition
-  reserved "continue"
-  pos' <- getPosition
-  -- Ensure that the identifier is on the same line as 'continue.'
-  id <- (if (sourceLine pos == sourceLine pos')
-           then (liftM Just identifier) <|> (return Nothing)
-           else return Nothing)
-  return (ContinueStmt pos id)
-
-parseBreakStmt:: StatementParser st
-parseBreakStmt = do
-  pos <- getPosition
-  reserved "break"
-  pos' <- getPosition
-  -- Ensure that the identifier is on the same line as 'break.'
-  id <- (if (sourceLine pos == sourceLine pos')
-           then (liftM Just identifier) <|> (return Nothing)
-           else return Nothing)
-  optional semi           
-  return (BreakStmt pos id)
-
-parseBlockStmt:: StatementParser st
-parseBlockStmt = do
-  pos <- getPosition
-  statements <- braces (many parseStatement)
-  return (BlockStmt pos statements)
-
-parseEmptyStmt:: StatementParser st 
-parseEmptyStmt = do
-  pos <- getPosition
-  semi
-  return (EmptyStmt pos)
-
-parseLabelledStmt:: StatementParser st
-parseLabelledStmt = do
-  pos <- getPosition
-  -- Lookahead for the colon.  If we don't see it, we are parsing an identifier
-  -- for an expression statement.
-  label <- try (do label <- identifier
-                   colon
-                   return label)
-  statement <- parseStatement
-  return (LabelledStmt pos label statement)
-
-parseExpressionStmt:: StatementParser st
-parseExpressionStmt = do
-  pos <- getPosition
-  expr <- parseListExpr -- TODO: spec 12.4?
-  optional semi
-  return (ExprStmt pos expr)
-
-
-parseForInStmt:: StatementParser st
-parseForInStmt =
-  let parseInit = (reserved "var" >> liftM ForInVar identifier)
-                  <|> (liftM ForInNoVar identifier)
-    in do pos <- getPosition
-          -- Lookahead, so that we don't clash with parseForStmt
-          (init,expr) <- try (do reserved "for"
-                                 parens (do init <- parseInit
-                                            reserved "in"
-                                            expr <- parseExpression
-                                            return (init,expr)))
-          body <- parseStatement
-          return (ForInStmt pos init expr body) 
-
-parseForStmt:: StatementParser st
-parseForStmt =
-  let parseInit =
-        (reserved "var" >> liftM VarInit (parseVarDecl `sepBy` comma)) <|>
-        (liftM ExprInit parseListExpr) <|>
-        (return NoInit)
-    in do pos <- getPosition
-          reserved "for"
-          reservedOp "("
-          init <- parseInit
-          semi
-          test <- (liftM Just parseExpression) <|> (return Nothing)
-          semi
-          iter <- (liftM Just parseExpression) <|> (return Nothing)
-          reservedOp ")" <?> "closing paren"
-          stmt <- parseStatement
-          return (ForStmt pos init test iter stmt)
-
-parseTryStmt:: StatementParser st
-parseTryStmt =
-  let parseCatchClause = do
-        pos <- getPosition
-        reserved "catch"
-        id <- parens identifier
-        stmt <- parseStatement
-        return (CatchClause pos id stmt)
-    in do reserved "try"
-          pos <- getPosition
-          guarded <- parseStatement
-          catches <- many parseCatchClause
-          finally <- (reserved "finally" >> liftM Just parseStatement) 
-                      <|> (return Nothing)
-          return (TryStmt pos guarded catches finally)
-
-parseThrowStmt:: StatementParser st
-parseThrowStmt = do
-  pos <- getPosition
-  reserved "throw"
-  expr <- parseExpression
-  optional semi
-  return (ThrowStmt pos expr)
-
-parseReturnStmt:: StatementParser st
-parseReturnStmt = do
-  pos <- getPosition
-  reserved "return"
-  expr <- (liftM Just parseListExpr) <|> (return Nothing)
-  optional semi
-  return (ReturnStmt pos expr)
-
-parseWithStmt:: StatementParser st
-parseWithStmt = do
-  pos <- getPosition
-  reserved "with"
-  context <- parseParenExpr
-  stmt <- parseStatement
-  return (WithStmt pos context stmt)
-
-parseVarDecl = do
-  pos <- getPosition
-  id <- identifier
-  init <- (reservedOp "=" >> liftM Just parseExpression) <|> (return Nothing)
-  return (VarDecl pos id init)
-
-parseVarDeclStmt:: StatementParser st
-parseVarDeclStmt = do 
-  pos <- getPosition
-  reserved "var"
-  decls <- parseVarDecl `sepBy` comma
-  optional semi
-  return (VarDeclStmt pos decls)
-
-parseFunctionStmt:: StatementParser st
-parseFunctionStmt = do
-  pos <- getPosition
-  name <- try (reserved "function" >> identifier) -- ambiguity with FuncExpr
-  args <- parens (identifier `sepBy` comma)
-  body <- parseBlockStmt <?> "function body in { ... }"
-  return (FunctionStmt pos name args body)
-
-parseStatement:: StatementParser st
-parseStatement = parseIfStmt <|> parseSwitchStmt <|> parseWhileStmt 
-  <|> parseDoWhileStmt <|> parseContinueStmt <|> parseBreakStmt 
-  <|> parseBlockStmt <|> parseEmptyStmt <|> parseForInStmt <|> parseForStmt
-  <|> parseTryStmt <|> parseThrowStmt <|> parseReturnStmt <|> parseWithStmt 
-  <|> parseVarDeclStmt  <|> parseFunctionStmt
-  -- labelled, expression and the error message always go last, in this order
-  <|> parseLabelledStmt <|> parseExpressionStmt <?> "statement"
-
---}}}
-
---{{{ Expressions
-
--- References used to construct this stuff:
--- + http://developer.mozilla.org/en/docs/
---     Core_JavaScript_1.5_Reference:Operators:Operator_Precedence
--- + http://www.mozilla.org/js/language/grammar14.html
---
--- Aren't expression tables nice?  Well, we can't quite use them, because of 
--- JavaScript's ternary (?:) operator.  We have to use two expression tables.
--- We use one expression table for the assignment operators that bind looser 
--- than ?: (assignTable).  The terms of assignTable are ternary expressions 
--- (parseTernaryExpr).  parseTernaryExpr left-factors the left-recursive
--- production for ?:, and is defined over the second expression table, 
--- exprTable, which consists of operators that bind tighter than ?:.  The terms
--- of exprTable are atomic expressions, parenthesized expressions, functions and
--- array references.
-
---{{{ Primary expressions
-
-parseThisRef:: ExpressionParser st
-parseThisRef = do
-  pos <- getPosition
-  reserved "this"
-  return (ThisRef pos)
-
-parseNullLit:: ExpressionParser st
-parseNullLit = do
-  pos <- getPosition
-  reserved "null"
-  return (NullLit pos)
-
-
-parseBoolLit:: ExpressionParser st
-parseBoolLit = do
-    pos <- getPosition
-    let parseTrueLit  = reserved "true"  >> return (BoolLit pos True)
-        parseFalseLit = reserved "false" >> return (BoolLit pos False)
-    parseTrueLit <|> parseFalseLit
-
-parseVarRef:: ExpressionParser st
-parseVarRef = liftM2 VarRef getPosition identifier
-
-parseArrayLit:: ExpressionParser st
-parseArrayLit = liftM2 ArrayLit getPosition (squares (parseExpression `sepBy` comma))
-  
-parseFuncExpr = do
-  pos <- getPosition
-  reserved "function"
-  args <- parens (identifier `sepBy` comma)
-  body <- parseBlockStmt
-  return $ FuncExpr pos args body
-
---{{{ parsing strings
-
-escapeChars =
- [('\'','\''),('\"','\"'),('\\','\\'),('b','\b'),('f','\f'),('n','\n'),
-  ('r','\r'),('t','\t'),('v','\v'),('/','/')]
-
-allEscapes:: String
-allEscapes = map fst escapeChars
-
-parseEscapeChar = do
-  c <- oneOf allEscapes
-  let (Just c') = lookup c escapeChars -- will succeed due to line above
-  return c' 
-
-parseAsciiHexChar = do
-  char 'x'
-  d1 <- hexDigit
-  d2 <- hexDigit
-  return ((chr.fst.head.readHex) (d1:d2:""))
-
-parseUnicodeHexChar = do
-  char 'u'
-  liftM (chr.fst.head.readHex) 
-        (sequence [hexDigit,hexDigit,hexDigit,hexDigit])
-        
-isWhitespace ch = ch `elem` " \t"
-
-
--- The endWith argument is either single-quote or double-quote, depending on how
--- we opened the string.
-parseStringLit' endWith =
-  (char endWith >> return "") <|>
-  (do try (string "\\'")
-      cs <- parseStringLit' endWith
-      return $ "'" ++ cs) <|>
-  (do char '\\'
-      c <- parseEscapeChar <|> parseAsciiHexChar <|> parseUnicodeHexChar <|> 
-           char '\r' <|> char '\n'
-      cs <- parseStringLit' endWith
-      if c == '\r' || c == '\n' 
-        then return (c:(dropWhile isWhitespace cs)) 
-        else return (c:cs)) <|>
-   (liftM2 (:) anyChar (parseStringLit' endWith))
-
-parseStringLit:: ExpressionParser st
-parseStringLit = do
-  pos <- getPosition
-  -- parseStringLit' takes as an argument the quote-character that opened the
-  -- string.
-  str <- lexeme $ (char '\'' >>= parseStringLit') <|> (char '\"' >>= parseStringLit')
-  -- CRUCIAL: Parsec.Token parsers expect to find their token on the first
-  -- character, and read whitespaces beyond their tokens.  Without 'lexeme'
-  -- above, expressions like:
-  --   var s = "string"   ;
-  -- do not parse.
-  return $ StringLit pos str
-
---}}}
-
-parseRegexpLit:: ExpressionParser st
-parseRegexpLit = do
-  let parseFlags = do
-        flags <- many (oneOf "mgi")
-        return $ \f -> f ('g' `elem` flags) ('i' `elem` flags) 
-  let parseEscape = char '\\' >> anyChar
-  let parseChar = noneOf "/"
-  let parseRe = (char '/' >> return "") <|> 
-                (do char '\\'
-                    ch <- anyChar -- TOOD: too lenient
-                    rest <- parseRe
-                    return ('\\':ch:rest)) <|> 
-                (liftM2 (:) anyChar parseRe)
-  pos <- getPosition
-  char '/'
-  pat <- parseRe --many1 parseChar
-  flags <- parseFlags
-  spaces -- crucial for Parsec.Token parsers
-  return $ flags (RegexpLit pos pat)
-          
-parseObjectLit:: ExpressionParser st
-parseObjectLit =
-  let parseProp = do
-        -- Parses a string, identifier or integer as the property name.  I
-        -- apologize for the abstruse style, but it really does make the code
-        -- much shorter.
-        name <- (liftM (uncurry PropString) 
-                       (liftM (\(StringLit p s) -> (p,s)) parseStringLit))
-                <|> (liftM2 PropId getPosition identifier)
-                <|> (liftM2 PropNum getPosition decimal)
-        colon
-        val <- parseAssignExpr
-        return (name,val)
-    in do pos <- getPosition
-          props <- braces (parseProp `sepEndBy` comma) <?> "object literal"
-          return $ ObjectLit pos props
-
---{{{ Parsing numbers.  From pg. 17-18 of ECMA-262.
-
-hexLit = do
-  try (string "0x")
-  digits <- many1 (oneOf "0123456789abcdefABCDEF")
-  [(hex,"")] <- return $ Numeric.readHex digits
-  return hex
-
--- Creates a decimal value from a whole, fractional and exponent part.
-mkDecimal:: Double -> Double -> Int -> Double
-mkDecimal w f e =
-  if (f >= 1.0)
-    then mkDecimal w (f / 10.0) e
-    else (w + f) * (10.0 ^^ e)
-
-exponentPart = do
-  oneOf "eE"
-  (char '+' >> decimal) <|> (char '-' >> negate `fmap` decimal) <|> decimal
-  
-decLit =
-  (do whole <- decimal
-      frac <- option 0 (char '.' >> decimal)
-      exp <- option 0  exponentPart
-      return $ mkDecimal (fromIntegral whole) (fromIntegral frac) (fromIntegral exp)) <|>
-  (do frac <- char '.' >> decimal
-      exp <- option 0  exponentPart
-      return $ mkDecimal 0.0 (fromIntegral frac) (fromIntegral exp))
-
-parseNumLit:: ExpressionParser st
-parseNumLit = do
-    pos <- getPosition
-    num <- lexeme $ hexLit <|> decLit
-    notFollowedBy identifierStart <?> "whitespace"
-    return $ NumLit pos num
-
---}}}
-
-------------------------------------------------------------------------------
--- Position Helper
-------------------------------------------------------------------------------
-
-withPos cstr p = do { pos <- getPosition; e <- p; return $ cstr pos e }
-
--------------------------------------------------------------------------------
--- Compound Expression Parsers
--------------------------------------------------------------------------------
-
-dotRef e = (reservedOp "." >> withPos cstr identifier) <?> "property.ref"
-    where cstr pos key = DotRef pos e key
-
-funcApp e = (parens $ withPos cstr (parseExpression `sepBy` comma)) <?> "(function application)"
-    where cstr pos args = CallExpr pos e args
-
-bracketRef e = (brackets $ withPos cstr parseExpression) <?> "[property-ref]"
-    where cstr pos key = BracketRef pos e key
-
--------------------------------------------------------------------------------
--- Expression Parsers
--------------------------------------------------------------------------------
-
-parseParenExpr:: ExpressionParser st
-parseParenExpr = withPos ParenExpr (parens parseListExpr)
-
--- everything above expect functions
-parseExprForNew = parseThisRef <|> parseNullLit <|> parseBoolLit <|> parseStringLit 
-  <|> parseArrayLit <|> parseParenExpr <|> parseNewExpr <|> parseNumLit 
-  <|> parseRegexpLit <|> parseObjectLit <|> parseVarRef
-
--- all the expression parsers defined above
-parseSimpleExpr' = parseThisRef <|> parseNullLit <|> parseBoolLit 
-  <|> parseStringLit <|> parseArrayLit <|> parseParenExpr
-  <|> parseFuncExpr <|> parseNumLit <|> parseRegexpLit <|> parseObjectLit
-  <|> parseVarRef
-
-parseNewExpr =
-  (do pos <- getPosition
-      reserved "new"
-      constructor <- parseSimpleExprForNew Nothing -- right-associativity
-      arguments <- (try (parens (parseExpression `sepBy` comma))) <|> (return [])
-      return (NewExpr pos constructor arguments)) <|>
-  parseSimpleExpr'
-
-parseSimpleExpr (Just e) = (do
-    e' <- dotRef e <|> funcApp e <|> bracketRef e
-    parseSimpleExpr $ Just e') <|> (return e)
-parseSimpleExpr Nothing = do
-  e <- parseNewExpr <?> "expression (3)"
-  parseSimpleExpr (Just e)
-
-parseSimpleExprForNew (Just e) = (do
-    e' <- dotRef e <|> bracketRef e
-    parseSimpleExprForNew $ Just e') <|> (return e)
-parseSimpleExprForNew Nothing = do
-  e <- parseNewExpr <?> "expression (3)"
-  parseSimpleExprForNew (Just e)
-    
---}}}
-
-makeInfixExpr str constr = Infix parser AssocLeft where
-  parser:: CharParser st (Expression SourcePos -> Expression SourcePos -> Expression SourcePos)
-  parser = do
-    pos <- getPosition
-    reservedOp str
-    return (InfixExpr pos constr)  -- points-free, returns a function
-
-makePrefixExpr str constr = Prefix parser where
-  parser = do
-    pos <- getPosition
-    (reservedOp str <|> reserved str)
-    return (PrefixExpr pos constr) -- points-free, returns a function
-    
-mkPrefix operator constr = Prefix $ do
-  pos <- getPosition
-  operator
-  return (\operand -> PrefixExpr pos constr operand)
-
-makePostfixExpr str constr = Postfix parser where
-  parser = do
-    pos <- getPosition
-    (reservedOp str <|> reserved str)
-    return (PostfixExpr pos constr) -- points-free, returns a function
-
-prefixIncDecExpr = do
-  pos <- getPosition
-  op <- optionMaybe $ (reservedOp "++" >> return PrefixInc) <|>
-                      (reservedOp "--" >> return PrefixDec)
-  case op of
-    Nothing -> parseSimpleExpr Nothing
-    Just op -> do
-      innerExpr <- parseSimpleExpr Nothing -- TODO: must be an l-val, I think
-      return (PrefixExpr pos op innerExpr)
-
--- apparently, expression tables can't handle immediately-nested prefixes
-
-parsePrefixedExpr = do
-  pos <- getPosition
-  op <- optionMaybe $ (reservedOp "!" >> return PrefixLNot) <|> 
-                      (reservedOp "~" >> return PrefixBNot) <|>
-                      (try (lexeme $ char '-' >> notFollowedBy (char '-')) >>
-                       return PrefixMinus) <|>
-                      (try (lexeme $ char '+' >> notFollowedBy (char '+')) >>
-                       return PrefixPlus) <|>
-                      (reserved "typeof" >> return PrefixTypeof) <|>
-                      (reserved "void" >> return PrefixVoid) <|>
-                      (reserved "delete" >> return PrefixDelete)
-  case op of
-    Nothing -> prefixIncDecExpr  -- new is treated as a simple expr
-    Just op -> do
-      innerExpr <- parsePrefixedExpr
-      return (PrefixExpr pos op innerExpr)
-
-exprTable:: [[Operator Char st ParsedExpression]]
-exprTable = 
-  [
-   [makePrefixExpr "++" PrefixInc,
-    makePostfixExpr "++" PostfixInc],
-   [makePrefixExpr "--" PrefixDec,
-    makePostfixExpr "--" PostfixDec],
-   [makeInfixExpr "*" OpMul, makeInfixExpr "/" OpDiv, makeInfixExpr "%" OpMod],
-   [makeInfixExpr "+" OpAdd, makeInfixExpr "-" OpSub],
-   [makeInfixExpr "<<" OpLShift, makeInfixExpr ">>" OpSpRShift,
-    makeInfixExpr ">>>" OpZfRShift],
-   [makeInfixExpr "<" OpLT, makeInfixExpr "<=" OpLEq, makeInfixExpr ">" OpGT,
-    makeInfixExpr ">=" OpGEq, 
-    makeInfixExpr "instanceof" OpInstanceof, makeInfixExpr "in" OpIn],
-   [makeInfixExpr "&" OpBAnd], 
-   [makeInfixExpr "^" OpBXor], 
-   [makeInfixExpr "|" OpBOr],
-   [makeInfixExpr "&&" OpLAnd],
-   [makeInfixExpr "||" OpLOr],  
-   [makeInfixExpr "==" OpEq, makeInfixExpr "!=" OpNEq,
-    makeInfixExpr "===" OpStrictEq, makeInfixExpr "!==" OpStrictNEq]
-    ]
-  
-parseExpression' = 
-  buildExpressionParser exprTable parsePrefixedExpr <?> "simple expression"
-
---{{{ Parsing ternary operators: left factored
-
-parseTernaryExpr':: CharParser st (ParsedExpression,ParsedExpression)
-parseTernaryExpr' = do
-    reservedOp "?"
-    l <- parseAssignExpr
-    colon
-    r <- parseAssignExpr
-    return $(l,r)
-
-parseTernaryExpr:: ExpressionParser st
-parseTernaryExpr = do
-  e <- parseExpression'
-  e' <- optionMaybe parseTernaryExpr'
-  case e' of
-    Nothing -> return e
-    Just (l,r) -> do p <- getPosition
-                     return $ CondExpr p e l r
---}}}
-
--- Parsing assignment operations.
-makeAssignExpr str constr = Infix parser AssocRight where
-  parser:: CharParser st (ParsedExpression -> ParsedExpression -> ParsedExpression)
-  parser = do
-    pos <- getPosition
-    reservedOp str
-    return (AssignExpr pos constr)
-
-assignTable:: [[Operator Char st ParsedExpression]]
-assignTable = [
-  [makeAssignExpr "=" OpAssign, makeAssignExpr "+=" OpAssignAdd, 
-    makeAssignExpr "-=" OpAssignSub, makeAssignExpr "*=" OpAssignMul,
-    makeAssignExpr "/=" OpAssignDiv, makeAssignExpr "%=" OpAssignMod,
-    makeAssignExpr "<<=" OpAssignLShift, makeAssignExpr ">>=" OpAssignSpRShift,
-    makeAssignExpr ">>>=" OpAssignZfRShift, makeAssignExpr "&=" OpAssignBAnd,
-    makeAssignExpr "^=" OpAssignBXor, makeAssignExpr "|=" OpAssignBOr
-  ]]
-
-
-parseAssignExpr:: ExpressionParser st
-parseAssignExpr = buildExpressionParser assignTable parseTernaryExpr  
-
-parseExpression:: ExpressionParser st
-parseExpression = parseAssignExpr
-
-parseListExpr =
-  liftM2 ListExpr getPosition (parseAssignExpr `sepBy1` comma)
-
---}}}
-
-parseScript:: CharParser state (JavaScript SourcePos)
-parseScript = do
-  whiteSpace
-  liftM2 Script getPosition (parseStatement `sepBy` whiteSpace)
-  
-parseJavaScriptFromFile :: MonadIO m => String -> m [Statement SourcePos]
-parseJavaScriptFromFile filename = do
-  chars <- liftIO $ readFile filename
-  case parse parseScript filename chars of
-    Left err               -> fail (show err)
-    Right (Script _ stmts) -> return stmts
-
-
-parseScriptFromString:: String -> String -> Either ParseError (JavaScript SourcePos)
-parseScriptFromString src script = parse parseScript src script
-
-emptyParsedJavaScript = 
-  Script (error "Parser.emptyParsedJavaScript--no annotation") []
-
-parseString :: String -> [Statement SourcePos]
-parseString str = case parse parseScript "" str of
-  Left err -> error (show err)
-  Right (Script _ stmts) -> stmts
− src/WebBits/JavaScript/PrettyPrint.hs
@@ -1,261 +0,0 @@--- |Pretty-printing JavaScript.  This module doesn't export any names, but--- importing it declares PrettyPrintable instances for JavaScript.Syntax.-module WebBits.JavaScript.PrettyPrint() where--import Text.PrettyPrint.HughesPJ-import WebBits.JavaScript.Syntax-import WebBits.JavaScript.Combinators-import WebBits.Common----{{{ Helper functions for common printing patterns---- Displays the statement in { ... }, unless it already is in a block.-inBlock:: (Statement a) -> Doc-inBlock stmt@(BlockStmt _ _) = pp stmt-inBlock stmt                 = text "{" $+$ pp stmt $+$ text "}"---- Displays the expression in ( ... ), unless it already is in parens.-inParens:: (Expression a) -> Doc-inParens expr@(ParenExpr _ _) = pp expr-inParens expr                 = parens (pp expr)--commaSep:: (PrettyPrintable a) => [a] -> Doc-commaSep = hsep.(punctuate comma).(map pp)----}}}--instance PrettyPrintable (Id a) where-  pp (Id _ str) = text str--instance PrettyPrintable (ForInit a) where-  pp NoInit         = empty-  pp (VarInit vs) = text "var" <+> commaSep vs -  pp (ExprInit e) = pp e-  -instance PrettyPrintable (ForInInit a) where-  pp (ForInVar id)   = text "var" <+> pp id-  pp (ForInNoVar id) = pp id----{{{ Pretty-printing statements--instance PrettyPrintable (CaseClause a) where-  pp (CaseClause _ expr stmts) =-    text "case" $+$ pp expr <+> colon $$ (nest 2 (vcat (map pp stmts)))-  pp (CaseDefault _ stmts) =-    text "default:" $$ (nest 2 (vcat (map pp stmts)))--instance PrettyPrintable (CatchClause a) where-  pp (CatchClause _ id stmt) =-    text "catch" <+> (parens.pp) id <+> inBlock stmt---instance PrettyPrintable (VarDecl a) where-  pp (VarDecl _ id Nothing) =-    pp id-  pp (VarDecl _ id (Just expr)) =-    pp id <+> equals <+> pp expr--instance PrettyPrintable (Statement a) where-  pp (BlockStmt _ stmts) =-    text "{" $+$ nest 2 (vcat (map pp stmts)) $+$ text "}"-  pp (EmptyStmt _) =-    semi-  pp (ExprStmt _ expr) =-    pp expr <> semi-  pp (IfSingleStmt _ test cons) =-    text "if" <+> inParens test $$ (nest 2 (pp cons))-  pp (IfStmt _ test cons alt) =-    text "if" <+> inParens test $$ (nest 2 $ pp cons) $$ text "else"-      $$ (nest 2 $ pp alt)-  pp (SwitchStmt _ expr cases) =-    text "switch" <+> inParens expr $$ braces (nest 2 (vcat (map pp cases)))-  pp (WhileStmt _ test body) =-    text "while" <+> inParens test $$ (nest 2 (pp body))-  pp (ReturnStmt _ expr) =-    text "return" <+> pp expr <> semi-  pp (DoWhileStmt _ stmt expr) =-    text "do" $$ (nest 2 (pp stmt <+> text "while" <+> inParens expr))-  pp (BreakStmt _ Nothing) =-    text "break;"-  pp (BreakStmt _ (Just label)) =-    text "break" <+> pp label <> semi-  pp (ContinueStmt _ Nothing) =-    text "continue;"-  pp (ContinueStmt _ (Just label)) =-    text"continue" <+> pp label <> semi-  pp (LabelledStmt _ label stmt) =-    pp label <> colon $$ pp stmt-  pp (ForInStmt p init expr body) =-    text "for" <+> parens (pp init <+> text "in" <+> pp expr)-      $$ (nest 2 (pp body))-  pp (ForStmt _ init incr test body) =-    text "for" <+> parens (pp init <> semi <+> pp incr <> semi <+> pp test)-      $$ (nest 2 (pp body))-  pp (TryStmt _ stmt catches finally) =-    text "try" $$ inBlock stmt $$ (vcat (map pp catches)) $$ ppFinally where -      ppFinally = case finally of-        Nothing -> empty-        Just stmt -> text "finally" <> inBlock stmt-  pp (ThrowStmt _ expr) =-    text "throw" <+> pp expr <> semi-  pp (WithStmt _ expr stmt) | isParenExpr expr =-    (text "with" <+> inParens expr $$ pp stmt)-  pp (WithStmt _ expr stmt) | otherwise =-      (text "with" <+> inParens expr $$ pp stmt)-  pp (VarDeclStmt _ decls) =-    text "var" <+> commaSep decls <> semi-  pp (FunctionStmt _ name args stmt) =-    text "function" <+> pp name <> (parens.commaSep) args $$ inBlock stmt----}}}--instance PrettyPrintable (Prop a) where-  pp (PropId _ id) = pp id-  pp (PropString _ str) = doubleQuotes (text (jsEscape str))-  pp (PropNum _ n) = text (show n)-----{{{ infix-operators--showInfix op =-  case op of-    OpMul -> "*"-    OpDiv -> "/"-    OpMod -> "%" -    OpAdd -> "+" -    OpSub -> "-"-    OpLShift -> "<<"-    OpSpRShift -> ">>"-    OpZfRShift -> ">>>"-    OpLT -> "<"-    OpLEq -> "<="-    OpGT -> ">"-    OpGEq -> ">="-    OpIn -> "in"-    OpInstanceof -> "instanceof"-    OpEq -> "=="-    OpNEq -> "!="-    OpStrictEq -> "==="-    OpStrictNEq -> "!=="-    OpBAnd -> "&"-    OpBXor -> "^"-    OpBOr -> "|"-    OpLAnd -> "&&"-    OpLOr -> "||"--instance PrettyPrintable InfixOp where-  pp op = text (showInfix op)---}}}----{{{ prefix operators--showPrefix PrefixInc = "++"-showPrefix PrefixDec = "--"-showPrefix PrefixLNot = "!"-showPrefix PrefixBNot = "~"-showPrefix PrefixPlus = "+"-showPrefix PrefixMinus = "-"-showPrefix PrefixTypeof = "typeof"-showPrefix PrefixVoid = "void"-showPrefix PrefixDelete = "delete"--instance PrettyPrintable PrefixOp where-  pp op = text (showPrefix op)----}}}----{{{ postfix operators--instance PrettyPrintable PostfixOp where-  pp PostfixInc = text "++"-  pp PostfixDec = text "--"----}}}----{{{ assignment operators--showAssignOp OpAssign = "="-showAssignOp OpAssignAdd = "+="-showAssignOp OpAssignSub = "-="-showAssignOp OpAssignMul = "*="-showAssignOp OpAssignDiv = "/="-showAssignOp OpAssignMod = "%="-showAssignOp OpAssignLShift = "<<="-showAssignOp OpAssignSpRShift = ">>="-showAssignOp OpAssignZfRShift = ">>>="-showAssignOp OpAssignBAnd = "&="-showAssignOp OpAssignBXor = "^="-showAssignOp OpAssignBOr = "|="--instance PrettyPrintable AssignOp where-  pp = text.showAssignOp----}}}----{{{ expressions---- Based on:---   http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Guide:Literals-jsEscape:: String -> String-jsEscape "" = ""-jsEscape (ch:chs) = (sel ch) ++ jsEscape chs where-    sel '\b' = "\\b"-    sel '\f' = "\\f"-    sel '\n' = "\\n"-    sel '\r' = "\\r"-    sel '\t' = "\\t"-    sel '\v' = "\\v"-    sel '\'' = "\\'"-    sel '\"' = "\\\""-    sel '\\' = "\\\\"-    sel x    = [x]-    -- We don't have to do anything about \X, \x and \u escape sequences.--  -instance PrettyPrintable (Expression a) where-  pp (StringLit _ str) = doubleQuotes (text (jsEscape str))-  pp (RegexpLit _ re global ci) =-    text "/" <> text re <> text "/" <> g <> i where-      g = if global then text "g" else empty-      i = if ci then text "i" else empty-  pp (NumLit _ n) =  text (show n)-  pp (BoolLit _ True) = text "true"-  pp (BoolLit _ False) = text "false"-  pp (NullLit _) = text "null"-  pp (ArrayLit _ xs) = -    (brackets.commaSep) xs-  pp (ObjectLit _ xs) = -    braces (hsep (punctuate comma (map pp' xs))) where-      pp' (n,v) = pp n <> colon <+> pp v-  pp (ThisRef _) = text "this"-  pp (VarRef _ id) = pp id-  pp (DotRef _ expr id) =-    pp expr <> text "." <> pp id-  pp (BracketRef _ container key) =-    pp container <> brackets (pp key)-  pp (NewExpr _ constr args) =-    text "new" <+> pp constr <> (parens.commaSep) args-  pp (PrefixExpr _ op expr) =-    pp op <+> pp expr-  pp (PostfixExpr _ op expr) =-    pp expr <+> pp op-  pp (InfixExpr _ op left right) = -    pp left <+> pp op <+> pp right-  pp (CondExpr _ test cons alt) =-    pp test <+> text "?" <+> pp cons <+> colon <+> pp alt-  pp (AssignExpr _ op l r) =-    pp l <+> pp op <+> pp r-  pp (ParenExpr _ expr) =-    parens (pp expr)-  pp (ListExpr _ exprs) = commaSep exprs-  pp (CallExpr _ f args) =-    pp f <> (parens.commaSep) args-  pp (FuncExpr _ args body) =-    text "function" <+> (parens.commaSep) args $$ inBlock body--instance PrettyPrintable (JavaScript a) where-  pp (Script _ stmts) =-    vcat (map pp stmts)----}}}-
− src/WebBits/JavaScript/Syntax.hs
@@ -1,117 +0,0 @@--- |JavaScript's syntax.
-module WebBits.JavaScript.Syntax(Expression(..),CaseClause(..),Statement(..),
-         InfixOp(..),CatchClause(..),VarDecl(..),JavaScript(..),
-         AssignOp(..),Id(..),PrefixOp(..),PostfixOp(..),Prop(..),
-         ForInit(..),ForInInit(..)) where
-
-import Text.ParserCombinators.Parsec(SourcePos) -- used by data JavaScript
-import Data.Generics(Data,Typeable)
-
-data JavaScript a
-  -- |A script in <script> ... </script> tags.  This may seem a little silly,
-  -- but the Flapjax analogue has an inline variant and attribute-inline 
-  -- variant.
-  = Script a [Statement a] 
-  deriving (Show,Data,Typeable,Eq,Ord)
-
-data Id a = Id a String deriving (Show,Eq,Ord,Data,Typeable)
-
--- http://developer.mozilla.org/en/docs/
---   Core_JavaScript_1.5_Reference:Operators:Operator_Precedence
-data InfixOp = OpLT | OpLEq | OpGT | OpGEq  | OpIn  | OpInstanceof | OpEq | OpNEq
-             | OpStrictEq | OpStrictNEq | OpLAnd | OpLOr 
-             | OpMul | OpDiv | OpMod  | OpSub | OpLShift | OpSpRShift
-             | OpZfRShift | OpBAnd | OpBXor | OpBOr | OpAdd
-    deriving (Show,Data,Typeable,Eq,Ord,Enum)
-
-data AssignOp = OpAssign | OpAssignAdd | OpAssignSub | OpAssignMul | OpAssignDiv
-  | OpAssignMod | OpAssignLShift | OpAssignSpRShift | OpAssignZfRShift
-  | OpAssignBAnd | OpAssignBXor | OpAssignBOr
-  deriving (Show,Data,Typeable,Eq,Ord)
-
-data PrefixOp = PrefixInc | PrefixDec | PrefixLNot | PrefixBNot | PrefixPlus
-  | PrefixMinus | PrefixTypeof | PrefixVoid | PrefixDelete
-  deriving (Show,Data,Typeable,Eq,Ord)
-  
-data PostfixOp 
-  = PostfixInc | PostfixDec
-  deriving (Show,Data,Typeable,Eq,Ord)
-  
-data Prop a 
-  = PropId a (Id a) | PropString a String | PropNum a Integer
-  deriving (Show,Data,Typeable,Eq,Ord)
-
-data Expression a
-  = StringLit a String
-  | RegexpLit a String Bool {- global? -} Bool {- case-insensitive? -}
-  | NumLit a Double -- pg. 5 of ECMA-262
-  | BoolLit a Bool
-  | NullLit a
-  | ArrayLit a [Expression a]
-  | ObjectLit a [(Prop a, Expression a)]
-  | ThisRef a
-  | VarRef a (Id a)
-  | DotRef a (Expression a) (Id a)
-  | BracketRef a (Expression a) {- container -} (Expression a) {- key -}
-  | NewExpr a (Expression a) {- constructor -} [Expression a]
-  | PostfixExpr a PostfixOp (Expression a)
-  | PrefixExpr a PrefixOp (Expression a)
-  | InfixExpr a InfixOp (Expression a) (Expression a)
-  | CondExpr a (Expression a) (Expression a) (Expression a)
-  | AssignExpr a AssignOp (Expression a) (Expression a)
-  | ParenExpr a (Expression a)
-  | ListExpr a [Expression a]
-  | CallExpr a (Expression a) [Expression a]
-  | FuncExpr a [(Id a)] (Statement a)
-  deriving (Show,Data,Typeable,Eq,Ord)
-
-data CaseClause a 
-  = CaseClause a (Expression a) [Statement a]
-  | CaseDefault a [Statement a]
-  deriving (Show,Data,Typeable,Eq,Ord)
-  
-data CatchClause a 
-  = CatchClause a (Id a) (Statement a) 
-  deriving (Show,Data,Typeable,Eq,Ord)
-
-data VarDecl a 
-  = VarDecl a (Id a) (Maybe (Expression a)) 
-  deriving (Show,Data,Typeable,Eq,Ord)
-  
-data ForInit a
-  = NoInit
-  | VarInit [VarDecl a]
-  | ExprInit (Expression a)
-  deriving (Show,Data,Typeable,Eq,Ord)
-
-data ForInInit a
- = ForInVar (Id a)
- | ForInNoVar (Id a)
- deriving (Show,Data,Typeable,Eq,Ord)
-  
-  
-data Statement a
-  = BlockStmt a [Statement a]
-  | EmptyStmt a
-  | ExprStmt a (Expression a)
-  | IfStmt a (Expression a) (Statement a) (Statement a)
-  | IfSingleStmt a (Expression a) (Statement a)
-  | SwitchStmt a (Expression a) [CaseClause a]
-  | WhileStmt a (Expression a) (Statement a)
-  | DoWhileStmt a (Statement a) (Expression a)
-  | BreakStmt a (Maybe (Id a))
-  | ContinueStmt a (Maybe (Id a))
-  | LabelledStmt a (Id a) (Statement a)
-  | ForInStmt a (ForInInit a) (Expression a) (Statement a)
-  | ForStmt a (ForInit a)        
-              (Maybe (Expression a)) -- increment
-              (Maybe (Expression a)) -- test
-              (Statement a)          -- body
-  | TryStmt a (Statement a) {-body-} [CatchClause a] {-catches-}
-      (Maybe (Statement a)) {-finally-}
-  | ThrowStmt a (Expression a)
-  | ReturnStmt a (Maybe (Expression a))
-  | WithStmt a (Expression a) (Statement a)
-  | VarDeclStmt a [VarDecl a]
-  | FunctionStmt a (Id a) {-name-} [(Id a)] {-args-} (Statement a) {-body-}
-  deriving (Show,Data,Typeable,Eq,Ord)