packages feed

hjsmin 0.0.9 → 0.0.11

raw patch · 7 files changed

+211/−1932 lines, 7 filesdep −attoparsecdep ~language-javascriptPVP ok

version bump matches the API change (PVP)

Dependencies removed: attoparsec

Dependency ranges changed: language-javascript

API changes (from Hackage documentation)

Files

README.markdown view
@@ -25,6 +25,12 @@  ./dist/build/runtests/runtests +Changes+-------++0.0.11 - Worked in language-javascript 0.4.*, with source locations in the AST+         Worked in processing of property get/set in object literals+0.0.10 - Removed attoparsec dependency and historical Parse/Token   
Text/Jasmine.hs view
@@ -42,8 +42,8 @@ lbToStr :: S8.ByteString -> [Char] lbToStr str = S8.unpack str -strToLb :: String -> S8.ByteString-strToLb str = S8.pack str---strToLb str = (LB.fromChunks [(E.encodeUtf8 $ T.pack str)])+_strToLb :: String -> S8.ByteString+_strToLb str = S8.pack str+       -- EOF    
− Text/Jasmine/Parse.hs
@@ -1,1186 +0,0 @@-{-# LANGUAGE DeriveDataTypeable #-}-module Text.Jasmine.Parse-    (       -      readJs-    , readJsm  -    , JasmineSettings (..)-    , defaultJasmineSettings-    , JSNode(..)  -    , parseFile  -    , parseString  -    -- For testing      -    , parseProgram  -    {-  -    , doParse-    , program  -    , functionDeclaration-    , identifier-    , statementList  -    , iterationStatement  -    , main  -    -}-    ) where---- -----------------------------------------------------------------------import Control.Applicative ( (<|>) )-import Control.Monad-import Data.Attoparsec.Lazy (eitherResult,parse,Result(..))-import Data.Attoparsec.Char8 (char, satisfy, try, Parser, (<?>), endOfInput, many, sepBy, sepBy1, many1, takeWhile)-import Data.Char-import Data.Data-import Data.List hiding (takeWhile)-import Prelude hiding (catch, takeWhile)-import System.Environment-import qualified Data.ByteString.Lazy as LB-import qualified Data.Text as T-import qualified Data.Text.Encoding as E-import qualified Text.Jasmine.Token as P-import qualified Data.ByteString.Char8 as S8---- ----------------------------------------------------------------------{--data Result v = Error String | Ok v-    deriving (Show, Eq, Read, Data, Typeable)-instance Monad Result where-    return = Ok-    Error s >>= _ = Error s-    Ok v >>= f = f v-    fail = Error-instance Functor Result where-    fmap = liftM-instance Applicative Result where-    pure = return-    (<*>) = ap--}---- -----------------------------------------------------------------------data JSNode = JSArguments [[JSNode]]  -              | JSArrayLiteral [JSNode]-              | JSBlock JSNode-              | JSBreak [JSNode] [JSNode]-              | JSCallExpression String [JSNode] -- type : ., (), []; rest  -              | JSCase JSNode JSNode-              | JSCatch JSNode [JSNode] JSNode-              | JSContinue [JSNode]-              | JSDecimal Integer   -              | JSDefault JSNode-              | JSDoWhile JSNode JSNode JSNode-              | JSElement String [JSNode]-              | JSElementList [JSNode]  -              | JSElision [JSNode]  -              | JSEmpty JSNode-              | JSExpression [JSNode]-              | JSExpressionBinary String [JSNode] [JSNode]-              | JSExpressionParen JSNode-              | JSExpressionPostfix String [JSNode]-              | JSExpressionTernary [JSNode] [JSNode] [JSNode]-              | JSFinally JSNode  -              | JSFor [JSNode] [JSNode] [JSNode] JSNode                -              | JSForIn [JSNode] JSNode JSNode-              | JSForVar [JSNode] [JSNode] [JSNode] JSNode                -              | JSForVarIn JSNode JSNode JSNode -              | JSFunction JSNode [JSNode] JSNode -- name, parameter list, body-              | JSFunctionBody [JSNode]-              | JSFunctionExpression [JSNode] JSNode -- name, parameter list, body                -              | JSHexInteger Integer  -              | JSIdentifier String-              | JSIf JSNode JSNode  -              | JSIfElse JSNode JSNode JSNode -              | JSLabelled JSNode JSNode  -              | JSLiteral String  -              | JSMemberDot [JSNode]  -              | JSMemberSquare JSNode [JSNode]  -              | JSObjectLiteral [JSNode]  -              | JSOperator String  -              | JSPropertyNameandValue JSNode [JSNode]-              | JSRegEx String-              | JSReturn [JSNode]-              | JSSourceElements [JSNode]-              | JSSourceElementsTop [JSNode]-              | JSStatementList [JSNode]-              | JSStringLiteral Char [Char]-              | JSSwitch JSNode [JSNode]-              | JSThrow JSNode  -              | JSTry JSNode [JSNode]  -              | JSUnary String  -              | JSVarDecl JSNode [JSNode]-              | JSVariables String [JSNode]  -              | JSWhile JSNode JSNode-              | JSWith JSNode [JSNode]-    deriving (Show, Eq, Read, Data, Typeable)----- ------------------------------------------------------------------------ | Settings for parsing of a javascript document.-data JasmineSettings = JasmineSettings-    {-      -- | Placeholder in the structure, no actual settings yet-      hjsminPlaceholder :: String-    }---- ------------------------------------------------------------------------ | Defaults settings: settings not currently used-defaultJasmineSettings :: JasmineSettings-defaultJasmineSettings = JasmineSettings "foo"---- ------------------------------------------------------------------------ Interface to the Tokeniser--identifier :: Parser JSNode-identifier  = do{ val <- P.identifier;-                  return (JSIdentifier val)}--autoSemi :: Parser JSNode-autoSemi = fmap JSLiteral P.autoSemi--autoSemi' :: Parser JSNode-autoSemi' = fmap JSLiteral P.autoSemi'---- TODO: Maybe? get rid of these, and call them directly via the full name.---       BUT, compiler optimisation should get rid of them anyway-rOp :: String -> Parser ()-rOp = P.rOp--lChar :: Char -> Parser ()-lChar = P.lChar---- ------------------------------------------------------------------------ Make Attoparsec work with parsec--letter :: Parser Char-letter = satisfy isAlpha <?> "letter"--eof :: Parser ()-eof = endOfInput---- ------------------------------------------------------------------------ The parser, based on the gold parser for Javascript--- http://www.devincook.com/GOLDParser/grammars/files/JavaScript.zip- --- ---------------------------------------------------------------Modified from HJS--stringLiteral :: Parser JSNode-stringLiteral =-    P.lexeme $  go '"' <|> go '\''-  where-    go c = do-        _ <- char c-        s <- takeWhile $ \x -> isPrint x && x /= c-        _ <- char c-        return $ JSStringLiteral c $ S8.unpack s---- ---------------------------------------------------------------decimalLiteral :: Parser Integer-decimalLiteral = P.dec--hexIntegerLiteral :: Parser Integer-hexIntegerLiteral = P.hex  ---- {String Chars1} = {Printable} + {HT} - ["\] --- {RegExp Chars} = {Letter}+{Digit}+['^']+['$']+['*']+['+']+['?']+['{']+['}']+['|']+['-']+['.']+[',']+['#']+['[']+[']']+['_']+['<']+['>']--- {Non Terminator} = {String Chars1} - {CR} - {LF}--- RegExp         = '/' ({RegExp Chars} | '\' {Non Terminator})+ '/' ( 'g' | 'i' | 'm' )*---- ------------------------------------------------------------------------ From HJS--regex :: Parser [Char]-regex = do { _ <- char '/'; body <- do { c <- firstchar; cs <- many otherchar; return $ concat (c:cs) }; _ <- char '/'; -             flg <- identPart; return $ ("/"++body++"/"++flg) }--firstchar :: Parser [Char]-firstchar = do { c <- satisfy (\c -> isPrint c && c /= '*' && c /= '\\' && c /= '/'); -                 return [c]} <|> escapeseq--escapeseq :: Parser [Char]-escapeseq = do { _ <- char '\\'; c <- satisfy (\cc -> isPrint cc); return ['\\',c]}--otherchar :: Parser [Char]-otherchar = do { c <- satisfy (\c -> isPrint c && c /= '\\' && c /= '/'); -                 return [c]} <|> escapeseq--identPart :: Parser [Char]-identPart = many letter---- ------------------------------------------------------------------------regExp :: Parser JSNode-regExp = P.lexeme $ do { v1 <- regex;       -              return (JSRegEx v1)}---- <Literal> ::= <Null Literal>---             | <Boolean Literal>---             | <Numeric Literal>---             | StringLiteral-literal :: Parser JSNode-literal = nullLiteral-      <|> booleanLiteral-      <|> numericLiteral-      <|> stringLiteral---- <Null Literal>    ::= null-nullLiteral :: Parser JSNode-nullLiteral = do { _ <- P.reserved "null"; -                   return (JSLiteral "null")}---- <Boolean Literal> ::= 'true'---                     | 'false'-booleanLiteral :: Parser JSNode-booleanLiteral = do{ _ <- P.reserved "true" ; -                     return (JSLiteral "true")}-             <|> do{ P.reserved "false"; -                     return (JSLiteral "false")}---- <Numeric Literal> ::= DecimalLiteral---                     | HexIntegerLiteral-numericLiteral :: Parser JSNode-numericLiteral = do {val <- decimalLiteral; -                     return (JSDecimal val)}-             <|> do {val <- hexIntegerLiteral; -                     return (JSHexInteger val)}----- <Regular Expression Literal> ::= RegExp -regularExpressionLiteral :: Parser JSNode-regularExpressionLiteral = regExp----- <Primary Expression> ::= 'this'---                        | Identifier---                        | <Literal> ---                        | <Array Literal>---                        | <Object Literal>---                        | '(' <Expression> ')'---                        | <Regular Expression Literal>-primaryExpression :: Parser JSNode-primaryExpression = do {P.reserved "this"; -                        -- return [""]} -                        return (JSLiteral "this")}-                <|> identifier-                <|> literal-                <|> arrayLiteral-                <|> objectLiteral-                <|> do{ rOp "("; val <- expression; rOp ")"; -                        return (JSExpressionParen val)}-                <|> regularExpressionLiteral---- ------------------------------------------------------------------------ Rework array literal----- <Array Literal> ::= '[' ']'---                   | '[' <Elision> ']'---                   | '[' <Element List> ']'---                   | '[' <Element List> ',' <Elision> ']'---- <Elision> ::= ','---             | <Elision> ','---- <Element List> ::= <Elision> <Assignment Expression>---                  | <Element List> ',' <Elision>  <Assignment Expression>---                  | <Element List> ',' <Assignment Expression>---                  | <Assignment Expression>-------------so---- <Array Literal> ::= '[' many (',' <|> assignment) ']'----- ------------------------------------------------------------------------- <Array Literal> ::= '[' ']'---                   | '[' <Elision> ']'---                   | '[' <Element List> ']'---                   | '[' <Element List> ',' <Elision> ']'-arrayLiteral :: Parser JSNode-arrayLiteral = do {rOp "["; v1 <- many (do { rOp ","; return [(JSElision [])]} <|> assignmentExpression); rOp "]";-                   return (JSArrayLiteral (flatten v1)) }--{--arrayLiteral :: GenParser Char P.JSPState JSNode-arrayLiteral = do {rOp "["; -                   do {-                        do { rOp "]"; -                             return (JSArrayLiteral [])}-                    <|> do { v1 <- elision; rOp "]"; -                             return (JSArrayLiteral [v1])}-                    <|> do { v1 <- elementList; rOp "]"; -                             do {-                               do { rOp ","; v2 <- elision; rOp "]"; -                                    return (JSArrayLiteral (v1++[v2]))}-                               <|> return (JSArrayLiteral v1)-                               }-                             }-                        }-                   }----- <Elision> ::= ','---             | <Elision> ','-elision :: GenParser Char P.JSPState JSNode-elision = do{ rOp ",";-              return (JSElision [])}-      <|> do{ v1 <- elision; rOp ",";-              return (JSElision [v1])}-    ---- <Element List> ::= <Elision> <Assignment Expression>---                  | <Element List> ',' <Elision>  <Assignment Expression>---                  | <Element List> ',' <Assignment Expression>---                  | <Assignment Expression>-elementList :: GenParser Char P.JSPState [JSNode]-elementList = do { v1 <- elision; v2 <- assignmentExpression; v3 <-rest;-                   return [(JSElementList (v1:(v2++v3)))] }-          <|> do { v1 <- assignmentExpression; v2 <- rest;-                   return [(JSElementList (v1++v2))]}-          where   -            rest =-                  do {rOp ",";-                      do { -                            do { v2 <- elision; v3 <- assignmentExpression;-                                return [] {- ([v2]++v3)-}}-                        <|> do { v2 <- assignmentExpression;-                                return [] {-v2-}}-                         }-                      }-                  <|> do {return []}--}   ---- <Object Literal> ::= '{' <Property Name and Value List> '}'-objectLiteral :: Parser JSNode-objectLiteral = do{ rOp "{"; val <- propertyNameandValueList; rOp "}"; -                   return (JSObjectLiteral val)}---- <Property Name and Value List> ::= <Property Name> ':' <Assignment Expression>---                                  | <Property Name and Value List> ',' <Property Name> ':' <Assignment Expression>-propertyNameandValueList :: Parser [JSNode]-propertyNameandValueList = do{ val <- sepBy propertyNameandValue (rOp ","); -- Note: can be zero elements-                               return val}-                           --- Seems we can have function declarations in the value part too                           -propertyNameandValue :: Parser JSNode-propertyNameandValue = do{ v1 <- propertyName; rOp ":"; -                           do {-                                do {v2 <- assignmentExpression;-                                    return (JSPropertyNameandValue v1 v2)}-                            <|> do {v2 <- functionDeclaration;    -                                    return (JSPropertyNameandValue v1 [v2])}-                                }-                           }---- <Property Name> ::= Identifier---                   | StringLiteral---                   | <Numeric Literal>-propertyName :: Parser JSNode-propertyName = identifier-           <|> stringLiteral-           <|> numericLiteral----- <Member Expression > ::= <Primary Expression>---                        | <Function Expression>---                        | <Member Expression> '[' <Expression> ']'---                        | <Member Expression> '.' Identifier---                        | 'new' <Member Expression> <Arguments>-memberExpression :: Parser [JSNode]-memberExpression = (do{ P.reserved "new"; v1 <- memberExpression; v2 <- arguments; -                        return (((JSLiteral "new "):v1)++[v2])}) -- xxxx-                <|> memberExpression'----memberExpression' :: GenParser Char P.JSPState [JSNode]-memberExpression' :: Parser [JSNode]-memberExpression' = do-    v1 <- functionExpression <|> primaryExpression-    v2 <- rest-    return $ v1 : v2--                where-                  rest = do{ rOp "["; v1 <- expression; rOp "]"; v2 <- rest;-                             return [JSMemberSquare v1 v2]}-                     <|> do{ rOp "."; v1 <- identifier ; v2 <- rest;-                             return [JSMemberDot (v1:v2)]}-                     <|> return []-                         ----- <New Expression> ::= <Member Expression>---                    | new <New Expression>-newExpression :: Parser [JSNode]-newExpression = memberExpression-           <|> do{ P.reserved "new"; val <- newExpression;-                   return ((JSLiteral "new "):val)}---- <Call Expression> ::= <Member Expression> <Arguments>---                     | <Call Expression> <Arguments> ---                     | <Call Expression> '[' <Expression> ']'---                     | <Call Expression> '.' Identifier--callExpression :: Parser [JSNode]-callExpression = do{ v1 <- memberExpression; v2 <- arguments; -                      do { v3 <- rest; -                          return (v1++[v2]++v3)}-                  <|> do {return (v1++[v2]    )}-                   }-                 where-                   rest =-                         do{ v4 <- arguments ; v5 <- rest;-                             return ([(JSCallExpression "()" [v4])]++v5)}-                     <|> do{ rOp "["; v4 <- expression; rOp "]"; v5 <- rest;-                             return ([JSCallExpression "[]" [v4]]++v5)}-                     <|> do{ rOp "."; v4 <- identifier; v5 <- rest;-                             return ([JSCallExpression "." [v4]]++v5)}-                     <|> return [] -- As per HJS, seems to extend the syntax---- ------------------------------------------------------------------------ From HJS-{-                   -callExpr = do { x <- memberExpr;-               do {rOp "("; whiteSpace; args <- commaSep assigne; whiteSpace; rOp ")"; rest $ CallMember x args } -           <|> do { return $ CallPrim x } -           <|> do { rOp "++"; return $ CallPrim x }-              }-           where-                  rest x = -                               try (do { rOp "("; args <- commaSep assigne; rOp ")" ; rest $ CallCall x args })-                           <|> try (do { rOp "."; i <- identifier; rest $ CallDot x i })-                           <|> try (do { rOp "["; e <- expr; rOp "]"; rest $ CallSquare x e })-                           <|> return x --}--- -----------------------------------------------------------------------lparen, rparen, comma :: Char-lparen = '('-rparen = ')'-comma  = ','---- <Arguments> ::= '(' ')'---               | '(' <Argument List> ')'-arguments :: Parser JSNode-arguments = do-    _ <- lChar lparen-    x <- ((lChar rparen) >> return [[]]) -         <|> (do x <- argumentList-                 _ <- lChar rparen-                 return x)-    return $ JSArguments x---- <Argument List> ::= <Assignment Expression>---                   | <Argument List> ',' <Assignment Expression>-argumentList :: Parser [[JSNode]]-argumentList = sepBy1 assignmentExpression $ lChar comma---- <Left Hand Side Expression> ::= <New Expression> ---                               | <Call Expression>-leftHandSideExpression :: Parser [JSNode]-leftHandSideExpression = callExpression-                     <|> newExpression-                     <?> "leftHandSideExpression"----- <Postfix Expression> ::= <Left Hand Side Expression>---                        | <Postfix Expression> '++'---                        | <Postfix Expression> '--'-postfixExpression :: Parser [JSNode]-postfixExpression = do{ v1 <- leftHandSideExpression;-                        do {-                              do{ rOp "++"; return [(JSExpressionPostfix "++" v1)]}-                          <|> do{ rOp "--"; return [(JSExpressionPostfix "--" v1)]}-                          <|> return v1-                           }-                        }---- <Unary Expression> ::= <Postfix Expression>---                      | 'delete' <Unary Expression>---                      | 'void' <Unary Expression>---                      | 'typeof' <Unary Expression>---                      | '++' <Unary Expression>---                      | '--' <Unary Expression>---                      | '+' <Unary Expression>---                      | '-' <Unary Expression>---                      | '~' <Unary Expression>---                      | '!' <Unary Expression>-unaryExpression :: Parser [JSNode]-unaryExpression = do{ v1 <- postfixExpression; -                      return v1}-              <|> do{ P.reserved "delete"; v1 <- unaryExpression;-                      return ((JSUnary "delete "):v1)}-              <|> do{ P.reserved "void";   v1 <- unaryExpression;-                      return ((JSUnary "void"):v1)}-              <|> do{ P.reserved "typeof"; v1 <- unaryExpression; -                      return ((JSUnary "typeof "):v1)} -- TODO: should the space always be there?-              <|> do{ rOp "++"; v1 <- unaryExpression;-                      return ((JSUnary "++"):v1)}-              <|> do{ rOp "--"; v1 <- unaryExpression;-                      return ((JSUnary "--"):v1)}-              <|> do{ rOp "+"; v1 <- unaryExpression;-                      return ((JSUnary "+"):v1)}-              <|> do{ rOp "-"; v1 <- unaryExpression;-                      return ((JSUnary "-"):v1)}-              <|> do{ rOp "~"; v1 <- unaryExpression;-                      return ((JSUnary "~"):v1)}-              <|> do{ rOp "!"; v1 <- unaryExpression;-                      return ((JSUnary "!"):v1)}---- <Multiplicative Expression> ::= <Unary Expression>---                               | <Unary Expression> '*' <Multiplicative Expression> ---                               | <Unary Expression> '/' <Multiplicative Expression>                               ---                               | <Unary Expression> '%' <Multiplicative Expression> -multiplicativeExpression :: Parser [JSNode]-multiplicativeExpression = do{ v1 <- unaryExpression; v2 <- rest;-                               return (v1++v2)}-                           where-                             rest =-                                  do{ rOp "*"; v2 <- multiplicativeExpression; v3 <- rest;-                                      return [(JSExpressionBinary "*" v2 v3)]}-                                  <|> do{ rOp "/"; v2 <- multiplicativeExpression; v3 <- rest;-                                          return [(JSExpressionBinary "/" v2 v3)]}-                                  <|> do{ rOp "%"; v2 <- multiplicativeExpression; v3 <- rest;-                                          return [(JSExpressionBinary "%" v2 v3)]}-                                  <|> return []----- <Additive Expression> ::= <Additive Expression>'+'<Multiplicative Expression> ---                         | <Additive Expression>'-'<Multiplicative Expression>  ---                         | <Multiplicative Expression>-additiveExpression :: Parser [JSNode]-additiveExpression = do{ v1 <- multiplicativeExpression; v2 <- rest;-                         return (v1++v2)}-                     where-                       rest =-                             do { rOp "+"; v2 <- multiplicativeExpression; v3 <- rest;-                                  return ([(JSExpressionBinary "+" v2 v3)])}-                         <|> do { rOp "-"; v2 <- multiplicativeExpression; v3 <- rest;-                                  return ([(JSExpressionBinary "-" v2 v3)])}-                         <|>  return []----- <Shift Expression> ::= <Shift Expression> '<<' <Additive Expression>---                      | <Shift Expression> '>>' <Additive Expression>---                      | <Shift Expression> '>>>' <Additive Expression>---                      | <Additive Expression>-shiftExpression :: Parser [JSNode]-shiftExpression = do{ v1 <- additiveExpression; v2 <- rest;   -                      return (v1++v2)}-                  where-                    rest =-                          do{ rOp "<<"; v2 <- additiveExpression; v3 <- rest;-                              return [(JSExpressionBinary "<<" v2 v3)]}-                      <|> do{ rOp ">>>"; v2 <- additiveExpression; v3 <- rest;-                              return [(JSExpressionBinary ">>>" v2 v3)]}-                      <|> do{ rOp ">>"; v2 <- additiveExpression; v3 <- rest;-                              return [(JSExpressionBinary ">>" v2 v3)]}-                      <|> return []----- <Relational Expression>::= <Shift Expression> ---                          | <Relational Expression> '<' <Shift Expression> ---                          | <Relational Expression> '>' <Shift Expression> ---                          | <Relational Expression> '<=' <Shift Expression> ---                          | <Relational Expression> '>=' <Shift Expression> ---                          | <Relational Expression> 'instanceof' <Shift Expression> -relationalExpression :: Parser [JSNode]-relationalExpression = do{ v1 <- shiftExpression; v2 <- rest;-                           return (v1++v2)}-                       where-                         rest =-                                 do{ rOp "<="; v2 <- shiftExpression; v3 <- rest;-                                     return [(JSExpressionBinary "<=" v2 v3)]}-                             <|> do{ rOp ">="; v2 <- shiftExpression; v3 <- rest;-                                     return [(JSExpressionBinary ">=" v2 v3)]}--                             <|> do{ rOp "<"; v2 <- shiftExpression; v3 <- rest;-                                     return [(JSExpressionBinary "<" v2 v3)]}-                             <|> do{ rOp ">"; v2 <- shiftExpression; v3 <- rest;-                                     return [(JSExpressionBinary ">" v2 v3)]}-                             <|> do{ P.reserved "instanceof"; v2 <- shiftExpression; v3 <- rest;-                                     return [(JSExpressionBinary " instanceof " v2 v3)]}-                             -- Strictly speaking should have all the NoIn variants of expressions,    -                             -- but we assume syntax is checked so no problem. Cross fingers.    -                             <|> do{ P.reserved "in"; v2 <- shiftExpression; v3 <- rest;-                                     return [(JSExpressionBinary " in " v2 v3)]}-                             <|> return []------ <Equality Expression> ::= <Relational Expression>---                         | <Equality Expression> '==' <Relational Expression>---                         | <Equality Expression> '!=' <Relational Expression>---                         | <Equality Expression> '===' <Relational Expression>---                         | <Equality Expression> '!==' <Relational Expression>-equalityExpression :: Parser [JSNode]-equalityExpression = do-    v1 <- relationalExpression-    v2 <- rest-    return $ v1 ++ v2-  where-    rest = equals <|> exclaim <|> return []-    equals = do-        _ <- char '='-        _ <- char '='-        sign <- P.lexeme $ (char '=' >> return "===") <|> return "=="-        v2 <- relationalExpression-        v3 <- rest-        return [JSExpressionBinary sign v2 v3]-    exclaim = do-        _ <- char '!'-        _ <- char '='-        sign <- P.lexeme $ (char '=' >> return "!==") <|> return "!="-        v2 <- relationalExpression-        v3 <- rest-        return [JSExpressionBinary sign v2 v3]--bitwiseExpression :: Parser [JSNode] -> Char -> Parser [JSNode]-bitwiseExpression prev op = do-    v1 <- prev-    v2 <- rest-    return $ v1 ++ v2-  where-    rest = (do-        _ <- P.lexeme $ char op-        v2 <- equalityExpression-        v3 <- rest-        return [JSExpressionBinary [op] v2 v3]) <|> return []---- <Bitwise And Expression> ::= <Equality Expression>---                            | <Bitwise And Expression> '&' <Equality Expression>-bitwiseAndExpression :: Parser [JSNode]-bitwiseAndExpression = bitwiseExpression equalityExpression '&'---- <Bitwise XOr Expression> ::= <Bitwise And Expression>---                            | <Bitwise XOr Expression> '^' <Bitwise And Expression>-bitwiseXOrExpression :: Parser [JSNode]-bitwiseXOrExpression = bitwiseExpression bitwiseAndExpression '^'---- <Bitwise Or Expression> ::= <Bitwise XOr Expression>---                           | <Bitwise Or Expression> '|' <Bitwise XOr Expression>-bitwiseOrExpression :: Parser [JSNode]-bitwiseOrExpression = bitwiseExpression bitwiseXOrExpression '|'---- <Logical And Expression> ::= <Bitwise Or Expression>---                            | <Logical And Expression> '&&' <Bitwise Or Expression>-logicalAndExpression :: Parser [JSNode]-logicalAndExpression = do{ v1 <- bitwiseOrExpression; v2 <- rest;-                           return (v1++v2)}-                       where-                         rest =-                               do{ rOp "&&"; v2 <- bitwiseOrExpression; v3 <- rest;-                                   return [(JSExpressionBinary "&&" v2 v3)]}-                            <|> return []------- <Logical Or Expression> ::= <Logical And Expression>---                           | <Logical Or Expression> '||' <Logical And Expression>-logicalOrExpression :: Parser [JSNode]-logicalOrExpression =  do{ v1 <- logicalAndExpression; v2 <- rest;-                           return (v1++v2)}-                       where-                         rest =-                                  (do{ rOp "||"; v2 <- logicalAndExpression; v3 <- rest;-                                   return [(JSExpressionBinary "||" v2 v3)]})-                            <|> return []----- <Conditional Expression> ::= <Logical Or Expression> ---                            | <Logical Or Expression> '?' <Assignment Expression> ':' <Assignment Expression>-conditionalExpression :: Parser [JSNode]-conditionalExpression = do{ v1 <- logicalOrExpression;-                            do {-                                 do{ rOp "?"; v2 <- assignmentExpression; rOp ":"; v3 <- assignmentExpression;-                                     return [(JSExpressionTernary v1 v2 v3)]}-                             <|> return v1-                               }-                            }----- <Assignment Expression> ::= <Conditional Expression>---                           | <Left Hand Side Expression> <Assignment Operator> <Assignment Expression> -assignmentExpression :: Parser [JSNode]-assignmentExpression = try (do {v1 <- assignmentStart; v2 <- assignmentExpression; -- FIXME unintuitive, but tests pass after removing this try-                           return [(JSElement "assignmentExpression" (v1++v2))]})-                    <|> conditionalExpression-                       -assignmentStart :: Parser [JSNode]-assignmentStart = do {v1 <- leftHandSideExpression; v2 <- assignmentOperator; -                           return (v1++[v2])}---- <Assignment Operator> ::= '=' | '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '>>>=' | '&=' | '^=' | '|='--- TODO : unwind this lot into some sort of deterministic processing, DFA style.-assignmentOperator :: Parser JSNode-assignmentOperator = rOp' "=" <|> rOp' "*=" <|> rOp' "/=" <|> rOp' "%=" <|> rOp' "+=" <|> rOp' "-="-                 <|> rOp' "<<=" <|> rOp' ">>=" <|> rOp' ">>>=" <|> rOp' "&=" <|> rOp' "^=" <|> rOp' "|="-                     -rOp' :: String -> Parser JSNode-rOp' x = do{ rOp x; return $ JSOperator x}---- <Expression> ::= <Assignment Expression>---                | <Expression> ',' <Assignment Expression>-expression :: Parser JSNode-expression = do{ val <- sepBy1 assignmentExpression (rOp ",");-                 return (JSExpression (flattenExpression val))}---flattenExpression :: [[JSNode]] -> [JSNode]-flattenExpression val = flatten $ intersperse litComma val-                        where-                          litComma :: [JSNode]-                          litComma = [(JSLiteral ",")]---- <Statement> ::= <Block>---               | <Variable Statement>---               | <Empty Statement>---               | <If Statement>---               | <If Else Statement>---               | <Iteration Statement>---               | <Continue Statement>---               | <Break Statement>---               | <Return Statement>---               | <With Statement>---               | <Labelled Statement>---               | <Switch Statement>---               | <Throw Statement>---               | <Try Statement>---               | <Expression> -statement :: Parser JSNode-statement = statementBlock-        <|> labelledStatement-        <|> expression -        <|> variableStatement-        <|> emptyStatement -        <|> ifElseStatement-        <|> ifStatement-        <|> iterationStatement-        <|> continueStatement -        <|> breakStatement    -        <|> returnStatement     -        <|> withStatement-        <|> switchStatement-        <|> throwStatement -        <|> tryStatement-        <?> "statement"---statementBlock :: Parser JSNode-statementBlock = do {v1 <- statementBlock'; return (if (v1 == []) then (JSLiteral ";") else (head v1))}---- <Block > ::= '{' '}'---            | '{' <Statement List> '}'-statementBlock' :: Parser [JSNode]-statementBlock' = (do-    _ <- P.lexeme $ char '{'-    (P.lexeme (char '}') >> return []) <|> (do-        val <- statementList-        _ <- P.lexeme $ char '}'-        return $-            if val == JSStatementList [JSLiteral ";"]-                then []-                else [JSBlock val])-    ) <?> "statementBlock"---- <Block > ::= '{' '}'---            | '{' <Statement List> '}'-block :: Parser JSNode-block = (do-    _ <- P.lexeme $ char '{'-    x <- (P.lexeme (char '}') >> return (JSStatementList [])) <|> (do-        val <- statementList-        _ <- P.lexeme $ char '}'-        return val)-    return $ JSBlock x) <?> "block"---- <Statement List> ::= <Statement>---                    | <Statement List> <Statement>-statementList :: Parser JSNode-statementList = do {v1 <- many1 statement;-                    return (JSStatementList v1)}----- <Variable Statement> ::= var <Variable Declaration List> ';'--- Note: Mozilla introduced const declarations, not part of official spec-variableStatement :: Parser JSNode-variableStatement = do {P.reserved "var"; val <- variableDeclarationList;-                        return (JSVariables "var" val)}-                <|> do {P.reserved "const"; val <- variableDeclarationList;-                        return (JSVariables "const" val)}--                    --- <Variable Declaration List> ::= <Variable Declaration>---                               | <Variable Declaration List> ',' <Variable Declaration>-variableDeclarationList :: Parser [JSNode]-variableDeclarationList = do{ val <- sepBy1 variableDeclaration (rOp ","); -                              return val }----- <Variable Declaration> ::= Identifier---                          | Identifier <Initializer>-variableDeclaration :: Parser JSNode-variableDeclaration = do{ v1 <- identifier; -                          do {-                            do {v2 <- initializer; -                                return (JSVarDecl v1 v2)}-                            <|> return (JSVarDecl v1 [])-                               }-                          }---- <Initializer> ::= '=' <Assignment Expression>-initializer :: Parser [JSNode]-initializer = do {rOp "="; val <- assignmentExpression; -                  return val}---- <Empty Statement> ::= ';'-emptyStatement :: Parser JSNode---emptyStatement = do { v1 <- autoSemi'; return (JSEmpty v1)}-emptyStatement = do { v1 <- autoSemi'; return v1}----- <If Statement> ::= 'if' '(' <Expression> ')' <Statement> -ifStatement :: Parser JSNode-ifStatement = do{ P.reserved "if"; rOp "("; v1 <- expression; rOp ")"; v2 <- statement;-                  return (JSIf v1 v2) }---- <If Else Statement> ::= 'if' '(' <Expression> ')' <Statement> 'else' <Statement>-ifElseStatement :: Parser JSNode-ifElseStatement = do{ try $ P.reserved "if"; rOp "("; v1 <- expression; rOp ")"; v2 <- statementSemi; P.reserved "else"; v3 <- statement ; -- FIXME can this try be removed?-                      return (JSIfElse v1 v2 v3) }--statementSemi :: Parser JSNode-statementSemi = do { v1 <- statement;-                     do { -                            do { rOp ";"; return (JSBlock (JSStatementList [v1]))} -                        <|> return v1-                        }-                     }----- <Iteration Statement> ::= 'do' <Statement> 'while' '(' <Expression> ')' ';'---                         | 'while' '(' <Expression> ')' <Statement> ---                         | 'for' '(' <Expression> ';' <Expression> ';' <Expression> ')' <Statement> ---                         | 'for' '(' 'var' <Variable Declaration List> ';' <Expression> ';' <Expression> ')' <Statement> ---                         | 'for' '(' <Left Hand Side Expression> in <Expression> ')' <Statement> ---                         | 'for' '(' 'var' <Variable Declaration> in <Expression> ')' <Statement> -iterationStatement :: Parser JSNode-iterationStatement = do{ P.reserved "do"; v1 <- statement; P.reserved "while"; rOp "("; v2 <- expression; rOp ")"; v3 <- autoSemi ; -                         return (JSDoWhile v1 v2 v3)}-                 <|> do{ P.reserved "while"; rOp "("; v1 <- expression; rOp ")"; v2 <- statement; -                         return (JSWhile v1 v2)}-                     -                 <|> do{ P.reserved "for"; rOp "("; -                         do {-                           do{ P.reserved "var"; v1 <- variableDeclaration; -                             do {-                               do { rOp ","; v1' <- variableDeclarationList; rOp ";"; v2 <- optionalExpression ";"; -                                    v3 <- optionalExpression ")"; v4 <- statement; -                                    return (JSForVar (v1:v1') v2 v3 v4)}-                           <|> do { rOp ";"; v2 <- optionalExpression ";"; -                                    v3 <- optionalExpression ")"; v4 <- statement; -                                    return (JSForVar [v1] v2 v3 v4)}-                           <|> do { P.reserved "in"; v2 <- expression; rOp ")"; v3 <- statement; -                                    return (JSForVarIn v1 v2 v3)}-                                }-                             }-                         <|> try(do{ v1 <- leftHandSideExpression; P.reserved "in"; v2 <- expression; rOp ")"; -                                     v3 <- statement; -                                     return (JSForIn v1 v2 v3)})-                         <|> do { v1 <- optionalExpression ";"; v2 <- optionalExpression ";"; -                                  v3 <- optionalExpression ")"; v4 <- statement; -                                  return (JSFor v1 v2 v3 v4)}-                           }-                       }-                 <?> "iterationStatement"    -                     -optionalExpression :: [Char] -> Parser [JSNode]-optionalExpression s = do { rOp s; -                            return []}-                   <|> do { v1 <- expression; rOp s ;-                            return [v1]}---- <Continue Statement> ::= 'continue' ';'---                        | 'continue' Identifier ';'-continueStatement :: Parser JSNode-continueStatement = do {P.reserved "continue"; v1 <- autoSemi; -                        return (JSContinue [v1])}-                <|> do {P.reserved "continue"; v1 <- identifier; v2 <- autoSemi; -                        return (JSContinue [v1,v2])}----- <Break Statement> ::= 'break' ';'---                        | 'break' Identifier ';'-breakStatement :: Parser JSNode-breakStatement = do {P.reserved "break"; -                     do {-                          do {v1 <- identifier; v2 <- autoSemi; -                              return (JSBreak [v1] [v2])}-                     <|>  do {v1 <- autoSemi; -                              return (if (v1 == JSLiteral "") then (JSBreak [] []) else (JSBreak [] [v1]))}-                        }-                     }----- <Return Statement> ::= 'return' ';'---                        | 'return' <Expression> ';'-returnStatement :: Parser JSNode-returnStatement = do {P.reserved "return"; -                      do{-                            do {v1 <- expression; v2 <- autoSemi; -                                return (JSReturn [v1,v2])}-                        <|> do {v1 <- autoSemi; return (JSReturn [v1])}-                        -                        }-                      }----- <With Statement> ::= 'with' '(' <Expression> ')' <Statement> ';'-withStatement :: Parser JSNode-withStatement = do{ P.reserved "with"; rOp "("; v1 <- expression; rOp ")"; v2 <- statement; v3 <- autoSemi; -                    return (JSWith v1 [v2,v3])}----- <Switch Statement> ::= 'switch' '(' <Expression> ')' <Case Block>  -switchStatement :: Parser JSNode-switchStatement = do{ P.reserved "switch"; rOp "("; v1 <- expression; rOp ")"; v2 <- caseBlock;-                      return (JSSwitch v1 v2)}---- <Case Block> ::= '{' '}'---                | '{' <Case Clauses> '}'---                | '{' <Case Clauses> <Default Clause> '}'---                | '{' <Case Clauses> <Default Clause> <Case Clauses> '}'---                | '{' <Default Clause> <Case Clauses> '}'---                | '{' <Default Clause> '}'--- TODO: get rid of the try clauses by unwinding this-caseBlock :: Parser [JSNode]-caseBlock = do-    _ <- P.lexeme $ char '{'-    a <- caseClauses <|> return []-    b <- fmap return defaultClause <|> return []-    c <- caseClauses <|> return []-    _ <- P.lexeme $ char '}'-    return $ concat [a, b, c]---- <Case Clauses> ::= <Case Clause>---                  | <Case Clauses> <Case Clause>-caseClauses :: Parser [JSNode]-caseClauses = do{ val <- many1 caseClause;-                  return val}---- <Case Clause> ::= 'case' <Expression> ':' <Statement List>---                 | 'case' <Expression> ':'-caseClause :: Parser JSNode-caseClause = do { P.reserved "case"; v1 <- expression; rOp ":"; -                  do {-                       do { v2 <- statementList;-                            return (JSCase v1 v2)}-                   <|> return (JSCase v1 (JSStatementList []))-                     }-                  }---- <Default Clause> ::= 'default' ':' ---                    | 'default' ':' <Statement List>-defaultClause :: Parser JSNode-defaultClause = do{ P.reserved "default"; rOp ":"; v1 <- statementList;-                    return (JSDefault v1)}-            <|> do{ P.reserved "default"; rOp ":"; -                    return (JSDefault (JSStatementList []))}---- <Labelled Statement> ::= Identifier ':' <Statement> -labelledStatement :: Parser JSNode-labelledStatement = do { v1 <- try identifier; rOp ":"; v2 <- statement; -- FIXME can this try be removed?-                         return (JSLabelled v1 v2)}---- <Throw Statement> ::= 'throw' <Expression>-throwStatement :: Parser JSNode-throwStatement = do{ P.reserved "throw"; val <- expression;-                     return (JSThrow val)}---- Note: worked in updated syntax as per https://developer.mozilla.org/en/JavaScript/Reference/Statements/try...catch--- <Try Statement> ::= 'try' <Block> <Catch>---                   | 'try' <Block> <Finally>---                   | 'try' <Block> <Catch> <Finally>-tryStatement :: Parser JSNode-tryStatement = do{ P.reserved "try"; v1 <- block; -                   do {-                     do { v2 <- many1 catch;-                        do { v3 <- finally;-                             return (JSTry v1 (v2++[v3]))}-                        <|> return (JSTry v1 v2)-                        }-                 <|> do{ v2 <- finally;-                         return (JSTry v1 [v2])}-                     }-                 }---- Note: worked in updated syntax as per https://developer.mozilla.org/en/JavaScript/Reference/Statements/try...catch--- <Catch> ::= 'catch' '(' Identifier ')' <Block>---   becomes--- <Catch> ::= 'catch' '(' Identifier ')' <Block>---           | 'catch' '(' Identifier 'if' Condition ')' <Block>-catch :: Parser JSNode-catch = do{ P.reserved "catch"; rOp "("; v1 <- identifier; -            do {-                  do { rOp ")"; v3 <- block;-                       return (JSCatch v1 [] v3)}-              <|> do { P.reserved "if"; v2 <- conditionalExpression; rOp ")"; v3 <- block;-                       return (JSCatch v1 v2 v3)}-                  }-            }---- <Finally> ::= 'finally' <Block>-finally :: Parser JSNode-finally = do{ P.reserved "finally"; v1 <- block;-            return (JSFinally v1)}---- <Function Declaration> ::= 'function' Identifier '(' <Formal Parameter List> ')' '{' <Function Body> '}'---                          | 'function' Identifier '(' ')' '{' <Function Body> '}'-functionDeclaration :: Parser JSNode-functionDeclaration = do {P.reserved "function"; v1 <- identifier; rOp "("; v2 <- formalParameterList; rOp ")"; -                          v3 <- functionBody; -                          return (JSFunction v1 v2 v3) } -                  <?> "functionDeclaration"----- <Function Expression> ::= 'function' '(' ')' '{' <Function Body> '}'----                        | 'function' '(' <Formal Parameter List> ')' '{' <Function Body> '}'-functionExpression :: Parser JSNode-functionExpression = do{ P.reserved "function"; rOp "("; -                         do {-                           do { rOp ")"; v2 <- functionBody; -                                return (JSFunctionExpression [] v2)}-                           <|> do {v1 <- formalParameterList; rOp ")"; v2 <- functionBody; -                                   return (JSFunctionExpression v1 v2)}-                           }-                         }---- <Formal Parameter List> ::= Identifier---                           | <Formal Parameter List> ',' Identifier-formalParameterList :: Parser [JSNode]-formalParameterList = sepBy identifier (rOp ",")---- <Function Body> ::= '{' <Source Elements> '}'---                   | '{' '}'-functionBody :: Parser JSNode-functionBody = do{ rOp "{"; -                 do {         -                      do{ rOp "}";-                       return (JSFunctionBody []) }-                  <|> do{ v1 <- sourceElements; rOp "}";-                          return (JSFunctionBody [v1]) }-                      }-                 }-           <?> "functionBody"    ---- <Program> ::= <Source Elements>-program :: Parser JSNode-program = do {P.whiteSpace; val <- sourceElementsTop; eof; -              return val}----- <Source Elements> ::= <Source Element>---                     | <Source Elements>  <Source Element>-sourceElements :: Parser JSNode-sourceElements = do{ val <- many1 sourceElement;-                     return (JSSourceElements val)}-                 -sourceElementsTop :: Parser JSNode-sourceElementsTop = do{ val <- many1 sourceElement;-                        return (JSSourceElementsTop val)}----- <Source Element> ::= <Statement>---                    | <Function Declaration>-sourceElement :: Parser JSNode-sourceElement = functionDeclaration-            <|> statement-            <?> "sourceElement"--                       -                       --- ------------------------------------------------------------------ Testing---- -----------------------------------------------------------------------flatten :: [[a]] -> [a]-flatten xs = foldl' (++) [] xs---- -----------------------------------------------------------------------main :: IO ()-main =-  do args <- getArgs-     x <- LB.readFile (args !! 0)-     putStrLn (show $ doParse program x)            --    --- ---------------------------------------------------------------------     -          -readJs :: LB.ByteString -> JSNode-readJs input = case doParse program input of-    Fail _unparsed contexts err -> error("Parse failed" ++ show(contexts) ++ ":" ++ show err)-    -- Partial _f -> error("Unexpected partial")-    Done _unparsed val -> val---- ---------------------------------------------------------------------     -          -{--readJsm :: (Monad m) => B.ByteString -> m JSNode-readJsm input = case eitherResult $ doParse program input of-    Left msg  -> fail ("Parse failed:" ++ msg)-    Right val -> return val--}--readJsm :: LB.ByteString -> Either String JSNode-readJsm input = eitherResult $ doParse program input ---- ----------------------------------------------------------------------    -{-                -_doParse' :: Parser a -> String -> a-_doParse' p input = case parse (p' p) (LB.fromChunks [E.encodeUtf8 $ T.pack input]) of-    Fail _unparsed contexts err -> error("Parse failed" ++ show(contexts) ++ ":" ++ show err)-    Partial _f -> error("Unexpected partial")-    Done _unparsed val -> val--}--{--doParseStrict :: Parser r -> B.ByteString -> Result r-doParseStrict p input = {-maybeResult $-} feed (parse (p' p) input) LB.empty--}                       --doParse :: Parser r -> LB.ByteString -> Result r-doParse p input = parse (p' p) input--parseString :: Parser r -> String -> Result r-parseString p input = doParse p (LB.fromChunks [E.encodeUtf8 $ T.pack input])--parseProgram :: String -> Result JSNode-parseProgram input = doParse program (LB.fromChunks [E.encodeUtf8 $ T.pack input])---- ----------------------------------------------------------------------    -p' :: Parser b -> Parser b-p' p = do {val <- p; eof; return val}---- -----------------------------------------------------------------------_showFile :: FilePath -> IO String-_showFile filename =-  do -     x <- readFile (filename)-     return $ (show x)---- -----------------------------------------------------------------------parseFile :: FilePath -> IO JSNode-parseFile filename =-  do -     x <- LB.readFile (filename)-     return $ (readJs x)---- EOF
Text/Jasmine/Pretty.hs view
@@ -41,101 +41,113 @@  -- --------------------------------------------------------------------- - renderJS :: JSNode -> BB.Builder-renderJS (JSEmpty l)             = (renderJS l)-renderJS (JSIdentifier s)        = text s-renderJS (JSDecimal i)           = text i-renderJS (JSOperator s)          = text s-renderJS (JSExpression xs)       = rJS xs-renderJS (JSSourceElements xs)   = rJS (map fixBlock $ fixSourceElements xs)-renderJS (JSSourceElementsTop xs)= rJS (fixTop $ map fixBlock $ fixSourceElements xs)-renderJS (JSFunction s p xs)     = (text "function") <+> (renderJS s) <> (text "(") <> (commaList p) <> (text ")") <> (renderJS xs)-renderJS (JSFunctionBody xs)     = (text "{") <> (rJS xs) <> (text "}")-renderJS (JSFunctionExpression [] p xs) = (text "function")             <> (text "(") <> (commaList p) <> (text ")") <> (renderJS xs)-renderJS (JSFunctionExpression  s p xs) = (text "function") <+> (rJS s) <> (text "(") <> (commaList p) <> (text ")") <> (renderJS xs)-renderJS (JSArguments xs)        = (text "(") <> (commaListList $ map fixLiterals xs) <> (text ")")+renderJS (NS node _) = rn node -renderJS (JSBlock x)             = (text "{") <> (renderJS x) <> (text "}")+rn :: Node -> BB.Builder+rn (JSEmpty l)             = (renderJS l)+rn (JSIdentifier s)        = text s+rn (JSDecimal i)           = text i+rn (JSOperator s)          = text s+rn (JSExpression xs)       = rJS xs -renderJS (JSIf c (JSLiteral ";"))= (text "if") <> (text "(") <> (renderJS c) <> (text ")") -renderJS (JSIf c t)              = (text "if") <> (text "(") <> (renderJS c) <> (text ")") <> (renderJS $ fixBlock t)+--rn (JSSourceElements xs)   = rJS (map fixBlock $ fixSourceElements xs)+rn (JSSourceElements xs)   = rJS (fixSourceElements $ map fixBlock xs) -renderJS (JSIfElse c t (JSLiteral ";")) = (text "if") <> (text "(") <> (renderJS c) <> (text ")")  <> (renderJS t) +--rn (JSSourceElementsTop xs)= rJS (fixTop $ map fixBlock $ fixSourceElements xs)+rn (JSSourceElementsTop xs)= rJS (fixTop $ fixSourceElements $ map fixBlock xs)+++rn (JSFunction s p xs)     = (text "function") <+> (renderJS s) <> (text "(") <> (commaList p) <> (text ")") <> (renderJS xs)+rn (JSFunctionBody xs)     = (text "{") <> (rJS xs) <> (text "}")+rn (JSFunctionExpression [] p xs) = (text "function")             <> (text "(") <> (commaList p) <> (text ")") <> (renderJS xs)+rn (JSFunctionExpression  s p xs) = (text "function") <+> (rJS s) <> (text "(") <> (commaList p) <> (text ")") <> (renderJS xs)+rn (JSArguments xs)        = (text "(") <> (commaListList $ map fixLiterals xs) <> (text ")")++rn (JSBlock x)             = (text "{") <> (renderJS x) <> (text "}")++rn (JSIf c (NS (JSLiteral ";") _))= (text "if") <> (text "(") <> (renderJS c) <> (text ")") +rn (JSIf c t)                     = (text "if") <> (text "(") <> (renderJS c) <> (text ")") <> (renderJS $ fixBlock t)++rn (JSIfElse c t (NS (JSLiteral ";") _)) = (text "if") <> (text "(") <> (renderJS c) <> (text ")")  <> (renderJS t)                                     <> (text "else") -renderJS (JSIfElse c t e)        = (text "if") <> (text "(") <> (renderJS c) <> (text ")") <> (renderJS t) +rn (JSIfElse c t e)        = (text "if") <> (text "(") <> (renderJS c) <> (text ")") <> (renderJS t)                                     <> (text "else") <> (spaceOrBlock $ fixBlock e)-renderJS (JSMemberDot xs y)        = (rJS xs) <> (text ".") <> (renderJS y)-renderJS (JSMemberSquare xs x)   = (rJS xs) <> (text "[") <> (renderJS x) <> (text "]") -renderJS (JSLiteral l)           = (text l)-renderJS (JSStringLiteral s l)   = empty <> (char s) <> (text l) <> (char s)-renderJS (JSUnary l  )           = text l-renderJS (JSArrayLiteral xs)     = (text "[") <> (rJS xs) <> (text "]")+rn (JSMemberDot xs y)        = (rJS xs) <> (text ".") <> (renderJS y)+rn (JSMemberSquare xs x)   = (rJS xs) <> (text "[") <> (renderJS x) <> (text "]") +rn (JSLiteral l)           = (text l)+rn (JSStringLiteral s l)   = empty <> (char s) <> (text l) <> (char s)+rn (JSUnary l  )           = text l+rn (JSArrayLiteral xs)     = (text "[") <> (rJS xs) <> (text "]") -renderJS (JSBreak [] [])            = (text "break")-renderJS (JSBreak [] _xs)           = (text "break") -- <> (rJS xs) -- <> (text ";")-renderJS (JSBreak is _xs)           = (text "break") <+> (rJS is) -- <> (rJS xs)+rn (JSBreak [] [])            = (text "break")+rn (JSBreak [] _xs)           = (text "break") -- <> (rJS xs) -- <> (text ";")+rn (JSBreak is _xs)           = (text "break") <+> (rJS is) -- <> (rJS xs) -renderJS (JSCallExpression "()" xs) = (rJS xs)-renderJS (JSCallExpression   t  xs) = (char $ head t) <> (rJS xs) <> (if ((length t) > 1) then (char $ last t) else empty)+rn (JSCallExpression "()" xs) = (rJS xs)+rn (JSCallExpression   t  xs) = (char $ head t) <> (rJS xs) <> (if ((length t) > 1) then (char $ last t) else empty)  -- No space between 'case' and string literal. TODO: what about expression in parentheses?-renderJS (JSCase (JSExpression [JSStringLiteral sepa s]) xs) = (text "case") <> (renderJS (JSStringLiteral sepa s)) +--rn (JSCase (JSExpression [JSStringLiteral sepa s]) xs) = (text "case") <> (renderJS (JSStringLiteral sepa s)) +rn (JSCase (NS (JSExpression [(NS (JSStringLiteral sepa s) s1)]) _) xs) = (text "case") <> (renderJS (NS (JSStringLiteral sepa s) s1))                                                                 <> (char ':') <> (renderJS xs)          -renderJS (JSCase e xs)           = (text "case") <+> (renderJS e) <> (char ':') <> (renderJS xs) -- <> (text ";");         +rn (JSCase e xs)           = (text "case") <+> (renderJS e) <> (char ':') <> (renderJS xs) -- <> (text ";");          -renderJS (JSCatch i [] s)        = (text "catch") <> (char '(') <> (renderJS i) <>  (char ')') <> (renderJS s)-renderJS (JSCatch i c s)         = (text "catch") <> (char '(') <> (renderJS i) <>  +rn (JSCatch i [] s)        = (text "catch") <> (char '(') <> (renderJS i) <>  (char ')') <> (renderJS s)+rn (JSCatch i c s)         = (text "catch") <> (char '(') <> (renderJS i) <>                                      (text " if ") <> (rJS c) <> (char ')') <> (renderJS s) -renderJS (JSContinue is)         = (text "continue") <> (rJS is) -- <> (char ';')-renderJS (JSDefault xs)          = (text "default") <> (char ':') <> (renderJS xs)-renderJS (JSDoWhile s e _ms)     = (text "do") <> (renderJS s) <> (text "while") <> (char '(') <> (renderJS e) <> (char ')') -- <> (renderJS ms)---renderJS (JSElementList xs)      = rJS xs-renderJS (JSElision xs)          = (char ',') <> (rJS xs)-renderJS (JSExpressionBinary o e1 e2) = (rJS e1) <> (text o) <> (rJS e2)---renderJS (JSExpressionBinary o e1 e2) = (text o) <> (rJS e1) <> (rJS e2)-renderJS (JSExpressionParen e)        = (char '(') <> (renderJS e) <> (char ')')-renderJS (JSExpressionPostfix o e)    = (rJS e) <> (text o)-renderJS (JSExpressionTernary c v1 v2) = (rJS c) <> (char '?') <> (rJS v1) <> (char ':') <> (rJS v2)-renderJS (JSFinally b)                 = (text "finally") <> (renderJS b)+rn (JSContinue is)         = (text "continue") <> (rJS is) -- <> (char ';')+rn (JSDefault xs)          = (text "default") <> (char ':') <> (renderJS xs)+rn (JSDoWhile s e _ms)     = (text "do") <> (renderJS s) <> (text "while") <> (char '(') <> (renderJS e) <> (char ')') -- <> (renderJS ms)+--rn (JSElementList xs)      = rJS xs+rn (JSElision xs)          = (char ',') <> (rJS xs)+rn (JSExpressionBinary o e1 e2) = (rJS e1) <> (text o) <> (rJS e2)+--rn (JSExpressionBinary o e1 e2) = (text o) <> (rJS e1) <> (rJS e2)+rn (JSExpressionParen e)        = (char '(') <> (renderJS e) <> (char ')')+rn (JSExpressionPostfix o e)    = (rJS e) <> (text o)+rn (JSExpressionTernary c v1 v2) = (rJS c) <> (char '?') <> (rJS v1) <> (char ':') <> (rJS v2)+rn (JSFinally b)                 = (text "finally") <> (renderJS b) -renderJS (JSFor e1 e2 e3 s)            = (text "for") <> (char '(') <> (commaList e1) <> (char ';') +rn (JSFor e1 e2 e3 s)            = (text "for") <> (char '(') <> (commaList e1) <> (char ';')                                           <> (rJS e2) <> (char ';') <> (rJS e3) <> (char ')') <> (renderJS $ fixBlock s)-renderJS (JSForIn e1 e2 s)             = (text "for") <> (char '(') <> (rJS e1) <+> (text "in")+rn (JSForIn e1 e2 s)             = (text "for") <> (char '(') <> (rJS e1) <+> (text "in")                                          <+> (renderJS e2) <> (char ')') <> (renderJS $ fixBlock s)-renderJS (JSForVar e1 e2 e3 s)         = (text "for") <> (char '(') <> (text "var") <+> (commaList e1) <> (char ';') +rn (JSForVar e1 e2 e3 s)         = (text "for") <> (char '(') <> (text "var") <+> (commaList e1) <> (char ';')                                           <> (rJS e2) <> (char ';') <> (rJS e3) <> (char ')') <> (renderJS $ fixBlock s)-renderJS (JSForVarIn e1 e2 s)          = (text "for") <> (char '(') <> (text "var") <+> (renderJS e1) <+> (text "in") +rn (JSForVarIn e1 e2 s)          = (text "for") <> (char '(') <> (text "var") <+> (renderJS e1) <+> (text "in")                                           <+> (renderJS e2) <> (char ')') <> (renderJS $ fixBlock s)                                          -renderJS (JSHexInteger i)              = (text $ show i) -- TODO: need to tweak this                                         -renderJS (JSLabelled l v)              = (renderJS l) <> (text ":") <> (renderJS v)-renderJS (JSObjectLiteral xs)          = (text "{") <> (commaList xs) <> (text "}")-renderJS (JSPropertyNameandValue n vs) = (renderJS n) <> (text ":") <> (rJS vs)-renderJS (JSRegEx s)                   = (text s)+rn (JSHexInteger i)              = (text $ show i) -- TODO: need to tweak this                                         +rn (JSLabelled l v)              = (renderJS l) <> (text ":") <> (rJS $ fixSourceElements [fixBlock v])+rn (JSObjectLiteral xs)          = (text "{") <> (commaList xs) <> (text "}")+rn (JSPropertyAccessor s n ps b) = (text s) <+> (renderJS n) <> (char '(') <> (rJS ps) <> (text ")") <> (renderJS b)+rn (JSPropertyNameandValue n vs) = (renderJS n) <> (text ":") <> (rJS vs)+rn (JSRegEx s)                   = (text s) -renderJS (JSReturn [])                 = (text "return")-renderJS (JSReturn [JSLiteral ";"])    = (text "return;")-renderJS (JSReturn xs)                 = (text "return") <> (if (spaceNeeded xs) then (text " ") else (empty)) <> (rJS $ fixSourceElements xs) +rn (JSReturn [])                 = (text "return")+rn (JSReturn [(NS (JSLiteral ";") _)])    = (text "return;")+rn (JSReturn xs)                 = (text "return") <> (if (spaceNeeded xs) then (text " ") else (empty)) <> (rJS $ fixSourceElements xs)  -renderJS (JSThrow e)                   = (text "throw") <+> (renderJS e)+rn (JSThrow e)                   = (text "throw") <+> (renderJS e) -renderJS (JSStatementList xs)          = rJS (fixSourceElements $ map fixBlock xs)+rn (JSStatementBlock x)          = (text "{") <> (renderJS x) <> (text "}") -renderJS (JSSwitch e xs)               = (text "switch") <> (char '(') <> (renderJS e) <> (char ')') <> +rn (JSStatementList xs)          = rJS (fixSourceElements $ map fixBlock xs)++rn (JSSwitch e xs)               = (text "switch") <> (char '(') <> (renderJS e) <> (char ')') <>                                           (char '{') <> (rJS $ fixSemis xs)  <> (char '}')-renderJS (JSTry e xs)                  = (text "try") <> (renderJS e) <> (rJS xs)+rn (JSTry e xs)                  = (text "try") <> (renderJS e) <> (rJS xs) -renderJS (JSVarDecl i [])              = (renderJS i) -renderJS (JSVarDecl i xs)              = (renderJS i) <> (text "=") <> (rJS xs)+rn (JSVarDecl i [])              = (renderJS i) +rn (JSVarDecl i xs)              = (renderJS i) <> (text "=") <> (rJS xs) -renderJS (JSVariables kw xs)           = (text kw) <+> (commaList xs)+rn (JSVariables kw xs)           = (text kw) <+> (commaList xs) -renderJS (JSWhile e (JSLiteral ";"))   = (text "while") <> (char '(') <> (renderJS e) <> (char ')') -- <> (renderJS s)-renderJS (JSWhile e s)                 = (text "while") <> (char '(') <> (renderJS e) <> (char ')') <> (renderJS s)+rn (JSWhile e (NS (JSLiteral ";") _))   = (text "while") <> (char '(') <> (renderJS e) <> (char ')') -- <> (renderJS s)+rn (JSWhile e s)                 = (text "while") <> (char '(') <> (renderJS e) <> (char ')') <> (renderJS s) -renderJS (JSWith e s)                  = (text "with") <> (char '(') <> (renderJS e) <> (char ')') <> (rJS s)+rn (JSWith e s)                  = (text "with") <> (char '(') <> (renderJS e) <> (char ')') <> (rJS s)            -- Helper functions rJS :: [JSNode] -> BB.Builder@@ -145,8 +157,10 @@ commaList [] = empty commaList xs = (hcat $ (punctuate comma (toDoc xs') ++ trail))   where-    (xs', trail) = if (last xs == JSLiteral ",") then (init xs, [comma]) else (xs,[])-+    -- (xs', trail) = if (last xs == JSLiteral ",") then (init xs, [comma]) else (xs,[])+    (xs', trail) = if (x' == JSLiteral ",") then (init xs, [comma]) else (xs,[])+    (NS x' _) = last xs+     commaListList :: [[JSNode]] -> BB.Builder commaListList xs = (hcat $ punctuate comma $ map rJS xs) @@ -154,16 +168,26 @@ toDoc xs = map renderJS xs  spaceOrBlock :: JSNode -> BB.Builder-spaceOrBlock (JSBlock xs) = renderJS (JSBlock xs)+spaceOrBlock (NS (JSBlock xs) _) = rn (JSBlock xs)+spaceOrBlock (NS (JSStatementBlock xs) _) = rn (JSStatementBlock xs) spaceOrBlock x            = (text " ") <> (renderJS x) ++{-++TODO: Collapse this into JSLiteral ";"++JSStatementBlock (JSStatementList [JSStatementBlock (JSStatementList [])])+-} -- --------------------------------------------------------------- -- Utility stuff   fixTop :: [JSNode] -> [JSNode] fixTop [] = []-fixTop xs = if (last xs == (JSLiteral ";")) then (init xs) else (xs)+fixTop xs = if (n == (JSLiteral ";")) then (init xs) else (xs)+  where+    (NS n _) = last xs  -- Fix semicolons in output of sourceelements and statementlist @@ -172,67 +196,96 @@    myFix :: [JSNode] -> [JSNode] myFix []      = []++-- Sort out empty IF statements+myFix ((NS (JSIf c (NS (JSStatementBlock (NS (JSStatementList []) s1)) s2)) _s3):xs) = (NS (JSIf c (NS (JSLiteral "") s1)) s2) : myFix (xs)+ myFix [x]     = [x]-myFix (x:(JSFunction v1 v2 v3):xs)  = x : (JSLiteral "\n") : myFix ((JSFunction v1 v2 v3) : xs)++myFix (x:(NS (JSFunction v1 v2 v3) s1):xs)  = x : (NS (JSLiteral "\n") s1) : myFix ((NS (JSFunction v1 v2 v3) s1) : xs) -- Messy way, but it works, until the 3rd element arrives ..-myFix ((JSExpression x):(JSExpression y):xs) = (JSExpression x):(JSLiteral ";"):myFix ((JSExpression y):xs)-myFix ((JSExpression x):(JSBlock y):xs)      = (JSExpression x):(JSLiteral ";"):myFix ((JSBlock y):xs)-myFix ((JSBlock x)     :(JSBlock y):xs)      = (JSBlock x)     :(JSLiteral ";"):myFix ((JSBlock y):xs)-myFix ((JSBlock x)     :(JSExpression y):xs) = (JSBlock x)     :(JSLiteral ";"):myFix ((JSExpression y):xs)+-- TODO: JSStatementBlock.  Damn.+myFix ((NS (JSExpression x) s1):(NS (JSExpression y) s2):xs) = (NS (JSExpression x) s1):(NS (JSLiteral ";") s1):myFix ((NS (JSExpression y) s2):xs)+myFix ((NS (JSExpression x) s1):(NS (JSBlock y) s2):xs)      = (NS (JSExpression x) s1):(NS (JSLiteral ";") s1):myFix ((NS (JSBlock y) s2):xs)+myFix ((NS (JSBlock x) s1)     :(NS (JSBlock y) s2):xs)      = (NS (JSBlock x) s1)     :(NS (JSLiteral ";") s1):myFix ((NS (JSBlock y) s2):xs)+myFix ((NS (JSBlock x) s1)     :(NS (JSExpression y) s2):xs) = (NS (JSBlock x) s1)     :(NS (JSLiteral ";") s1):myFix ((NS (JSExpression y) s2):xs) +myFix ((NS (JSExpression x) s1):(NS (JSStatementBlock y) s2):xs)      = +  (NS (JSExpression x) s1):(NS (JSLiteral ";") s1):myFix ((NS (JSStatementBlock y) s2):xs)+myFix ((NS (JSStatementBlock x) s1)     :(NS (JSStatementBlock y) s2):xs)      = +  (NS (JSStatementBlock x) s1)     :(NS (JSLiteral ";") s1):myFix ((NS (JSStatementBlock y) s2):xs)+myFix ((NS (JSStatementBlock x) s1)     :(NS (JSExpression y) s2):xs) = +  (NS (JSStatementBlock x) s1)     :(NS (JSLiteral ";") s1):myFix ((NS (JSExpression y) s2):xs)+ -- Merge adjacent variable declarations, but only of the same type-myFix ((JSVariables t1 x1s):(JSLiteral l):(JSVariables t2 x2s):xs) -  | t1 == t2 = myFix ((JSVariables t1 (x1s++x2s)):xs)-  | otherwise = (JSVariables t1 x1s):myFix ((JSLiteral l):(JSVariables t2 x2s):xs)+myFix ((NS (JSVariables t1 x1s) s1):(NS (JSLiteral l) s2):(NS (JSVariables t2 x2s) s3):xs) +  | t1 == t2 = myFix ((NS (JSVariables t1 (x1s++x2s)) s1):xs)+  | otherwise = (NS (JSVariables t1 x1s) s1):myFix ((NS (JSLiteral l) s2):(NS (JSVariables t2 x2s) s3):xs) -myFix ((JSVariables t1 x1s):(JSVariables t2 x2s):xs) -  | t1 == t2 = myFix ((JSVariables t1 (x1s++x2s)):xs)-  | otherwise = (JSVariables t1 x1s):myFix ((JSVariables t2 x2s):xs)+myFix ((NS (JSVariables t1 x1s) s1):(NS (JSVariables t2 x2s) s2):xs) +  | t1 == t2 = myFix ((NS (JSVariables t1 (x1s++x2s)) s1):xs)+  | otherwise = (NS (JSVariables t1 x1s) s1):myFix ((NS (JSVariables t2 x2s) s2):xs)  -- Merge adjacent semi colons-myFix ((JSLiteral ";"):(JSLiteral ";"):xs)  = myFix ((JSLiteral ";"):xs)-myFix ((JSLiteral ";"):(JSLiteral "" ):xs)  = myFix ((JSLiteral ""):xs)+myFix ((NS (JSLiteral ";") s1):(NS (JSLiteral ";") _s2):xs)  = myFix ((NS (JSLiteral ";") s1):xs)+myFix ((NS (JSLiteral ";") s1):(NS (JSLiteral "" ) _s2):xs)  = myFix ((NS (JSLiteral "") s1):xs) +                        myFix (x:xs)  = x : myFix xs  -- Merge strings split over lines and using "+" fixLiterals :: [JSNode] -> [JSNode] fixLiterals [] = [] -- Old version-fixLiterals ((JSStringLiteral d1 s1):(JSExpressionBinary "+" [JSStringLiteral d2 s2] r):xs)-       | d1 == d2 = fixLiterals ((JSStringLiteral d1 (s1++s2)):(r++xs))-       | otherwise = (JSStringLiteral d1 s1):fixLiterals ((JSExpressionBinary "+" [JSStringLiteral d2 s2] r):xs) --fixLiterals ((JSExpressionBinary "+" [JSStringLiteral d1 s1] [JSStringLiteral d2 s2]):xs)-       | d1 == d2 = fixLiterals ((JSStringLiteral d1 (s1++s2)):xs)-       | otherwise = (JSExpressionBinary "+" [JSStringLiteral d1 s1] [JSStringLiteral d2 s2]):fixLiterals xs              +fixLiterals ((NS (JSStringLiteral d1 s1) ss1):(NS (JSExpressionBinary "+" [(NS (JSStringLiteral d2 s2) ss2)] r) ss3):xs)+       | d1 == d2 = fixLiterals ((NS (JSStringLiteral d1 (s1++s2)) ss1):(r++xs))+       | otherwise = (NS (JSStringLiteral d1 s1) ss1):fixLiterals ((NS (JSExpressionBinary "+" [(NS (JSStringLiteral d2 s2) ss2)] r) ss3):xs)  +fixLiterals ((NS (JSExpressionBinary "+" [(NS (JSStringLiteral d1 s1) ss2)] [(NS (JSStringLiteral d2 s2) ss3)]) ss4):xs)+       | d1 == d2 = fixLiterals ((NS (JSStringLiteral d1 (s1++s2)) ss2):xs)+       | otherwise = (NS (JSExpressionBinary "+" [(NS (JSStringLiteral d1 s1) ss2)] [(NS (JSStringLiteral d2 s2) ss3)]) ss4):fixLiterals xs             fixLiterals (x:xs) = x:fixLiterals xs  -- Sort out Semicolons fixSemis :: [JSNode] -> [JSNode]-fixSemis xs = fixSemis' $ filter (\x -> x /= JSLiteral ";" && x /= JSLiteral "") xs+--fixSemis xs = fixSemis' $ filter (\x -> x /= JSLiteral ";" && x /= JSLiteral "") xs+fixSemis xs = fixSemis' $ filter (\(NS x _) -> x /= JSLiteral ";" && x /= JSLiteral "") xs  fixSemis' :: [JSNode] -> [JSNode] fixSemis' [] = []-fixSemis' [JSContinue [JSLiteral ";"]] = [JSContinue []]+fixSemis' [(NS (JSContinue [(NS (JSLiteral ";") _)]) s2)] = [(NS (JSContinue []) s2)] fixSemis' [x] = [x]-fixSemis' ((JSIf c (JSReturn [JSLiteral ";"])):xs)    = (JSIf c (JSReturn [JSLiteral ";"])):(fixSemis' xs)-fixSemis' ((JSIf c (JSContinue [JSLiteral ";"])):xs)    = (JSIf c (JSContinue [JSLiteral ";"])):(fixSemis' xs)-fixSemis' (x:(JSLiteral "\n"):xs) = x:(JSLiteral "\n"):(fixSemis' xs)-fixSemis' ((JSCase e1 ((JSStatementList []))):(JSCase e2 x):xs) = (JSCase e1 ((JSStatementList []))):fixSemis' ((JSCase e2 x):xs)-fixSemis' (x:xs) = x:(JSLiteral ";"):fixSemis' xs+fixSemis' ((NS (JSIf c (NS (JSReturn [(NS (JSLiteral ";") s1)]) s2) ) s3):xs)  = +  (NS (JSIf c (NS (JSReturn [(NS (JSLiteral ";") s1)]) s2)) s3):(fixSemis' xs)+fixSemis' ((NS (JSIf c (NS (JSContinue [(NS (JSLiteral ";") s1)]) s2) ) s3):xs)    = +  (NS (JSIf c (NS (JSContinue [(NS (JSLiteral ";") s1)]) s2)) s3):(fixSemis' xs)+fixSemis' (x:(NS (JSLiteral "\n") s1):xs) = x:(NS (JSLiteral "\n") s1):(fixSemis' xs) -- TODO: is this needed?+fixSemis' ((NS (JSCase e1 ((NS (JSStatementList []) s1))) s2):(NS (JSCase e2 x) s3):xs) = +  (NS (JSCase e1 ((NS (JSStatementList []) s1))) s2):fixSemis' ((NS (JSCase e2 x) s3):xs)+fixSemis' (x:xs) = x:(NS (JSLiteral ";") SpanEmpty):fixSemis' xs  -- Remove extraneous braces around blocks fixBlock :: JSNode -> JSNode-fixBlock (JSBlock (JSStatementList [x])) = x-fixBlock (JSBlock (JSStatementList xs)) = fixBlock' (JSBlock (JSStatementList (fixSourceElements xs)))++fixBlock (NS (JSBlock          (NS (JSStatementList []) s1) ) _) = (NS (JSLiteral ";") s1)+fixBlock (NS (JSStatementBlock (NS (JSStatementList []) s1) ) _) = (NS (JSLiteral ";") s1)++fixBlock (NS (JSBlock          (NS (JSStatementList [x]) _) ) _) = fixBlock x+fixBlock (NS (JSStatementBlock (NS (JSStatementList [x]) _) ) _) = fixBlock x++fixBlock (NS (JSBlock (NS (JSStatementList xs) s1) ) s2) = +  fixBlock' (NS (JSBlock (NS (JSStatementList (fixSourceElements xs)) s1)) s2)++fixBlock (NS (JSStatementBlock (NS (JSStatementList xs) s1) ) s2) = +  fixBlock' (NS (JSStatementBlock (NS (JSStatementList (fixSourceElements xs)) s1)) s2)+ fixBlock x = x  fixBlock' :: JSNode -> JSNode-fixBlock' (JSBlock (JSStatementList [x])) = x-fixBlock' (JSBlock (JSStatementList [x,JSLiteral ""])) = x -- TODO: fix parser to not emit this case+fixBlock' (NS (JSBlock          (NS (JSStatementList [x]) _)) _) = x+fixBlock' (NS (JSStatementBlock (NS (JSStatementList [x]) _)) _) = x+--fixBlock' (JSBlock (JSStatementList [x,JSLiteral ""])) = x -- TODO: fix parser to not emit this case fixBlock' x = x  -- A space is needed if this expression starts with an identifier etc, but not if with a '('@@ -247,362 +300,29 @@ -- --------------------------------------------------------------------- -- Test stuff --- readJs "x=1;"-_case0 :: JSNode-_case0 = JSSourceElements -          [-            JSExpression [JSIdentifier "x",JSOperator "=",JSDecimal "1"],-            JSEmpty (JSLiteral ";")-          ]---- doParse statementList "a=1;"  -_case1 :: [JSNode]-_case1 = [JSExpression -         [JSIdentifier "a",JSOperator "=",JSDecimal "1"]-        ,JSEmpty (JSLiteral ";")-        ]-        -          --- doParse expression "opTypeNames={'\\n':\"NEWLINE\",';':\"SEMICOLON\",',':\"COMMA\"}"          -_case4 :: JSNode-_case4 = JSExpression -          [-               JSIdentifier "opTypeNames",-               JSOperator "=",-               JSObjectLiteral -                 [JSPropertyNameandValue (JSStringLiteral '\'' "\\n") [JSStringLiteral '"' "NEWLINE"],-                  JSPropertyNameandValue (JSStringLiteral '\'' ";")   [JSStringLiteral '"' "SEMICOLON"],-                  JSPropertyNameandValue (JSStringLiteral '\'' ",")   [JSStringLiteral '"' "COMMA"]-                 ]-          ]-          ---- doParse program "function load(s){if(typeof s!=\"string\")return s;a=1}"-_case5 :: JSNode-_case5 = JSSourceElements -          [JSFunction (JSIdentifier "load") -           [JSIdentifier "s"] -             (JSFunctionBody -              [-                JSSourceElements -                  [-                    JSIf -                      (JSExpression [JSUnary "typeof ",JSIdentifier "s",-                                     JSExpressionBinary "!=" [JSStringLiteral '"' "string"] []]) -                      (JSReturn [JSExpression [JSIdentifier "s"],JSLiteral ";"])-                    ,JSLiteral ";"-                    ,JSExpression [JSIdentifier "a",JSOperator "=",JSDecimal "1"]-                    ]-              ]-             )-          ]-          --- doParse program "{if(typeof s!=\"string\")return s;evaluate(1)}"-_case6 :: JSNode-_case6 = JSSourceElements [] +_r :: JSNode -> [Char]+_r js = map (\x -> chr (fromIntegral x)) $ LB.unpack $ BB.toLazyByteString $ renderJS js ---doParse program  "function load(s){if(typeof s!=\"string\")return s;evaluate(1)}"-_case7 :: JSNode-_case7 = JSSourceElements -        [-          JSFunction (JSIdentifier "load") [JSIdentifier "s"] -            (JSFunctionBody -             [JSSourceElements -              [JSIf -                 (JSExpression [JSUnary "typeof ",JSIdentifier "s",JSExpressionBinary "!=" [JSStringLiteral '"' "string"] []]) -                 (JSReturn [JSExpression [JSIdentifier "s"],JSLiteral ";"])-              ,-               JSExpression [JSIdentifier "evaluate",JSArguments [[JSDecimal "1"]]]-              ]-             ]-            )-        ]+--readJs "{{{}}}"+_case0 :: JSNode+_case0 = NS (JSSourceElementsTop [NS (JSStatementBlock (NS (JSStatementList [NS (JSStatementBlock (NS (JSStatementList [NS (JSStatementBlock (NS (JSStatementList []) (SpanPoint {span_filename = "", span_row = 1, span_column = 3}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 3})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 3}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 2})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 2}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 1})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 1}) ---doParse program "for(i=0,j=assignOps.length;i<j;i++){}"-_case8 :: JSNode-_case8 = undefined-          -                 --- doParse returnStatement "return this.name;"-_case9 :: JSNode-_case9 = undefined+_case01 :: [JSNode]+_case01 = [NS (JSStatementBlock (NS (JSStatementList [NS (JSStatementBlock (NS (JSStatementList [NS (JSStatementBlock (NS (JSStatementList []) (SpanPoint {span_filename = "", span_row = 1, span_column = 3}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 3})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 3}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 2})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 2}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 1})]  ---parseFile "./test/parsingonly/02_sm.js"-{-+-- readJs "if(x){}{a=2}"+_case1 :: JSNode+_case1 = NS (JSSourceElementsTop [NS (JSIf (NS (JSExpression [NS (JSIdentifier "x") (SpanPoint {span_filename = "", span_row = 1, span_column = 4})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 4})) (NS (JSStatementBlock (NS (JSStatementList []) (SpanPoint {span_filename = "", span_row = 1, span_column = 6}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 6}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 1}),NS (JSStatementBlock (NS (JSStatementList [NS (JSExpression [NS (JSIdentifier "a") (SpanPoint {span_filename = "", span_row = 1, span_column = 9}),NS (JSOperator "=") (SpanPoint {span_filename = "", span_row = 1, span_column = 10}),NS (JSDecimal "2") (SpanPoint {span_filename = "", span_row = 1, span_column = 11})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 9})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 9}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 8})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 1}) -{zero}-one;two-{- three- four;five;-  {-  six;{seven;}-  }-}+_case11 :: [JSNode]+_case11 = [NS (JSIf (NS (JSExpression [NS (JSIdentifier "x") (SpanPoint {span_filename = "", span_row = 1, span_column = 4})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 4})) (NS (JSStatementBlock (NS (JSStatementList []) (SpanPoint {span_filename = "", span_row = 1, span_column = 6}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 6}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 1}),NS (JSStatementBlock (NS (JSStatementList [NS (JSExpression [NS (JSIdentifier "a") (SpanPoint {span_filename = "", span_row = 1, span_column = 9}),NS (JSOperator "=") (SpanPoint {span_filename = "", span_row = 1, span_column = 10}),NS (JSDecimal "2") (SpanPoint {span_filename = "", span_row = 1, span_column = 11})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 9})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 9}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 8})] --}-_case10 :: JSNode-_case10 = JSSourceElements -            [-              JSBlock (JSStatementList [JSExpression [JSIdentifier "zero"]]),-              JSExpression [JSIdentifier "one"],-              JSLiteral ";",-              JSExpression [JSIdentifier "two"],-              JSBlock (JSStatementList -                       [JSExpression [JSIdentifier "three"],-                        JSExpression [JSIdentifier "four"],-                        JSLiteral ";",-                        JSExpression [JSIdentifier "five"],-                        JSLiteral ";",-                        JSBlock (JSStatementList -                                 [JSExpression [JSIdentifier "six"],-                                  JSLiteral ";",-                                  JSBlock (JSStatementList -                                           [-                                             JSExpression [JSIdentifier "seven"],-                                             JSLiteral ""-                                           ]-                                          )-                                 ]-                                )-                       ]-                      )-            ]-            ---parseFile "./test/parsingonly/05_comments_simple.js"-_case11 :: JSNode-_case11 = JSSourceElements -            [-              JSExpression [JSIdentifier "a",JSExpressionBinary "+" [JSDecimal "1"] []],-              JSLiteral ";",-              JSLiteral ";"-            ]            -            ---doParse program "var newlines=spaces.match(/\\n/g);var newlines=spaces.match(/\\n/g);" _case12 :: JSNode-_case12 = undefined----doParse program "for(i=0;;){var t=1};for(var i=0,j=1;;){x=1}"-_case13 :: JSNode-_case13 = JSSourceElements -          [-            JSFor [JSExpression [JSIdentifier "i",JSOperator "=",JSDecimal "0"]] -            [] -            [] -            (JSBlock (-                JSStatementList [JSVariables "var" [JSVarDecl (JSIdentifier "t") [JSDecimal "1"]]]-                )-            ),-            JSLiteral ";",-            JSForVar [JSVarDecl (JSIdentifier "i") [JSDecimal "0"],JSVarDecl (JSIdentifier "j") [JSDecimal "1"]] -            [] -            [] -            (JSBlock (-                JSStatementList [JSExpression [JSIdentifier "x",JSOperator "=",JSDecimal "1"]]-                )-            )-          ]          -          --- doParse program "if (/^[a-z]/.test(t)) {consts += t.toUpperCase();keywords[t] = i;} else {consts += (/^\\W/.test(t) ? opTypeNames[t] : t);}consts += \" = \" + x;"-_case14 :: JSNode-_case14 = undefined-          --- doParse program "a+1;{}"-_case15 :: JSNode-_case15 = JSSourceElements -            [-              JSExpression [JSIdentifier "a",JSExpressionBinary "+" [JSDecimal "1"] []],-              JSLiteral ";",-              JSLiteral ";"-            ]-            --- doParse program "for (i = 0;;){var t=1;;}\nx=1;"--- (renderJS _case16) should become "for (i = 0;;)var t=1;x=1"-_case16 :: JSNode-_case16 = JSSourceElementsTop -            [-              JSFor [JSExpression [JSIdentifier "i",JSOperator "=",JSDecimal "0"]] [] [] -                (JSBlock -                 (JSStatementList -                  [-                    JSVariables "var" [JSVarDecl (JSIdentifier "t") [JSDecimal "1"]],-                    JSLiteral ";",-                    JSLiteral ""-                  ]-                 )-                ),-              JSExpression [JSIdentifier "x",JSOperator "=",JSDecimal "1"],-              JSLiteral ";"-            ]---- doParse program "return new global.Boolean(v);"-_case17 :: JSNode-_case17 = undefined-            ---doParse program "if(typeof s!=\"string\")return;while(--n>=0)s+=t;"-_case18 :: JSNode-_case18 = JSSourceElementsTop -            [-              JSIf -                (JSExpression [JSUnary "typeof ",JSIdentifier "s",JSExpressionBinary "!=" [JSStringLiteral '"' "string"] []]) -                (JSReturn [JSLiteral ";"]),-              JSWhile (JSExpression [JSUnary "--",JSIdentifier "n",JSExpressionBinary ">=" [JSDecimal "0"] []]) -                (JSExpression -                   [JSIdentifier "s",JSOperator "+=",JSIdentifier "t"]-                ),-              JSLiteral ";"-            ]            ---- doParse program "function f(){return n;\nx=1}"-_case19 :: JSNode-_case19 = JSSourceElementsTop -            [-              JSFunction (JSIdentifier "f") [] -                (JSFunctionBody -                 [-                   JSSourceElements -                     [-                       JSReturn [JSExpression [JSIdentifier "n"],JSLiteral ";"],-                       JSExpression -                         [-                            JSIdentifier "x",JSOperator "=",JSDecimal "1"-                         ]-                     ]-                 ]-                )-            ]-            ---fixSourceElements ([JSReturn [JSExpression [JSIdentifier "n"],JSLiteral ";"],JSExpression [JSElement "assignmentExpression" [JSIdentifier "x",JSOperator "=",JSDecimal 1]]])-_case20 :: [JSNode]-_case20 = [-           JSReturn [JSExpression [JSIdentifier "n"],JSLiteral ";"],-           JSExpression -             [JSIdentifier "x",JSOperator "=",JSDecimal "1"]-          ]            -            ---doParse program "if(!u)continue;t=n"-_case21 :: JSNode-_case21 = JSSourceElementsTop -            [-              JSIf (JSExpression [JSUnary "!",JSIdentifier "u"]) -                   (JSContinue [JSLiteral ";"]),-              JSExpression [JSIdentifier "t",JSOperator "=",JSIdentifier "n"]-            ]          -            ---doParse program "if (!v.base){throw new ReferenceError(v.propertyName + \" is not defined\");};x=1"-_case22 :: JSNode-_case22 = undefined----parseString program "{throw new TypeError(\"Function.prototype.apply called on\"+\n\" uncallable object\");}"-_case23 :: JSNode-_case23 = JSSourceElementsTop -            [-              JSBlock -               (-                 JSStatementList -                   [-                     JSThrow -                       (JSExpression -                          [-                            JSLiteral "new ",-                            JSIdentifier "TypeError",-                            JSArguments -                              [-                                [-                                  JSStringLiteral '"' "Function.prototype.apply called on",-                                  JSExpressionBinary "+" -                                    [-                                      JSStringLiteral '"' " uncallable object"-                                    ] -                                    []-                                ]-                              ]-                          ]-                       ),-                     JSLiteral ""-                   ]-               )-            ]+_case12 = (NS (JSIf (NS (JSExpression [NS (JSIdentifier "x") (SpanPoint {span_filename = "", span_row = 1, span_column = 4})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 4})) (NS (JSLiteral "") (SpanPoint {span_filename = "", span_row = 1, span_column = 6}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 6})) -            ---doParse program "x=\"hello \" + \"world\";"-_case24 :: JSNode-_case24 = JSSourceElementsTop -            [-              JSExpression -                    [JSIdentifier "x",-                     JSOperator "=",-                     JSStringLiteral '"' "hello ",-                     JSExpressionBinary "+" -                       [JSStringLiteral '"' "world"] []-                    ]-                ,-              JSLiteral ";"-            ]            -            ---doParse program (U.fromString "try{}catch(e){continue;}")-_case25 :: JSNode-_case25 = JSSourceElementsTop -            [-              JSTry -                (JSBlock (JSStatementList [])) -                [-                  JSCatch -                    (JSIdentifier "e") -                    [] -                    (JSBlock -                      (JSStatementList -                        [-                          JSContinue [JSLiteral ";"]-                        ]-                      )-                    )-                ]-            ]+-- readJs "bob:if(x){}\n{a}"+_case2 :: JSNode+_case2 = NS (JSSourceElementsTop [NS (JSLabelled (NS (JSIdentifier "bob") (SpanPoint {span_filename = "", span_row = 1, span_column = 1})) (NS (JSIf (NS (JSExpression [NS (JSIdentifier "x") (SpanPoint {span_filename = "", span_row = 1, span_column = 8})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 8})) (NS (JSStatementBlock (NS (JSStatementList []) (SpanPoint {span_filename = "", span_row = 1, span_column = 10}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 10}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 5}))) (SpanPoint {span_filename = "", span_row = 1, span_column = 1}),NS (JSStatementBlock (NS (JSStatementList [NS (JSExpression [NS (JSIdentifier "a") (SpanPoint {span_filename = "", span_row = 2, span_column = 2})]) (SpanPoint {span_filename = "", span_row = 2, span_column = 2})]) (SpanPoint {span_filename = "", span_row = 2, span_column = 2}))) (SpanPoint {span_filename = "", span_row = 2, span_column = 1})]) (SpanPoint {span_filename = "", span_row = 1, span_column = 1}) --- readJs "var newlines=spaces.match(/\\n/g);var newlines=spaces.match(/\\n/g);"-_case26 :: JSNode-_case26 = JSSourceElementsTop -          [-            JSVariables "var" -              [-                JSVarDecl (JSIdentifier "newlines") -                  [JSMemberDot [JSIdentifier "spaces"] (JSIdentifier "match"),JSArguments [[JSRegEx "/\\n/g"]]]-              ],-            JSVariables "var" -              [-                JSVarDecl (JSIdentifier "newlines") [JSMemberDot [JSIdentifier "spaces"] (JSIdentifier "match"),-                                                     JSArguments [[JSRegEx "/\\n/g"]]]-              ]-          ]-          --- readJs "\"mary\"+\"had\""-_case27 :: JSNode-_case27 = JSSourceElementsTop -          [-            JSExpression [JSExpressionBinary "+" [JSStringLiteral '"' "mary"] [JSStringLiteral '"' "had"]]-          ]-          --- readJs "throw new TypeError(\"Function.prototype.apply called on\"+\" uncallable object\")"-_case28 :: JSNode-_case28 = JSSourceElementsTop -          [-            JSThrow -              (-                JSExpression -                  [-                    JSLiteral "new ",-                    JSIdentifier "TypeError",-                    JSArguments -                      [-                        [-                          JSExpressionBinary "+" -                            [JSStringLiteral '"' "Function.prototype.apply called on"] -                            [JSStringLiteral '"' " uncallable object"]-                        ]-                      ]-                  ]-              )-          ]           -- EOF 
− Text/Jasmine/Token.hs
@@ -1,267 +0,0 @@-module Text.Jasmine.Token-    (-      identifier  -    , reserved  -    , whiteSpace  -    , dec  -    , hex  -    , autoSemi  -    , autoSemi'  -    , rOp  -    , lChar  -    , lexeme  -    -- Testing  -    , isAlpha  -    ) where---- -----------------------------------------------------------------------import Control.Applicative ( (<|>) )-import Data.Attoparsec.Char8 (hexadecimal, decimal, char, Parser, satisfy, try, many, (<?>), skipMany, skipMany1, isDigit, string, skipWhile, anyChar)-import Data.Char ( isAlpha, isSpace )-import qualified Data.Set as Set-import qualified Data.ByteString.Char8 as S8---- ------------------------------------------------------------------------- Do not use the lexer, it is greedy and consumes subsequent symbols, ---   e.g. "!" in a==!b-rOp :: String -> Parser ()-rOp x = lexeme $ do { _ <- string $ S8.pack x; return () }--lChar :: Char -> Parser ()-lChar x = lexeme $ do { _ <- char x; return () }-               --- ------------------------------------------------------------------------- Need to deal with the following cases--- 1. Missing semi, because following } => empty--- 2. Additional semi, with following } => empty--- 3. semi with no following }          => semi--- 4. no semi, but prior NL             => semi--autoSemi :: Parser [Char]-autoSemi = do{ _ <- rOp ";"; return (";");}-          <|> return ("")---autoSemi' :: Parser [Char]-autoSemi' = do{ _ <- rOp ";"; return (";");}---- -------------------------------------------------------------------------identifier = lexeme $ many1 (letter <|> oneOf "_")-identifier :: Parser String-identifier =-        lexeme $ try $-        do{ name <- ident-          ; if (isReservedName name)-             then fail ("reserved word " ++ show name)-             else return name-          }--ident :: Parser [Char]-ident-        = do{ c <- identStart-            ; cs <- many identLetter-            ; return (c:cs)-            }-        <?> "identifier"--isReservedName :: String -> Bool-isReservedName = flip Set.member reservedNames---- TODO: fix trailing characters test          -reserved :: String -> Parser ()-reserved name = lexeme $ do { _ <- string $ S8.pack name; return () }-{--reserved name =-        lexeme $ try $-        do{ _ <- string name-          ; notFollowedBy identLetter <?> ("end of " ++ show name)-          }--}----whiteSpace = skipMany (simpleSpace <|> oneLineComment <|> multiLineComment <?> "")---whiteSpace = skipMany (simpleSpace <|> oneLineComment <|> multiLineComment <|> do { _ <- char '\n'; setNLFlag} <?> "")-whiteSpace :: Parser ()-whiteSpace = skipMany (do { _ <- string $ S8.pack "\n"; return ()} <|> simpleSpace <|> comment <?> "")--- whiteSpace = try $ many $ (do { equal TokenWhite } <|> do { (equal TokenNL); setNLFlag})---simpleSpace :: Parser ()--- Note : Data.Char.isSpace includes a variety of non-breaking space chars, and unicode variants-simpleSpace  = skipMany1 $ (satisfy isSpace) --comment :: Parser ()-comment = do-    isMulti <- try $ do-        _ <- char fslash-        (char asterisk >> return True) <|> (char fslash >> return False)-    if isMulti then inComment else skipWhile (/= linefeed)--inComment :: Parser ()-inComment =-    theEnd <|> (anyChar >> inComment) <?> "end of comment"-  where-    theEnd = char asterisk >> (char fslash >> return ()) <|> inComment--fslash, asterisk, linefeed :: Char-fslash = '/'-asterisk = '*'-linefeed = '\n'--identLetter :: Parser Char-identLetter = alphaNum <|> oneOf "_"--identStart :: Parser Char-identStart  = letter <|> oneOf "_$"--reservedNames :: Set.Set String-reservedNames = Set.fromAscList [ -  "break",-  "case", "catch", "const", "continue",-  "debugger", "default", "delete", "do",-  "else", "enum",-  "false", "finally", "for", "function",-  "if", "in", "instanceof",-  "new", "null",-  "return",-  "switch",-  "this", "throw", "true", "try", "typeof",-  "var", "void",-  "while", "with"-  ]---hex :: Parser Integer-hex = lexeme $ do{ _ <- oneOf "xX"; hexadecimal }--dec :: Parser Integer-dec = lexeme $ decimal---- | @lexeme p@ first applies parser @p@ and than the 'whiteSpace'--- parser, returning the value of @p@. Every lexical--- token (lexeme) is defined using @lexeme@, this way every parse--- starts at a point without white space. Parsers that use @lexeme@ are--- called /lexeme/ parsers in this document.--- --- The only point where the 'whiteSpace' parser should be--- called explicitly is the start of the main parser in order to skip--- any leading white space.------ >    mainParser  = do{ whiteSpace--- >                     ; ds <- many (lexeme digit)--- >                     ; eof--- >                     ; return (sum ds)--- >                     }--lexeme :: Parser b -> Parser b-lexeme p = do{ x <- p; whiteSpace; return x  }---- ------------------------------------------------------------------------ Stuff from Parsec needed to make Attoparsec work----- | @oneOf cs@ succeeds if the current character is in the supplied--- list of characters @cs@. Returns the parsed character. See also--- 'satisfy'.--- --- >   vowel  = oneOf "aeiou"--oneOf :: String -> Parser Char-oneOf = satisfy . flip elem----- | Parses a letter or digit (a character between \'0\' and \'9\').--- Returns the parsed character. --alphaNum :: Parser Char-alphaNum = satisfy isAlphaNum    <?> "letter or digit"---- | Parses a letter (an upper case or lower case character). Returns the--- parsed character. --letter :: Parser Char-letter = satisfy isAlpha       <?> "letter"---- | Parses a digit. Returns the parsed character. ----- | Parses a hexadecimal digit (a digit or a letter between \'a\' and--- \'f\' or \'A\' and \'F\'). Returns the parsed character. --isAlphaNum :: Char -> Bool-isAlphaNum c =  isAlpha c || isDigit c---- ----------------------------------------------------------------------{--javascriptDef :: LanguageDef st-javascriptDef = javaStyle-		{ reservedNames = [ -                     "break",-                     "case", "catch", "const", "continue",-                     "debugger", "default", "delete", "do",-                     "else", "enum",-                     "false", "finally", "for", "function",-                     "if", "in", "instanceof",-                     "new", "null",-                     "return",-                     "switch",-                     "this", "throw", "true", "try", "typeof",-                     "var", "void",-                     "while", "with"-                     ]-                -- TODO: make the following constants, so the parser defn is simpler. e,g op_COMMA = ","-                , reservedOpNames= [-                     ";"	, -- "SEMICOLON",-                     ","	, -- "COMMA",-                     "?"	, -- "HOOK",-                     ":"	, -- "COLON",-                     "||"	, -- "OR",-                     "&&"	, -- "AND",-                     "|"	, -- "BITWISE_OR",-                     "^"	, -- "BITWISE_XOR",-                     "&"	, -- "BITWISE_AND",-                     "==="	, -- "STRICT_EQ",-                     "=="	, -- "EQ",-                     "="	, -- "ASSIGN",-                     "!=="	, -- "STRICT_NE",-                     "!="	, -- "NE",-                     "<<"	, -- "LSH",-                     "<="	, -- "LE",-                     "<"	, -- "LT",-                     ">>>"	, -- "URSH",-                     ">>"	, -- "RSH",-                     ">="	, -- "GE",-                     ">"	, -- "GT",-                     "++"	, -- "INCREMENT",-                     "--"	, -- "DECREMENT",-                     "+"	, -- "PLUS",-                     "-"	, -- "MINUS",-                     "*"	, -- "MUL",-                     "/"	, -- "DIV",-                     "%"	, -- "MOD",-                     "!"	, -- "NOT",-                     "~"	, -- "BITWISE_NOT",-                     "."	, -- "DOT",-                     "["	, -- "LEFT_BRACKET",-                     "]"	, -- "RIGHT_BRACKET",-                     "{"	, -- "LEFT_CURLY",-                     "}"	, -- "RIGHT_CURLY",-                     "("	, -- "LEFT_PAREN",-                     ")"	, -- "RIGHT_PAREN",-                     "@*/"	  -- "CONDCOMMENT_END"-                ]-                , opLetter = oneOf "!%&()*+,-./:;<=>?[]^{|}~"-                , opStart = opLetter javascriptDef -                , identStart = letter <|> oneOf "_"-                , identLetter = alphaNum <|> oneOf "_"-                               -                , caseSensitive  = True-		}-                -        --}---- EOF
hjsmin.cabal view
@@ -1,5 +1,5 @@ name:            hjsmin-version:         0.0.9+version:         0.0.11 license:         BSD3 license-file:    LICENSE author:          Alan Zimmerman <alan.zimm@gmail.com>@@ -26,13 +26,12 @@ library     build-depends:   base                >= 4       && < 5                    , bytestring          >= 0.9     && < 0.10-                   , attoparsec          >= 0.8     && < 0.9                    , blaze-builder       >= 0.2     && < 1                    , text                >= 0.8     && < 1                    , containers          >= 0.2     && < 0.5-                   , language-javascript >= 0.3     && < 0.5+                   , language-javascript >= 0.4     && < 0.5     exposed-modules: Text.Jasmine-    other-modules:   Text.Jasmine.Parse, Text.Jasmine.Pretty, Text.Jasmine.Token+    other-modules:   Text.Jasmine.Pretty     ghc-options:     -Wall  executable             runtests
runtests.hs view
@@ -30,6 +30,7 @@     , testCase "min_100_animals"  case_min_100_animals     , testCase "mergeStrings"     caseMergeStrings     , testCase "TrailingCommas"   caseTrailingCommas+    , testCase "GetSet"           caseGetSet     ]  testSuiteMin :: Test@@ -47,6 +48,7 @@     , testCase "EitherLeft"       caseEitherLeft       , testCase "EitherRight"      caseEitherRight       , testCase "TrailingCommas"   caseMinTrailingCommas+    , testCase "GetSet"           caseMinGetSet     ]  testSuiteFiles :: Test@@ -116,7 +118,7 @@ srcHelloWorld = "function Hello(a) {}" caseHelloWorld =     "Right (JSSourceElementsTop [JSFunction (JSIdentifier \"Hello\") [JSIdentifier \"a\"] (JSFunctionBody [])])"-  @=? (show $ parseProgram srcHelloWorld)+  @=? (showStrippedMaybe $ parseProgram srcHelloWorld) caseMinHelloWorld =    -- "function Hello(a){}" @=? (minify (U.fromString srcHelloWorld))   testMinify "function Hello(a){}" srcHelloWorld@@ -124,7 +126,7 @@ srcHelloWorld2 = "function Hello(a) {b=1}"  caseHelloWorld2 =     "Right (JSSourceElementsTop [JSFunction (JSIdentifier \"Hello\") [JSIdentifier \"a\"] (JSFunctionBody [JSSourceElements [JSExpression [JSIdentifier \"b\",JSOperator \"=\",JSDecimal \"1\"]]])])"-  @=? (show $ parseProgram srcHelloWorld2)+  @=? (showStrippedMaybe $ parseProgram srcHelloWorld2) caseMinHelloWorld2 =     -- "function Hello(a){b=1}" @=? (minify (U.fromString srcHelloWorld2))   testMinify "function Hello(a){b=1}" srcHelloWorld2@@ -132,37 +134,35 @@ srcSimpleAssignment = "a=1;"    caseSimpleAssignment =    "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"a\",JSOperator \"=\",JSDecimal \"1\"],JSLiteral \";\"])"-  @=? (show $ parseProgram srcSimpleAssignment)+  @=? (showStrippedMaybe $ parseProgram srcSimpleAssignment) caseMinSimpleAssignment =   testMinify "a=1" srcSimpleAssignment  srcEmptyFor = "for (i = 0;;){}" caseEmptyFor =-  "Right (JSSourceElementsTop [JSFor [JSExpression [JSIdentifier \"i\",JSOperator \"=\",JSDecimal \"0\"]] [] [] (JSLiteral \";\")])"-  @=? (show $ parseProgram srcEmptyFor)  +  "Right (JSSourceElementsTop [JSFor [JSExpression [JSIdentifier \"i\",JSOperator \"=\",JSDecimal \"0\"]] [] [] (JSStatementBlock (JSStatementList []))])"+  @=? (showStrippedMaybe $ parseProgram srcEmptyFor)   srcFullFor = "for (i = 0;i<10;i++){}" caseFullFor =-  "Right (JSSourceElementsTop [JSFor [JSExpression [JSIdentifier \"i\",JSOperator \"=\",JSDecimal \"0\"]] [JSExpression [JSExpressionBinary \"<\" [JSIdentifier \"i\"] [JSDecimal \"10\"]]] [JSExpression [JSExpressionPostfix \"++\" [JSIdentifier \"i\"]]] (JSLiteral \";\")])"-  @=? (show $ parseProgram srcFullFor)+  "Right (JSSourceElementsTop [JSFor [JSExpression [JSIdentifier \"i\",JSOperator \"=\",JSDecimal \"0\"]] [JSExpression [JSExpressionBinary \"<\" [JSIdentifier \"i\"] [JSDecimal \"10\"]]] [JSExpression [JSExpressionPostfix \"++\" [JSIdentifier \"i\"]]] (JSStatementBlock (JSStatementList []))])"+  @=? (showStrippedMaybe $ parseProgram srcFullFor)    srcForVarFull = "for(var i=0,j=tokens.length;i<j;i++){}" caseForVarFull =-  "Right (JSSourceElementsTop [JSForVar [JSVarDecl (JSIdentifier \"i\") [JSDecimal \"0\"],JSVarDecl (JSIdentifier \"j\") [JSMemberDot [JSIdentifier \"tokens\"] (JSIdentifier \"length\")]] [JSExpression [JSExpressionBinary \"<\" [JSIdentifier \"i\"] [JSIdentifier \"j\"]]] [JSExpression [JSExpressionPostfix \"++\" [JSIdentifier \"i\"]]] (JSLiteral \";\")])"-  @=? (show $ parseProgram srcForVarFull)+  "Right (JSSourceElementsTop [JSForVar [JSVarDecl (JSIdentifier \"i\") [JSDecimal \"0\"],JSVarDecl (JSIdentifier \"j\") [JSMemberDot [JSIdentifier \"tokens\"] (JSIdentifier \"length\")]] [JSExpression [JSExpressionBinary \"<\" [JSIdentifier \"i\"] [JSIdentifier \"j\"]]] [JSExpression [JSExpressionPostfix \"++\" [JSIdentifier \"i\"]]] (JSStatementBlock (JSStatementList []))])"+  @=? (showStrippedMaybe $ parseProgram srcForVarFull)  srcIfElse1 = "if(a){b=1}else c=2"; caseIfElse1 =-  "Right (JSSourceElementsTop [JSIfElse (JSExpression [JSIdentifier \"a\"]) (JSBlock (JSStatementList [JSExpression [JSIdentifier \"b\",JSOperator \"=\",JSDecimal \"1\"]])) (JSExpression [JSIdentifier \"c\",JSOperator \"=\",JSDecimal \"2\"])])"-  -- @=? (show $ parseString program srcIfElse1)-  @=? (show $ parseProgram srcIfElse1)+  "Right (JSSourceElementsTop [JSIfElse (JSExpression [JSIdentifier \"a\"]) (JSStatementBlock (JSStatementList [JSExpression [JSIdentifier \"b\",JSOperator \"=\",JSDecimal \"1\"]])) (JSExpression [JSIdentifier \"c\",JSOperator \"=\",JSDecimal \"2\"])])"+  @=? (showStrippedMaybe $ parseProgram srcIfElse1) caseMinIfElse1 =   testMinify "if(a){b=1}else c=2" srcIfElse1  srcIfElse2 = "if(a){b=1}else {c=2;d=4}"; caseIfElse2 =-  "Right (JSSourceElementsTop [JSIfElse (JSExpression [JSIdentifier \"a\"]) (JSBlock (JSStatementList [JSExpression [JSIdentifier \"b\",JSOperator \"=\",JSDecimal \"1\"]])) (JSBlock (JSStatementList [JSExpression [JSIdentifier \"c\",JSOperator \"=\",JSDecimal \"2\"],JSLiteral \";\",JSExpression [JSIdentifier \"d\",JSOperator \"=\",JSDecimal \"4\"]]))])"-  -- @=? (show $ parseString program srcIfElse2)-  @=? (show $ parseProgram srcIfElse2)+  "Right (JSSourceElementsTop [JSIfElse (JSExpression [JSIdentifier \"a\"]) (JSStatementBlock (JSStatementList [JSExpression [JSIdentifier \"b\",JSOperator \"=\",JSDecimal \"1\"]])) (JSStatementBlock (JSStatementList [JSExpression [JSIdentifier \"c\",JSOperator \"=\",JSDecimal \"2\"],JSLiteral \";\",JSExpression [JSIdentifier \"d\",JSOperator \"=\",JSDecimal \"4\"]]))])"+  @=? (showStrippedMaybe $ parseProgram srcIfElse2) caseMinIfElse2 =   testMinify "if(a){b=1}else{c=2;d=4}" srcIfElse2 @@ -171,7 +171,7 @@   -- "Right (JSSourceElementsTop [JSFunction (JSIdentifier \"Hello\") [JSIdentifier \"a\"] (JSFunctionBody [JSSourceElements [JSExpression [JSIdentifier \"ExprArray\",JSArguments [[JSDecimal 1],[JSDecimal 1]]],JSLiteral \"\"]])]"   "Right (JSSourceElementsTop [JSFunction (JSIdentifier \"Hello\") [JSIdentifier \"a\"] (JSFunctionBody [JSSourceElements [JSExpression [JSIdentifier \"ExprArray\",JSArguments [[JSDecimal \"1\"],[JSDecimal \"1\"]]],JSLiteral \";\"]])])"   -- @=? (show $ parseString program src0_f)-  @=? (show $ parseProgram src0_f)+  @=? (showStrippedMaybe $ parseProgram src0_f) caseMin0_f =   testMinify "function Hello(a){ExprArray(1,1)}" src0_f   @@ -183,29 +183,29 @@     "// five\n"++     "five")   case01_semi1 =-  "Right (JSSourceElementsTop [JSBlock (JSStatementList [JSExpression [JSMemberDot [JSIdentifier \"zero\"] (JSIdentifier \"one1\")],JSLiteral \";\",JSExpression [JSIdentifier \"zero\"]]),JSExpression [JSIdentifier \"one1\"],JSExpression [JSIdentifier \"two\"],JSLiteral \";\",JSExpression [JSIdentifier \"three\"],JSLiteral \";\",JSExpression [JSIdentifier \"four\"],JSLiteral \";\",JSExpression [JSIdentifier \"five\"]])"-  @=? (show $ parseProgram src01_semi1)+  "Right (JSSourceElementsTop [JSStatementBlock (JSStatementList [JSExpression [JSMemberDot [JSIdentifier \"zero\"] (JSIdentifier \"one1\")],JSLiteral \";\",JSExpression [JSIdentifier \"zero\"]]),JSExpression [JSIdentifier \"one1\"],JSExpression [JSIdentifier \"two\"],JSLiteral \";\",JSExpression [JSIdentifier \"three\"],JSStatementBlock (JSStatementList [JSStatementBlock (JSStatementList [])]),JSExpression [JSIdentifier \"four\"],JSLiteral \";\",JSExpression [JSIdentifier \"five\"]])"+  @=? (showStrippedMaybe $ parseProgram src01_semi1) caseMin01_semi1 =   testMinify "{zero.one1;zero};one1;two;three;four;five" src01_semi1    src_min_100_animals = "function Animal(name){if(!name)throw new Error('Must specify an animal name');this.name=name};Animal.prototype.toString=function(){return this.name};o=new Animal(\"bob\");o.toString()==\"bob\""  case_min_100_animals =   "Right (JSSourceElementsTop [JSFunction (JSIdentifier \"Animal\") [JSIdentifier \"name\"] (JSFunctionBody [JSSourceElements [JSIf (JSExpression [JSUnary \"!\",JSIdentifier \"name\"]) (JSBlock (JSStatementList [JSThrow (JSExpression [JSLiteral \"new \",JSIdentifier \"Error\",JSArguments [[JSStringLiteral '\\'' \"Must specify an animal name\"]]])])),JSExpression [JSMemberDot [JSLiteral \"this\"] (JSIdentifier \"name\"),JSOperator \"=\",JSIdentifier \"name\"]]]),JSLiteral \";\",JSExpression [JSMemberDot [JSMemberDot [JSIdentifier \"Animal\"] (JSIdentifier \"prototype\")] (JSIdentifier \"toString\"),JSOperator \"=\",JSFunctionExpression [] [] (JSFunctionBody [JSSourceElements [JSReturn [JSExpression [JSMemberDot [JSLiteral \"this\"] (JSIdentifier \"name\")],JSLiteral \"\"]]])],JSLiteral \";\",JSExpression [JSIdentifier \"o\",JSOperator \"=\",JSLiteral \"new \",JSIdentifier \"Animal\",JSArguments [[JSStringLiteral '\"' \"bob\"]]],JSLiteral \";\",JSExpression [JSExpressionBinary \"==\" [JSMemberDot [JSIdentifier \"o\"] (JSIdentifier \"toString\"),JSArguments []] [JSStringLiteral '\"' \"bob\"]]])"-  @=? (show $ parseProgram src_min_100_animals)+  @=? (showStrippedMaybe $ parseProgram src_min_100_animals) caseMin_min_100_animals =   testMinify src_min_100_animals src_min_100_animals    srcMergeStrings = "throw new TypeError(\"Function.prototype.apply called on\"+\" uncallable object\");" caseMergeStrings =     "Right (JSSourceElementsTop [JSThrow (JSExpression [JSLiteral \"new \",JSIdentifier \"TypeError\",JSArguments [[JSExpressionBinary \"+\" [JSStringLiteral '\"' \"Function.prototype.apply called on\"] [JSStringLiteral '\"' \" uncallable object\"]]]]),JSLiteral \";\"])"-  @=? (show $ parseProgram srcMergeStrings)+  @=? (showStrippedMaybe $ parseProgram srcMergeStrings) caseMinMergeStrings =     testMinify "throw new TypeError(\"Function.prototype.apply called on uncallable object\")" srcMergeStrings    srcNestedSquare = "this.cursor+=match[0].length;" caseNestedSquare =   "Right (JSSourceElementsTop [JSExpression [JSMemberDot [JSLiteral \"this\"] (JSIdentifier \"cursor\"),JSOperator \"+=\",JSMemberDot [JSMemberSquare [JSIdentifier \"match\"] (JSExpression [JSDecimal \"0\"])] (JSIdentifier \"length\")],JSLiteral \";\"])"-  @=? (show $ parseProgram srcNestedSquare)+  @=? (showStrippedMaybe $ parseProgram srcNestedSquare) caseMinNestedSquare =     testMinify "this.cursor+=match[0].length" srcNestedSquare   @@ -220,9 +220,16 @@ srcTrailingCommas = "x={a:1,};y=[d,e,];" caseTrailingCommas =   "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator \"=\",JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"a\") [JSDecimal \"1\"],JSLiteral \",\"]],JSLiteral \";\",JSExpression [JSIdentifier \"y\",JSOperator \"=\",JSArrayLiteral [JSIdentifier \"d\",JSElision [],JSIdentifier \"e\",JSLiteral \",\"]],JSLiteral \";\"])"-  @=? (show $ parseProgram srcTrailingCommas)+  @=? (showStrippedMaybe $ parseProgram srcTrailingCommas) caseMinTrailingCommas =     testMinify "x={a:1,};y=[d,e,]" srcTrailingCommas+  +srcGetSet = "x={get foo() {return 1},set foo(a) {x=a}}"+caseGetSet =+  "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator \"=\",JSObjectLiteral [JSPropertyAccessor \"get\" (JSIdentifier \"foo\") [] (JSFunctionBody [JSSourceElements [JSReturn [JSExpression [JSDecimal \"1\"],JSLiteral \"\"]]]),JSPropertyAccessor \"set\" (JSIdentifier \"foo\") [JSIdentifier \"a\"] (JSFunctionBody [JSSourceElements [JSExpression [JSIdentifier \"x\",JSOperator \"=\",JSIdentifier \"a\"]]])]]])"+  @=? (showStrippedMaybe $ parseProgram srcGetSet)+caseMinGetSet =  +  testMinify "x={get foo(){return 1},set foo(a){x=a}}" srcGetSet    -- --------------------------------------------------------------------- -- utilities