git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Guards, named patterns, fixed array patterns
commit0c57401678e60342257b4261002b23e758193bf4 authorPhil Freeman <paf31@cantab.net> dateSat 26 Oct 2013, 14:49 (13 years ago) parent80a4d8e
6 files changed+45−5
examples/Guards.ps+3 examples/NamedPatterns.ps+6 src/PureScript/CodeGen/JS.hs+8−1 src/PureScript/Parser/Values.hs+14−2 src/PureScript/TypeChecker/Types.hs+9 src/PureScript/Values.hs+5−2
examples/Guards.psnew file+3
@@ -0,0 +1,3 @@
1+collatz = \x -> case x of
2+ y | y % 2 == 0 -> y / 2
3+ y -> y * 3 + 1
examples/NamedPatterns.psnew file+6
@@ -0,0 +1,6 @@
1+foo = \x -> case x of
2+ y@{ foo = "Foo" } -> y
3+ y -> (do
4+ var copy = y
5+ copy.foo = "Bar"
6+ return copy)
src/PureScript/CodeGen/JS.hs+8−1
@@ -167,6 +167,7 @@ binaryOperatorString Or = "||"
167167binaryOperatorString Concat = "+"
168168
169169binderToJs :: String -> String -> Binder -> Gen String
170+binderToJs varName done NullBinder = return done
170171binderToJs varName done (StringBinder str) =
171172 return $ "if (" ++ varName ++ " === \"" ++ str ++ "\") {" ++ done ++ " }"
172173binderToJs varName done (NumberBinder num) =
@@ -191,7 +192,7 @@ binderToJs varName done (ObjectBinder bs) = go done bs
191192 done' <- go done bs
192193 js <- binderToJs propVar done' binder
193194 return $ "var " ++ propVar ++ " = " ++ varName ++ "." ++ prop ++ ";" ++ js
194−binderToJs done varName (ArrayBinder bs rest) = do
195+binderToJs varName done (ArrayBinder bs rest) = do
195196 js <- go done rest 0 bs
196197 return $ "if (" ++ varName ++ ".length " ++ cmp ++ " " ++ show (length bs) ++ ") { " ++ js ++ " }"
197198 where
@@ -206,6 +207,12 @@ binderToJs done varName (ArrayBinder bs rest) = do
206207 done' <- go done rest (index + 1) bs
207208 js <- binderToJs elVar done' binder
208209 return $ "var " ++ elVar ++ " = " ++ varName ++ "[" ++ show index ++ "]; " ++ js
210+binderToJs varName done (NamedBinder ident binder) = do
211+ js <- binderToJs varName done binder
212+ return $ "var " ++ identToJs ident ++ " = " ++ varName ++ "; " ++ js
213+binderToJs varName done (GuardedBinder cond binder) = binderToJs varName done' binder
214+ where
215+ done' = "if (" ++ valueToJs cond ++ ") { " ++ done ++ "}"
209216
210217objectPropertyToJs :: (String, Value) -> String
211218objectPropertyToJs (key, value) = key ++ ":" ++ valueToJs value
src/PureScript/Parser/Values.hs+14−2
@@ -72,7 +72,7 @@ parseCase = Case <$> (P.between (C.reserved "case") (C.indented *> C.reserved "o
7272 <*> (C.indented *> C.mark (P.many (C.same *> C.mark parseCaseAlternative)))
7373
7474parseCaseAlternative :: P.Parsec String P.Column (Binder, Value)
75−parseCaseAlternative = (,) <$> (parseBinder <* C.lexeme (P.string "->")) <*> parseValue
75+parseCaseAlternative = (,) <$> (parseGuardedBinder <* C.lexeme (P.string "->")) <*> parseValue
7676
7777parseBlock :: P.Parsec String P.Column Value
7878parseBlock = Block <$> (C.reserved "do" *> parseManyStatements)
@@ -211,6 +211,13 @@ parseArrayBinder :: P.Parsec String P.Column Binder
211211parseArrayBinder = C.squares $ ArrayBinder <$> ((C.indented *> parseBinder) `P.sepBy` (C.indented *> C.comma))
212212 <*> P.optionMaybe (C.indented *> C.colon *> C.indented *> parseBinder)
213213
214+parseNamedBinder :: P.Parsec String P.Column Binder
215+parseNamedBinder = NamedBinder <$> (C.parseIdent <* C.indented <* C.lexeme (P.char '@'))
216+ <*> (C.indented *> parseBinder)
217+
218+parseNullBinder :: P.Parsec String P.Column Binder
219+parseNullBinder = C.lexeme (P.char '_') *> P.notFollowedBy C.identLetter *> return NullBinder
220+
214221parseIdentifierAndBinder :: P.Parsec String P.Column (String, Binder)
215222parseIdentifierAndBinder = do
216223 name <- C.lexeme C.identifier
@@ -220,9 +227,11 @@ parseIdentifierAndBinder = do
220227
221228parseBinder :: P.Parsec String P.Column Binder
222229parseBinder = P.choice (map P.try
223− [ parseStringBinder
230+ [ parseNullBinder
231+ , parseStringBinder
224232 , parseBooleanBinder
225233 , parseNumberBinder
234+ , parseNamedBinder
226235 , parseVarBinder
227236 , parseUnaryBinder
228237 , parseNullaryBinder
@@ -230,6 +239,9 @@ parseBinder = P.choice (map P.try
230239 , parseArrayBinder
231240 , C.parens parseBinder ])
232241
242+parseGuardedBinder :: P.Parsec String P.Column Binder
243+parseGuardedBinder = flip ($) <$> parseBinder <*> P.option id (GuardedBinder <$> (C.indented *> C.lexeme (P.char '|') *> C.indented *> parseValue))
244+
233245parseAssignmentTarget :: P.Parsec String P.Column AssignmentTarget
234246parseAssignmentTarget = buildExpressionParser operators (AssignVariable <$> C.parseIdent)
235247 where
src/PureScript/TypeChecker/Types.hs+9
@@ -317,6 +317,7 @@ asymBinOpConstraints :: Type -> Type -> Int -> Int -> Int -> [TypeConstraint]
317317asymBinOpConstraints ty res left right result = [TypeConstraint left ty, TypeConstraint right ty, TypeConstraint result res]
318318
319319typeConstraintsForBinder :: Int -> Binder -> Check ([TypeConstraint], M.Map Ident Int)
320+typeConstraintsForBinder _ NullBinder = return ([], M.empty)
320321typeConstraintsForBinder val (StringBinder _) = constantBinder val String
321322typeConstraintsForBinder val (NumberBinder _) = constantBinder val Number
322323typeConstraintsForBinder val (BooleanBinder _) = constantBinder val Boolean
@@ -363,6 +364,14 @@ typeConstraintsForBinder val (ArrayBinder binders rest) = do
363364 Just binder -> do
364365 (cs2, m2) <- typeConstraintsForBinder val binder
365366 return (arrayConstraint : cs1 ++ cs2, M.union m1 m2)
367+typeConstraintsForBinder val (NamedBinder name binder) = do
368+ me <- fresh
369+ (cs, m) <- typeConstraintsForBinder val binder
370+ return (TypeConstraint me (TUnknown val) : cs, M.insert name me m)
371+typeConstraintsForBinder val (GuardedBinder cond binder) = do
372+ (cs1, m) <- typeConstraintsForBinder val binder
373+ (cs2, n) <- typeConstraints m cond
374+ return (TypeConstraint n Boolean : cs1 ++ cs2, m)
366375
367376constantBinder :: Int -> Type -> Check ([TypeConstraint], M.Map Ident Int)
368377constantBinder val ty = return ([TypeConstraint val ty], M.empty)
src/PureScript/Values.hs+5−2
@@ -82,14 +82,17 @@ data ElseStatement
8282 | ElseIf IfStatement deriving (Show, Data, Typeable)
8383
8484data Binder
85− = BooleanBinder Bool
85+ = NullBinder
86+ | BooleanBinder Bool
8687 | StringBinder String
8788 | NumberBinder (Either Integer Double)
8889 | VarBinder Ident
8990 | NullaryBinder String
9091 | UnaryBinder String Binder
9192 | ObjectBinder [(String, Binder)]
92− | ArrayBinder [Binder] (Maybe Binder) deriving (Show, Data, Typeable)
93+ | ArrayBinder [Binder] (Maybe Binder)
94+ | NamedBinder Ident Binder
95+ | GuardedBinder Value Binder deriving (Show, Data, Typeable)
9396
9497data AssignmentTarget
9598 = AssignVariable Ident