git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Allow JS reserved identifiers
commit29fdee5134ba0fc511af5cb839a585df8572a4a1 authorGary Burgess <garyb@users.noreply.github.com> dateThu 6 Feb 2014, 20:48 (13 years ago) parent6019f26
6 files changed+156−78
examples/passing/JSReserved.purs+30 src/Language/PureScript/Parser/Common.hs+106−68 src/Language/PureScript/Parser/Declarations.hs+3−3 src/Language/PureScript/Parser/JS.hs+11−4 src/Language/PureScript/Parser/Types.hs+4−1 src/Language/PureScript/Parser/Values.hs+2−2
examples/passing/JSReserved.pursnew file+30
@@ -0,0 +1,30 @@
1+module Main where
2+
3+ import Prelude
4+
5+ const = "test"
6+ member = "test"
7+
8+ fortest = {
9+ var return = 0;
10+ for (i <- 0 until 10) {
11+ return = return + i;
12+ }
13+ return return;
14+ }
15+
16+ whiletest = {
17+ var for = 0;
18+ while (for > 0) {
19+ for = for - 1;
20+ }
21+ return for;
22+ }
23+
24+ vartest = {
25+ var var = 1;
26+ var = var + 1;
27+ return var;
28+ }
29+
30+ main = Trace.trace "Done"
src/Language/PureScript/Parser/Common.hs+106−68
@@ -27,60 +27,106 @@ import qualified Text.Parsec.Token as PT
2727import Language.PureScript.Names
2828
2929-- |
30−-- A list of reserved identifiers
31−--
32−reservedNames :: [String]
33−reservedNames = [ "case"
34− , "of"
35− , "data"
36− , "type"
37− , "var"
38− , "val"
39− , "while"
40− , "for"
41− , "foreach"
42− , "if"
43− , "then"
44− , "else"
45− , "return"
46− , "true"
47− , "false"
48− , "foreign"
49− , "import"
50− , "member"
51− , "forall"
52− , "do"
53− , "until"
54− , "in"
55− , "break"
56− , "catch"
57− , "continue"
58− , "debugger"
59− , "default"
60− , "delete"
61− , "finally"
62− , "function"
63− , "instanceof"
64− , "new"
65− , "switch"
66− , "this"
67− , "throw"
68− , "try"
69− , "typeof"
70− , "void"
71− , "with"
72− , "Number"
73− , "String"
74− , "Boolean"
75− , "infixl"
76− , "infixr"
77− , "module"
78− , "let"
79− , "class"
80− , "instance"
81− , "where"
82− , "null"
83− , "undefined" ]
30+-- A list of purescript reserved identifiers
31+--
32+reservedPsNames :: [String]
33+reservedPsNames = [ "data"
34+ , "type"
35+ , "foreign"
36+ , "import"
37+ , "infixl"
38+ , "infixr"
39+ , "class"
40+ , "instance"
41+ , "module"
42+ , "case"
43+ , "of"
44+ , "if"
45+ , "then"
46+ , "else"
47+ , "do"
48+ , "let"
49+ , "true"
50+ , "false"
51+ , "until"
52+ ]
53+
54+-- |
55+-- A list of javascript reserved identifiers
56+--
57+reservedJsNames :: [String]
58+reservedJsNames = [ "abstract"
59+ , "boolean"
60+ , "break"
61+ , "byte"
62+ , "case"
63+ , "catch"
64+ , "char"
65+ , "class"
66+ , "const"
67+ , "continue"
68+ , "debugger"
69+ , "default"
70+ , "delete"
71+ , "do"
72+ , "double"
73+ , "else"
74+ , "enum"
75+ , "export"
76+ , "extends"
77+ , "final"
78+ , "finally"
79+ , "float"
80+ , "for"
81+ , "function"
82+ , "goto"
83+ , "if"
84+ , "implements"
85+ , "import"
86+ , "in"
87+ , "instanceof"
88+ , "int"
89+ , "interface"
90+ , "let"
91+ , "long"
92+ , "native"
93+ , "new"
94+ , "package"
95+ , "private"
96+ , "protected"
97+ , "public"
98+ , "return"
99+ , "short"
100+ , "static"
101+ , "super"
102+ , "switch"
103+ , "synchronized"
104+ , "this"
105+ , "throw"
106+ , "throws"
107+ , "transient"
108+ , "try"
109+ , "typeof"
110+ , "var"
111+ , "void"
112+ , "volatile"
113+ , "while"
114+ , "with"
115+ , "yield" ]
116+
117+-- |
118+-- A list of reserved identifiers for types
119+--
120+reservedTypeNames :: [String]
121+reservedTypeNames = [ "forall"
122+ , "where" ]
123+
124+-- |
125+-- A list of reserved identifiers for block statements
126+--
127+reservedStatementNames :: [String]
128+reservedStatementNames = [ "for"
129+ , "return" ]
84130
85131-- |
86132-- A list of reserved operators
@@ -123,7 +169,7 @@ opLetter = P.oneOf ":!#$%&*+./<=>?@\\^|-~"
123169--
124170langDef :: PT.GenLanguageDef String u Identity
125171langDef = PT.LanguageDef
126− { PT.reservedNames = reservedNames
172+ { PT.reservedNames = reservedPsNames
127173 , PT.reservedOpNames = reservedOpNames
128174 , PT.commentStart = "{-"
129175 , PT.commentEnd = "-}"
@@ -253,20 +299,12 @@ integerOrFloat = (Left <$> P.try (PT.natural tokenParser) <|>
253299-- Parse an identifier or parenthesized operator
254300--
255301parseIdent :: P.Parsec String ParseState Ident
256−parseIdent = (Ident <$> identifier) <|> (Op <$> parens operator)
257−
258−
259−-- |
260−-- Parse an identifier or parenthesized operator that is not a reserved keyword or operator
261−--
262−parseNonReservedIdent :: P.Parsec String ParseState Ident
263−parseNonReservedIdent = do
264− ident <- parseIdent
265− when (isReserved ident) $ P.unexpected $ "reserved identifier " ++ show ident
266− return ident
302+parseIdent = parseIdent' <|> (Op <$> parens operator)
267303 where
268− isReserved (Ident ident) = ident `elem` reservedNames
269− isReserved (Op op) = op `elem` reservedOpNames
304+ parseIdent' :: P.Parsec String ParseState Ident
305+ parseIdent' = do
306+ ident <- identifier
307+ return $ if (ident `elem` reservedJsNames) then (Escaped $ "$" ++ ident) else (Ident ident)
270308
271309-- |
272310-- Parse a token inside square brackets
src/Language/PureScript/Parser/Declarations.hs+3−3
@@ -46,7 +46,7 @@ parseDataDeclaration = do
4646
4747parseTypeDeclaration :: P.Parsec String ParseState Declaration
4848parseTypeDeclaration =
49− TypeDeclaration <$> P.try (parseNonReservedIdent <* lexeme (indented *> P.string "::"))
49+ TypeDeclaration <$> P.try (parseIdent <* lexeme (indented *> P.string "::"))
5050 <*> parsePolyType
5151
5252parseTypeSynonymDeclaration :: P.Parsec String ParseState Declaration
@@ -57,7 +57,7 @@ parseTypeSynonymDeclaration =
5757
5858parseValueDeclaration :: P.Parsec String ParseState Declaration
5959parseValueDeclaration =
60− ValueDeclaration <$> parseNonReservedIdent
60+ ValueDeclaration <$> parseIdent
6161 <*> P.many parseBinderNoParens
6262 <*> P.optionMaybe parseGuard
6363 <*> ((lexeme (indented *> P.char '=')) *> parseValue)
@@ -66,7 +66,7 @@ parseExternDeclaration :: P.Parsec String ParseState Declaration
6666parseExternDeclaration = P.try (reserved "foreign") *> indented *> (reserved "import") *> indented *>
6767 (ExternDataDeclaration <$> (P.try (reserved "data") *> indented *> properName)
6868 <*> (lexeme (indented *> P.string "::") *> parseKind)
69− <|> do ident <- parseNonReservedIdent
69+ <|> do ident <- parseIdent
7070 js <- P.optionMaybe (parseJSLiteral <$> stringLiteral)
7171 ty <- (lexeme (indented *> P.string "::") *> parsePolyType)
7272 return $ ExternDeclaration (if isJust js then InlineJavascript else ForeignImport) ident js ty)
src/Language/PureScript/Parser/JS.hs+11−4
@@ -22,6 +22,7 @@ import Language.PureScript.Names
2222import Language.PureScript.CodeGen.JS.AST
2323import qualified Language.PureScript.Parser.Common as C
2424import Control.Applicative
25+import Control.Monad
2526import Data.Functor.Identity
2627import qualified Text.Parsec as P
2728import qualified Text.Parsec.Token as P
@@ -46,14 +47,20 @@ parseObjectLiteral :: P.Parsec String u JS
4647parseObjectLiteral = JSObjectLiteral <$> P.braces C.tokenParser (P.commaSep C.tokenParser parseIdentifierAndValue)
4748
4849parseIdentifierAndValue :: P.Parsec String u (String, JS)
49−parseIdentifierAndValue = (,) <$> (C.identifier <* C.colon)
50+parseIdentifierAndValue = (,) <$> (identifier <* C.colon)
5051 <*> parseJS
5152
53+identifier :: P.Parsec String u String
54+identifier = do
55+ ident <- C.identifier
56+ when (ident `elem` C.reservedJsNames) $ P.unexpected $ ("reserved identifier " ++ show ident)
57+ return ident
58+
5259parseFunction :: P.Parsec String u JS
5360parseFunction = do
5461 C.reserved "function"
5562 name <- P.optionMaybe C.identifier
56− args <- P.parens C.tokenParser $ P.commaSep C.tokenParser C.identifier
63+ args <- P.parens C.tokenParser $ P.commaSep C.tokenParser identifier
5764 body <- parseJS
5865 return $ JSFunction name args body
5966
@@ -61,7 +68,7 @@ parseBlock :: P.Parsec String u JS
6168parseBlock = JSBlock <$> P.braces C.tokenParser (P.many parseJS)
6269
6370parseVar :: P.Parsec String u JS
64−parseVar = JSVar <$> C.identifier
71+parseVar = JSVar <$> identifier
6572
6673parseJSAtom :: P.Parsec String u JS
6774parseJSAtom = P.choice
@@ -80,7 +87,7 @@ parseJSAtom = P.choice
8087 , P.parens C.tokenParser parseJS ]
8188
8289parseAccessor :: JS -> P.Parsec String u JS
83−parseAccessor js = P.try $ flip JSAccessor js <$> (C.dot *> P.notFollowedBy C.opLetter *> C.identifier)
90+parseAccessor js = P.try $ flip JSAccessor js <$> (C.dot *> P.notFollowedBy C.opLetter *> identifier)
8491
8592parseIndexer :: JS -> P.Parsec String u JS
8693parseIndexer js = P.try $ flip JSIndexer js <$> (P.squares C.tokenParser parseJS)
src/Language/PureScript/Parser/Types.hs+4−1
@@ -48,7 +48,10 @@ parseObject :: P.Parsec String ParseState Type
4848parseObject = braces $ Object <$> parseRow False
4949
5050parseTypeVariable :: P.Parsec String ParseState Type
51−parseTypeVariable = TypeVar <$> identifier
51+parseTypeVariable = do
52+ ident <- identifier
53+ when (ident `elem` reservedTypeNames) $ P.unexpected $ ident
54+ return $ TypeVar ident
5255
5356parseTypeConstructor :: P.Parsec String ParseState Type
5457parseTypeConstructor = TypeConstructor <$> parseQualified properName
src/Language/PureScript/Parser/Values.hs+2−2
@@ -209,8 +209,8 @@ parseReturn = Return <$> (C.reserved "return" *> parseValue <* C.indented <* C.s
209209--
210210parseStatement :: P.Parsec String ParseState Statement
211211parseStatement = P.choice
212− [ parseVariableIntroduction
213− , parseAssignment
212+ [ parseAssignment
213+ , parseVariableIntroduction
214214 , parseWhile
215215 , parseFor
216216 , parseIf