@@ -22,6 +22,7 @@ import qualified PureScript.Parser.Common as C
22import Control.Applicative
22import Control.Applicative
23import qualified Text.Parsec as P
23import qualified Text.Parsec as P
24import Text.Parsec.Expr
24import Text.Parsec.Expr
25import Control.Arrow (Arrow(..))
26import Control.Arrow (Arrow(..))
26import PureScript.Parser.Types
27import PureScript.Parser.Types
27import PureScript.Types
28import PureScript.Types
@@ -74,7 +75,7 @@ parseCaseAlternative :: P.Parsec String () (Binder, Value)
74parseCaseAlternative = (,) <$> (parseBinder <* C.lexeme (P.string "->")) <*> parseValue
75parseCaseAlternative = (,) <$> (parseBinder <* C.lexeme (P.string "->")) <*> parseValue
76parseBlock :: P.Parsec String () Value
77parseBlock :: P.Parsec String () Value
77−parseBlock = Block <$> (C.braces $ P.many parseStatement)
78+parseBlock = Block <$> (C.braces $ P.many (parseStatement True))
79parseValueAtom :: P.Parsec String () Value
80parseValueAtom :: P.Parsec String () Value
80parseValueAtom = P.choice $ map P.try
81parseValueAtom = P.choice $ map P.try
@@ -100,7 +101,10 @@ parseValue = buildExpressionParser operators $ C.fold (C.lexeme typedValue) (C.l
100 , [ Prefix $ C.lexeme (P.char '!') >> return (Unary Not)
101 , [ Prefix $ C.lexeme (P.char '!') >> return (Unary Not)
101 , Prefix $ C.lexeme (P.char '~') >> return (Unary BitwiseNot)
102 , Prefix $ C.lexeme (P.char '~') >> return (Unary BitwiseNot)
102 , Prefix $ C.lexeme (P.char '-') >> return (Unary Negate) ]
103 , Prefix $ C.lexeme (P.char '-') >> return (Unary Negate) ]
103− , [ Infix (C.lexeme (P.char '*') >> return (Binary Multiply)) AssocRight
104+ , [ Infix (C.lexeme (P.try (P.string "<=")) >> return (Binary LessThanOrEqualTo)) AssocRight
105+ , Infix (C.lexeme (P.try (P.string ">=")) >> return (Binary GreaterThanOrEqualTo)) AssocRight
106+ , Infix (C.lexeme (P.try (P.char '<' <* P.notFollowedBy (P.char '<'))) >> return (Binary LessThan)) AssocRight ]
107+ , [ Infix (C.lexeme (P.try (P.char '>' <* P.notFollowedBy (P.char '>'))) >> return (Binary GreaterThan)) AssocRight
104 , Infix (C.lexeme (P.char '/') >> return (Binary Divide)) AssocRight
108 , Infix (C.lexeme (P.char '/') >> return (Binary Divide)) AssocRight
105 , Infix (C.lexeme (P.char '%') >> return (Binary Modulus)) AssocRight ]
109 , Infix (C.lexeme (P.char '%') >> return (Binary Modulus)) AssocRight ]
106 , [ Infix (C.lexeme (P.try (P.string "++")) >> return (Binary Concat)) AssocRight
110 , [ Infix (C.lexeme (P.try (P.string "++")) >> return (Binary Concat)) AssocRight
@@ -118,25 +122,25 @@ parseValue = buildExpressionParser operators $ C.fold (C.lexeme typedValue) (C.l
118 , [ Infix (C.lexeme (P.string "||") >> return (Binary Or)) AssocRight ]
122 , [ Infix (C.lexeme (P.string "||") >> return (Binary Or)) AssocRight ]
121−parseVariableIntroduction :: P.Parsec String () Statement
125+parseVariableIntroduction :: Bool -> P.Parsec String () Statement
122−parseVariableIntroduction = do
126+parseVariableIntroduction requireSemi = do
123 C.reserved "var"
127 C.reserved "var"
124 name <- C.identifier
128 name <- C.identifier
125 C.lexeme $ P.char '='
129 C.lexeme $ P.char '='
126 value <- parseValue
130 value <- parseValue
127− C.semi
131+ when requireSemi (void C.semi)
128 return $ VariableIntroduction name value
132 return $ VariableIntroduction name value
130−parseAssignment :: P.Parsec String () (Statement)
134+parseAssignment :: Bool -> P.Parsec String () (Statement)
131−parseAssignment = do
135+parseAssignment requireSemi = do
132− tgt <- C.identifier
136+ tgt <- parseAssignmentTarget
133 C.lexeme $ P.char '='
137 C.lexeme $ P.char '='
134 value <- parseValue
138 value <- parseValue
135− C.semi
139+ when requireSemi (void C.semi)
136 return $ Assignment tgt value
140 return $ Assignment tgt value
138parseManyStatements :: P.Parsec String () [Statement]
142parseManyStatements :: P.Parsec String () [Statement]
139−parseManyStatements = C.braces $ P.many parseStatement
143+parseManyStatements = C.braces $ P.many (parseStatement True)
141parseWhile :: P.Parsec String () Statement
145parseWhile :: P.Parsec String () Statement
142parseWhile = While <$> (C.reserved "while" *> C.parens parseValue)
146parseWhile = While <$> (C.reserved "while" *> C.parens parseValue)
@@ -146,9 +150,9 @@ parseFor :: P.Parsec String () Statement
146parseFor = For <$> (C.reserved "for" *> C.parens forIntro)
150parseFor = For <$> (C.reserved "for" *> C.parens forIntro)
147 <*> parseManyStatements
151 <*> parseManyStatements
149− forIntro = (,,) <$> parseStatement
153+ forIntro = (,,) <$> parseStatement False
150 <*> (C.semi *> parseValue)
154 <*> (C.semi *> parseValue)
151− <*> (C.semi *> parseStatement)
155+ <*> (C.semi *> parseStatement False)
153parseIfThenElse :: P.Parsec String () Statement
157parseIfThenElse :: P.Parsec String () Statement
154parseIfThenElse = IfThenElse
158parseIfThenElse = IfThenElse
@@ -156,17 +160,17 @@ parseIfThenElse = IfThenElse
156 <*> parseManyStatements
160 <*> parseManyStatements
157 <*> P.optionMaybe (C.reserved "else" *> parseManyStatements)
161 <*> P.optionMaybe (C.reserved "else" *> parseManyStatements)
159−parseReturn :: P.Parsec String () Statement
163+parseReturn :: Bool -> P.Parsec String () Statement
160−parseReturn = Return <$> (C.reserved "return" *> parseValue <* C.semi)
164+parseReturn requireSemi = Return <$> (C.reserved "return" *> parseValue <* when requireSemi (void C.semi))
162−parseStatement :: P.Parsec String () Statement
166+parseStatement :: Bool -> P.Parsec String () Statement
163−parseStatement = P.choice $ map P.try
167+parseStatement requireSemi = P.choice $ map P.try
164− [ parseVariableIntroduction
168+ [ parseVariableIntroduction requireSemi
165− , parseAssignment
169+ , parseAssignment requireSemi
166 , parseWhile
170 , parseWhile
167 , parseFor
171 , parseFor
168 , parseIfThenElse
172 , parseIfThenElse
169− , parseReturn ]
173+ , parseReturn requireSemi ]
171parseStringBinder :: P.Parsec String () Binder
175parseStringBinder :: P.Parsec String () Binder
172parseStringBinder = StringBinder <$> C.stringLiteral
176parseStringBinder = StringBinder <$> C.stringLiteral
@@ -210,3 +214,9 @@ parseBinder = P.choice $ map P.try
210 , parseObjectBinder
214 , parseObjectBinder
211 , parseArrayBinder
215 , parseArrayBinder
212 , C.parens parseBinder ]
216 , C.parens parseBinder ]
218+parseAssignmentTarget :: P.Parsec String () AssignmentTarget
219+parseAssignmentTarget = buildExpressionParser operators (AssignVariable <$> C.identifier)
221+ operators = [ [ Postfix $ AssignArrayIndex <$> C.squares parseValue
222+ , Postfix $ AssignObjectProperty <$> (C.dot *> C.identifier) ] ]