Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge remote-tracking branch 'origin/round-trip'

Conflicts:
	.gitignore
	README
	language-javascript.cabal
	src/Language/JavaScript/Parser/Lexer.hs
  • Loading branch information...
commit 93f9aec6035182d4d4f8bd97befeadff633ace3f 2 parents 3a4d672 + 7966005
@alanz authored
View
8 .gitignore
@@ -1,17 +1,15 @@
*~
/dist/*
/parse.txt
+/src/Language/JavaScript/Parser/Lexer.info
/unicode/uc-ll.htm
/unicode/uc-lm.htm
/unicode/uc-lo.htm
/unicode/uc-lt.htm
/unicode/uc-lu.htm
-/unicode/uc-nl.htm
-/unicode/combiningmark.sh~
-/unicode/connector-punctuation.sh~
/unicode/uc-mc.htm
/unicode/uc-mn.htm
/unicode/uc-nd.htm
+/unicode/uc-nl.htm
+/unicode/uc-nl.htm
/unicode/uc-pc.htm
-
-/src/Language/JavaScript/Parser/Lexer.info
View
3  README
@@ -35,6 +35,9 @@ dependency in the cabal file.
Changes
+0.5.0 Rework AST to allow full round-trip parsing and output of
+ JavaScript. Breaks AST compatibility with prior versions
+
0.4.10 Moved Lexer.x into a separate directory, and made a script to
call alex to generate Lexer.hs. This means alex is not required
at install time
View
4 TODO.txt
@@ -31,5 +31,9 @@ manipulation.
13. Numeric literals Infinity, NaN
+14. Look at http://jsshaper.org/
+
+15. Store number of rows/cols in a comment, to speed output
+
EOF
View
12 language-javascript.cabal
@@ -1,7 +1,10 @@
Name: language-javascript
-Version: 0.4.10
+Version: 0.5.0
Synopsis: Parser for JavaScript
Description: Parses Javascript into an Abstract Syntax Tree (AST). Initially intended as frontend to hjsmin.
+ .
+ Note: Version 0.5.0 breaks compatibility with prior versions, the AST has been reworked to allow
+ round trip processing of JavaScript.
Homepage: https://github.com/alanz/language-javascript
License: BSD3
License-file: LICENSE
@@ -29,9 +32,11 @@ Library
, mtl >= 1.1 && < 2.9
, containers >= 0.2 && < 0.5
, utf8-light >= 0.4 && < 1.0
+ -- For the round trip output
+ , blaze-builder >= 0.2 && < 1
+ , bytestring >= 0.9.1 && < 1
+ , utf8-string >= 0.3.7 && < 1
build-tools: happy >= 1.18.5
- -- , alex >= 3.0
-
hs-source-dirs: src
Exposed-modules: Language.JavaScript.Parser
Language.JavaScript.Parser.Parser
@@ -45,7 +50,6 @@ Library
Language.JavaScript.Parser.StringEscape
Language.JavaScript.Parser.Token
Build-tools: happy
- -- , alex
ghc-options: -Wall
executable runtests
View
625 runtests.hs
@@ -1,4 +1,3 @@
-
import Test.Framework (defaultMain, testGroup, Test)
import Test.Framework.Providers.HUnit
import Test.HUnit hiding (Test)
@@ -6,11 +5,12 @@ import Test.HUnit hiding (Test)
import Control.Monad (liftM)
import Language.JavaScript.Parser.Parser
+import Language.JavaScript.Parser
--import Language.JavaScript.Parser.Grammar
import Language.JavaScript.Parser.Grammar5
main :: IO ()
-main = defaultMain [testSuite]
+main = defaultMain [testSuite,{- ++AZ++temporary++ commentSuite ,-}commentPrintSuite]
one :: IO ()
one = defaultMain [oneSuite]
@@ -61,28 +61,28 @@ testSuite = testGroup "Parser"
, testCase "Identifier2" (testPE "this_" "Right (JSIdentifier \"this_\")")
, testCase "ArrayLiteral1" (testPE "[]" "Right (JSArrayLiteral [])")
- , testCase "ArrayLiteral2" (testPE "[,]" "Right (JSArrayLiteral [JSElision []])")
- , testCase "ArrayLiteral3" (testPE "[,,]" "Right (JSArrayLiteral [JSElision [],JSElision []])")
- , testCase "ArrayLiteral4" (testPE "[,,x]" "Right (JSArrayLiteral [JSElision [],JSElision [],JSIdentifier \"x\"])")
- , testCase "ArrayLiteral5" (testPE "[,,x]" "Right (JSArrayLiteral [JSElision [],JSElision [],JSIdentifier \"x\"])")
- , testCase "ArrayLiteral6" (testPE "[,x,,x]" "Right (JSArrayLiteral [JSElision [],JSIdentifier \"x\",JSElision [],JSElision [],JSIdentifier \"x\"])")
+ , testCase "ArrayLiteral2" (testPE "[,]" "Right (JSArrayLiteral [JSElision JSLiteral \",\"])")
+ , testCase "ArrayLiteral3" (testPE "[,,]" "Right (JSArrayLiteral [JSElision JSLiteral \",\",JSElision JSLiteral \",\"])")
+ , testCase "ArrayLiteral4" (testPE "[,,x]" "Right (JSArrayLiteral [JSElision JSLiteral \",\",JSElision JSLiteral \",\",JSIdentifier \"x\"])")
+ , testCase "ArrayLiteral5" (testPE "[,,x]" "Right (JSArrayLiteral [JSElision JSLiteral \",\",JSElision JSLiteral \",\",JSIdentifier \"x\"])")
+ , testCase "ArrayLiteral6" (testPE "[,x,,x]" "Right (JSArrayLiteral [JSElision JSLiteral \",\",JSIdentifier \"x\",JSElision JSLiteral \",\",JSElision JSLiteral \",\",JSIdentifier \"x\"])")
, testCase "ArrayLiteral7" (testPE "[x]" "Right (JSArrayLiteral [JSIdentifier \"x\"])")
, testCase "ArrayLiteral8" (testPE "[x,]" "Right (JSArrayLiteral [JSIdentifier \"x\",JSLiteral \",\"])")
- , testCase "ObjectLiteral1" (testPE "{}" "Right (JSObjectLiteral [])")
- , testCase "ObjectLiteral2" (testPE "{x:1}" "Right (JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"x\") [JSDecimal \"1\"]])")
- , testCase "ObjectLiteral3" (testPE "{x:1,y:2}" "Right (JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"x\") [JSDecimal \"1\"],JSPropertyNameandValue (JSIdentifier \"y\") [JSDecimal \"2\"]])")
+ , testCase "ObjectLiteral1" (testPE "{}" "Right (JSObjectLiteral [])")
+ , testCase "ObjectLiteral2" (testPE "{x:1}" "Right (JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"x\") [JSDecimal \"1\"]])")
+ , testCase "ObjectLiteral3" (testPE "{x:1,y:2}" "Right (JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"x\") [JSDecimal \"1\"],JSLiteral \",\",JSPropertyNameandValue (JSIdentifier \"y\") [JSDecimal \"2\"]])")
- , testCase "ObjectLiteral4" (testPE "{evaluate:evaluate,load:function load(s){if(x)return s;1}}" "Right (JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"evaluate\") [JSIdentifier \"evaluate\"],JSPropertyNameandValue (JSIdentifier \"load\") [JSFunctionExpression [JSIdentifier \"load\"] [JSIdentifier \"s\"] (JSFunctionBody [JSSourceElements [JSIf (JSExpression [JSIdentifier \"x\"]) (JSReturn [JSExpression [JSIdentifier \"s\"],JSLiteral \";\"]),JSExpression [JSDecimal \"1\"]]])]])")
+ , testCase "ObjectLiteral4" (testPE "{evaluate:evaluate,load:function load(s){if(x)return s;1}}" "Right (JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"evaluate\") [JSIdentifier \"evaluate\"],JSLiteral \",\",JSPropertyNameandValue (JSIdentifier \"load\") [JSFunctionExpression [JSIdentifier \"load\"] [JSIdentifier \"s\"] (JSFunctionBody [JSSourceElements [JSIf (JSExpression [JSIdentifier \"x\"]) (JSReturn [JSExpression [JSIdentifier \"s\"]] JSLiteral \";\") ([]),JSExpression [JSDecimal \"1\"]]])]])")
, testCase "ObjectLiteral5" (testPE "{x:1,}" "Right (JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"x\") [JSDecimal \"1\"],JSLiteral \",\"])")
- , testCase "ObjectLiteral6" (testProg "a={\n values: 7,\n}\n" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"a\",JSOperator \"=\",JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"values\") [JSDecimal \"7\"],JSLiteral \",\"]]])")
+ , testCase "ObjectLiteral6" (testProg "a={\n values: 7,\n}\n" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"a\",JSOperator JSLiteral \"=\",JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"values\") [JSDecimal \"7\"],JSLiteral \",\"]],JSLiteral \"\"])")
-- Edition 5 extensions
- , testCase "ObjectLiteral7" (testProg "x={get foo() {return 1},set foo(a) {x=a}}" "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\"]]])]]])")
+ , testCase "ObjectLiteral7" (testProg "x={get foo() {return 1},set foo(a) {x=a}}" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSObjectLiteral [JSPropertyAccessor NT (JSLiteral \"get\") (TokenPn 3 1 4) [NoComment] (JSIdentifier \"foo\") [] (JSFunctionBody [JSSourceElements [JSReturn [JSExpression [JSDecimal \"1\"]] JSLiteral \"\"]]),JSLiteral \",\",JSPropertyAccessor NT (JSLiteral \"set\") (TokenPn 24 1 25) [NoComment] (JSIdentifier \"foo\") [JSIdentifier \"a\"] (JSFunctionBody [JSSourceElements [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSIdentifier \"a\"]]])]],JSLiteral \"\"])")
- , testCase "ObjectLiteral8" (testProg "a={if:1,interface:2}" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"a\",JSOperator \"=\",JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"if\") [JSDecimal \"1\"],JSPropertyNameandValue (JSIdentifier \"interface\") [JSDecimal \"2\"]]]])")
+ , testCase "ObjectLiteral8" (testProg "a={if:1,interface:2}" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"a\",JSOperator JSLiteral \"=\",JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"if\") [JSDecimal \"1\"],JSLiteral \",\",JSPropertyNameandValue (JSIdentifier \"interface\") [JSDecimal \"2\"]]],JSLiteral \"\"])")
, testCase "ExpressionParen" (testPE "(56)" "Right (JSExpressionParen (JSExpression [JSDecimal \"56\"]))")
@@ -132,85 +132,85 @@ testSuite = testGroup "Parser"
, testCase "Statement28" (testStmt "y--" "Right (JSExpression [JSExpressionPostfix \"--\" [JSIdentifier \"y\"]])")
-- Member Expressions
- , testCase "MemberExpression1" (testStmt "function(){}" "Right (JSExpression [JSFunctionExpression [] [] (JSFunctionBody [])])")
- , testCase "MemberExpression1" (testStmt "function(a){}" "Right (JSExpression [JSFunctionExpression [] [JSIdentifier \"a\"] (JSFunctionBody [])])")
- , testCase "MemberExpression1" (testStmt "function(a,b){}" "Right (JSExpression [JSFunctionExpression [] [JSIdentifier \"a\",JSIdentifier \"b\"] (JSFunctionBody [])])")
+ , testCase "MemberExpression1a" (testStmt "function(){}" "Right (JSExpression [JSFunctionExpression [] [] (JSFunctionBody [])])")
+ , testCase "MemberExpression1b" (testStmt "function(a){}" "Right (JSExpression [JSFunctionExpression [] [JSIdentifier \"a\"] (JSFunctionBody [])])")
+ , testCase "MemberExpression1c" (testStmt "function(a,b){}" "Right (JSExpression [JSFunctionExpression [] [JSIdentifier \"a\",JSLiteral \",\",JSIdentifier \"b\"] (JSFunctionBody [])])")
- , testCase "MemberExpression1" (testStmt "x[y]" "Right (JSExpression [JSMemberSquare [JSIdentifier \"x\"] (JSExpression [JSIdentifier \"y\"])])")
- , testCase "MemberExpression1" (testStmt "x[y][z]" "Right (JSExpression [JSMemberSquare [JSMemberSquare [JSIdentifier \"x\"] (JSExpression [JSIdentifier \"y\"])] (JSExpression [JSIdentifier \"z\"])])")
- , testCase "MemberExpression1" (testStmt "x.y" "Right (JSExpression [JSMemberDot [JSIdentifier \"x\"] (JSIdentifier \"y\")])")
- , testCase "MemberExpression1" (testStmt "x.y.z" "Right (JSExpression [JSMemberDot [JSMemberDot [JSIdentifier \"x\"] (JSIdentifier \"y\")] (JSIdentifier \"z\")])")
+ , testCase "MemberExpression1d" (testStmt "x[y]" "Right (JSExpression [JSMemberSquare [JSIdentifier \"x\"] (JSExpression [JSIdentifier \"y\"])])")
+ , testCase "MemberExpression1e" (testStmt "x[y][z]" "Right (JSExpression [JSMemberSquare [JSMemberSquare [JSIdentifier \"x\"] (JSExpression [JSIdentifier \"y\"])] (JSExpression [JSIdentifier \"z\"])])")
+ , testCase "MemberExpression1f" (testStmt "x.y" "Right (JSExpression [JSMemberDot [JSIdentifier \"x\"] (JSIdentifier \"y\")])")
+ , testCase "MemberExpression1g" (testStmt "x.y.z" "Right (JSExpression [JSMemberDot [JSMemberDot [JSIdentifier \"x\"] (JSIdentifier \"y\")] (JSIdentifier \"z\")])")
- , testCase "MemberExpression1" (testStmt "new x()" "Right (JSExpression [JSLiteral \"new \",JSIdentifier \"x\",JSArguments []])")
+ , testCase "MemberExpression1h" (testStmt "new x()" "Right (JSExpression [JSLiteral \"new\",JSIdentifier \"x\",JSArguments []])")
- , testCase "NewExpression1" (testStmt "new x.y" "Right (JSExpression [JSLiteral \"new \",JSMemberDot [JSIdentifier \"x\"] (JSIdentifier \"y\")])")
+ , testCase "NewExpression1" (testStmt "new x.y" "Right (JSExpression [JSLiteral \"new\",JSMemberDot [JSIdentifier \"x\"] (JSIdentifier \"y\")])")
, testCase "CallExpression1" (testStmt "x()" "Right (JSExpression [JSIdentifier \"x\",JSArguments []])")
, testCase "CallExpression2" (testStmt "x()()" "Right (JSExpression [JSIdentifier \"x\",JSArguments [],JSCallExpression \"()\" [JSArguments []]])")
, testCase "CallExpression3" (testStmt "x()[4]" "Right (JSExpression [JSIdentifier \"x\",JSArguments [],JSCallExpression \"[]\" [JSExpression [JSDecimal \"4\"]]])")
, testCase "CallExpression4" (testStmt "x().x" "Right (JSExpression [JSIdentifier \"x\",JSArguments [],JSCallExpression \".\" [JSIdentifier \"x\"]])")
- , testCase "CallExpression5" (testStmt "x(a,b=2).x" "Right (JSExpression [JSIdentifier \"x\",JSArguments [[JSIdentifier \"a\"],[JSIdentifier \"b\",JSOperator \"=\",JSDecimal \"2\"]],JSCallExpression \".\" [JSIdentifier \"x\"]])")
-
- , testCase "AssignExpression1" (testStmt "x=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator \"=\",JSDecimal \"1\"])")
- , testCase "AssignExpression1" (testStmt "x*=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator \"*=\",JSDecimal \"1\"])")
- , testCase "AssignExpression1" (testStmt "x/=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator \"/=\",JSDecimal \"1\"])")
- , testCase "AssignExpression1" (testStmt "x%=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator \"%=\",JSDecimal \"1\"])")
- , testCase "AssignExpression1" (testStmt "x+=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator \"+=\",JSDecimal \"1\"])")
- , testCase "AssignExpression1" (testStmt "x-=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator \"-=\",JSDecimal \"1\"])")
- , testCase "AssignExpression1" (testStmt "x<<=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator \"<<=\",JSDecimal \"1\"])")
- , testCase "AssignExpression1" (testStmt "x>>=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator \">>=\",JSDecimal \"1\"])")
- , testCase "AssignExpression1" (testStmt "x>>>=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator \">>>=\",JSDecimal \"1\"])")
- , testCase "AssignExpression1" (testStmt "x&=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator \"&=\",JSDecimal \"1\"])")
- , testCase "AssignExpression1" (testStmt "x^=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator \"^=\",JSDecimal \"1\"])")
- , testCase "AssignExpression1" (testStmt "x|=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator \"|=\",JSDecimal \"1\"])")
+ , testCase "CallExpression5" (testStmt "x(a,b=2).x" "Right (JSExpression [JSIdentifier \"x\",JSArguments [JSIdentifier \"a\",JSLiteral \",\",JSIdentifier \"b\",JSOperator JSLiteral \"=\",JSDecimal \"2\"],JSCallExpression \".\" [JSIdentifier \"x\"]])")
+
+ , testCase "AssignExpression1" (testStmt "x=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSDecimal \"1\"])")
+ , testCase "AssignExpression2" (testStmt "x*=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"*=\",JSDecimal \"1\"])")
+ , testCase "AssignExpression3" (testStmt "x/=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"/=\",JSDecimal \"1\"])")
+ , testCase "AssignExpression4" (testStmt "x%=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"%=\",JSDecimal \"1\"])")
+ , testCase "AssignExpression5" (testStmt "x+=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"+=\",JSDecimal \"1\"])")
+ , testCase "AssignExpression6" (testStmt "x-=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"-=\",JSDecimal \"1\"])")
+ , testCase "AssignExpression7" (testStmt "x<<=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"<<=\",JSDecimal \"1\"])")
+ , testCase "AssignExpression8" (testStmt "x>>=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \">>=\",JSDecimal \"1\"])")
+ , testCase "AssignExpression9" (testStmt "x>>>=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \">>>=\",JSDecimal \"1\"])")
+ , testCase "AssignExpression10" (testStmt "x&=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"&=\",JSDecimal \"1\"])")
+ , testCase "AssignExpression11" (testStmt "x^=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"^=\",JSDecimal \"1\"])")
+ , testCase "AssignExpression12" (testStmt "x|=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"|=\",JSDecimal \"1\"])")
, testCase "Block1" (testStmt "{}" "Right (JSStatementBlock (JSStatementList []))")
- , testCase "Block2" (testStmt "{x=1}" "Right (JSStatementBlock (JSStatementList [JSExpression [JSIdentifier \"x\",JSOperator \"=\",JSDecimal \"1\"]]))")
- , testCase "Block3" (testStmt "{x=1;y=2}" "Right (JSStatementBlock (JSStatementList [JSExpression [JSIdentifier \"x\",JSOperator \"=\",JSDecimal \"1\"],JSLiteral \";\",JSExpression [JSIdentifier \"y\",JSOperator \"=\",JSDecimal \"2\"]]))")
+ , testCase "Block2" (testStmt "{x=1}" "Right (JSStatementBlock (JSStatementList [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSDecimal \"1\"]]))")
+ , testCase "Block3" (testStmt "{x=1;y=2}" "Right (JSStatementBlock (JSStatementList [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSDecimal \"1\"],JSLiteral \";\",JSExpression [JSIdentifier \"y\",JSOperator JSLiteral \"=\",JSDecimal \"2\"]]))")
, testCase "Block4" (testStmt "{{}}" "Right (JSStatementBlock (JSStatementList [JSStatementBlock (JSStatementList [])]))")
, testCase "Block5" (testStmt "{{{}}}" "Right (JSStatementBlock (JSStatementList [JSStatementBlock (JSStatementList [JSStatementBlock (JSStatementList [])])]))")
- , testCase "If1" (testStmt "if (1) {}" "Right (JSIf (JSExpression [JSDecimal \"1\"]) (JSStatementBlock (JSStatementList [])))")
+ , testCase "If1" (testStmt "if (1) {}" "Right (JSIf (JSExpression [JSDecimal \"1\"]) (JSStatementBlock (JSStatementList [])) ([]))")
- , testCase "IfElse1" (testStmt "if (1) {} else {}" "Right (JSIfElse (JSExpression [JSDecimal \"1\"]) (JSStatementBlock (JSStatementList [])) (JSStatementBlock (JSStatementList [])))")
- , testCase "IfElse2" (testStmt "if (1) x=1; else {}" "Right (JSIfElse (JSExpression [JSDecimal \"1\"]) (JSBlock (JSStatementList [JSExpression [JSIdentifier \"x\",JSOperator \"=\",JSDecimal \"1\"]])) (JSStatementBlock (JSStatementList [])))")
+ , testCase "IfElse1" (testStmt "if (1) {} else {}" "Right (JSIf (JSExpression [JSDecimal \"1\"]) (JSBlock (JSStatementList [JSStatementBlock (JSStatementList [])])) ([JSLiteral \"else\",JSStatementBlock (JSStatementList [])]))")
+ , testCase "IfElse2" (testStmt "if (1) x=1; else {}" "Right (JSIf (JSExpression [JSDecimal \"1\"]) (JSBlock (JSStatementList [JSBlock (JSStatementList [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSDecimal \"1\"],JSLiteral \";\"])])) ([JSLiteral \"else\",JSStatementBlock (JSStatementList [])]))")
- , testCase "DoWhile1" (testStmt "do {x=1} while (true);" "Right (JSDoWhile (JSStatementBlock (JSStatementList [JSExpression [JSIdentifier \"x\",JSOperator \"=\",JSDecimal \"1\"]])) (JSExpression [JSLiteral \"true\"]) (JSLiteral \";\"))")
+ , testCase "DoWhile1" (testStmt "do {x=1} while (true);" "Right (JSDoWhile (JSStatementBlock (JSStatementList [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSDecimal \"1\"]])) (JSExpression [JSLiteral \"true\"]) (JSLiteral \";\"))")
, testCase "While1" (testStmt "while(true);" "Right (JSWhile (JSExpression [JSLiteral \"true\"]) (JSLiteral \";\"))")
, testCase "For1" (testStmt "for(;;);" "Right (JSFor [] [] [] (JSLiteral \";\"))")
- , testCase "For2" (testStmt "for(x=1;x<10;x++);" "Right (JSFor [JSExpression [JSIdentifier \"x\",JSOperator \"=\",JSDecimal \"1\"]] [JSExpression [JSExpressionBinary \"<\" [JSIdentifier \"x\"] [JSDecimal \"10\"]]] [JSExpression [JSExpressionPostfix \"++\" [JSIdentifier \"x\"]]] (JSLiteral \";\"))")
+ , testCase "For2" (testStmt "for(x=1;x<10;x++);" "Right (JSFor [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSDecimal \"1\"]] [JSExpression [JSExpressionBinary \"<\" [JSIdentifier \"x\"] [JSDecimal \"10\"]]] [JSExpression [JSExpressionPostfix \"++\" [JSIdentifier \"x\"]]] (JSLiteral \";\"))")
, testCase "ForVar1" (testStmt "for(var x;;);" "Right (JSForVar [JSVarDecl (JSIdentifier \"x\") []] [] [] (JSLiteral \";\"))")
- , testCase "ForVar2" (testStmt "for(var x=1;;);" "Right (JSForVar [JSVarDecl (JSIdentifier \"x\") [JSDecimal \"1\"]] [] [] (JSLiteral \";\"))")
+ , testCase "ForVar2" (testStmt "for(var x=1;;);" "Right (JSForVar [JSVarDecl (JSIdentifier \"x\") [JSLiteral \"=\",JSDecimal \"1\"]] [] [] (JSLiteral \";\"))")
, testCase "ForVar2" (testStmt "for(var x;y;z){}" "Right (JSForVar [JSVarDecl (JSIdentifier \"x\") []] [JSExpression [JSIdentifier \"y\"]] [JSExpression [JSIdentifier \"z\"]] (JSStatementBlock (JSStatementList [])))")
, testCase "ForIn1" (testStmt "for(x in 5){}" "Right (JSForIn [JSIdentifier \"x\"] (JSExpression [JSDecimal \"5\"]) (JSStatementBlock (JSStatementList [])))")
, testCase "ForVarIn1" (testStmt "for(var x in 5){}" "Right (JSForVarIn (JSVarDecl (JSIdentifier \"x\") []) (JSExpression [JSDecimal \"5\"]) (JSStatementBlock (JSStatementList [])))")
- , testCase "Var1" (testStmt "var x=1;" "Right (JSVariables \"var\" [JSVarDecl (JSIdentifier \"x\") [JSDecimal \"1\"]])")
- , testCase "Var2" (testStmt "const x=1,y=2;" "Right (JSVariables \"const\" [JSVarDecl (JSIdentifier \"x\") [JSDecimal \"1\"],JSVarDecl (JSIdentifier \"y\") [JSDecimal \"2\"]])")
+ , testCase "Var1" (testStmt "var x=1;" "Right (JSVariables JSLiteral \"var\" [JSVarDecl (JSIdentifier \"x\") [JSLiteral \"=\",JSDecimal \"1\"]])")
+ , testCase "Var2" (testStmt "const x=1,y=2;" "Right (JSVariables JSLiteral \"const\" [JSVarDecl (JSIdentifier \"x\") [JSLiteral \"=\",JSDecimal \"1\"],JSLiteral \",\",JSVarDecl (JSIdentifier \"y\") [JSLiteral \"=\",JSDecimal \"2\"]])")
- , testCase "Continue1" (testStmt "continue;" "Right (JSContinue [JSLiteral \";\"])")
- , testCase "Continue2" (testStmt "continue x;" "Right (JSContinue [JSIdentifier \"x\",JSLiteral \";\"])")
+ , testCase "Continue1" (testStmt "continue;" "Right (JSContinue [] JSLiteral \";\")")
+ , testCase "Continue2" (testStmt "continue x;" "Right (JSContinue [JSIdentifier \"x\"] JSLiteral \";\")")
- , testCase "Break1" (testStmt "break;" "Right (JSBreak [] [JSLiteral \";\"])")
- , testCase "Break2" (testStmt "break x;" "Right (JSBreak [JSIdentifier \"x\"] [JSLiteral \";\"])")
+ , testCase "Break1" (testStmt "break;" "Right (JSBreak [] JSLiteral \";\")")
+ , testCase "Break2" (testStmt "break x;" "Right (JSBreak [JSIdentifier \"x\"] JSLiteral \";\")")
- , testCase "Return1" (testStmt "return;" "Right (JSReturn [JSLiteral \";\"])")
- , testCase "Return2" (testStmt "return x;" "Right (JSReturn [JSExpression [JSIdentifier \"x\"],JSLiteral \";\"])")
+ , testCase "Return1" (testStmt "return;" "Right (JSReturn [] JSLiteral \";\")")
+ , testCase "Return2" (testStmt "return x;" "Right (JSReturn [JSExpression [JSIdentifier \"x\"]] JSLiteral \";\")")
- , testCase "With1" (testStmt "with (x) {};" "Right (JSWith (JSExpression [JSIdentifier \"x\"]) [JSStatementBlock (JSStatementList []),JSLiteral \";\"])")
+ , testCase "With1" (testStmt "with (x) {};" "Right (JSWith (JSExpression [JSIdentifier \"x\"]) [JSStatementBlock (JSStatementList []),JSLiteral \";\"])")
- , testCase "Labelled1" (testStmt "abc:x=1" "Right (JSLabelled (JSIdentifier \"abc\") (JSExpression [JSIdentifier \"x\",JSOperator \"=\",JSDecimal \"1\"]))")
+ , testCase "Labelled1" (testStmt "abc:x=1" "Right (JSLabelled (JSIdentifier \"abc\") (JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSDecimal \"1\"]))")
- , testCase "Switch1" (testStmt "switch (x) {}" "Right (JSSwitch (JSExpression [JSIdentifier \"x\"]) [])")
- , testCase "Switch2" (testStmt "switch (x) {case 1:break;}" "Right (JSSwitch (JSExpression [JSIdentifier \"x\"]) [JSCase (JSExpression [JSDecimal \"1\"]) (JSStatementList [JSBreak [] [JSLiteral \";\"]])])")
- , testCase "Switch3" (testStmt "switch (x) {case 0:\ncase 1:break;}" "Right (JSSwitch (JSExpression [JSIdentifier \"x\"]) [JSCase (JSExpression [JSDecimal \"0\"]) (JSStatementList []),JSCase (JSExpression [JSDecimal \"1\"]) (JSStatementList [JSBreak [] [JSLiteral \";\"]])])")
- , testCase "Switch4" (testStmt "switch (x) {default:break;}" "Right (JSSwitch (JSExpression [JSIdentifier \"x\"]) [JSDefault (JSStatementList [JSBreak [] [JSLiteral \";\"]])])")
- , testCase "Switch5" (testStmt "switch (x) {default:\ncase 1:break;}" "Right (JSSwitch (JSExpression [JSIdentifier \"x\"]) [JSDefault (JSStatementList []),JSCase (JSExpression [JSDecimal \"1\"]) (JSStatementList [JSBreak [] [JSLiteral \";\"]])])")
+ , testCase "Switch1" (testStmt "switch (x) {}" "Right (JSSwitch (JSExpression [JSIdentifier \"x\"]) [JSLiteral \"{\",JSLiteral \"\",JSLiteral \"}\"])")
+ , testCase "Switch2" (testStmt "switch (x) {case 1:break;}" "Right (JSSwitch (JSExpression [JSIdentifier \"x\"]) [JSLiteral \"{\",JSCase (JSExpression [JSDecimal \"1\"]) (JSStatementList [JSBreak [] JSLiteral \";\"]),JSLiteral \"}\"])")
+ , testCase "Switch3" (testStmt "switch (x) {case 0:\ncase 1:break;}" "Right (JSSwitch (JSExpression [JSIdentifier \"x\"]) [JSLiteral \"{\",JSCase (JSExpression [JSDecimal \"0\"]) (JSStatementList []),JSCase (JSExpression [JSDecimal \"1\"]) (JSStatementList [JSBreak [] JSLiteral \";\"]),JSLiteral \"}\"])")
+ , testCase "Switch4" (testStmt "switch (x) {default:break;}" "Right (JSSwitch (JSExpression [JSIdentifier \"x\"]) [JSLiteral \"{\",JSLiteral \"\",JSDefault (JSStatementList [JSBreak [] JSLiteral \";\"]),JSLiteral \"\",JSLiteral \"}\"])")
+ , testCase "Switch5" (testStmt "switch (x) {default:\ncase 1:break;}" "Right (JSSwitch (JSExpression [JSIdentifier \"x\"]) [JSLiteral \"{\",JSLiteral \"\",JSDefault (JSStatementList []),JSCase (JSExpression [JSDecimal \"1\"]) (JSStatementList [JSBreak [] JSLiteral \";\"]),JSLiteral \"}\"])")
, testCase "Throw1" (testStmt "throw 1" "Right (JSThrow (JSExpression [JSDecimal \"1\"]))")
@@ -220,124 +220,521 @@ testSuite = testGroup "Parser"
, testCase "Try4" (testStmt "try{}catch(a){}catch(b){}finally{}" "Right (JSTry (JSBlock (JSStatementList [])) [JSCatch (JSIdentifier \"a\") [] (JSBlock (JSStatementList [])),JSCatch (JSIdentifier \"b\") [] (JSBlock (JSStatementList [])),JSFinally (JSBlock (JSStatementList []))])")
, testCase "Try5" (testStmt "try{}catch(a){}catch(b){}" "Right (JSTry (JSBlock (JSStatementList [])) [JSCatch (JSIdentifier \"a\") [] (JSBlock (JSStatementList [])),JSCatch (JSIdentifier \"b\") [] (JSBlock (JSStatementList []))])")
- , testCase "Try6" (testStmt "try{}catch(a if true){}catch(b){}" "Right (JSTry (JSBlock (JSStatementList [])) [JSCatch (JSIdentifier \"a\") [JSLiteral \"true\"] (JSBlock (JSStatementList [])),JSCatch (JSIdentifier \"b\") [] (JSBlock (JSStatementList []))])")
+ , testCase "Try6" (testStmt "try{}catch(a if true){}catch(b){}" "Right (JSTry (JSBlock (JSStatementList [])) [JSCatch (JSIdentifier \"a\") [JSLiteral \"if\",JSLiteral \"true\"] (JSBlock (JSStatementList [])),JSCatch (JSIdentifier \"b\") [] (JSBlock (JSStatementList []))])")
- , testCase "Function1" (testProg "function a(){}" "Right (JSSourceElementsTop [JSFunction (JSIdentifier \"a\") [] (JSFunctionBody [])])")
- , testCase "Function2" (testProg "function a(b,c){}" "Right (JSSourceElementsTop [JSFunction (JSIdentifier \"a\") [JSIdentifier \"b\",JSIdentifier \"c\"] (JSFunctionBody [])])")
+ , testCase "Function1" (testProg "function a(){}" "Right (JSSourceElementsTop [JSFunction (JSIdentifier \"a\") [] (JSFunctionBody []),JSLiteral \"\"])")
+ , testCase "Function2" (testProg "function a(b,c){}" "Right (JSSourceElementsTop [JSFunction (JSIdentifier \"a\") [JSIdentifier \"b\",JSLiteral \",\",JSIdentifier \"c\"] (JSFunctionBody []),JSLiteral \"\"])")
- , testCase "Comment1" (testProg "//blah\nx=1;//foo\na" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator \"=\",JSDecimal \"1\"],JSLiteral \";\",JSExpression [JSIdentifier \"a\"]])")
+ , testCase "Comment1" (testProg "//blah\nx=1;//foo\na" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSDecimal \"1\"],JSLiteral \";\",JSExpression [JSIdentifier \"a\"],JSLiteral \"\"])")
- , testCase "Comment2" (testProg "/*x=1\ny=2\n*/z=2;//foo\na" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"z\",JSOperator \"=\",JSDecimal \"2\"],JSLiteral \";\",JSExpression [JSIdentifier \"a\"]])")
+ , testCase "Comment2" (testProg "/*x=1\ny=2\n*/z=2;//foo\na" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"z\",JSOperator JSLiteral \"=\",JSDecimal \"2\"],JSLiteral \";\",JSExpression [JSIdentifier \"a\"],JSLiteral \"\"])")
- , testCase "min_100_animals1" (testProg "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\"" "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\"]]])")
+ , testCase "min_100_animals1" (testProg "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\""
+ "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\"]]),JSLiteral \";\"])) ([]),JSExpression [JSMemberDot [JSLiteral \"this\"] (JSIdentifier \"name\"),JSOperator JSLiteral \"=\",JSIdentifier \"name\"]]]),JSLiteral \";\",JSExpression [JSMemberDot [JSMemberDot [JSIdentifier \"Animal\"] (JSIdentifier \"prototype\")] (JSIdentifier \"toString\"),JSOperator JSLiteral \"=\",JSFunctionExpression [] [] (JSFunctionBody [JSSourceElements [JSReturn [JSExpression [JSMemberDot [JSLiteral \"this\"] (JSIdentifier \"name\")]] JSLiteral \"\"]])],JSLiteral \";\",JSExpression [JSIdentifier \"o\",JSOperator JSLiteral \"=\",JSLiteral \"new\",JSIdentifier \"Animal\",JSArguments [JSStringLiteral '\"' \"bob\"]],JSLiteral \";\",JSExpression [JSExpressionBinary \"==\" [JSMemberDot [JSIdentifier \"o\"] (JSIdentifier \"toString\"),JSArguments []] [JSStringLiteral '\"' \"bob\"]],JSLiteral \"\"])")
- , testCase "min_100_animals2" (testProg "Animal=function(){return this.name};" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"Animal\",JSOperator \"=\",JSFunctionExpression [] [] (JSFunctionBody [JSSourceElements [JSReturn [JSExpression [JSMemberDot [JSLiteral \"this\"] (JSIdentifier \"name\")],JSLiteral \"\"]]])],JSLiteral \";\"])")
+ , testCase "min_100_animals2" (testProg "Animal=function(){return this.name};" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"Animal\",JSOperator JSLiteral \"=\",JSFunctionExpression [] [] (JSFunctionBody [JSSourceElements [JSReturn [JSExpression [JSMemberDot [JSLiteral \"this\"] (JSIdentifier \"name\")]] JSLiteral \"\"]])],JSLiteral \";\",JSLiteral \"\"])")
- , testCase "min_100_animals3" (testProg "if(a)x=1;y=2" "Right (JSSourceElementsTop [JSIf (JSExpression [JSIdentifier \"a\"]) (JSBlock (JSStatementList [JSExpression [JSIdentifier \"x\",JSOperator \"=\",JSDecimal \"1\"]])),JSExpression [JSIdentifier \"y\",JSOperator \"=\",JSDecimal \"2\"]])")
+ , testCase "min_100_animals3" (testProg "if(a)x=1;y=2" "Right (JSSourceElementsTop [JSIf (JSExpression [JSIdentifier \"a\"]) (JSBlock (JSStatementList [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSDecimal \"1\"],JSLiteral \";\"])) ([]),JSExpression [JSIdentifier \"y\",JSOperator JSLiteral \"=\",JSDecimal \"2\"],JSLiteral \"\"])")
- , testCase "min_100_animals4" (testProg "if(a)x=a()y=2" "Right (JSSourceElementsTop [JSIf (JSExpression [JSIdentifier \"a\"]) (JSExpression [JSIdentifier \"x\",JSOperator \"=\",JSIdentifier \"a\",JSArguments []]),JSExpression [JSIdentifier \"y\",JSOperator \"=\",JSDecimal \"2\"]])")
+ , testCase "min_100_animals4" (testProg "if(a)x=a()y=2" "Right (JSSourceElementsTop [JSIf (JSExpression [JSIdentifier \"a\"]) (JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSIdentifier \"a\",JSArguments []]) ([]),JSExpression [JSIdentifier \"y\",JSOperator JSLiteral \"=\",JSDecimal \"2\"],JSLiteral \"\"])")
- , testCase "05_regex" (testProg "newlines=spaces.match(/\\n/g)" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"newlines\",JSOperator \"=\",JSMemberDot [JSIdentifier \"spaces\"] (JSIdentifier \"match\"),JSArguments [[JSRegEx \"/\\\\n/g\"]]]])")
+ , testCase "05_regex" (testProg "newlines=spaces.match(/\\n/g)" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"newlines\",JSOperator JSLiteral \"=\",JSMemberDot [JSIdentifier \"spaces\"] (JSIdentifier \"match\"),JSArguments [JSRegEx \"/\\\\n/g\"]],JSLiteral \"\"])")
- , testCase "05_regex2" (testProg "x=/\\n/g" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator \"=\",JSRegEx \"/\\\\n/g\"]])")
+ , testCase "05_regex2" (testProg "x=/\\n/g" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSRegEx \"/\\\\n/g\"],JSLiteral \"\"])")
- , testCase "05_regex3" (testProg "x=i(/[?|^&(){}\\[\\]+\\-*\\/\\.]/g,\"\\\\$&\")" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator \"=\",JSIdentifier \"i\",JSArguments [[JSRegEx \"/[?|^&(){}\\\\[\\\\]+\\\\-*\\\\/\\\\.]/g\"],[JSStringLiteral '\"' \"\\\\\\\\$&\"]]]])")
+ , testCase "05_regex3" (testProg "x=i(/[?|^&(){}\\[\\]+\\-*\\/\\.]/g,\"\\\\$&\")" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSIdentifier \"i\",JSArguments [JSRegEx \"/[?|^&(){}\\\\[\\\\]+\\\\-*\\\\/\\\\.]/g\",JSLiteral \",\",JSStringLiteral '\"' \"\\\\\\\\$&\"]],JSLiteral \"\"])")
- , testCase "05_regex4" (testProg "x=i(/^$/g,\"\\\\$&\")" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator \"=\",JSIdentifier \"i\",JSArguments [[JSRegEx \"/^$/g\"],[JSStringLiteral '\"' \"\\\\\\\\$&\"]]]])")
+ , testCase "05_regex4" (testProg "x=i(/^$/g,\"\\\\$&\")" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSIdentifier \"i\",JSArguments [JSRegEx \"/^$/g\",JSLiteral \",\",JSStringLiteral '\"' \"\\\\\\\\$&\"]],JSLiteral \"\"])")
- , testCase "05_regex5" (testProg "if(/^[a-z]/.test(t)){consts+=t.toUpperCase();keywords[t]=i}else consts+=(/^\\W/.test(t)?opTypeNames[t]:t);" "Right (JSSourceElementsTop [JSIfElse (JSExpression [JSMemberDot [JSRegEx \"/^[a-z]/\"] (JSIdentifier \"test\"),JSArguments [[JSIdentifier \"t\"]]]) (JSStatementBlock (JSStatementList [JSExpression [JSIdentifier \"consts\",JSOperator \"+=\",JSMemberDot [JSIdentifier \"t\"] (JSIdentifier \"toUpperCase\"),JSArguments []],JSLiteral \";\",JSExpression [JSMemberSquare [JSIdentifier \"keywords\"] (JSExpression [JSIdentifier \"t\"]),JSOperator \"=\",JSIdentifier \"i\"]])) (JSExpression [JSIdentifier \"consts\",JSOperator \"+=\",JSExpressionParen (JSExpression [JSExpressionTernary [JSMemberDot [JSRegEx \"/^\\\\W/\"] (JSIdentifier \"test\"),JSArguments [[JSIdentifier \"t\"]]] [JSMemberSquare [JSIdentifier \"opTypeNames\"] (JSExpression [JSIdentifier \"t\"])] [JSIdentifier \"t\"]])]),JSLiteral \";\"])")
+ , testCase "05_regex5" (testProg "if(/^[a-z]/.test(t)){consts+=t.toUpperCase();keywords[t]=i}else consts+=(/^\\W/.test(t)?opTypeNames[t]:t);"
+ "Right (JSSourceElementsTop [JSIf (JSExpression [JSMemberDot [JSRegEx \"/^[a-z]/\"] (JSIdentifier \"test\"),JSArguments [JSIdentifier \"t\"]]) (JSBlock (JSStatementList [JSStatementBlock (JSStatementList [JSExpression [JSIdentifier \"consts\",JSOperator JSLiteral \"+=\",JSMemberDot [JSIdentifier \"t\"] (JSIdentifier \"toUpperCase\"),JSArguments []],JSLiteral \";\",JSExpression [JSMemberSquare [JSIdentifier \"keywords\"] (JSExpression [JSIdentifier \"t\"]),JSOperator JSLiteral \"=\",JSIdentifier \"i\"]])])) ([JSLiteral \"else\",JSExpression [JSIdentifier \"consts\",JSOperator JSLiteral \"+=\",JSExpressionParen (JSExpression [JSExpressionTernary [JSMemberDot [JSRegEx \"/^\\\\W/\"] (JSIdentifier \"test\"),JSArguments [JSIdentifier \"t\"]] [JSMemberSquare [JSIdentifier \"opTypeNames\"] (JSExpression [JSIdentifier \"t\"])] [JSIdentifier \"t\"]])]]),JSLiteral \";\",JSLiteral \"\"])")
- , testCase "if_semi" (testProg "if(x);x=1" "Right (JSSourceElementsTop [JSIf (JSExpression [JSIdentifier \"x\"]) (JSLiteral \";\"),JSExpression [JSIdentifier \"x\",JSOperator \"=\",JSDecimal \"1\"]])")
+ , testCase "if_semi" (testProg "if(x);x=1" "Right (JSSourceElementsTop [JSIf (JSExpression [JSIdentifier \"x\"]) (JSLiteral \";\") ([]),JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSDecimal \"1\"],JSLiteral \"\"])")
- , testCase "67_bob" (testProg "(match = /^\"(?:\\\\.|[^\"])*\"|^'(?:[^']|\\\\.)*'/(input))" "Right (JSSourceElementsTop [JSExpression [JSExpressionParen (JSExpression [JSIdentifier \"match\",JSOperator \"=\",JSRegEx \"/^\\\"(?:\\\\\\\\.|[^\\\"])*\\\"|^'(?:[^']|\\\\\\\\.)*'/\",JSArguments [[JSIdentifier \"input\"]]])]])")
+ , testCase "67_bob" (testProg "(match = /^\"(?:\\\\.|[^\"])*\"|^'(?:[^']|\\\\.)*'/(input))" "Right (JSSourceElementsTop [JSExpression [JSExpressionParen (JSExpression [JSIdentifier \"match\",JSOperator JSLiteral \"=\",JSRegEx \"/^\\\"(?:\\\\\\\\.|[^\\\"])*\\\"|^'(?:[^']|\\\\\\\\.)*'/\",JSArguments [JSIdentifier \"input\"]])],JSLiteral \"\"])")
- , testCase "122_jsexec" (testProg "v = getValue(execute(n[0], x)) in getValue(execute(n[1], x));" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"v\",JSOperator \"=\",JSExpressionBinary \" in \" [JSIdentifier \"getValue\",JSArguments [[JSIdentifier \"execute\",JSArguments [[JSMemberSquare [JSIdentifier \"n\"] (JSExpression [JSDecimal \"0\"])],[JSIdentifier \"x\"]]]]] [JSIdentifier \"getValue\",JSArguments [[JSIdentifier \"execute\",JSArguments [[JSMemberSquare [JSIdentifier \"n\"] (JSExpression [JSDecimal \"1\"])],[JSIdentifier \"x\"]]]]]],JSLiteral \";\"])")
+ , testCase "122_jsexec" (testProg "v = getValue(execute(n[0], x)) in getValue(execute(n[1], x));" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"v\",JSOperator JSLiteral \"=\",JSExpressionBinary \" in \" [JSIdentifier \"getValue\",JSArguments [JSIdentifier \"execute\",JSArguments [JSMemberSquare [JSIdentifier \"n\"] (JSExpression [JSDecimal \"0\"]),JSLiteral \",\",JSIdentifier \"x\"]]] [JSIdentifier \"getValue\",JSArguments [JSIdentifier \"execute\",JSArguments [JSMemberSquare [JSIdentifier \"n\"] (JSExpression [JSDecimal \"1\"]),JSLiteral \",\",JSIdentifier \"x\"]]]],JSLiteral \";\",JSLiteral \"\"])")
- , testCase "bug1" (testProg "/* */\nfunction f() {\n/* */\n}\n" "Right (JSSourceElementsTop [JSFunction (JSIdentifier \"f\") [] (JSFunctionBody [])])")
- , testCase "bug1" (testProg "/* **/\nfunction f() {\n/* */\n}\n" "Right (JSSourceElementsTop [JSFunction (JSIdentifier \"f\") [] (JSFunctionBody [])])")
+ , testCase "bug1a" (testProg "/* */\nfunction f() {\n/* */\n}\n" "Right (JSSourceElementsTop [JSFunction (JSIdentifier \"f\") [] (JSFunctionBody []),JSLiteral \"\"])")
+ , testCase "bug1b" (testProg "/* **/\nfunction f() {\n/* */\n}\n" "Right (JSSourceElementsTop [JSFunction (JSIdentifier \"f\") [] (JSFunctionBody []),JSLiteral \"\"])")
- , testCase "unicode1-ws" (testProg "a \f\v\t\r\n=\x00a0\x1680\x180e\x2000\x2001\x2002\x2003\x2004\x2005\x2006\x2007\x2008\x2009\x200a\x2028\x2029\x202f\x205f\x3000\&1;" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"a\",JSOperator \"=\",JSDecimal \"1\"],JSLiteral \";\"])")
+ , testCase "unicode1-ws" (testProg "a \f\v\t\r\n=\x00a0\x1680\x180e\x2000\x2001\x2002\x2003\x2004\x2005\x2006\x2007\x2008\x2009\x200a\x2028\x2029\x202f\x205f\x3000\&1;" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"a\",JSOperator JSLiteral \"=\",JSDecimal \"1\"],JSLiteral \";\",JSLiteral \"\"])")
- , testCase "unicode2-lt" (testProg "//comment\x000Ax=1;" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator \"=\",JSDecimal \"1\"],JSLiteral \";\"])")
- , testCase "unicode3-lt" (testProg "//comment\x000Dx=1;" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator \"=\",JSDecimal \"1\"],JSLiteral \";\"])")
- , testCase "unicode4-lt" (testProg "//comment\x2028x=1;" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator \"=\",JSDecimal \"1\"],JSLiteral \";\"])")
- , testCase "unicode5-lt" (testProg "//comment\x2029x=1;" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator \"=\",JSDecimal \"1\"],JSLiteral \";\"])")
+ , testCase "unicode2-lt" (testProg "//comment\x000Ax=1;" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSDecimal \"1\"],JSLiteral \";\",JSLiteral \"\"])")
+ , testCase "unicode3-lt" (testProg "//comment\x000Dx=1;" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSDecimal \"1\"],JSLiteral \";\",JSLiteral \"\"])")
+ , testCase "unicode4-lt" (testProg "//comment\x2028x=1;" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSDecimal \"1\"],JSLiteral \";\",JSLiteral \"\"])")
+ , testCase "unicode5-lt" (testProg "//comment\x2029x=1;" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSDecimal \"1\"],JSLiteral \";\",JSLiteral \"\"])")
- , testCase "unicode2" (testProg "àáâãäå = 1;" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"\\224\\225\\226\\227\\228\\229\",JSOperator \"=\",JSDecimal \"1\"],JSLiteral \";\"])")
+ , testCase "unicode2" (testProg "àáâãäå = 1;" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"\\224\\225\\226\\227\\228\\229\",JSOperator JSLiteral \"=\",JSDecimal \"1\"],JSLiteral \";\",JSLiteral \"\"])")
- , testCase "unicode3" (testProg "$aà = 1;_b=2;\0065a=2" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"$a\\224\",JSOperator \"=\",JSDecimal \"1\"],JSLiteral \";\",JSExpression [JSIdentifier \"_b\",JSOperator \"=\",JSDecimal \"2\"],JSLiteral \";\",JSExpression [JSIdentifier \"Aa\",JSOperator \"=\",JSDecimal \"2\"]])")
+ , testCase "unicode3" (testProg "$aà = 1;_b=2;\0065a=2" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"$a\\224\",JSOperator JSLiteral \"=\",JSDecimal \"1\"],JSLiteral \";\",JSExpression [JSIdentifier \"_b\",JSOperator JSLiteral \"=\",JSDecimal \"2\"],JSLiteral \";\",JSExpression [JSIdentifier \"Aa\",JSOperator JSLiteral \"=\",JSDecimal \"2\"],JSLiteral \"\"])")
- , testCase "unicode4" (testProg "x=\"àáâãäå\";y='\3012a\0068'" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator \"=\",JSStringLiteral '\"' \"\\224\\225\\226\\227\\228\\229\"],JSLiteral \";\",JSExpression [JSIdentifier \"y\",JSOperator \"=\",JSStringLiteral '\\'' \"\\3012aD\"]])")
+ , testCase "unicode4" (testProg "x=\"àáâãäå\";y='\3012a\0068'" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSStringLiteral '\"' \"\\224\\225\\226\\227\\228\\229\"],JSLiteral \";\",JSExpression [JSIdentifier \"y\",JSOperator JSLiteral \"=\",JSStringLiteral '\\'' \"\\3012aD\"],JSLiteral \"\"])")
- , testCase "unicode5" (testFile "./test/Unicode.js" "JSSourceElementsTop [JSExpression [JSIdentifier \"\\224\\225\\226\\227\\228\\229\",JSOperator \"=\",JSDecimal \"1\"],JSLiteral \";\"]")
+ , testCase "unicode5" (testFile "./test/Unicode.js" "JSSourceElementsTop [JSExpression [JSIdentifier \"\\224\\225\\226\\227\\228\\229\",JSOperator JSLiteral \"=\",JSDecimal \"1\"],JSLiteral \";\",JSLiteral \"\"]")
- , testCase "bug2.a" (testProg "function() {\nz = function /*z*/(o) {\nreturn r;\n};}" "Right (JSSourceElementsTop [JSExpression [JSFunctionExpression [] [] (JSFunctionBody [JSSourceElements [JSExpression [JSIdentifier \"z\",JSOperator \"=\",JSFunctionExpression [] [JSIdentifier \"o\"] (JSFunctionBody [JSSourceElements [JSReturn [JSExpression [JSIdentifier \"r\"],JSLiteral \";\"]]])],JSLiteral \";\"]])]])")
+ , testCase "bug2.a" (testProg "function() {\nz = function /*z*/(o) {\nreturn r;\n};}" "Right (JSSourceElementsTop [JSExpression [JSFunctionExpression [] [] (JSFunctionBody [JSSourceElements [JSExpression [JSIdentifier \"z\",JSOperator JSLiteral \"=\",JSFunctionExpression [] [JSIdentifier \"o\"] (JSFunctionBody [JSSourceElements [JSReturn [JSExpression [JSIdentifier \"r\"]] JSLiteral \";\"]])],JSLiteral \";\"]])],JSLiteral \"\"])")
- , testCase "bug2.b" (testProg "function() {\nz = function z(o) {\nreturn r;\n};}" "Right (JSSourceElementsTop [JSExpression [JSFunctionExpression [] [] (JSFunctionBody [JSSourceElements [JSExpression [JSIdentifier \"z\",JSOperator \"=\",JSFunctionExpression [JSIdentifier \"z\"] [JSIdentifier \"o\"] (JSFunctionBody [JSSourceElements [JSReturn [JSExpression [JSIdentifier \"r\"],JSLiteral \";\"]]])],JSLiteral \";\"]])]])")
+ , testCase "bug2.b" (testProg "function() {\nz = function z(o) {\nreturn r;\n};}" "Right (JSSourceElementsTop [JSExpression [JSFunctionExpression [] [] (JSFunctionBody [JSSourceElements [JSExpression [JSIdentifier \"z\",JSOperator JSLiteral \"=\",JSFunctionExpression [JSIdentifier \"z\"] [JSIdentifier \"o\"] (JSFunctionBody [JSSourceElements [JSReturn [JSExpression [JSIdentifier \"r\"]] JSLiteral \";\"]])],JSLiteral \";\"]])],JSLiteral \"\"])")
-- https://github.com/alanz/hjsmin/issues/#issue/3
- , testCase "bug3" (testProg "var myLatlng = new google.maps.LatLng(56.8379100, 60.5806664);" "Right (JSSourceElementsTop [JSVariables \"var\" [JSVarDecl (JSIdentifier \"myLatlng\") [JSLiteral \"new \",JSMemberDot [JSMemberDot [JSIdentifier \"google\"] (JSIdentifier \"maps\")] (JSIdentifier \"LatLng\"),JSArguments [[JSDecimal \"56.8379100\"],[JSDecimal \"60.5806664\"]]]]])")
+ , testCase "bug3" (testProg "var myLatlng = new google.maps.LatLng(56.8379100, 60.5806664);" "Right (JSSourceElementsTop [JSVariables JSLiteral \"var\" [JSVarDecl (JSIdentifier \"myLatlng\") [JSLiteral \"=\",JSLiteral \"new\",JSMemberDot [JSMemberDot [JSIdentifier \"google\"] (JSIdentifier \"maps\")] (JSIdentifier \"LatLng\"),JSArguments [JSDecimal \"56.8379100\",JSLiteral \",\",JSDecimal \"60.5806664\"]]],JSLiteral \"\"])")
-- https://github.com/alanz/hjsmin/issues/#issue/4
- , testCase "bug4" (testProg "/* * geolocation. пытаемся определить свое местоположение * если не получается то используем defaultLocation * @Param {object} map экземпляр карты * @Param {object LatLng} defaultLocation Координаты центра по умолчанию * @Param {function} callbackAfterLocation Фу-ия которая вызывается после * геолокации. Т.к запрос геолокации асинхронен */x" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\"]])")
+ , testCase "bug4" (testProg "/* * geolocation. пытаемся определить свое местоположение * если не получается то используем defaultLocation * @Param {object} map экземпляр карты * @Param {object LatLng} defaultLocation Координаты центра по умолчанию * @Param {function} callbackAfterLocation Фу-ия которая вызывается после * геолокации. Т.к запрос геолокации асинхронен */x" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\"],JSLiteral \"\"])")
- , testCase "02_sm.js" (testProg "{zero}\none1;two\n{three\nfour;five;\n{\nsix;{seven;}\n}\n}" "Right (JSSourceElementsTop [JSStatementBlock (JSStatementList [JSExpression [JSIdentifier \"zero\"]]),JSExpression [JSIdentifier \"one1\"],JSLiteral \";\",JSExpression [JSIdentifier \"two\"],JSStatementBlock (JSStatementList [JSExpression [JSIdentifier \"three\"],JSExpression [JSIdentifier \"four\"],JSLiteral \";\",JSExpression [JSIdentifier \"five\"],JSLiteral \";\",JSStatementBlock (JSStatementList [JSExpression [JSIdentifier \"six\"],JSLiteral \";\",JSStatementBlock (JSStatementList [JSExpression [JSIdentifier \"seven\"],JSLiteral \";\"])])])])")
+ , testCase "02_sm.js" (testProg "{zero}\none1;two\n{three\nfour;five;\n{\nsix;{seven;}\n}\n}" "Right (JSSourceElementsTop [JSStatementBlock (JSStatementList [JSExpression [JSIdentifier \"zero\"]]),JSExpression [JSIdentifier \"one1\"],JSLiteral \";\",JSExpression [JSIdentifier \"two\"],JSStatementBlock (JSStatementList [JSExpression [JSIdentifier \"three\"],JSExpression [JSIdentifier \"four\"],JSLiteral \";\",JSExpression [JSIdentifier \"five\"],JSLiteral \";\",JSStatementBlock (JSStatementList [JSExpression [JSIdentifier \"six\"],JSLiteral \";\",JSStatementBlock (JSStatementList [JSExpression [JSIdentifier \"seven\"],JSLiteral \";\"])])]),JSLiteral \"\"])")
- , testCase "02_sm.js.2" (testProg "{zero}\nget;two\n{three\nfour;set;\n{\nsix;{seven;}\n}\n}" "Right (JSSourceElementsTop [JSStatementBlock (JSStatementList [JSExpression [JSIdentifier \"zero\"]]),JSExpression [JSIdentifier \"get\"],JSLiteral \";\",JSExpression [JSIdentifier \"two\"],JSStatementBlock (JSStatementList [JSExpression [JSIdentifier \"three\"],JSExpression [JSIdentifier \"four\"],JSLiteral \";\",JSExpression [JSIdentifier \"set\"],JSLiteral \";\",JSStatementBlock (JSStatementList [JSExpression [JSIdentifier \"six\"],JSLiteral \";\",JSStatementBlock (JSStatementList [JSExpression [JSIdentifier \"seven\"],JSLiteral \";\"])])])])")
+ , testCase "02_sm.js.2" (testProg "{zero}\nget;two\n{three\nfour;set;\n{\nsix;{seven;}\n}\n}" "Right (JSSourceElementsTop [JSStatementBlock (JSStatementList [JSExpression [JSIdentifier \"zero\"]]),JSExpression [JSIdentifier \"get\"],JSLiteral \";\",JSExpression [JSIdentifier \"two\"],JSStatementBlock (JSStatementList [JSExpression [JSIdentifier \"three\"],JSExpression [JSIdentifier \"four\"],JSLiteral \";\",JSExpression [JSIdentifier \"set\"],JSLiteral \";\",JSStatementBlock (JSStatementList [JSExpression [JSIdentifier \"six\"],JSLiteral \";\",JSStatementBlock (JSStatementList [JSExpression [JSIdentifier \"seven\"],JSLiteral \";\"])])]),JSLiteral \"\"])")
- , testCase "loc1" (testProgUn "x = 1\n y=2;" "Right (NS (JSSourceElementsTop [NS (JSExpression [NS (JSIdentifier \"x\") (SpanPoint {span_filename = \"\", span_row = 1, span_column = 1}),NS (JSOperator \"=\") (SpanPoint {span_filename = \"\", span_row = 1, span_column = 3}),NS (JSDecimal \"1\") (SpanPoint {span_filename = \"\", span_row = 1, span_column = 5})]) (SpanPoint {span_filename = \"\", span_row = 1, span_column = 1}),NS (JSExpression [NS (JSIdentifier \"y\") (SpanPoint {span_filename = \"\", span_row = 2, span_column = 3}),NS (JSOperator \"=\") (SpanPoint {span_filename = \"\", span_row = 2, span_column = 4}),NS (JSDecimal \"2\") (SpanPoint {span_filename = \"\", span_row = 2, span_column = 5})]) (SpanPoint {span_filename = \"\", span_row = 2, span_column = 3}),NS (JSLiteral \";\") (SpanPoint {span_filename = \"\", span_row = 2, span_column = 6})]) (SpanPoint {span_filename = \"\", span_row = 1, span_column = 1}))")
+ , testCase "loc1" (testProgUn "x = 1\n y=2;" "Right (NN (JSSourceElementsTop [NN (JSExpression [NT (JSIdentifier \"x\") (TokenPn 0 1 1) [NoComment],NN (JSOperator (NT (JSLiteral \"=\") (TokenPn 2 1 3) [WhiteSpace (TokenPn 1 1 2) \" \"])),NT (JSDecimal \"1\") (TokenPn 4 1 5) [WhiteSpace (TokenPn 3 1 4) \" \"]]),NN (JSExpression [NT (JSIdentifier \"y\") (TokenPn 8 2 3) [WhiteSpace (TokenPn 5 1 6) \"\\n \"],NN (JSOperator (NT (JSLiteral \"=\") (TokenPn 9 2 4) [NoComment])),NT (JSDecimal \"2\") (TokenPn 10 2 5) [NoComment]]),NT (JSLiteral \";\") (TokenPn 11 2 6) [NoComment],NT (JSLiteral \"\") (TokenPn 0 0 0) [NoComment]]))")
-- https://github.com/alanz/language-javascript/issues/2
- , testCase "issue2" (testProg "var img = document.createElement('img');\nimg.src = \"mylogo.jpg\";\n$(img).click(function() {\n alert('clicked!');\n});" "Right (JSSourceElementsTop [JSVariables \"var\" [JSVarDecl (JSIdentifier \"img\") [JSMemberDot [JSIdentifier \"document\"] (JSIdentifier \"createElement\"),JSArguments [[JSStringLiteral '\\'' \"img\"]]]],JSExpression [JSMemberDot [JSIdentifier \"img\"] (JSIdentifier \"src\"),JSOperator \"=\",JSStringLiteral '\"' \"mylogo.jpg\"],JSLiteral \";\",JSExpression [JSIdentifier \"$\",JSArguments [[JSIdentifier \"img\"]],JSCallExpression \".\" [JSIdentifier \"click\"],JSCallExpression \"()\" [JSArguments [[JSFunctionExpression [] [] (JSFunctionBody [JSSourceElements [JSExpression [JSIdentifier \"alert\",JSArguments [[JSStringLiteral '\\'' \"clicked!\"]]],JSLiteral \";\"]])]]]],JSLiteral \";\"])")
+ , testCase "issue2" (testProg "var img = document.createElement('img');\nimg.src = \"mylogo.jpg\";\n$(img).click(function() {\n alert('clicked!');\n});" "Right (JSSourceElementsTop [JSVariables JSLiteral \"var\" [JSVarDecl (JSIdentifier \"img\") [JSLiteral \"=\",JSMemberDot [JSIdentifier \"document\"] (JSIdentifier \"createElement\"),JSArguments [JSStringLiteral '\\'' \"img\"]]],JSExpression [JSMemberDot [JSIdentifier \"img\"] (JSIdentifier \"src\"),JSOperator JSLiteral \"=\",JSStringLiteral '\"' \"mylogo.jpg\"],JSLiteral \";\",JSExpression [JSIdentifier \"$\",JSArguments [JSIdentifier \"img\"],JSCallExpression \".\" [JSIdentifier \"click\"],JSCallExpression \"()\" [JSArguments [JSFunctionExpression [] [] (JSFunctionBody [JSSourceElements [JSExpression [JSIdentifier \"alert\",JSArguments [JSStringLiteral '\\'' \"clicked!\"]],JSLiteral \";\"]])]]],JSLiteral \";\",JSLiteral \"\"])")
-- Working in ECMASCRIPT 5.1 changes
- , testCase "lineTerminatorInString1" (testProg "x='abc\\\ndef';" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator \"=\",JSStringLiteral '\\'' \"abcdef\"],JSLiteral \";\"])")
- , testCase "lineTerminatorInString2" (testProg "x=\"abc\\\ndef\";" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator \"=\",JSStringLiteral '\"' \"abcdef\"],JSLiteral \";\"])")
- , testCase "lineTerminatorInString3" (testProg "x=\"abc\\\rdef\";" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator \"=\",JSStringLiteral '\"' \"abcdef\"],JSLiteral \";\"])")
- , testCase "lineTerminatorInString4" (testProg "x=\"abc\\\x2028 def\";" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator \"=\",JSStringLiteral '\"' \"abc def\"],JSLiteral \";\"])")
- , testCase "lineTerminatorInString5" (testProg "x=\"abc\\\x2029 def\";" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator \"=\",JSStringLiteral '\"' \"abc def\"],JSLiteral \";\"])")
- , testCase "lineTerminatorInString6" (testProg "x=\"abc\\\r\ndef\";" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator \"=\",JSStringLiteral '\"' \"abcdef\"],JSLiteral \";\"])")
+ , testCase "lineTerminatorInString1" (testProg "x='abc\\\ndef';" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSStringLiteral '\\'' \"abc\\\\\\ndef\"],JSLiteral \";\",JSLiteral \"\"])")
+ , testCase "lineTerminatorInString2" (testProg "x=\"abc\\\ndef\";" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSStringLiteral '\"' \"abc\\\\\\ndef\"],JSLiteral \";\",JSLiteral \"\"])")
+ , testCase "lineTerminatorInString3" (testProg "x=\"abc\\\rdef\";" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSStringLiteral '\"' \"abc\\\\\\rdef\"],JSLiteral \";\",JSLiteral \"\"])")
+ , testCase "lineTerminatorInString4" (testProg "x=\"abc\\\x2028 def\";" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSStringLiteral '\"' \"abc\\\\\\8232 def\"],JSLiteral \";\",JSLiteral \"\"])")
+ , testCase "lineTerminatorInString5" (testProg "x=\"abc\\\x2029 def\";" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSStringLiteral '\"' \"abc\\\\\\8233 def\"],JSLiteral \";\",JSLiteral \"\"])")
+ , testCase "lineTerminatorInString6" (testProg "x=\"abc\\\r\ndef\";" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSStringLiteral '\"' \"abc\\\\\\r\\ndef\"],JSLiteral \";\",JSLiteral \"\"])")
-- https://github.com/alanz/language-javascript/issues/4
- , testCase "issue4ok" (testProg "var k = {\ny: somename\n}" "Right (JSSourceElementsTop [JSVariables \"var\" [JSVarDecl (JSIdentifier \"k\") [JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"y\") [JSIdentifier \"somename\"]]]]])")
- , testCase "issue4bug1" (testProg "var k = {\ny: code\n}" "Right (JSSourceElementsTop [JSVariables \"var\" [JSVarDecl (JSIdentifier \"k\") [JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"y\") [JSIdentifier \"code\"]]]]])")
- , testCase "issue4bug2" (testProg "var k = {\ny: mode\n}" "Right (JSSourceElementsTop [JSVariables \"var\" [JSVarDecl (JSIdentifier \"k\") [JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"y\") [JSIdentifier \"mode\"]]]]])")
+ , testCase "issue4ok" (testProg "var k = {\ny: somename\n}" "Right (JSSourceElementsTop [JSVariables JSLiteral \"var\" [JSVarDecl (JSIdentifier \"k\") [JSLiteral \"=\",JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"y\") [JSIdentifier \"somename\"]]]],JSLiteral \"\"])")
+ , testCase "issue4bug1" (testProg "var k = {\ny: code\n}" "Right (JSSourceElementsTop [JSVariables JSLiteral \"var\" [JSVarDecl (JSIdentifier \"k\") [JSLiteral \"=\",JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"y\") [JSIdentifier \"code\"]]]],JSLiteral \"\"])")
+ , testCase "issue4bug2" (testProg "var k = {\ny: mode\n}" "Right (JSSourceElementsTop [JSVariables JSLiteral \"var\" [JSVarDecl (JSIdentifier \"k\") [JSLiteral \"=\",JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"y\") [JSIdentifier \"mode\"]]]],JSLiteral \"\"])")
-- https://github.com/alanz/language-javascript/issues/5
- , testCase "issue5bug1" (testProg "x = { y: 1e8 }" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator \"=\",JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"y\") [JSDecimal \"1e8\"]]]])")
- , testCase "issue5ok2" (testProg "{ y: 1e8 }" "Right (JSSourceElementsTop [JSStatementBlock (JSStatementList [JSLabelled (JSIdentifier \"y\") (JSExpression [JSDecimal \"1e8\"])])])")
- , testCase "issue5ok3" (testProg "{ y: 18 }" "Right (JSSourceElementsTop [JSStatementBlock (JSStatementList [JSLabelled (JSIdentifier \"y\") (JSExpression [JSDecimal \"18\"])])])")
- , testCase "issue5ok4" (testProg "x = { y: 18 }" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator \"=\",JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"y\") [JSDecimal \"18\"]]]])")
+ , testCase "issue5bug1" (testProg "x = { y: 1e8 }" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"y\") [JSDecimal \"1e8\"]]],JSLiteral \"\"])")
+ , testCase "issue5ok2" (testProg "{ y: 1e8 }" "Right (JSSourceElementsTop [JSStatementBlock (JSStatementList [JSLabelled (JSIdentifier \"y\") (JSExpression [JSDecimal \"1e8\"])]),JSLiteral \"\"])")
+ , testCase "issue5ok3" (testProg "{ y: 18 }" "Right (JSSourceElementsTop [JSStatementBlock (JSStatementList [JSLabelled (JSIdentifier \"y\") (JSExpression [JSDecimal \"18\"])]),JSLiteral \"\"])")
+ , testCase "issue5ok4" (testProg "x = { y: 18 }" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"y\") [JSDecimal \"18\"]]],JSLiteral \"\"])")
]
srcHelloWorld = "Hello"
caseHelloWorld =
- "JSSourceElementsTop [JSExpression [JSIdentifier \"Hello\"]]"
+ "JSSourceElementsTop [JSExpression [JSIdentifier \"Hello\"],JSLiteral \"\"]"
-- @=? (show $ parse srcHelloWorld "src")
@=? (showStripped $ readJs srcHelloWorld)
-- ---------------------------------------------------------------------
+
+commentSuite :: Test
+commentSuite = testGroup "Comments"
+ [
+ testCase "helloWorld" caseHelloWorld
+ , testCase "LiteralNull" (testLiteralC "/*a*/null" "Right (NS (JSLiteral \"null\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"])")
+ , testCase "LiteralFalse" (testLiteralC "/*b*/false" "Right (NS (JSLiteral \"false\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*b*/\"])")
+ , testCase "LiteralTrue" (testLiteralC "true" "Right (NS (JSLiteral \"true\") (TokenPn 0 1 1) [NoComment])")
+ , testCase "LiteralTrue" (testLiteralC "/*c*/true" "Right (NS (JSLiteral \"true\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*c*/\"])")
+
+ , testCase "LiteralHexInteger" (testLiteralC "/*d*/0x1234fF" "Right (NS (JSHexInteger \"0x1234fF\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*d*/\"])")
+ , testCase "LiteralDecimal" (testLiteralC "/*e*/1.0e4" "Right (NS (JSDecimal \"1.0e4\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*e*/\"])")
+ , testCase "LiteralString1" (testLiteralC "/*f*/\"hello\\nworld\"" "Right (NS (JSStringLiteral '\"' \"hello\\\\nworld\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*f*/\"])")
+ , testCase "LiteralString2" (testLiteralC "/*g*/'hello\\nworld'" "Right (NS (JSStringLiteral '\\'' \"hello\\\\nworld\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*g*/\"])")
+
+
+ , testCase "LiteralThis" (testPEC "/*h*/this" "Right (NS (JSLiteral \"this\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*h*/\"])")
+
+ , testCase "LiteralRegex1" (testPEC "/*i*//blah/" "Right (NS (JSRegEx \"/blah/\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*i*/\"])")
+
+ , testCase "Identifier2" (testPEC "//j\nthis_" "Right (NS (JSIdentifier \"this_\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"//j\"])")
+
+ , testCase "ArrayLiteral1" (testPEC "/*a*/[/*b*/]" "Right (NS (JSArrayLiteral []) (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\",CommentA (TokenPn 6 1 7) \"/*b*/\"])")
+ , testCase "ArrayLiteral2" (testPEC "/*a*/[/*b*/,/*c*/]" "Right (NS (JSArrayLiteral [NS (JSElision []) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]]) (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\",CommentA (TokenPn 12 1 13) \"/*c*/\"])")
+ , testCase "ArrayLiteral3" (testPEC "/*a*/[/*b*/,/*c*/,/*d*/]" "Right (NS (JSArrayLiteral [NS (JSElision []) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"],NS (JSElision []) (TokenPn 12 1 13) [CommentA (TokenPn 12 1 13) \"/*c*/\"]]) (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\",CommentA (TokenPn 18 1 19) \"/*d*/\"])")
+ , testCase "ArrayLiteral4" (testPEC "/*a*/[/*b/*,/*c*/,/*d*/x/*e*/]" "Right (NS (JSArrayLiteral [NS (JSElision []) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b/*,/*c*/\"],NS (JSIdentifier \"x\") (TokenPn 18 1 19) [CommentA (TokenPn 18 1 19) \"/*d*/\"]]) (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\",CommentA (TokenPn 24 1 25) \"/*e*/\"])")
+ , testCase "ArrayLiteral5" (testPEC "/*a*/[/*b*/,/*c*/,/*d*/x/*e*/]" "Right (NS (JSArrayLiteral [NS (JSElision []) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"],NS (JSElision []) (TokenPn 12 1 13) [CommentA (TokenPn 12 1 13) \"/*c*/\"],NS (JSIdentifier \"x\") (TokenPn 18 1 19) [CommentA (TokenPn 18 1 19) \"/*d*/\"]]) (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\",CommentA (TokenPn 24 1 25) \"/*e*/\"])")
+ , testCase "ArrayLiteral6" (testPEC "/*a*/[/*b*/,/*c*/x/*d*/,/*e*/,/*f*/x/*g*/]" "Right (NS (JSArrayLiteral [NS (JSElision []) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"],NS (JSIdentifier \"x\") (TokenPn 12 1 13) [CommentA (TokenPn 12 1 13) \"/*c*/\"],NS (JSElision []) (TokenPn 18 1 19) [CommentA (TokenPn 18 1 19) \"/*d*/\"],NS (JSElision []) (TokenPn 24 1 25) [CommentA (TokenPn 24 1 25) \"/*e*/\"],NS (JSIdentifier \"x\") (TokenPn 30 1 31) [CommentA (TokenPn 30 1 31) \"/*f*/\"]]) (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\",CommentA (TokenPn 36 1 37) \"/*g*/\"])")
+ , testCase "ArrayLiteral7" (testPEC "/*a*/[/*b*/x/*c*/]" "Right (NS (JSArrayLiteral [NS (JSIdentifier \"x\") (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]]) (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\",CommentA (TokenPn 12 1 13) \"/*c*/\"])")
+ , testCase "ArrayLiteral8" (testPEC "/*a*/[/*b*/x/*c*/,/*d*/]" "Right (NS (JSArrayLiteral [NS (JSIdentifier \"x\") (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"],NS (JSLiteral \",\") (TokenPn 17 1 18) [CommentA (TokenPn 12 1 13) \"/*c*/\"]]) (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\",CommentA (TokenPn 18 1 19) \"/*d*/\"])")
+
+ , testCase "ObjectLiteral1" (testPEC "/*a*/{/*b*/}" "Right (NS (JSObjectLiteral []) (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\",CommentA (TokenPn 6 1 7) \"/*b*/\"])")
+ , testCase "ObjectLiteral2" (testPEC "/*a*/{/*b*/x/*c*/:/*d*/1/*e*/}" "Right (NS (JSObjectLiteral [NS (JSPropertyNameandValue (NS (JSIdentifier \"x\") (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]) [NS (JSDecimal \"1\") (TokenPn 18 1 19) [CommentA (TokenPn 18 1 19) \"/*d*/\"]]) (TokenPn 12 1 13) [CommentA (TokenPn 12 1 13) \"/*c*/\"]]) (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\",CommentA (TokenPn 24 1 25) \"/*e*/\"])")
+ , testCase "ObjectLiteral3" (testPEC "/*a*/{/*b*/x/*c*/:/*d*/1/*e*/,/*f*/y/*g*/:/*h*/2/*i*/}" "Right (NS (JSObjectLiteral [NS (JSPropertyNameandValue (NS (JSIdentifier \"x\") (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]) [NS (JSDecimal \"1\") (TokenPn 18 1 19) [CommentA (TokenPn 18 1 19) \"/*d*/\"]]) (TokenPn 12 1 13) [CommentA (TokenPn 12 1 13) \"/*c*/\"],NS (JSPropertyNameandValue (NS (JSIdentifier \"y\") (TokenPn 30 1 31) [CommentA (TokenPn 30 1 31) \"/*f*/\"]) [NS (JSDecimal \"2\") (TokenPn 42 1 43) [CommentA (TokenPn 42 1 43) \"/*h*/\"]]) (TokenPn 36 1 37) [CommentA (TokenPn 24 1 25) \"/*e*/\",CommentA (TokenPn 36 1 37) \"/*g*/\"]]) (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\",CommentA (TokenPn 48 1 49) \"/*i*/\"])")
+
+ , testCase "ObjectLiteral5" (testPEC "/*a*/{/*b*/x/*c*/:/*d*/1/*e*/,/*f*/}" "Right (NS (JSObjectLiteral [NS (JSPropertyNameandValue (NS (JSIdentifier \"x\") (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]) [NS (JSDecimal \"1\") (TokenPn 18 1 19) [CommentA (TokenPn 18 1 19) \"/*d*/\"]]) (TokenPn 12 1 13) [CommentA (TokenPn 12 1 13) \"/*c*/\"],NS (JSLiteral \",\") (TokenPn 29 1 30) [CommentA (TokenPn 24 1 25) \"/*e*/\"]]) (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\",CommentA (TokenPn 30 1 31) \"/*f*/\"])")
+
+ -- Edition 5 extensions
+ , testCase "ObjectLiteral7" (testProgC "/*a*/x/*b*/=/*c*/{/*d*/get/*e*/ foo/*f*/(/*g*/)/*h*/ {/*i*/return/*j*/ 1/*k*/}/*l*/,/*m*/set/*n*/ foo/*o*/(/*p*/a/*q*/) /*r*/{/*s*/x/*t*/=/*u*/a/*v*/}/*w*/}" "Right (NS (JSSourceElementsTop [NS (JSExpression [NS (JSIdentifier \"x\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"],NS (JSOperator \"=\") (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"],NS (JSObjectLiteral [NS (JSPropertyAccessor \"get\" (NS (JSIdentifier \"foo\") (TokenPn 26 1 27) [CommentA (TokenPn 26 1 27) \"/*e*/\"]) [] (NS (JSFunctionBody [NS (JSSourceElements [NS (JSReturn [NS (JSExpression [NS (JSDecimal \"1\") (TokenPn 65 1 66) [CommentA (TokenPn 65 1 66) \"/*j*/\"]]) (TokenPn 65 1 66) [],NS (JSLiteral \"\") (TokenPn 0 0 0) []]) (TokenPn 54 1 55) [CommentA (TokenPn 54 1 55) \"/*i*/\"]]) (TokenPn 54 1 55) []]) (TokenPn 54 1 55) [])) (TokenPn 18 1 19) [CommentA (TokenPn 18 1 19) \"/*d*/\",CommentA (TokenPn 35 1 36) \"/*f*/\",CommentA (TokenPn 41 1 42) \"/*g*/\",CommentA (TokenPn 47 1 48) \"/*h*/\",CommentA (TokenPn 72 1 73) \"/*k*/\"],NS (JSPropertyAccessor \"set\" (NS (JSIdentifier \"foo\") (TokenPn 92 1 93) [CommentA (TokenPn 92 1 93) \"/*n*/\"]) [NS (JSIdentifier \"a\") (TokenPn 107 1 108) [CommentA (TokenPn 107 1 108) \"/*p*/\"]] (NS (JSFunctionBody [NS (JSSourceElements [NS (JSExpression [NS (JSIdentifier \"x\") (TokenPn 126 1 127) [CommentA (TokenPn 126 1 127) \"/*s*/\"],NS (JSOperator \"=\") (TokenPn 132 1 133) [CommentA (TokenPn 132 1 133) \"/*t*/\"],NS (JSIdentifier \"a\") (TokenPn 138 1 139) [CommentA (TokenPn 138 1 139) \"/*u*/\"]]) (TokenPn 126 1 127) []]) (TokenPn 126 1 127) []]) (TokenPn 126 1 127) [])) (TokenPn 84 1 85) [CommentA (TokenPn 78 1 79) \"/*l*/\",CommentA (TokenPn 84 1 85) \"/*m*/\",CommentA (TokenPn 101 1 102) \"/*o*/\",CommentA (TokenPn 113 1 114) \"/*q*/\",CommentA (TokenPn 120 1 121) \"/*r*/\",CommentA (TokenPn 144 1 145) \"/*v*/\"]]) (TokenPn 12 1 13) [CommentA (TokenPn 12 1 13) \"/*c*/\",CommentA (TokenPn 150 1 151) \"/*w*/\"]]) (TokenPn 0 1 1) []]) (TokenPn 0 1 1) [])")
+
+ , testCase "ExpressionParen" (testPEC "/*a*/(/*b*/56/*c*/)" "Right (NS (JSExpressionParen (NS (JSExpression [NS (JSDecimal \"56\") (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]]) (TokenPn 6 1 7) [])) (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\",CommentA (TokenPn 13 1 14) \"/*c*/\"])")
+
+ , testCase "Statement1" (testStmtC "/*a*/x" "Right (NS (JSExpression [NS (JSIdentifier \"x\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"]]) (TokenPn 0 1 1) [])")
+
+ , testCase "Statement2" (testStmtC "/*a*/null" "Right (NS (JSExpression [NS (JSLiteral \"null\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"]]) (TokenPn 0 1 1) [])")
+
+ , testCase "Statement3" (testStmtC "/*a*/true/*b*/?/*c*/1/*d*/:/*e*/2" "Right (NS (JSExpression [NS (JSExpressionTernary [NS (JSLiteral \"true\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"]] [NS (JSDecimal \"1\") (TokenPn 15 1 16) [CommentA (TokenPn 15 1 16) \"/*c*/\"]] [NS (JSDecimal \"2\") (TokenPn 27 1 28) [CommentA (TokenPn 27 1 28) \"/*e*/\"]]) (TokenPn 9 1 10) [CommentA (TokenPn 9 1 10) \"/*b*/\",CommentA (TokenPn 21 1 22) \"/*d*/\"]]) (TokenPn 9 1 10) [])")
+
+ , testCase "Statement4" (testStmtC "/*a*/x/*b*/||/*c*/y" "Right (NS (JSExpression [NS (JSExpressionBinary \"||\" [NS (JSIdentifier \"x\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"]] [NS (JSIdentifier \"y\") (TokenPn 13 1 14) [CommentA (TokenPn 13 1 14) \"/*c*/\"]]) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]]) (TokenPn 6 1 7) [])")
+
+ , testCase "Statement5" (testStmtC "/*a*/x/*b*/&&/*c*/y" "Right (NS (JSExpression [NS (JSExpressionBinary \"&&\" [NS (JSIdentifier \"x\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"]] [NS (JSIdentifier \"y\") (TokenPn 13 1 14) [CommentA (TokenPn 13 1 14) \"/*c*/\"]]) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]]) (TokenPn 6 1 7) [])")
+
+ , testCase "Statement6a" (testStmtC "/*a*/x/*b*/|/*c*/y" "Right (NS (JSExpression [NS (JSExpressionBinary \"|\" [NS (JSIdentifier \"x\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"]] [NS (JSIdentifier \"y\") (TokenPn 12 1 13) [CommentA (TokenPn 12 1 13) \"/*c*/\"]]) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]]) (TokenPn 6 1 7) [])")
+
+ , testCase "Statement6b" (testStmtC "/*a*/x/*b*/^/*c*/y" "Right (NS (JSExpression [NS (JSExpressionBinary \"^\" [NS (JSIdentifier \"x\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"]] [NS (JSIdentifier \"y\") (TokenPn 12 1 13) [CommentA (TokenPn 12 1 13) \"/*c*/\"]]) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]]) (TokenPn 6 1 7) [])")
+
+ , testCase "Statement7" (testStmtC "/*a*/x/*b*/&/*c*/y" "Right (NS (JSExpression [NS (JSExpressionBinary \"&\" [NS (JSIdentifier \"x\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"]] [NS (JSIdentifier \"y\") (TokenPn 12 1 13) [CommentA (TokenPn 12 1 13) \"/*c*/\"]]) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]]) (TokenPn 6 1 7) [])")
+
+ , testCase "Statement8" (testStmtC "/*a*/x/*b*/==/*c*/y" "Right (NS (JSExpression [NS (JSExpressionBinary \"==\" [NS (JSIdentifier \"x\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"]] [NS (JSIdentifier \"y\") (TokenPn 13 1 14) [CommentA (TokenPn 13 1 14) \"/*c*/\"]]) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]]) (TokenPn 6 1 7) [])")
+
+ , testCase "Statement9" (testStmtC "/*a*/x/*b*/!=/*c*/y" "Right (NS (JSExpression [NS (JSExpressionBinary \"!=\" [NS (JSIdentifier \"x\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"]] [NS (JSIdentifier \"y\") (TokenPn 13 1 14) [CommentA (TokenPn 13 1 14) \"/*c*/\"]]) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]]) (TokenPn 6 1 7) [])")
+
+ , testCase "Statement10" (testStmtC "/*a*/x/*b*/===/*c*/y" "Right (NS (JSExpression [NS (JSExpressionBinary \"===\" [NS (JSIdentifier \"x\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"]] [NS (JSIdentifier \"y\") (TokenPn 14 1 15) [CommentA (TokenPn 14 1 15) \"/*c*/\"]]) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]]) (TokenPn 6 1 7) [])")
+
+ , testCase "Statement11" (testStmtC "/*a*/x/*b*/!==/*c*/y" "Right (NS (JSExpression [NS (JSExpressionBinary \"!==\" [NS (JSIdentifier \"x\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"]] [NS (JSIdentifier \"y\") (TokenPn 14 1 15) [CommentA (TokenPn 14 1 15) \"/*c*/\"]]) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]]) (TokenPn 6 1 7) [])")
+
+ , testCase "Statement12a" (testStmtC "/*a*/x/*b*/</*c*/y" "Right (NS (JSExpression [NS (JSExpressionBinary \"<\" [NS (JSIdentifier \"x\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"]] [NS (JSIdentifier \"y\") (TokenPn 12 1 13) [CommentA (TokenPn 12 1 13) \"/*c*/\"]]) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]]) (TokenPn 6 1 7) [])")
+
+ , testCase "Statement12b" (testStmtC "/*a*/x/*b*/>/*c*/y" "Right (NS (JSExpression [NS (JSExpressionBinary \">\" [NS (JSIdentifier \"x\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"]] [NS (JSIdentifier \"y\") (TokenPn 12 1 13) [CommentA (TokenPn 12 1 13) \"/*c*/\"]]) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]]) (TokenPn 6 1 7) [])")
+
+ , testCase "Statement12c" (testStmtC "/*a*/x/*b*/<=/*c*/y" "Right (NS (JSExpression [NS (JSExpressionBinary \"<=\" [NS (JSIdentifier \"x\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"]] [NS (JSIdentifier \"y\") (TokenPn 13 1 14) [CommentA (TokenPn 13 1 14) \"/*c*/\"]]) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]]) (TokenPn 6 1 7) [])")
+
+ , testCase "Statement12d" (testStmtC "/*a*/x/*b*/>=/*c*/y" "Right (NS (JSExpression [NS (JSExpressionBinary \">=\" [NS (JSIdentifier \"x\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"]] [NS (JSIdentifier \"y\") (TokenPn 13 1 14) [CommentA (TokenPn 13 1 14) \"/*c*/\"]]) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]]) (TokenPn 6 1 7) [])")
+
+ , testCase "Statement12e" (testStmtC "/*a*/x /*b*/instanceof /*c*/y" "Right (NS (JSExpression [NS (JSExpressionBinary \" instanceof \" [NS (JSIdentifier \"x\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"]] [NS (JSIdentifier \"y\") (TokenPn 23 1 24) [CommentA (TokenPn 23 1 24) \"/*c*/\"]]) (TokenPn 7 1 8) [CommentA (TokenPn 7 1 8) \"/*b*/\"]]) (TokenPn 7 1 8) [])")
+
+ ]
+
+-- ---------------------------------------------------------------------
+
+commentPrintSuite :: Test
+commentPrintSuite = testGroup "Comments"
+ [
+ testCase "Multi-comment" (testRoundTrip "/*a*/\n//foo\nnull")
+
+
+ , testCase "LiteralNull" (testRoundTrip "/*a*/null")
+ , testCase "LiteralFalse" (testRoundTrip "/*b*/false")
+ , testCase "LiteralTrue" (testRoundTrip "true")
+ , testCase "LiteralTrue" (testRoundTrip "/*c*/true")
+
+ , testCase "LiteralHexInteger" (testRoundTrip "/*d*/0x1234fF")
+ , testCase "LiteralDecimal" (testRoundTrip "/*e*/1.0e4")
+ , testCase "LiteralString1" (testRoundTrip "/*f*/\"hello\\nworld\"")
+ , testCase "LiteralString2" (testRoundTrip "/*g*/'hello\\nworld'")
+
+
+ , testCase "LiteralThis" (testRoundTrip "/*h*/this")
+
+ , testCase "LiteralRegex1" (testRoundTrip "/*i*//blah/")
+
+ , testCase "Identifier2" (testRoundTrip "//j\nthis_")
+
+ , testCase "ArrayLiteral1" (testRoundTrip "/*a*/[/*b*/]")
+ , testCase "ArrayLiteral2" (testRoundTrip "/*a*/[/*b*/,/*c*/]")
+ , testCase "ArrayLiteral3" (testRoundTrip "/*a*/[/*b*/,/*c*/,/*d*/]")
+ , testCase "ArrayLiteral4" (testRoundTrip "/*a*/[/*b/*,/*c*/,/*d*/x/*e*/]")
+ , testCase "ArrayLiteral5" (testRoundTrip "/*a*/[/*b*/,/*c*/,/*d*/x/*e*/]")
+ , testCase "ArrayLiteral6" (testRoundTrip "/*a*/[/*b*/,/*c*/x/*d*/,/*e*/,/*f*/x/*g*/]")
+ , testCase "ArrayLiteral7" (testRoundTrip "/*a*/[/*b*/x/*c*/]")
+ , testCase "ArrayLiteral8" (testRoundTrip "/*a*/[/*b*/x/*c*/,/*d*/]")
+
+ , testCase "ObjectLiteral1" (testRoundTrip "/*a*/{/*b*/}")
+ , testCase "ObjectLiteral2" (testRoundTrip "/*a*/{/*b*/x/*c*/:/*d*/1/*e*/}")
+ , testCase "ObjectLiteral3" (testRoundTrip "x=/*a*/{/*b*/x/*c*/:/*d*/1/*e*/,/*f*/y/*g*/:/*h*/2/*i*/}")
+ , testCase "ObjectLiteral3a" (testRoundTrip "x=/*a*/{/*b*/x/*c*/:/*d*/1/*e*/,/*f*/y/*g*/:/*h*/2/*i*/,/*j*/z/*k*/:/*l*/3/*m*/}")
+
+ , testCase "ObjectLiteral5" (testRoundTrip "a=/*a*/{/*b*/x/*c*/:/*d*/1/*e*/,/*f*/}")
+
+ -- Edition 5 extensions
+ , testCase "ObjectLiteral7" (testRoundTrip "/*a*/x/*b*/=/*c*/{/*d*/get/*e*/ foo/*f*/(/*g*/)/*h*/ {/*i*/return/*j*/ 1/*k*/}/*l*/,/*m*/set/*n*/ foo/*o*/(/*p*/a/*q*/) /*r*/{/*s*/x/*t*/=/*u*/a/*v*/}/*w*/}")
+
+ , testCase "ExpressionParen" (testRoundTrip "/*a*/(/*b*/56/*c*/)")
+
+ , testCase "Statement1" (testRoundTrip "/*a*/x")
+
+ , testCase "Statement2" (testRoundTrip "/*a*/null")
+
+ , testCase "Statement3" (testRoundTrip "/*a*/true/*b*/?/*c*/1/*d*/:/*e*/2")
+
+ , testCase "Statement4" (testRoundTrip "/*a*/x/*b*/||/*c*/y")
+
+ , testCase "Statement5" (testRoundTrip "/*a*/x/*b*/&&/*c*/y")
+
+ , testCase "Statement6a" (testRoundTrip "/*a*/x/*b*/|/*c*/y")
+
+ , testCase "Statement6b" (testRoundTrip "/*a*/x/*b*/^/*c*/y")
+
+ , testCase "Statement7" (testRoundTrip "/*a*/x/*b*/&/*c*/y")
+
+ , testCase "Statement8" (testRoundTrip "/*a*/x/*b*/==/*c*/y")
+
+ , testCase "Statement9" (testRoundTrip "/*a*/x/*b*/!=/*c*/y")
+
+ , testCase "Statement10" (testRoundTrip "/*a*/x/*b*/===/*c*/y")
+
+ , testCase "Statement11" (testRoundTrip "/*a*/x/*b*/!==/*c*/y")
+
+ , testCase "Statement12a" (testRoundTrip "/*a*/x/*b*/</*c*/y")
+
+ , testCase "Statement12b" (testRoundTrip "/*a*/x/*b*/>/*c*/y")
+
+ , testCase "Statement12c" (testRoundTrip "/*a*/x/*b*/<=/*c*/y")
+
+ , testCase "Statement12d" (testRoundTrip "/*a*/x/*b*/>=/*c*/y")
+
+ , testCase "Statement12e" (testRoundTrip "/*a*/x /*b*/instanceof /*c*/y")
+
+
+
+ , testCase "Statement13" (testRoundTrip "x<<y")
+ , testCase "Statement13" (testRoundTrip "x>>y")
+ , testCase "Statement13" (testRoundTrip "x>>>y")
+
+ , testCase "Statement14" (testRoundTrip "x+y")
+ , testCase "Statement14" (testRoundTrip "x-y")
+
+ , testCase "Statement15" (testRoundTrip "x*y")
+ , testCase "Statement16" (testRoundTrip "x/y")
+ , testCase "Statement17" (testRoundTrip "x%y")
+
+ , testCase "Statement18" (testRoundTrip "delete y")
+ , testCase "Statement19" (testRoundTrip "void y")
+ , testCase "Statement20" (testRoundTrip "typeof y")
+ , testCase "Statement21" (testRoundTrip "++y")
+ , testCase "Statement22" (testRoundTrip "--y")
+ , testCase "Statement23" (testRoundTrip "+y")
+ , testCase "Statement24" (testRoundTrip "-y")
+ , testCase "Statement25" (testRoundTrip "~y")
+ , testCase "Statement26" (testRoundTrip "!y")
+
+ , testCase "Statement27" (testRoundTrip "y++")
+ , testCase "Statement28" (testRoundTrip "y--")
+
+ -- Member Expressions
+ , testCase "MemberExpression1a" (testRoundTrip "function(){}")
+ , testCase "MemberExpression1b" (testRoundTrip "function(a){}")
+ , testCase "MemberExpression1c" (testRoundTrip "function(a,b){}")
+
+ , testCase "MemberExpression1d" (testRoundTrip "x[y]")
+ , testCase "MemberExpression1e" (testRoundTrip "x[y][z]")
+ , testCase "MemberExpression1f" (testRoundTrip "x.y")
+ , testCase "MemberExpression1g" (testRoundTrip "x.y.z")
+
+ , testCase "MemberExpression1h" (testRoundTrip "new x()")
+
+ , testCase "NewExpression1" (testRoundTrip "new x.y")
+
+ , testCase "CallExpression1" (testRoundTrip "x()")
+ , testCase "CallExpression2" (testRoundTrip "x()()")
+ , testCase "CallExpression3" (testRoundTrip "x()[4]")
+ , testCase "CallExpression4" (testRoundTrip "x().x")
+ , testCase "CallExpression5" (testRoundTrip "x(a,b=2).x")
+
+ , testCase "AssignExpression1" (testRoundTrip "x=1")
+ , testCase "AssignExpression1" (testRoundTrip "x*=1")
+ , testCase "AssignExpression1" (testRoundTrip "x/=1")
+ , testCase "AssignExpression1" (testRoundTrip "x%=1")
+ , testCase "AssignExpression1" (testRoundTrip "x+=1")
+ , testCase "AssignExpression1" (testRoundTrip "x-=1")
+ , testCase "AssignExpression1" (testRoundTrip "x<<=1")
+ , testCase "AssignExpression1" (testRoundTrip "x>>=1")
+ , testCase "AssignExpression1" (testRoundTrip "x>>>=1")
+ , testCase "AssignExpression1" (testRoundTrip "x&=1")
+ , testCase "AssignExpression1" (testRoundTrip "x^=1")
+ , testCase "AssignExpression1" (testRoundTrip "x|=1")
+
+
+ , testCase "Block1" (testRoundTrip "{}")
+ , testCase "Block2" (testRoundTrip "{x=1}")
+ , testCase "Block3" (testRoundTrip "{x=1;y=2}")
+ , testCase "Block4" (testRoundTrip "{{}}")
+ , testCase "Block5" (testRoundTrip "{{{}}}")
+
+
+ , testCase "If1" (testRoundTrip "if (1) {}")
+
+ , testCase "IfElse1" (testRoundTrip "if (1) {} else {}")
+ , testCase "IfElse2" (testRoundTrip "if (1) x=1; else {}")
+
+ , testCase "DoWhile1" (testRoundTrip "do {x=1} while (true);")
+ , testCase "While1" (testRoundTrip "while(true);")
+
+ , testCase "For1" (testRoundTrip "for(;;);")
+ , testCase "For2" (testRoundTrip "for(x=1;x<10;x++);")
+
+ , testCase "ForVar1" (testRoundTrip "for(var x;;);")
+ , testCase "ForVar2" (testRoundTrip "for(var x=1;;);")
+ , testCase "ForVar2" (testRoundTrip "for(var x;y;z){}")
+
+ , testCase "ForIn1" (testRoundTrip "for(x in 5){}")
+
+ , testCase "ForVarIn1" (testRoundTrip "for(var x in 5){}")
+
+ , testCase "Var1" (testRoundTrip "var x=1;")
+ , testCase "Var2" (testRoundTrip "const x=1,y=2;")
+
+
+ , testCase "Continue1" (testRoundTrip "continue;")
+ , testCase "Continue2" (testRoundTrip "continue x;")
+
+ , testCase "Break1" (testRoundTrip "break;")
+ , testCase "Break2" (testRoundTrip "break x;")
+
+ , testCase "Return1" (testRoundTrip "return;")
+ , testCase "Return2" (testRoundTrip "return x;")
+
+ , testCase "With1" (testRoundTrip "with (x) {};")
+
+ , testCase "Labelled1" (testRoundTrip "abc:x=1")
+
+ , testCase "Switch1" (testRoundTrip "switch (x) {}")
+ , testCase "Switch2" (testRoundTrip "switch (x) {case 1:break;}")
+ , testCase "Switch3" (testRoundTrip "switch (x) {case 0:\ncase 1:break;}")
+ , testCase "Switch4" (testRoundTrip "switch (x) {default:break;}")
+ , testCase "Switch5" (testRoundTrip "switch (x) {default:\ncase 1:break;}")
+
+ , testCase "Throw1" (testRoundTrip "throw 1")
+
+ , testCase "Try1" (testRoundTrip "try{}catch(a){}")
+ , testCase "Try2" (testRoundTrip "try{}finally{}")
+ , testCase "Try3" (testRoundTrip "try{}catch(a){}finally{}")
+
+ , testCase "Try4" (testRoundTrip "try{}catch(a){}catch(b){}finally{}")
+ , testCase "Try5" (testRoundTrip "try{}catch(a){}catch(b){}")
+ , testCase "Try6" (testRoundTrip "try{}catch(a if true){}catch(b){}")
+
+ , testCase "Function1" (testRoundTrip "function a(){}")
+ , testCase "Function2" (testRoundTrip "function a(b,c){}")
+
+
+ , testCase "Comment1" (testRoundTrip "//blah\nx=1;//foo\na")
+
+ , testCase "Comment2" (testRoundTrip "/*x=1\ny=2\n*/z=2;//foo\na")
+
+ , testCase "min_100_animals1" (testRoundTrip "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\"")
+
+ , testCase "min_100_animals2" (testRoundTrip "Animal=function(){return this.name};")
+
+ , testCase "min_100_animals3" (testRoundTrip "if(a)x=1;y=2")
+
+ , testCase "min_100_animals4" (testRoundTrip "if(a)x=a()y=2")
+
+ , testCase "05_regex" (testRoundTrip "newlines=spaces.match(/\\n/g)")
+
+ , testCase "05_regex2" (testRoundTrip "x=/\\n/g")
+
+ , testCase "05_regex3" (testRoundTrip "x=i(/[?|^&(){}\\[\\]+\\-*\\/\\.]/g,\"\\\\$&\")")
+
+ , testCase "05_regex4" (testRoundTrip "x=i(/^$/g,\"\\\\$&\")")
+
+ , testCase "05_regex5" (testRoundTrip "if(/^[a-z]/.test(t)){consts+=t.toUpperCase();keywords[t]=i}else consts+=(/^\\W/.test(t)?opTypeNames[t]:t);")
+
+ , testCase "if_semi" (testRoundTrip "if(x);x=1")
+
+ , testCase "67_bob" (testRoundTrip "(match = /^\"(?:\\\\.|[^\"])*\"|^'(?:[^']|\\\\.)*'/(input))")
+
+ , testCase "122_jsexec" (testRoundTrip "v = getValue(execute(n[0], x)) in getValue(execute(n[1], x));")
+
+ , testCase "bug1a" (testRoundTrip "/* */\nfunction f() {\n/* */\n}")
+ , testCase "bug1b" (testRoundTrip "/* **/\nfunction f() {\n/* */\n}")
+
+ , testCase "unicode1-ws" (testRoundTrip "a \f\v\t\r\n=\x00a0\x1680\x180e\x2000\x2001\x2002\x2003\x2004\x2005\x2006\x2007\x2008\x2009\x200a\x2028\x2029\x202f\x205f\x3000\&1;")
+
+ , testCase "unicode2-lt" (testRoundTrip "//comment\x000Ax=1;")
+ , testCase "unicode3-lt" (testRoundTrip "//comment\x000Dx=1;")
+ , testCase "unicode4-lt" (testRoundTrip "//comment\x2028x=1;")
+ , testCase "unicode5-lt" (testRoundTrip "//comment\x2029x=1;")
+
+ , testCase "unicode2" (testRoundTrip "àáâãäå = 1;")
+
+ , testCase "unicode3" (testRoundTrip "$aà = 1;_b=2;\0065a=2")
+
+ , testCase "unicode4" (testRoundTrip "x=\"àáâãäå\";y='\3012a\0068'")
+
+ -- , testCase "unicode5" (testFile "./test/Unicode.js")
+
+ , testCase "bug2.a" (testRoundTrip "function() {\nz = function /*z*/(o) {\nreturn r;\n};}")
+
+ , testCase "bug2.b" (testRoundTrip "function() {\nz = function z(o) {\nreturn r;\n};}")
+
+ -- https://github.com/alanz/hjsmin/issues/#issue/3
+ , testCase "bug3" (testRoundTrip "var myLatlng = new google.maps.LatLng(56.8379100, 60.5806664);")
+
+ -- https://github.com/alanz/hjsmin/issues/#issue/4
+ , testCase "bug4" (testRoundTrip "/* * geolocation. пытаемся определить свое местоположение * если не получается то используем defaultLocation * @Param {object} map экземпляр карты * @Param {object LatLng} defaultLocation Координаты центра по умолчанию * @Param {function} callbackAfterLocation Фу-ия которая вызывается после * геолокации. Т.к запрос геолокации асинхронен */x")
+
+ , testCase "02_sm.js" (testRoundTrip "{zero}\none1;two\n{three\nfour;five;\n{\nsix;{seven;}\n}\n}")
+
+ , testCase "02_sm.js.2" (testRoundTrip "{zero}\nget;two\n{three\nfour;set;\n{\nsix;{seven;}\n}\n}")
+
+ , testCase "loc1" (testRoundTrip "x = 1\n y=2;")
+
+ -- https://github.com/alanz/language-javascript/issues/2
+ , testCase "issue2" (testRoundTrip "var img = document.createElement('img');\nimg.src = \"mylogo.jpg\";\n$(img).click(function() {\n alert('clicked!');\n});")
+
+
+ -- Working in ECMASCRIPT 5.1 changes
+ , testCase "lineTerminatorInString1" (testRoundTrip "x='abc\\\ndef';")
+ , testCase "lineTerminatorInString2" (testRoundTrip "x=\"abc\\\ndef\";")
+ , testCase "lineTerminatorInString3" (testRoundTrip "x=\"abc\\\rdef\";")
+ , testCase "lineTerminatorInString4" (testRoundTrip "x=\"abc\\\x2028 def\";")
+ , testCase "lineTerminatorInString5" (testRoundTrip "x=\"abc\\\x2029 def\";")
+ , testCase "lineTerminatorInString6" (testRoundTrip "x=\"abc\\\r\ndef\";")
+
+
+ -- https://github.com/alanz/language-javascript/issues/4
+ , testCase "issue4ok" (testRoundTrip "var k = {\ny: somename\n}")
+ , testCase "issue4bug1" (testRoundTrip "var k = {\ny: code\n}")
+ , testCase "issue4bug2" (testRoundTrip "var k = {\ny: mode\n}")
+
+ -- https://github.com/alanz/language-javascript/issues/5
+ , testCase "issue5bug1" (testRoundTrip "x = { y: 1e8 }")
+ , testCase "issue5ok2" (testRoundTrip "{ y: 1e8 }")
+ , testCase "issue5ok3" (testRoundTrip "{ y: 18 }")
+ , testCase "issue5ok4" (testRoundTrip "x = { y: 18 }")
+
+ -- function body
+ , testCase "functionbody" (testRoundTrip "function foo(a,b,c)\n{x=1;}")
+ , testCase "functionexpression" (testRoundTrip "function foo(a,b,c)\n{x=1;}")
+
+ , testCase "fn1" (testRoundTrip "function foo() { return 5; }")
+ , testCase "fn2" (testRoundTrip "var foo = function() { return 5; }")
+ , testCase "fn3" (testRoundTrip "var foo = function foo() { return 5; }")
+
+ ]
+
+-- ---------------------------------------------------------------------
-- Test utilities
-testLiteral literal expected = expected @=? (showStrippedMaybe $ parseUsing parseLiteral literal "src")
+testRoundTrip str = str @=? (renderToString $ readJs str)
+
+testLiteral :: String -> String -> Assertion
+testLiteral literal expected = expected @=? (showStrippedMaybe $ parseUsing parseLiteral literal "src")
+testLiteralC :: String -> String -> Assertion
+testLiteralC literal expected = expected @=? (show $ parseUsing parseLiteral literal "src")
+
-testPE str expected = expected @=? (showStrippedMaybe $ parseUsing parsePrimaryExpression str "src")
+testPE :: String -> String -> Assertion
+testPE str expected = expected @=? (showStrippedMaybe $ parseUsing parsePrimaryExpression str "src")
+testPEC :: String -> String -> Assertion
+testPEC str expected = expected @=? (show $ parseUsing parsePrimaryExpression str "src")
-testStmt str expected = expected @=? (showStrippedMaybe $ parseUsing parseStatement str "src")
+testStmt :: String -> String -> Assertion
+testStmt str expected = expected @=? (showStrippedMaybe $ parseUsing parseStatement str "src")
+testStmtC :: String -> String -> Assertion
+testStmtC str expected = expected @=? (show $ parseUsing parseStatement str "src")
--testProg str expected = expected @=? (show $ parseUsing parseProgram str "src")
-testProg str expected = expected @=? (showStrippedMaybe $ parseUsing parseProgram str "src")
+testProg :: String -> String -> Assertion
+testProg str expected = expected @=? (showStrippedMaybe $ parseUsing parseProgram str "src")
+testProgC :: String -> String -> Assertion
+testProgC str expected = expected @=? (show $ parseUsing parseProgram str "src")
+testProgUn :: String -> String -> Assertion
testProgUn str expected = expected @=? (show $ parseUsing parseProgram str "src")
+testFile :: FilePath -> String -> IO ()
testFile fileName expected = do
res <- parseFile fileName
-- expected @=? (liftM show $ parseFile fileName)
View
275 src-dev/Language/JavaScript/Parser/Lexer.x
@@ -2,7 +2,11 @@
module Language.JavaScript.Parser.Lexer (
Token(..)
+ , AlexPosn(..)
+ , Alex
, lexCont
+ , alexError
+ , runAlex
) where
--import Control.Monad
@@ -17,10 +21,9 @@ import Codec.Binary.UTF8.Light as UTF8
}
--- Not using a wrapper, rolling own below.
---%wrapper "basic"
---%wrapper "monad"
---%wrapper "monadUserState"
+-- %wrapper "basic"
+-- %wrapper "monad"
+%wrapper "monadUserState"
-- %wrapper "monad-bytestring"
-- character sets
@@ -169,11 +172,13 @@ tokens :-
<0> () ; -- { registerStates lexToken reg divide }
-- Skip Whitespace
-<reg,divide> $white_char+ ;
+-- <reg,divide> $white_char+ ;
+<reg,divide> $white_char+ { adapt (mkString wsToken) }
-- Skip one line comment
-<reg,divide> "//"($not_eol_char)* ;
-
+-- <reg,divide> "//"($not_eol_char)* ;
+<reg,divide> "//"($not_eol_char)* { adapt (mkString commentToken) }
+-- <reg,divide> "//"($not_eol_char)* { mkComment }
-- ---------------------------------------------------------------------
-- Comment definition from the ECMAScript spec, ver 3
@@ -193,27 +198,27 @@ tokens :-
-- Skip multi-line comments. Note: may not nest
-- <reg,divide> "/*"($any_char)*"*/" ;
-<reg,divide> "/*" (($MultiLineNotAsteriskChar)*| ("*")+ ($MultiLineNotForwardSlashOrAsteriskChar) )* ("*")+ "/" ;
-
+-- <reg,divide> "/*" (($MultiLineNotAsteriskChar)*| ("*")+ ($MultiLineNotForwardSlashOrAsteriskChar) )* ("*")+ "/" ;
+<reg,divide> "/*" (($MultiLineNotAsteriskChar)*| ("*")+ ($MultiLineNotForwardSlashOrAsteriskChar) )* ("*")+ "/" { adapt (mkString commentToken) }
-- Identifier = {ID Head}{ID Tail}*
---<reg,divide> @IDHead(@IDTail)* { \loc len str -> keywordOrIdent (take len str) loc }
-<reg,divide> @IdentifierStart(@IdentifierPart)* { \loc len str -> keywordOrIdent (take len str) loc }
+-- <reg,divide> @IDHead(@IDTail)* { \loc len str -> keywordOrIdent (take len str) loc }
+<reg,divide> @IdentifierStart(@IdentifierPart)* { \ap@(loc,_,str) len -> keywordOrIdent (take len str) (toTokenPosn loc) }
-- StringLiteral = '"' ( {String Chars1} | '\' {Printable} )* '"'
-- | '' ( {String Chars2} | '\' {Printable} )* ''
<reg,divide> $dq ( $StringChars1 | \\ $printable | @LineContinuation )* $dq
- | $sq ( $StringChars2 | \\ $printable | @LineContinuation )* $sq { mkString stringToken }
+ | $sq ( $StringChars2 | \\ $printable | @LineContinuation )* $sq { adapt (mkString stringToken) }
-- HexIntegerLiteral = '0x' {Hex Digit}+
-<reg,divide> ("0x"|"0X") @HexDigit+ { mkString hexIntegerToken }
+<reg,divide> ("0x"|"0X") @HexDigit+ { adapt (mkString hexIntegerToken) }
-- RegExp = '/' ({RegExp Chars} | '\' {Non Terminator})+ '/' ( 'g' | 'i' | 'm' )*
-- <reg> "/" ($RegExpChars | "\" $NonTerminator)+ "/" ("g"|"i"|"m")* { mkString regExToken }
-- Based on the Jint version
-<reg> "/" ($RegExpFirstChar | "\" $NonTerminator) ($RegExpChars | "\" $NonTerminator)* "/" ("g"|"i"|"m")* { mkString regExToken }
+<reg> "/" ($RegExpFirstChar | "\" $NonTerminator) ($RegExpChars | "\" $NonTerminator)* "/" ("g"|"i"|"m")* { adapt (mkString regExToken) }
@@ -238,67 +243,67 @@ tokens :-
| "." $digit+ ("e"|"E") ("+"|"-")? $non_zero_digit+ $digit*
| "0" ("e"|"E") ("+"|"-")? $non_zero_digit+ $digit*
| $non_zero_digit $digit* ("e"|"E") ("+"|"-")? $non_zero_digit+ $digit*
-
+-- ++FOO++
| "0" "." $digit*
| $non_zero_digit $digit* "." $digit*
| "." $digit+
| "0"
- | $non_zero_digit $digit* { mkString decimalToken }
+ | $non_zero_digit $digit* { adapt (mkString decimalToken) }
-- beginning of file
<bof> {
@eol_pattern ;
-- @eol_pattern { endOfLine lexToken }
- --@eol_pattern { endOfLine alexMonadScan }
+ -- @eol_pattern { endOfLine alexMonadScan }
}
-- / or /= only allowed in state 1
<divide> {
- "/=" { mkString assignToken}
- "/" { symbolToken DivToken}
+ "/=" { adapt (mkString assignToken)}
+ "/" { adapt (symbolToken DivToken)}
}
<reg,divide> {
- \; { symbolToken SemiColonToken}
- "," { symbolToken CommaToken}
- "?" { symbolToken HookToken}
- ":" { symbolToken ColonToken}
- "||" { symbolToken OrToken}
- "&&" { symbolToken AndToken}
- "|" { symbolToken BitwiseOrToken}
- "^" { symbolToken BitwiseXorToken}
- "&" { symbolToken BitwiseAndToken}
- "===" { symbolToken StrictEqToken}
- "==" { symbolToken EqToken}
+ \; { adapt (symbolToken SemiColonToken)}
+ "," { adapt (symbolToken CommaToken)}
+ "?" { adapt (symbolToken HookToken)}
+ ":" { adapt (symbolToken ColonToken)}
+ "||" { adapt (symbolToken OrToken)}
+ "&&" { adapt (symbolToken AndToken)}
+ "|" { adapt (symbolToken BitwiseOrToken)}
+ "^" { adapt (symbolToken BitwiseXorToken)}
+ "&" { adapt (symbolToken BitwiseAndToken)}
+ "===" { adapt (symbolToken StrictEqToken)}
+ "==" { adapt (symbolToken EqToken)}
"*=" | "%=" | "+=" | "-=" | "<<=" | ">>=" | ">>>=" | "&=" | "^=" | "|="
- { mkString assignToken}
- "=" { symbolToken SimpleAssignToken}
- "!==" { symbolToken StrictNeToken}
- "!=" { symbolToken NeToken}
- "<<" { symbolToken LshToken}
- "<=" { symbolToken LeToken}
- "<" { symbolToken LtToken}
- ">>>" { symbolToken UrshToken}
- ">>" { symbolToken RshToken}
- ">=" { symbolToken GeToken}
- ">" { symbolToken GtToken}
- "++" { symbolToken IncrementToken}
- "--" { symbolToken DecrementToken}
- "+" { symbolToken PlusToken}
- "-" { symbolToken MinusToken}
- "*" { symbolToken MulToken}
- "%" { symbolToken ModToken}
- "!" { symbolToken NotToken}
- "~" { symbolToken BitwiseNotToken}
- "." { symbolToken DotToken}
- "[" { symbolToken LeftBracketToken}
- "]" { symbolToken RightBracketToken}
- "{" { symbolToken LeftCurlyToken}
- "}" { symbolToken RightCurlyToken}
- "(" { symbolToken LeftParenToken}
- ")" { symbolToken RightParenToken}
- "@*/" { symbolToken CondcommentEndToken}
+ { adapt (mkString assignToken)}
+ "=" { adapt (symbolToken SimpleAssignToken)}
+ "!==" { adapt (symbolToken StrictNeToken)}
+ "!=" { adapt (symbolToken NeToken)}
+ "<<" { adapt (symbolToken LshToken)}
+ "<=" { adapt (symbolToken LeToken)}
+ "<" { adapt (symbolToken LtToken)}
+ ">>>" { adapt (symbolToken UrshToken)}
+ ">>" { adapt (symbolToken RshToken)}
+ ">=" { adapt (symbolToken GeToken)}
+ ">" { adapt (symbolToken GtToken)}
+ "++" { adapt (symbolToken IncrementToken)}
+ "--" { adapt (symbolToken DecrementToken)}
+ "+" { adapt (symbolToken PlusToken)}
+ "-" { adapt (symbolToken MinusToken)}
+ "*" { adapt (symbolToken MulToken)}
+ "%" { adapt (symbolToken ModToken)}
+ "!" { adapt (symbolToken NotToken)}
+ "~" { adapt (symbolToken BitwiseNotToken)}
+ "." { adapt (symbolToken DotToken)}
+ "[" { adapt (symbolToken LeftBracketToken)}
+ "]" { adapt (symbolToken RightBracketToken)}
+ "{" { adapt (symbolToken LeftCurlyToken)}
+ "}" { adapt (symbolToken RightCurlyToken)}
+ "(" { adapt (symbolToken LeftParenToken)}
+ ")" { adapt (symbolToken RightParenToken)}
+ "@*/" { adapt (symbolToken CondcommentEndToken)}
}
@@ -315,8 +320,8 @@ The method is inspired by the lexer in http://jint.codeplex.com/
-}
classifyToken :: Token -> Int
-classifyToken token =
- case token of
+classifyToken aToken =
+ case aToken of
IdentifierToken {} -> divide
NullToken {} -> divide
TrueToken {} -> divide
@@ -331,90 +336,142 @@ classifyToken token =
_other -> reg
--- Each right-hand side has type :: String -> Token
-
-lexToken :: P Token
+{-
+--lexToken :: Alex Token
lexToken = do
- -- location <- getLocation
- -- input <- getInput
- input@(_,_,_,inp) <- alexGetInput
- -- startCode <- getStartCode
- lt <- getLastToken
- -- case alexScan (location, input) (classifyToken lt) of
- case alexScan input (classifyToken lt) of
- AlexEOF -> return endOfFileToken
- AlexError _ -> lexicalError
- AlexSkip rest _len -> do
- -- setLocation nextLocation
- -- setInput rest
- alexSetInput rest
+ inp <- alexGetInput
+ lt <- getLastToken
+ case alexScan inp (classifyToken lt) of
+ AlexEOF -> alexEOF
+ AlexError inp'@(pos,_,_,_) -> alexError ("lexical error @ line " ++ show (getLineNum(pos)) ++
+ " and column " ++ show (getColumnNum(pos)))
+ AlexSkip inp' _len -> do
+ alexSetInput inp'
lexToken
- AlexToken rest len action -> do
- --setLocation nextLocation
- --setInput rest
- alexSetInput rest
- --token <- action (mkSrcSpan location $ decColumn 1 nextLocation) len input
- token <- action (ignorePendingBytes input) len inp
+ AlexToken inp' len action -> do
+ alexSetInput inp'
+ token <- action (ignorePendingBytes inp) len
setLastToken token
return token
+-}
+
+--lexToken :: Alex Token
+lexToken = do
+ inp <- alexGetInput
+ lt <- getLastToken
+ case lt of
+ TailToken {} -> alexEOF
+ _other ->
+ case alexScan inp (classifyToken lt) of
+ AlexEOF -> do
+ token <- tailToken
+ setLastToken token
+ return token
+ AlexError inp'@(pos,_,_,_) -> alexError ("lexical error @ line " ++ show (getLineNum(pos)) ++
+ " and column " ++ show (getColumnNum(pos)))
+ AlexSkip inp' _len -> do
+ alexSetInput inp'
+ lexToken
+ AlexToken inp' len action -> do
+ alexSetInput inp'
+ token <- action (ignorePendingBytes inp) len
+ setLastToken token
+ return token
+
-- This is called by the Happy parser.
-lexCont :: (Token -> P a) -> P a
+--lexCont :: (Token -> P a) -> P a
+--lexCont :: (Token -> Alex Token) -> Alex Token
lexCont cont = do
lexLoop
where
-- lexLoop :: P a
lexLoop = do
tok <- lexToken
- --tok <- alexMonadScan
case tok of
- {-
CommentToken {} -> do
addComment tok
lexLoop
- LineJoinToken {} -> lexLoop
- -}
- _other -> cont tok
+ WsToken {} -> do
+ addComment tok
+ lexLoop
+ _other -> do
+ cs <- getComment
+ let tok' = tok{ token_comment=(toCommentAnnotation cs) }
+ setComment []
+ cont tok'
+toCommentAnnotation [] = [NoComment]
+--toCommentAnnotation xs = reverse $ map (\tok -> (CommentA (token_span tok) (token_literal tok))) xs
-utf8Encode :: Char -> [Byte]
-utf8Encode c = head (UTF8.encodeUTF8' [UTF8.c2w c])
+toCommentAnnotation xs = reverse $ map go xs
+ where
+ go tok@(CommentToken {}) = (CommentA (token_span tok) (token_literal tok))
+ go tok@(WsToken {}) = (WhiteSpace (token_span tok) (token_literal tok))
---alexEOF = EOFToken alexSpanEmpty
+-- ---------------------------------------------------------------------
--- ignorePendingBytes :: forall t t1 t2 t3. (t, t1, t2, t3) -> (t, t1, t3)
-ignorePendingBytes (p,c,_ps,s) = (p,c,s)
+getLineNum :: AlexPosn -> Int
+getLineNum (AlexPn _offset lineNum _colNum) = lineNum
+getColumnNum :: AlexPosn -> Int
+getColumnNum (AlexPn _offset _lineNum colNum) = colNum
-alexInputPrevChar :: AlexInput -> Char
-alexInputPrevChar (p,c,bs,s) = c
+-- ---------------------------------------------------------------------
-alexGetByte :: AlexInput -> Maybe (Byte,AlexInput)
-alexGetByte (p,c,(b:bs),s) = Just (b,(p,c,bs,s))
-alexGetByte (_p,_c,[],[]) = Nothing
-alexGetByte (p,_,[],(c:s)) = let p' = alexMove p c
- (b:bs) = utf8Encode c
- in p' `seq` Just (b, (p', c, bs, s))
+getLastToken :: Alex Token
+getLastToken = Alex $ \s@AlexState{alex_ust=ust} -> Right (s, previousToken ust)
+
+setLastToken :: Token -> Alex ()
+setLastToken tok = Alex $ \s -> Right (s{alex_ust=(alex_ust s){previousToken=tok}}, ())
+
+getComment :: Alex [Token]
+--getComments = reverse <$> Alex $ \s@AlexState{alex_ust=ust} -> Right (s, comments ust)
+getComment = Alex $ \s@AlexState{alex_ust=ust} -> Right (s, comment ust)
+
+
+addComment :: Token -> Alex ()
+addComment c = Alex $ \s -> Right (s{alex_ust=(alex_ust s){comment=c:( comment (alex_ust s) )}}, ())
+
+
+setComment :: [Token] -> Alex ()
+setComment cs = Alex $ \s -> Right (s{alex_ust=(alex_ust s){comment=cs }}, ())
+
+alexEOF :: Alex Token
+alexEOF = do return (EOFToken tokenPosnEmpty [])
+
+tailToken :: Alex Token
+tailToken = do return (TailToken tokenPosnEmpty [])
+
+adapt :: (TokenPosn -> Int -> String -> Alex Token) -> (AlexPosn,Char,String) -> Int -> Alex Token
+adapt f loc@(p@(AlexPn offset line col),_,inp) len =
+ (f (TokenPn offset line col) len inp)
+
+{-
+mkComment :: (AlexPosn,Char,String) -> Int -> Alex Token
+mkComment loc@(p@(AlexPn offset line col),_,inp) len = do
+ return (CommentToken (TokenPn offset line col) (take len inp))
+-}
-alexMove :: AlexPosn -> Char -> AlexPosn
-alexMove (AlexPn a l c) '\t' = AlexPn (a+1) l (((c+7) `div` 8)*8+1)
-alexMove (AlexPn a l _c) '\n' = AlexPn (a+1) (l+1) 1
-alexMove (AlexPn a l c) _ = AlexPn (a+1) l (c+1)
+toTokenPosn :: AlexPosn -> TokenPosn
+toTokenPosn (AlexPn offset line col) = (TokenPn offset line col)
-- ---------------------------------------------------------------------
-- a keyword or an identifier (the syntax overlaps)
-keywordOrIdent :: String -> AlexSpan -> P Token
+keywordOrIdent :: String -> TokenPosn -> Alex Token
keywordOrIdent str location
= return $ case Map.lookup str keywords of
- Just symbol -> symbol location str
- Nothing -> IdentifierToken location str
+ Just symbol -> symbol location str []
+ Nothing -> IdentifierToken location str []
-- mapping from strings to keywords
-keywords :: Map.Map String (AlexSpan -> String -> Token)
+--keywords :: Map.Map String (TokenPosn -> String -> Token)
+keywords :: Map.Map String (TokenPosn -> String -> [CommentAnnotation] -> Token)
keywords = Map.fromList keywordNames
-keywordNames :: [(String, AlexSpan -> String -> Token)]
+--keywordNames :: [(String, TokenPosn -> String -> Token)]
+keywordNames :: [(String, TokenPosn -> String -> [CommentAnnotation] -> Token)]
keywordNames =
[
("break",BreakToken),
View
16 src/Language/JavaScript/Parser.hs
@@ -6,23 +6,23 @@ module Language.JavaScript.Parser
, PA.showStripped
, PA.showStrippedMaybe
, JSNode(..)
- , SrcSpan(..)
- , AlexSpan(..)
, Node(..)
- , ParseError(..)
+ -- , ParseError(..)
-- Source locations
- , AlexPosn(..)
- -- ParserMonad
- , P
- , ParseState (..)
+ , TokenPosn(..)
+ , tokenPosnEmpty
+ -- * Pretty Printing
+ , renderJS
+ , renderToString
) where
import Language.JavaScript.Parser.AST
import Language.JavaScript.Parser.ParseError
import qualified Language.JavaScript.Parser.Parser as PA
-import Language.JavaScript.Parser.ParserMonad
+--import Language.JavaScript.Parser.ParserMonad
import Language.JavaScript.Parser.SrcLocation
+import Language.JavaScript.Pretty.Printer
-- EOF
View
206 src/Language/JavaScript/Parser/AST.hs
@@ -3,73 +3,82 @@ module Language.JavaScript.Parser.AST
(
Node (..)
, JSNode(..)
- , SrcSpan (..)
- , AlexPosn(..)
+ -- , TokenPosn (..)
, showStripped
) where
import Data.Data
import Data.List
-import Language.JavaScript.Parser.SrcLocation (SrcSpan(..), AlexPosn(..))
+import Language.JavaScript.Parser.SrcLocation (TokenPosn(..))
+import Language.JavaScript.Parser.Token
-- ---------------------------------------------------------------------
-data JSNode = NS Node SrcSpan
+-- |The JSNode is the building block of the AST.
+-- Each has a syntactic part 'Node'. In addition, the leaf elements
+-- (terminals) have a position 'TokenPosn', as well as an array of comments
+-- and/or whitespace that was collected while parsing.
+
+data JSNode = NN Node -- ^Non Terminal node, does not have any position or comment information
+ | NT Node TokenPosn [CommentAnnotation] -- ^Terminal node, including position and comment/whitespace information
deriving (Show, Eq, Read, Data, Typeable)
-data Node = JSArguments [[JSNode]]
- | JSArrayLiteral [JSNode]
- | JSBlock JSNode
- | JSBreak [JSNode] [JSNode]
- | JSCallExpression String [JSNode] -- type : ., (), []; rest
- | JSCase JSNode JSNode
- | JSCatch JSNode [JSNode] JSNode
- | JSContinue [JSNode]
- | JSDecimal String -- Was Integer
- | JSDefault JSNode
- | JSDoWhile JSNode JSNode 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] JSNode -- name, parameter list, body
- | JSHexInteger String -- Was Integer
- | JSIdentifier String
- | JSIf JSNode JSNode
- | JSIfElse JSNode JSNode JSNode
- | JSLabelled JSNode JSNode
+data Node =
+ -- | Terminals
+ JSIdentifier String
+ | JSDecimal String
| JSLiteral String
- | JSMemberDot [JSNode] JSNode
- | JSMemberSquare [JSNode] JSNode
- | JSObjectLiteral [JSNode]
- | JSOperator String
- | JSPropertyNameandValue JSNode [JSNode]
- | JSPropertyAccessor String JSNode [JSNode] JSNode
- | JSRegEx String
- | JSReturn [JSNode]
- | JSSourceElements [JSNode]
- | JSSourceElementsTop [JSNode]
- | JSStatementBlock JSNode
- | JSStatementList [JSNode]
+ | JSHexInteger String
| 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]
+ | JSRegEx String
+
+ -- | Non Terminals
+
+ | JSArguments JSNode [JSNode] JSNode -- ^lb, args, rb
+ | JSArrayLiteral JSNode [JSNode] JSNode -- ^lb, contents, rb
+ | JSBlock [JSNode] JSNode [JSNode] -- ^optional lb,block,optional rb
+ | JSBreak JSNode [JSNode] JSNode -- ^break, optional identifier, autosemi
+ | JSCallExpression String [JSNode] [JSNode] [JSNode] -- ^type : ., (), []; opening [ or ., contents, closing
+ | JSCase JSNode JSNode JSNode JSNode -- ^case,expr,colon,stmtlist
+ | JSCatch JSNode JSNode JSNode [JSNode] JSNode JSNode -- ^ catch,lb,ident,[if,expr],rb,block
+ | JSContinue JSNode [JSNode] JSNode -- ^continue,optional identifier,autosemi
+ | JSDefault JSNode JSNode JSNode -- ^default,colon,stmtlist
+ | JSDoWhile JSNode JSNode JSNode JSNode JSNode JSNode JSNode -- ^do,stmt,while,lb,expr,rb,autosemi
+ | JSElision JSNode -- ^comma
+ | JSExpression [JSNode] -- ^expression components
+ | JSExpressionBinary String [JSNode] JSNode [JSNode] -- ^what, lhs, op, rhs
+ | JSExpressionParen JSNode JSNode JSNode -- ^lb,expression,rb
+ | JSExpressionPostfix String [JSNode] JSNode -- ^type, expression, operator
+ | JSExpressionTernary [JSNode] JSNode [JSNode] JSNode [JSNode] -- ^cond, ?, trueval, :, falseval
+ | JSFinally JSNode JSNode -- ^finally,block
+ | JSFor JSNode JSNode [JSNode] JSNode [JSNode] JSNode [JSNode] JSNode JSNode -- ^for,lb,expr,semi,expr,semi,expr,rb.stmt
+ | JSForIn JSNode JSNode [JSNode] JSNode JSNode JSNode JSNode -- ^for,lb,expr,in,expr,rb,stmt
+ | JSForVar JSNode JSNode JSNode [JSNode] JSNode [JSNode] JSNode [JSNode] JSNode JSNode -- ^for,lb,var,vardecl,semi,expr,semi,expr,rb,stmt
+ | JSForVarIn JSNode JSNode JSNode JSNode JSNode JSNode JSNode JSNode -- ^for,lb,var,vardecl,in,expr,rb,stmt
+ | JSFunction JSNode JSNode JSNode [JSNode] JSNode JSNode JSNode JSNode -- ^fn,name, lb,parameter list,rb,lb,body,rb
+ | JSFunctionBody [JSNode] -- ^body
+ | JSFunctionExpression JSNode [JSNode] JSNode [JSNode] JSNode JSNode JSNode JSNode -- ^fn,[name],lb, parameter list,rb,lb, body,rb
+ | JSIf JSNode JSNode JSNode JSNode JSNode [JSNode] -- ^if,(,expr,),stmt,optional rest
+ | JSLabelled JSNode JSNode JSNode -- ^identifier,colon,stmt
+ | JSMemberDot [JSNode] JSNode JSNode -- ^firstpart, dot, name
+ | JSMemberSquare [JSNode] JSNode JSNode JSNode -- ^firstpart, lb, expr, rb
+ | JSObjectLiteral JSNode [JSNode] JSNode -- ^lbrace contents rbrace
+ | JSOperator JSNode -- ^opnode
+ | JSPropertyAccessor JSNode JSNode JSNode [JSNode] JSNode JSNode JSNode JSNode -- ^(get|set), name, lb, params, rb, lb, functionbody, rb
+ | JSPropertyNameandValue JSNode JSNode [JSNode] -- ^name, colon, value
+ | JSReturn JSNode [JSNode] JSNode -- ^return,optional expression,autosemi
+ | JSSourceElements [JSNode] -- ^source elements
+ | JSSourceElementsTop [JSNode] -- ^source elements
+ | JSStatementBlock JSNode JSNode JSNode -- ^lb,block,rb
+ | JSStatementList [JSNode] -- ^statements
+ | JSSwitch JSNode JSNode JSNode JSNode [JSNode] -- ^switch,lb,expr,rb,stmt
+ | JSThrow JSNode JSNode -- ^throw val
+ | JSTry JSNode JSNode [JSNode] -- ^try,block,rest
+ | JSUnary String JSNode -- ^type, operator
+ | JSVarDecl JSNode [JSNode] -- ^identifier, optional initializer
+ | JSVariables JSNode [JSNode] JSNode -- ^var|const, decl, autosemi
+ | JSWhile JSNode JSNode JSNode JSNode JSNode -- ^while,lb,expr,rb,stmt
+ | JSWith JSNode JSNode JSNode JSNode [JSNode] -- ^with,lb,expr,rb,stmt list
deriving (Show, Eq, Read, Data, Typeable)
-- Strip out the location info, leaving the original JSNode text representation
@@ -78,69 +87,64 @@ showStripped = ss
-- Alias for internal use
ss :: JSNode -> String
-ss (NS node _) = showStrippedNode node
+ss (NN node ) = showStrippedNode node
+ss (NT node _ _) = showStrippedNode node
sss :: [JSNode] -> String
--sss xs = "[" ++ (concatMap ss xs) ++ "]"
sss xs = "[" ++ (concat (intersperse "," $ map ss xs)) ++ "]"
-ssss :: [[JSNode]] -> String
---ssss xss = "[" ++ (concatMap sss xss) ++ "]"
-ssss xss = "[" ++ (concat (intersperse "," $ map sss xss)) ++ "]"
-
showStrippedNode :: Node -> String
-showStrippedNode (JSArguments xss) = "JSArguments " ++ ssss xss
-showStrippedNode (JSArrayLiteral xs) = "JSArrayLiteral " ++ sss xs
-showStrippedNode (JSBlock x) = "JSBlock (" ++ ss x ++ ")"
-showStrippedNode (JSBreak x1s x2s) = "JSBreak " ++ sss x1s ++ " " ++ sss x2s
-showStrippedNode (JSCallExpression s xs) = "JSCallExpression " ++ show s ++ " " ++ sss xs
-showStrippedNode (JSCase x1 x2) = "JSCase (" ++ ss x1 ++ ") (" ++ ss x2 ++ ")"
-showStrippedNode (JSCatch x1 x2s x3) = "JSCatch (" ++ ss x1 ++ ") " ++ sss x2s ++ " (" ++ ss x3 ++ ")"
-showStrippedNode (JSContinue xs) = "JSContinue " ++ sss xs
+showStrippedNode (JSArguments _lb xs _rb) = "JSArguments " ++ sss xs
+showStrippedNode (JSArrayLiteral _lb xs _rb) = "JSArrayLiteral " ++ sss xs
+showStrippedNode (JSBlock _lb x _rb) = "JSBlock (" ++ ss x ++ ")"
+showStrippedNode (JSBreak _b x1s as) = "JSBreak " ++ sss x1s ++ " " ++ ss as
+showStrippedNode (JSCallExpression s _os xs _cs) = "JSCallExpression " ++ show s ++ " " ++ sss xs
+showStrippedNode (JSCase _ca x1 _c x2) = "JSCase (" ++ ss x1 ++ ") (" ++ ss x2 ++ ")"
+showStrippedNode (JSCatch _c _lb x1 x2s _rb x3) = "JSCatch (" ++ ss x1 ++ ") " ++ sss x2s ++ " (" ++ ss x3 ++ ")"
+showStrippedNode (JSContinue _c xs as) = "JSContinue " ++ sss xs ++ " " ++ ss as
showStrippedNode (JSDecimal s) = "JSDecimal " ++ show s
-showStrippedNode (JSDefault x) = "JSDefault (" ++ ss x ++ ")"
-showStrippedNode (JSDoWhile x1 x2 x3) = "JSDoWhile (" ++ ss x1 ++ ") (" ++ ss x2 ++ ") (" ++ ss x3 ++ ")"
-showStrippedNode (JSElision xs) = "JSElision " ++ sss xs
-showStrippedNode (JSEmpty x) = "JSEmpty (" ++ ss x ++ ")"
+showStrippedNode (JSDefault _d _c x) = "JSDefault (" ++ ss x ++ ")"
+showStrippedNode (JSDoWhile _d x1 _w _lb x2 _rb x3) = "JSDoWhile (" ++ ss x1 ++ ") (" ++ ss x2 ++ ") (" ++ ss x3 ++ ")"
+showStrippedNode (JSElision c) = "JSElision " ++ ss c
showStrippedNode (JSExpression xs) = "JSExpression " ++ sss xs
-showStrippedNode (JSExpressionBinary s x2s x3s) = "JSExpressionBinary " ++ show s ++ " " ++ sss x2s ++ " " ++ sss x3s
-showStrippedNode (JSExpressionParen x) = "JSExpressionParen (" ++ ss x ++ ")"
-showStrippedNode (JSExpressionPostfix s xs) = "JSExpressionPostfix " ++ show s ++ " " ++ sss xs
-showStrippedNode (JSExpressionTernary x1s x2s x3s) = "JSExpressionTernary " ++ sss x1s ++ " " ++ sss x2s ++ " " ++ sss x3s
-showStrippedNode (JSFinally x) = "JSFinally (" ++ ss x ++ ")"
-showStrippedNode (JSFor x1s x2s x3s x4) = "JSFor " ++ sss x1s ++ " " ++ sss x2s ++ " " ++ sss x3s ++ " (" ++ ss x4 ++ ")"
-showStrippedNode (JSForIn x1s x2 x3) = "JSForIn " ++ sss x1s ++ " (" ++ ss x2 ++ ") (" ++ ss x3 ++ ")"
-showStrippedNode (JSForVar x1s x2s x3s x4) = "JSForVar " ++ sss x1s ++ " " ++ sss x2s ++ " " ++ sss x3s ++ " (" ++ ss x4 ++ ")"
-showStrippedNode (JSForVarIn x1 x2 x3) = "JSForVarIn (" ++ ss x1 ++ ") (" ++ ss x2 ++ ") (" ++ ss x3 ++ ")"
-showStrippedNode (JSFunction x1 x2s x3) = "JSFunction (" ++ ss x1 ++ ") " ++ sss x2s ++ " (" ++ ss x3 ++ ")"
+showStrippedNode (JSExpressionBinary s x2s _op x3s) = "JSExpressionBinary " ++ show s ++ " " ++ sss x2s ++ " " ++ sss x3s
+showStrippedNode (JSExpressionParen _lp x _rp) = "JSExpressionParen (" ++ ss x ++ ")"
+showStrippedNode (JSExpressionPostfix s xs _op) = "JSExpressionPostfix " ++ show s ++ " " ++ sss xs
+showStrippedNode (JSExpressionTernary x1s _q x2s _c x3s) = "JSExpressionTernary " ++ sss x1s ++ " " ++ sss x2s ++ " " ++ sss x3s
+showStrippedNode (JSFinally _f x) = "JSFinally (" ++ ss x ++ ")"
+showStrippedNode (JSFor _f _lb x1s _s1 x2s _s2 x3s _rb x4) = "JSFor " ++ sss x1s ++ " " ++ sss x2s ++ " " ++ sss x3s ++ " (" ++ ss x4 ++ ")"
+showStrippedNode (JSForIn _f _lb x1s _i x2 _rb x3) = "JSForIn " ++ sss x1s ++ " (" ++ ss x2 ++ ") (" ++ ss x3 ++ ")"
+showStrippedNode (JSForVar _f _lb _v x1s _s1 x2s _s2 x3s _rb x4) = "JSForVar " ++ sss x1s ++ " " ++ sss x2s ++ " " ++ sss x3s ++ " (" ++ ss x4 ++ ")"
+showStrippedNode (JSForVarIn _f _lb _v x1 _i x2 _rb x3) = "JSForVarIn (" ++ ss x1 ++ ") (" ++ ss x2 ++ ") (" ++ ss x3 ++ ")"
+showStrippedNode (JSFunction _f x1 _lb x2s _rb _lb2 x3 _rb2) = "JSFunction (" ++ ss x1 ++ ") " ++ sss x2s ++ " (" ++ ss x3 ++ ")"
showStrippedNode (JSFunctionBody xs) = "JSFunctionBody " ++ sss xs
-showStrippedNode (JSFunctionExpression x1s x2s x3) = "JSFunctionExpression " ++ sss x1s ++ " " ++ sss x2s ++ " (" ++ ss x3 ++ ")"
+showStrippedNode (JSFunctionExpression _f x1s _lb x2s _rb _lb2 x3 _rb2) = "JSFunctionExpression " ++ sss x1s ++ " " ++ sss x2s ++ " (" ++ ss x3 ++ ")"
showStrippedNode (JSHexInteger s) = "JSHexInteger " ++ show s
showStrippedNode (JSIdentifier s) = "JSIdentifier " ++ show s
-showStrippedNode (JSIf x1 x2) = "JSIf (" ++ ss x1 ++ ") (" ++ ss x2 ++ ")"
-showStrippedNode (JSIfElse x1 x2 x3) = "JSIfElse (" ++ ss x1 ++ ") (" ++ ss x2 ++ ") (" ++ ss x3 ++ ")"
-showStrippedNode (JSLabelled x1 x2) = "JSLabelled (" ++ ss x1 ++ ") (" ++ ss x2 ++ ")"
+showStrippedNode (JSIf _i _lb x1 _rb x2 x3s) = "JSIf (" ++ ss x1 ++ ") (" ++ ss x2 ++ ") (" ++ sss x3s ++ ")"
+showStrippedNode (JSLabelled x1 _c x2) = "JSLabelled (" ++ ss x1 ++ ") (" ++ ss x2 ++ ")"
showStrippedNode (JSLiteral s) = "JSLiteral " ++ show s
-showStrippedNode (JSMemberDot x1s x2) = "JSMemberDot " ++ sss x1s ++ " (" ++ ss x2 ++ ")"
-showStrippedNode (JSMemberSquare x1s x2) = "JSMemberSquare " ++ sss x1s ++ " (" ++ ss x2 ++ ")"
-showStrippedNode (JSObjectLiteral xs) = "JSObjectLiteral " ++ sss xs
-showStrippedNode (JSOperator s) = "JSOperator " ++ show s
-showStrippedNode (JSPropertyNameandValue x1 x2s) = "JSPropertyNameandValue (" ++ ss x1 ++ ") " ++ sss x2s
-showStrippedNode (JSPropertyAccessor s x1 x2s x3) = "JSPropertyAccessor " ++ show s ++ " (" ++ ss x1 ++ ") " ++ sss x2s ++ " (" ++ ss x3 ++ ")"
+showStrippedNode (JSMemberDot x1s _d x2 ) = "JSMemberDot " ++ sss x1s ++ " (" ++ ss x2 ++ ")"
+showStrippedNode (JSMemberSquare x1s _lb x2 _rb) = "JSMemberSquare " ++ sss x1s ++ " (" ++ ss x2 ++ ")"
+showStrippedNode (JSObjectLiteral _lb xs _rb) = "JSObjectLiteral " ++ sss xs
+showStrippedNode (JSOperator n) = "JSOperator " ++ ss n
+showStrippedNode (JSPropertyNameandValue x1 _colon x2s) = "JSPropertyNameandValue (" ++ ss x1 ++ ") " ++ sss x2s
+showStrippedNode (JSPropertyAccessor s x1 _lb1 x2s _rb1 _lb2 x3 _rb2) = "JSPropertyAccessor " ++ show s ++ " (" ++ ss x1 ++ ") " ++ sss x2s ++ " (" ++ ss x3 ++ ")"
showStrippedNode (JSRegEx s) = "JSRegEx " ++ show s
-showStrippedNode (JSReturn xs) = "JSReturn " ++ sss xs
+showStrippedNode (JSReturn _r xs as) = "JSReturn " ++ sss xs ++ " " ++ ss as
showStrippedNode (JSSourceElements xs) = "JSSourceElements " ++ sss xs
showStrippedNode (JSSourceElementsTop xs) = "JSSourceElementsTop " ++ sss xs
-showStrippedNode (JSStatementBlock x) = "JSStatementBlock (" ++ ss x ++ ")"
+showStrippedNode (JSStatementBlock _lb x _rb) = "JSStatementBlock (" ++ ss x ++ ")"
showStrippedNode (JSStatementList xs) = "JSStatementList " ++ sss xs
showStrippedNode (JSStringLiteral c s) = "JSStringLiteral " ++ show c ++ " " ++ show s
-showStrippedNode (JSSwitch x x2s) = "JSSwitch (" ++ ss x ++ ") " ++ sss x2s
-showStrippedNode (JSThrow x) = "JSThrow (" ++ ss x ++ ")"
-showStrippedNode (JSTry x1 x2s) = "JSTry (" ++ ss x1 ++ ") " ++ sss x2s
-showStrippedNode (JSUnary s) = "JSUnary " ++ show s
+showStrippedNode (JSSwitch _s _lb x _rb x2s) = "JSSwitch (" ++ ss x ++ ") " ++ sss x2s
+showStrippedNode (JSThrow _t x) = "JSThrow (" ++ ss x ++ ")"
+showStrippedNode (JSTry _t x1 x2s) = "JSTry (" ++ ss x1 ++ ") " ++ sss x2s
+showStrippedNode (JSUnary s _x) = "JSUnary " ++ show s
showStrippedNode (JSVarDecl x1 x2s) = "JSVarDecl (" ++ ss x1 ++ ") " ++ sss x2s
-showStrippedNode (JSVariables s xs) = "JSVariables " ++ show s ++ " " ++ sss xs
-showStrippedNode (JSWhile x1 x2) = "JSWhile (" ++ ss x1 ++ ") (" ++ ss x2 ++ ")"
-showStrippedNode (JSWith x1 x2s) = "JSWith (" ++ ss x1 ++ ") " ++ sss x2s
+showStrippedNode (JSVariables n xs _as) = "JSVariables " ++ ss n ++ " " ++ sss xs
+showStrippedNode (JSWhile _w _lb x1 _rb x2) = "JSWhile (" ++ ss x1 ++ ") (" ++ ss x2 ++ ")"
+showStrippedNode (JSWith _w _lb x1 _rb x2s) = "JSWith (" ++ ss x1 ++ ") " ++ sss x2s
-- EOF
View
214 src/Language/JavaScript/Parser/Grammar.y
@@ -10,7 +10,7 @@ import Control.Monad.Error.Class (throwError)
import Data.Char
import Language.JavaScript.Parser.Lexer
import Language.JavaScript.Parser.ParserMonad
-import Language.JavaScript.Parser.SrcLocation
+--import Language.JavaScript.Parser.SrcLocation
import qualified Language.JavaScript.Parser.AST as AST
}
@@ -27,7 +27,7 @@ import qualified Language.JavaScript.Parser.AST as AST
%lexer { lexCont } { EOFToken {} }
-%token
+%token
';' { SemiColonToken {} }
',' { CommaToken {} }
@@ -67,7 +67,7 @@ import qualified Language.JavaScript.Parser.AST as AST
'(' { LeftParenToken {} }
')' { RightParenToken {} }
'@*/' { CondcommentEndToken {} }
-
+
'break' { BreakToken {} }
'case' { CaseToken {} }
'catch' { CatchToken {} }
@@ -99,8 +99,8 @@ import qualified Language.JavaScript.Parser.AST as AST
'void' { VoidToken {} }
'while' { WhileToken {} }
'with' { WithToken {} }
-
-
+
+
'ident' { IdentifierToken {} }
'decimal' { DecimalToken {} }
'hexinteger' { HexIntegerToken {} }
@@ -123,13 +123,13 @@ import qualified Language.JavaScript.Parser.AST as AST
-- "Start Symbol" = <Program>
-- "Case Sensitive" = 'True'
-
+
-- ! ------------------------------------------------- Sets
-- {ID Head} = {Letter} + [_] + [$]
-- {ID Tail} = {Alphanumeric} + [_] + [$]
--- {String Chars1} = {Printable} + {HT} - ["\]
--- {String Chars2} = {Printable} + {HT} - [\'']
+-- {String Chars1} = {Printable} + {HT} - ["\]
+-- {String Chars2} = {Printable} + {HT} - [\'']
-- {Hex Digit} = {Digit} + [ABCDEF] + [abcdef]
-- {RegExp Chars} = {Letter}+{Digit}+['^']+['$']+['*']+['+']+['?']+['{']+['}']+['|']+['-']+['.']+[',']+['#']+['[']+[']']+['_']+['<']+['>']
-- {Non Terminator} = {String Chars1} - {CR} - {LF}
@@ -159,7 +159,7 @@ import qualified Language.JavaScript.Parser.AST as AST
AutoSemi : ';' { AST.JSLiteral ";"}
| { AST.JSLiteral ""}
-
+
-- ---------------------------------------------------------------------
-- <Literal> ::= <Null Literal>
@@ -184,12 +184,12 @@ NumericLiteral : 'decimal' { AST.JSDecimal (token_literal $1)}
StringLiteral : 'string' {AST.JSStringLiteral (token_delimiter $1) (token_literal $1)}
--- <Regular Expression Literal> ::= RegExp
+-- <Regular Expression Literal> ::= RegExp
RegularExpressionLiteral : 'regex' {AST.JSRegEx (token_literal $1)}
-- <Primary Expression> ::= 'this'
-- | Identifier
--- | <Literal>
+-- | <Literal>
-- | <Array Literal>
-- | <Object Literal>
-- | '(' <Expression> ')'
@@ -202,7 +202,7 @@ PrimaryExpression : 'this' { AST.JSLiteral "this" }
| ObjectLiteral { $1 {- PrimaryExpression4 -}}
| '(' Expression ')' { AST.JSExpressionParen $2 }
| RegularExpressionLiteral { $1 {- PrimaryExpression5 -}} -- Not in ECMA ed 5?
-
+
Identifier : 'ident' { AST.JSIdentifier (token_literal $1) }
-- <Array Literal> ::= '[' ']'
@@ -237,18 +237,18 @@ ObjectLiteral : '{' PropertyNameandValueList '}' { AST.JSObjectLiteral $2 }
-- <Property Name and Value List> ::= <Property Name> ':' <Assignment Expression>
-- | <Property Name and Value List> ',' <Property Name> ':' <Assignment Expression>
--- Seems we can have function declarations in the value part too
+-- Seems we can have function declarations in the value part too
-- TODO: And can end with a comma
PropertyNameandValueList :: { [ AST.JSNode ] }
PropertyNameandValueList : PropertyName ':' AssignmentExpression { [(AST.JSPropertyNameandValue $1 $3)] }
| PropertyName ':' FunctionDeclaration { [(AST.JSPropertyNameandValue $1 [$3])] }
- | PropertyNameandValueList ',' PropertyName ':' AssignmentExpression
- { ($1 ++ [(AST.JSPropertyNameandValue $3 $5)]) }
- | PropertyNameandValueList ',' PropertyName ':' FunctionDeclaration
- { ($1 ++ [(AST.JSPropertyNameandValue $3 [$5])]) }
- | PropertyNameandValueList ','
- { ($1 ++ [(AST.JSLiteral ",")]) }
- | { [] }
+ | PropertyNameandValueList ',' PropertyName ':' AssignmentExpression
+ { ($1 ++ [(AST.JSPropertyNameandValue $3 $5)]) }
+ | PropertyNameandValueList ',' PropertyName ':' FunctionDeclaration
+ { ($1 ++ [(AST.JSPropertyNameandValue $3 [$5])]) }
+ | PropertyNameandValueList ','
+ { ($1 ++ [(AST.JSLiteral ",")]) }
+ | { [] }
-- <Property Name> ::= Identifier
@@ -264,23 +264,23 @@ PropertyName : Identifier { $1 {- PropertyName1 -}}
-- | <Member Expression> '.' Identifier
-- | 'new' <Member Expression> <Arguments>
MemberExpression :: { [AST.JSNode] }
-MemberExpression : PrimaryExpression { [$1] {- MemberExpression -}}
+MemberExpression : PrimaryExpression { [$1] {- MemberExpression -}}
| FunctionExpression { [$1] {- MemberExpression -}}
| MemberExpression '[' Expression ']' { [AST.JSMemberSquare $1 $3] }
- | MemberExpression '.' Identifier { [AST.JSMemberDot $1 $3] }
+ | MemberExpression '.' Identifier { [AST.JSMemberDot $1 $3] }
| 'new' MemberExpression Arguments { (((AST.JSLiteral "new "):$2)++[$3])}
-- <New Expression> ::= <Member Expression>
-- | new <New Expression>
-NewExpression : MemberExpression {$1 {- NewExpression -}}
+NewExpression : MemberExpression {$1 {- NewExpression -}}
| 'new' NewExpression { (AST.JSLiteral "new "):$2 }
-- <Call Expression> ::= <Member Expression> <Arguments>
--- | <Call Expression> <Arguments>
+-- | <Call Expression> <Arguments>
-- | <Call Expression> '[' <Expression> ']'