git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Allow definition of objects with unusual property names, as well as row types.
6691b8aPhil Freeman
examples/passing/Objects.purs+5
@@ -18,5 +18,10 @@ module Main where
18 test2 = \x -> x."!@#"
18 test2 = \x -> x."!@#"
19
19
20 test3 = typed."foo"
20 test3 = typed."foo"
21+
22+ test4 = test2 weirdObj
23+ where
24+ weirdObj :: { "!@#" :: Number }
25+ weirdObj = { "!@#": 1 }
21
26
22 main = Debug.Trace.trace "Done"
27 main = Debug.Trace.trace "Done"
src/Language/PureScript/CodeGen/Common.hs+7
@@ -130,5 +130,12 @@ nameIsJsReserved name =
130 , "with"
130 , "with"
131 , "yield" ]
131 , "yield" ]
132
132
133+-- |
134+-- Test if a string is a valid JS identifier (may return false negatives)
135+--
136+isIdent :: String -> Bool
137+isIdent s@(first : rest) | not (nameIsJsReserved s) && isAlpha first && all isAlphaNum rest = True
138+isIdent _ = False
139+
133moduleNameToJs :: ModuleName -> String
140moduleNameToJs :: ModuleName -> String
134moduleNameToJs (ModuleName pns) = intercalate "_" (runProperName `map` pns)
141moduleNameToJs (ModuleName pns) = intercalate "_" (runProperName `map` pns)
src/Language/PureScript/CodeGen/JS.hs+2−6
@@ -19,10 +19,10 @@ module Language.PureScript.CodeGen.JS (
19 module AST,
19 module AST,
20 declToJs,
20 declToJs,
21 moduleToJs,
21 moduleToJs,
22− wrapExportsContainer
22+ wrapExportsContainer,
23+ isIdent
23) where
24) where
24
25
25−import Data.Char (isAlpha, isAlphaNum)
26import Data.Maybe (fromMaybe, mapMaybe)
26import Data.Maybe (fromMaybe, mapMaybe)
27import Data.Function (on)
27import Data.Function (on)
28
28
@@ -145,10 +145,6 @@ valueToJs opts m e (PositionedValue _ val) = valueToJs opts m e val
145valueToJs _ _ _ (TypeClassDictionary _ _) = error "Type class dictionary was not replaced"
145valueToJs _ _ _ (TypeClassDictionary _ _) = error "Type class dictionary was not replaced"
146valueToJs _ _ _ _ = error "Invalid argument to valueToJs"
146valueToJs _ _ _ _ = error "Invalid argument to valueToJs"
147
147
148−isIdent :: String -> Bool
149−isIdent (first : rest) | isAlpha first && all isAlphaNum rest = True
150−isIdent _ = False
151−
152-- |
148-- |
153-- Shallow copy an object.
149-- Shallow copy an object.
154--
150--
src/Language/PureScript/Parser/Declarations.hs+2−2
@@ -227,7 +227,7 @@ parseObjectLiteral :: P.Parsec String ParseState Value
227parseObjectLiteral = ObjectLiteral <$> C.braces (C.commaSep parseIdentifierAndValue)
227parseObjectLiteral = ObjectLiteral <$> C.braces (C.commaSep parseIdentifierAndValue)
228
228
229parseIdentifierAndValue :: P.Parsec String ParseState (String, Value)
229parseIdentifierAndValue :: P.Parsec String ParseState (String, Value)
230−parseIdentifierAndValue = (,) <$> (C.indented *> C.identifier <* C.indented <* C.colon)
230+parseIdentifierAndValue = (,) <$> (C.indented *> (C.identifier <|> C.stringLiteral) <* C.indented <* C.colon)
231 <*> (C.indented *> parseValue)
231 <*> (C.indented *> parseValue)
232
232
233parseAbs :: P.Parsec String ParseState Value
233parseAbs :: P.Parsec String ParseState Value
@@ -290,7 +290,7 @@ parseValueAtom = P.choice
290
290
291parsePropertyUpdate :: P.Parsec String ParseState (String, Value)
291parsePropertyUpdate :: P.Parsec String ParseState (String, Value)
292parsePropertyUpdate = do
292parsePropertyUpdate = do
293− name <- C.lexeme C.identifier
293+ name <- C.lexeme (C.identifier <|> C.stringLiteral)
294 _ <- C.lexeme $ C.indented *> P.char '='
294 _ <- C.lexeme $ C.indented *> P.char '='
295 value <- C.indented *> parseValue
295 value <- C.indented *> parseValue
296 return (name, value)
296 return (name, value)
src/Language/PureScript/Parser/Types.hs+1−1
@@ -118,7 +118,7 @@ parsePolyType :: P.Parsec String ParseState Type
118parsePolyType = parseAnyType
118parsePolyType = parseAnyType
119
119
120parseNameAndType :: P.Parsec String ParseState t -> P.Parsec String ParseState (String, t)
120parseNameAndType :: P.Parsec String ParseState t -> P.Parsec String ParseState (String, t)
121−parseNameAndType p = (,) <$> (indented *> identifier <* indented <* lexeme (P.string "::")) <*> p
121+parseNameAndType p = (,) <$> (indented *> (identifier <|> stringLiteral) <* indented <* lexeme (P.string "::")) <*> p
122
122
123parseRowEnding :: P.Parsec String ParseState Type
123parseRowEnding :: P.Parsec String ParseState Type
124parseRowEnding = P.option REmpty (TypeVar <$> (lexeme (indented *> P.char '|') *> indented *> identifier))
124parseRowEnding = P.option REmpty (TypeVar <$> (lexeme (indented *> P.char '|') *> indented *> identifier))
src/Language/PureScript/Pretty/JS.hs+6−1
@@ -18,6 +18,7 @@ module Language.PureScript.Pretty.JS (
18) where
18) where
19
19
20import Language.PureScript.Pretty.Common
20import Language.PureScript.Pretty.Common
21+import Language.PureScript.CodeGen.JS (isIdent)
21import Language.PureScript.CodeGen.JS.AST
22import Language.PureScript.CodeGen.JS.AST
22
23
23import Data.List
24import Data.List
@@ -46,13 +47,17 @@ literals = mkPattern' match
46 match (JSObjectLiteral ps) = fmap concat $ sequence
47 match (JSObjectLiteral ps) = fmap concat $ sequence
47 [ return "{\n"
48 [ return "{\n"
48 , withIndent $ do
49 , withIndent $ do
49− jss <- forM ps $ \(key, value) -> fmap ((key ++ ": ") ++) . prettyPrintJS' $ value
50+ jss <- forM ps $ \(key, value) -> fmap ((objectPropertyToString key ++ ": ") ++) . prettyPrintJS' $ value
50 indentString <- currentIndent
51 indentString <- currentIndent
51 return $ intercalate ", \n" $ map (indentString ++) jss
52 return $ intercalate ", \n" $ map (indentString ++) jss
52 , return "\n"
53 , return "\n"
53 , currentIndent
54 , currentIndent
54 , return "}"
55 , return "}"
55 ]
56 ]
57+ where
58+ objectPropertyToString :: String -> String
59+ objectPropertyToString s | isIdent s = s
60+ | otherwise = show s
56 match (JSBlock sts) = fmap concat $ sequence
61 match (JSBlock sts) = fmap concat $ sequence
57 [ return "{\n"
62 [ return "{\n"
58 , withIndent $ prettyStatements sts
63 , withIndent $ prettyStatements sts