@@ -7,21 +7,22 @@ module Parse.Expression
77
88
99import qualified Data.Name as Name
10+import Data.Word (Word16)
1011
1112import qualified AST.Source as Src
12−import Parse.Primitives
13−import qualified Parse.Primitives.Keyword as Keyword
14−import qualified Parse.Primitives.Number as Number
15−import qualified Parse.Primitives.Symbol as Symbol
16−import qualified Parse.Primitives.Utf8 as Utf8
17−import qualified Parse.Primitives.Variable as Var
18−import qualified Parse.Primitives.Whitespace as W
13+import qualified Parse.Keyword as Keyword
14+import qualified Parse.Number as Number
1915import qualified Parse.Pattern as Pattern
2016import qualified Parse.Shader as Shader
17+import qualified Parse.Symbol as Symbol
2118import qualified Parse.Type as Type
19+import qualified Parse.Utf8 as Utf8
20+import qualified Parse.Variable as Var
21+import Parse.Utils
22+import Parse.Primitives hiding (Parser, State)
23+import qualified Parse.Primitives as P
2224import qualified Reporting.Annotation as A
2325import qualified Reporting.Error.Syntax as E
24−import qualified Reporting.Region as R
2526
2627
2728
@@ -30,9 +31,8 @@ import qualified Reporting.Region as R
3031
3132term :: Parser Src.Expr
3233term =
33− hint E.Expr $
3434 do start <- getPosition
35− oneOf
35+ oneOf E.XXX
3636 [ variable start >>= accessible start
3737 , string start
3838 , number start
@@ -45,21 +45,21 @@ term =
4545 ]
4646
4747
48−string :: R.Position -> Parser Src.Expr
48+string :: A.Position -> Parser Src.Expr
4949string start =
5050 do str <- Utf8.string
5151 end <- getPosition
5252 return (A.at start end (Src.Str str))
5353
5454
55−character :: R.Position -> Parser Src.Expr
55+character :: A.Position -> Parser Src.Expr
5656character start =
5757 do chr <- Utf8.character
5858 end <- getPosition
5959 return (A.at start end (Src.Chr chr))
6060
6161
62−number :: R.Position -> Parser Src.Expr
62+number :: A.Position -> Parser Src.Expr
6363number start =
6464 do nmbr <- Number.number
6565 end <- getPosition
@@ -72,25 +72,25 @@ number start =
7272 Src.Float float
7373
7474
75−accessor :: R.Position -> Parser Src.Expr
75+accessor :: A.Position -> Parser Src.Expr
7676accessor start =
77− do Symbol.dot
77+ do word1 0x2E {-.-} E.XXX
7878 field <- Var.lower
7979 end <- getPosition
8080 return (A.at start end (Src.Accessor field))
8181
8282
83−variable :: R.Position -> Parser Src.Expr
83+variable :: A.Position -> Parser Src.Expr
8484variable start =
8585 do var <- Var.foreignAlpha
8686 end <- getPosition
8787 return (A.at start end var)
8888
8989
90−accessible :: R.Position -> Src.Expr -> Parser Src.Expr
90+accessible :: A.Position -> Src.Expr -> Parser Src.Expr
9191accessible start expr =
92− oneOf
93− [ do Symbol.dot
92+ oneOf E.XXX
93+ [ do word1 0x2E {-.-} E.XXX
9494 pos <- getPosition
9595 field <- Var.lower
9696 end <- getPosition
@@ -104,30 +104,29 @@ accessible start expr =
104104-- LISTS
105105
106106
107−list :: R.Position -> Parser Src.Expr
107+list :: A.Position -> Parser Src.Expr
108108list start =
109− do Symbol.leftSquare
110− inContext start E.ExprList $
111− do spaces
112− oneOf
113− [ do (entry, _, pos) <- expression
114− checkSpace pos
115− listHelp start [entry]
116− , do Symbol.rightSquare
117− end <- getPosition
118− return (A.at start end (Src.List []))
119− ]
120−
121−
122−listHelp :: R.Position -> [Src.Expr] -> Parser Src.Expr
109+ inContext E.ExprList (word1 0x5B {-[-} E.XXX) $
110+ do spaces
111+ oneOf E.XXX
112+ [ do (entry, _, pos) <- expression
113+ checkSpace pos
114+ listHelp start [entry]
115+ , do word1 0x5D {-]-} E.XXX
116+ end <- getPosition
117+ return (A.at start end (Src.List []))
118+ ]
119+
120+
121+listHelp :: A.Position -> [Src.Expr] -> Parser Src.Expr
123122listHelp start entries =
124− oneOf
125− [ do Symbol.comma
123+ oneOf E.XXX
124+ [ do word1 0x2C {-,-} E.XXX
126125 spaces
127126 (entry, _, pos) <- expression
128127 checkSpace pos
129128 listHelp start (entry:entries)
130− , do Symbol.rightSquare
129+ , do word1 0x5D {-]-} E.XXX
131130 end <- getPosition
132131 return (A.at start end (Src.List (reverse entries)))
133132 ]
@@ -137,14 +136,14 @@ listHelp start entries =
137136-- TUPLES
138137
139138
140−tuple :: R.Position -> Parser Src.Expr
139+tuple :: A.Position -> Parser Src.Expr
141140tuple start =
142− do Symbol.leftParen
143− pos <- getPosition
144− spos <- W.whitespace
145− inContext start E.ExprTuple $ oneOf $
141+ inContext E.ExprTuple (word1 0x28 {-(-} E.XXX) $
142+ do pos <- getPosition
143+ spos <- whitespace
144+ oneOf E.XXX
146145 [ do noSpace pos spos
147− try (Symbol.minus >> Symbol.rightParen)
146+ word2 0x2D 0x29 {--)-} E.XXX
148147 end <- getPosition
149148 return $ A.at start end (Src.Op "-")
150149
@@ -155,27 +154,27 @@ tuple start =
155154
156155 , do noSpace pos spos
157156 op <- Symbol.binop
158− Symbol.rightParen
157+ word1 0x29 {-)-} E.XXX
159158 end <- getPosition
160159 return $ A.at start end (Src.Op op)
161160
162161 , do noSpace pos spos
163− Symbol.rightParen
162+ word1 0x29 {-)-} E.XXX
164163 end <- getPosition
165164 return (A.at start end Src.Unit)
166165
167166 ]
168167
169168
170−tupleHelp :: R.Position -> Src.Expr -> [Src.Expr] -> Parser Src.Expr
169+tupleHelp :: A.Position -> Src.Expr -> [Src.Expr] -> Parser Src.Expr
171170tupleHelp start firstExpr revExprs =
172− oneOf
173− [ do Symbol.comma
171+ oneOf E.XXX
172+ [ do word1 0x2C {-,-} E.XXX
174173 spaces
175174 (entry, _, pos) <- expression
176175 checkSpace pos
177176 tupleHelp start firstExpr (entry : revExprs)
178− , do Symbol.rightParen
177+ , do word1 0x29 {-)-} E.XXX
179178 end <- getPosition
180179 case reverse revExprs of
181180 [] ->
@@ -190,33 +189,32 @@ tupleHelp start firstExpr revExprs =
190189-- RECORDS
191190
192191
193−record :: R.Position -> Parser Src.Expr
192+record :: A.Position -> Parser Src.Expr
194193record start =
195− do Symbol.leftCurly
196− inContext start E.ExprRecord $
197− do spaces
198− oneOf
199− [ do Symbol.rightCurly
200− end <- getPosition
201− return (A.at start end (Src.Record []))
202− , do starter <- addLocation Var.lower
203− spaces
204− oneOf
205− [ do Symbol.pipe
206− spaces
207− firstField <- chompField
208− fields <- chompFields [firstField]
209− end <- getPosition
210− return (A.at start end (Src.Update starter fields))
211− , do Symbol.equals
212− spaces
213− (value, _, nextPos) <- expression
214− checkSpace nextPos
215− fields <- chompFields [(starter, value)]
216− end <- getPosition
217− return (A.at start end (Src.Record fields))
218− ]
219− ]
194+ inContext E.ExprRecord (word1 0x7B {- { -} E.XXX) $
195+ do spaces
196+ oneOf E.XXX
197+ [ do word1 0x7D {-}-} E.XXX
198+ end <- getPosition
199+ return (A.at start end (Src.Record []))
200+ , do starter <- addLocation Var.lower
201+ spaces
202+ oneOf E.XXX
203+ [ do word1 0x7C {-|-} E.XXX
204+ spaces
205+ firstField <- chompField
206+ fields <- chompFields [firstField]
207+ end <- getPosition
208+ return (A.at start end (Src.Update starter fields))
209+ , do word1 0x3D {-=-} E.XXX
210+ spaces
211+ (value, _, nextPos) <- expression
212+ checkSpace nextPos
213+ fields <- chompFields [(starter, value)]
214+ end <- getPosition
215+ return (A.at start end (Src.Record fields))
216+ ]
217+ ]
220218
221219
222220type Field = ( A.Located Name.Name, Src.Expr )
@@ -224,12 +222,12 @@ type Field = ( A.Located Name.Name, Src.Expr )
224222
225223chompFields :: [Field] -> Parser [Field]
226224chompFields fields =
227− oneOf
228− [ do Symbol.comma
225+ oneOf E.XXX
226+ [ do word1 0x2C {-,-} E.XXX
229227 spaces
230228 f <- chompField
231229 chompFields (f : fields)
232− , do Symbol.rightCurly
230+ , do word1 0x7D {-}-} E.XXX
233231 return (reverse fields)
234232 ]
235233
@@ -238,7 +236,7 @@ chompField :: Parser Field
238236chompField =
239237 do key <- addLocation Var.lower
240238 spaces
241− Symbol.equals
239+ word1 0x3D {-=-} E.XXX
242240 spaces
243241 (value, _, pos) <- expression
244242 checkSpace pos
@@ -255,16 +253,15 @@ type ExprParser =
255253
256254expression :: ExprParser
257255expression =
258− hint E.Expr $
259256 do start <- getPosition
260− oneOf
257+ oneOf E.XXX
261258 [ let_ start
262259 , if_ start
263260 , case_ start
264261 , function start
265262 , do expr <- possiblyNegativeTerm start
266263 end <- getPosition
267− space <- W.whitespace
264+ space <- whitespace
268265 exprHelp start (State [] expr [] end space)
269266 ]
270267
@@ -274,20 +271,19 @@ data State =
274271 { _ops :: ![(Src.Expr, A.Located Name.Name)]
275272 , _expr :: !Src.Expr
276273 , _args :: ![Src.Expr]
277− , _end :: !R.Position
274+ , _end :: !A.Position
278275 , _pos :: !SPos
279276 }
280277
281278
282−exprHelp :: R.Position -> State -> ExprParser
279+exprHelp :: A.Position -> State -> ExprParser
283280exprHelp start (State ops expr args end pos) =
284− oneOf
281+ oneOf E.XXX
285282 [ -- argument
286− hint E.Arg $
287283 do checkSpace pos
288284 arg <- term
289285 newEnd <- getPosition
290− newPos <- W.whitespace
286+ newPos <- whitespace
291287 exprHelp start (State ops expr (arg:args) newEnd newPos)
292288
293289 , -- infix operator
@@ -296,30 +292,29 @@ exprHelp start (State ops expr args end pos) =
296292 opName <- Symbol.binop
297293 opEnd <- getPosition
298294 let op = A.at opStart opEnd opName
299− spos <- W.whitespace
300− hint (E.AfterOpExpr opName) (checkSpace spos)
295+ spos <- whitespace
296+ checkSpace spos
301297 newStart <- getPosition
302− hint (E.AfterOpExpr opName) $
303− if "-" == opName && end /= opStart && opEnd == newStart
298+ if "-" == opName && end /= opStart && opEnd == newStart
304299 then
305300 -- negative terms
306301 do rawTerm <- term
307302 newEnd <- getPosition
308− newPos <- W.whitespace
303+ newPos <- whitespace
309304 let arg = A.at opStart newEnd (Src.Negate rawTerm)
310305 exprHelp start (State ops expr (arg:args) newEnd newPos)
311306 else
312− oneOf
307+ oneOf E.XXX
313308 [ -- term
314309 do newExpr <- possiblyNegativeTerm newStart
315310 newEnd <- getPosition
316− newPos <- W.whitespace
311+ newPos <- whitespace
317312 let newOps = (toCall expr args, op) : ops
318313 exprHelp start (State newOps newExpr [] newEnd newPos)
319314
320315 , -- final term
321316 do (newLast, newEnd, newPos) <-
322− oneOf
317+ oneOf E.XXX
323318 [ let_ newStart
324319 , case_ newStart
325320 , if_ newStart
@@ -341,10 +336,10 @@ exprHelp start (State ops expr args end pos) =
341336 ]
342337
343338
344−possiblyNegativeTerm :: R.Position -> Parser Src.Expr
339+possiblyNegativeTerm :: A.Position -> Parser Src.Expr
345340possiblyNegativeTerm start =
346− oneOf
347− [ do Symbol.minus
341+ oneOf E.XXX
342+ [ do word1 0x2D {---} E.XXX
348343 expr <- term
349344 end <- getPosition
350345 return (A.at start end (Src.Negate expr))
@@ -366,13 +361,13 @@ toCall func revArgs =
366361-- IF EXPRESSION
367362
368363
369−if_ :: R.Position -> ExprParser
364+if_ :: A.Position -> ExprParser
370365if_ start =
371− do Keyword.if_
372− inContext start E.ExprIf $ ifHelp start []
366+ inContext E.ExprIf Keyword.if_ $
367+ ifHelp start []
373368
374369
375−ifHelp :: R.Position -> [(Src.Expr, Src.Expr)] -> ExprParser
370+ifHelp :: A.Position -> [(Src.Expr, Src.Expr)] -> ExprParser
376371ifHelp start branches =
377372 do spaces
378373 (condition, _, condPos) <- expression
@@ -380,11 +375,11 @@ ifHelp start branches =
380375 Keyword.then_
381376 spaces
382377 (thenBranch, _, thenPos) <- expression
383− hint E.ElseBranch $ checkSpace thenPos
384− hint E.ElseBranch $ Keyword.else_
378+ checkSpace thenPos
379+ Keyword.else_
385380 spaces
386381 let newBranches = (condition, thenBranch) : branches
387− oneOf
382+ oneOf E.XXX
388383 [ do Keyword.if_
389384 ifHelp start newBranches
390385 , do (elseBranch, elseEnd, elseSpace) <- expression
@@ -397,27 +392,26 @@ ifHelp start branches =
397392-- LAMBDA EXPRESSION
398393
399394
400−function :: R.Position -> ExprParser
395+function :: A.Position -> ExprParser
401396function start =
402− do Symbol.lambda
403− inContext start E.ExprFunc $
404− do spaces
405− arg <- Pattern.term
406− spaces
407− revArgs <- gatherArgs [arg]
408− spaces
409− (body, end, space) <- expression
410− let func = A.at start end (Src.Lambda (reverse revArgs) body)
411− return ( func, end, space )
397+ inContext E.ExprFunc (word1 0x5C {-\-} E.XXX) $
398+ do spaces
399+ arg <- Pattern.term
400+ spaces
401+ revArgs <- gatherArgs [arg]
402+ spaces
403+ (body, end, space) <- expression
404+ let func = A.at start end (Src.Lambda (reverse revArgs) body)
405+ return ( func, end, space )
412406
413407
414408gatherArgs :: [Src.Pattern] -> Parser [Src.Pattern]
415409gatherArgs args =
416− oneOf
410+ oneOf E.XXX
417411 [ do arg <- Pattern.term
418412 spaces
419413 gatherArgs (arg:args)
420− , do Symbol.rightArrow
414+ , do word2 0x2D 0x3E {-->-} E.XXX
421415 return args
422416 ]
423417
@@ -426,41 +420,40 @@ gatherArgs args =
426420-- CASE EXPRESSIONS
427421
428422
429−case_ :: R.Position -> ExprParser
423+case_ :: A.Position -> ExprParser
430424case_ start =
431− do Keyword.case_
432− inContext start E.ExprCase $
433− do spaces
434− (switcher, _, switcherPos) <- expression
435− checkSpace switcherPos
436− Keyword.of_
437− spaces
438− oldIndent <- getIndent
439− newIndent <- getCol
440− setIndent newIndent
441− (firstBranch, firstEnd, firstPos) <- branchHelp
442− (branches, end, pos) <- caseHelp [firstBranch] firstEnd firstPos
443− setIndent oldIndent
444− return
445− ( A.at start end (Src.Case switcher branches)
446− , end
447− , pos
448− )
425+ inContext E.ExprCase Keyword.case_ $
426+ do spaces
427+ (switcher, _, switcherPos) <- expression
428+ checkSpace switcherPos
429+ Keyword.of_
430+ spaces
431+ oldIndent <- getIndent
432+ newIndent <- getCol
433+ setIndent newIndent
434+ (firstBranch, firstEnd, firstPos) <- branchHelp
435+ (branches, end, pos) <- caseHelp [firstBranch] firstEnd firstPos
436+ setIndent oldIndent
437+ return
438+ ( A.at start end (Src.Case switcher branches)
439+ , end
440+ , pos
441+ )
449442
450443
451444branchHelp :: SParser (Src.Pattern, Src.Expr)
452445branchHelp =
453446 do (pattern, patternPos) <- Pattern.expression
454447 checkSpace patternPos
455− Symbol.rightArrow
448+ word2 0x2D 0x3E {-->-} E.XXX
456449 spaces
457450 (branchExpr, end, pos) <- expression
458451 return ( (pattern, branchExpr), end, pos )
459452
460453
461−caseHelp :: [(Src.Pattern, Src.Expr)] -> R.Position -> SPos -> SParser [(Src.Pattern, Src.Expr)]
454+caseHelp :: [(Src.Pattern, Src.Expr)] -> A.Position -> SPos -> SParser [(Src.Pattern, Src.Expr)]
462455caseHelp branches end pos =
463− oneOf
456+ oneOf E.XXX
464457 [ do checkAligned pos
465458 (branch, newEnd, newPos) <- branchHelp
466459 caseHelp (branch:branches) newEnd newPos
@@ -472,7 +465,7 @@ caseHelp branches end pos =
472465-- LET EXPRESSION
473466
474467
475−let_ :: R.Position -> ExprParser
468+let_ :: A.Position -> ExprParser
476469let_ start =
477470 do oldIndent <- getIndent
478471 letIndent <- getCol
@@ -486,9 +479,9 @@ let_ start =
486479 letHelp start oldIndent [def] end space
487480
488481
489−letHelp :: R.Position -> Int -> [A.Located Src.Def] -> R.Position -> SPos -> ExprParser
482+letHelp :: A.Position -> Word16 -> [A.Located Src.Def] -> A.Position -> SPos -> ExprParser
490483letHelp start oldIndent revDefs end pos =
491− oneOf
484+ oneOf E.XXX
492485 [ do checkAligned pos
493486 (def, newEnd, newPos) <- letDef
494487 letHelp start oldIndent (def:revDefs) newEnd newPos
@@ -510,7 +503,7 @@ letHelp start oldIndent revDefs end pos =
510503
511504letDef :: SParser (A.Located Src.Def)
512505letDef =
513− oneOf
506+ oneOf E.XXX
514507 [ definition
515508 , destructure
516509 ]
@@ -524,33 +517,62 @@ definition :: SParser (A.Located Src.Def)
524517definition =
525518 do start <- getPosition
526519 name <- Var.lower
527− nameEnd <- getPosition
520+ end <- getPosition
528521 spaces
529− oneOf
530− [ do Symbol.hasType
531− inContext start (E.Annotation name) $
532− do spaces
533− (tipe, end, space) <- Type.expression
534− return ( A.at start end (Src.Annotate name tipe), end, space )
535− , inContext start (E.Definition name) $
536− definitionHelp start (A.at start nameEnd name) []
522+ oneOf E.XXX
523+ [
524+ do word1 0x3A {-:-} E.XXX
525+ pushContext start (E.Annotation name)
526+ spaces
527+ (tipe, _, space) <- Type.expression
528+ popContext ()
529+ checkAligned space
530+ defName <- matchingName name
531+ let (A.At (A.Region defStart _) _) = defName
532+ pushContext defStart (E.Definition name)
533+ spaces
534+ def <- definitionHelp start defName (Just tipe) []
535+ popContext def
536+ ,
537+ do pushContext start (E.Definition name)
538+ def <- definitionHelp start (A.at start end name) Nothing []
539+ popContext def
537540 ]
538541
539542
540−definitionHelp :: R.Position -> A.Located Name.Name -> [Src.Pattern] -> SParser (A.Located Src.Def)
541−definitionHelp start name revArgs =
542− oneOf
543− [ do arg <- hint E.Arg Pattern.term
543+definitionHelp :: A.Position -> A.Located Name.Name -> Maybe Src.Type -> [Src.Pattern] -> SParser (A.Located Src.Def)
544+definitionHelp start name tipe revArgs =
545+ oneOf E.XXX
546+ [ do arg <- Pattern.term
544547 spaces
545− definitionHelp start name (arg : revArgs)
546− , do Symbol.equals
548+ definitionHelp start name tipe (arg : revArgs)
549+ , do word1 0x3D {-=-} E.XXX
547550 spaces
548551 (body, end, space) <- expression
549− let def = A.at start end (Src.Define name (reverse revArgs) body)
552+ let def = A.at start end (Src.Define name (reverse revArgs) body tipe)
550553 return ( def, end, space )
551554 ]
552555
553556
557+matchingName :: Name.Name -> Parser (A.Located Name.Name)
558+matchingName expectedName =
559+ let (P.Parser parserL) = Var.lower in
560+ P.Parser $ \state@(P.State _ _ _ sr sc ctx) cok eok cerr eerr ->
561+ let
562+ cokL name newState@(P.State _ _ _ er ec _) =
563+ if expectedName == name
564+ then cok (A.At (A.Region (A.Position sr sc) (A.Position er ec)) name) newState
565+ else cerr sr sc ctx (E.MatchingName expectedName)
566+
567+ eokL name newState@(P.State _ _ _ er ec _) =
568+ if expectedName == name
569+ then eok (A.At (A.Region (A.Position sr sc) (A.Position er ec)) name) newState
570+ else eerr sr sc ctx (E.MatchingName expectedName)
571+ in
572+ parserL state cokL eokL cerr eerr
573+
574+
575+
554576
555577-- DESTRUCTURE
556578
@@ -560,7 +582,7 @@ destructure =
560582 do start <- getPosition
561583 pattern <- Pattern.term
562584 spaces
563− Symbol.equals
585+ word1 0x3D {-=-} E.XXX
564586 spaces
565587 (expr, end, space) <- expression
566588 return ( A.at start end (Src.Destruct pattern expr), end, space )