on master help sign in
Get a bunch of Parser/* modules working with new error tracking
commit22a426422cf76f53d523432fb1f3ca293697cc70 authorEvan Czaplicki <evancz@users.noreply.github.com> dateThu 25 Apr 2019, 16:40 (8 years ago) parentaa10604
9 files changed+762−790
compiler/src/Parse/Expression.hs+317−340 compiler/src/Parse/Keyword.hs+83−84 compiler/src/Parse/Number.hs+25−25 compiler/src/Parse/Pattern.hs+103−120 compiler/src/Parse/Shader.hs+17−17 compiler/src/Parse/Symbol.hs+18−18 compiler/src/Parse/Type.hs+106−103 compiler/src/Parse/Utf8.hs+57−45 compiler/src/Parse/Variable.hs+36−38
compiler/src/Parse/Expression.hs+317−340
@@ -7,19 +7,18 @@ module Parse.Expression
77
88
99import qualified Data.Name as Name
10−import Data.Word (Word16)
1110
1211import qualified AST.Source as Src
1312import qualified Parse.Keyword as Keyword
1413import qualified Parse.Number as Number
1514import qualified Parse.Pattern as Pattern
1615import qualified Parse.Shader as Shader
16+import qualified Parse.Space as Space
1717import qualified Parse.Symbol as Symbol
1818import qualified Parse.Type as Type
1919import qualified Parse.Utf8 as Utf8
2020import qualified Parse.Variable as Var
21−import Parse.Utils
22−import Parse.Primitives hiding (Parser, State)
21+import Parse.Primitives hiding (State)
2322import qualified Parse.Primitives as P
2423import qualified Reporting.Annotation as A
2524import qualified Reporting.Error.Syntax as E
@@ -29,10 +28,10 @@ import qualified Reporting.Error.Syntax as E
2928-- TERMS
3029
3130
32−term :: Parser Src.Expr
31+term :: Parser E.Expr Src.Expr
3332term =
3433 do start <- getPosition
35− oneOf E.XXX
34+ oneOf E.Start
3635 [ variable start >>= accessible start
3736 , string start
3837 , number start
@@ -45,90 +44,80 @@ term =
4544 ]
4645
4746
48−string :: A.Position -> Parser Src.Expr
47+string :: A.Position -> Parser E.Expr Src.Expr
4948string start =
50− do str <- Utf8.string
51− end <- getPosition
52− return (A.at start end (Src.Str str))
49+ do str <- Utf8.string E.Start E.String
50+ addEnd start (Src.Str str)
5351
5452
55−character :: A.Position -> Parser Src.Expr
53+character :: A.Position -> Parser E.Expr Src.Expr
5654character start =
57− do chr <- Utf8.character
58− end <- getPosition
59− return (A.at start end (Src.Chr chr))
55+ do chr <- Utf8.character E.Start E.Char
56+ addEnd start (Src.Chr chr)
6057
6158
62−number :: A.Position -> Parser Src.Expr
59+number :: A.Position -> Parser E.Expr Src.Expr
6360number start =
64− do nmbr <- Number.number
65− end <- getPosition
66− return $ A.at start end $
61+ do nmbr <- Number.number E.Start E.Number
62+ addEnd start $
6763 case nmbr of
68− Number.Int int ->
69− Src.Int int
64+ Number.Int int -> Src.Int int
65+ Number.Float float -> Src.Float float
7066
71− Number.Float float ->
72− Src.Float float
7367
74−
75−accessor :: A.Position -> Parser Src.Expr
68+accessor :: A.Position -> Parser E.Expr Src.Expr
7669accessor start =
77− do word1 0x2E {-.-} E.XXX
78− field <- Var.lower
79− end <- getPosition
80− return (A.at start end (Src.Accessor field))
70+ do word1 0x2E {-.-} E.Dot
71+ field <- Var.lower E.Access
72+ addEnd start (Src.Accessor field)
8173
8274
83−variable :: A.Position -> Parser Src.Expr
75+variable :: A.Position -> Parser E.Expr Src.Expr
8476variable start =
85− do var <- Var.foreignAlpha
86− end <- getPosition
87− return (A.at start end var)
77+ do var <- Var.foreignAlpha E.Start
78+ addEnd start var
8879
8980
90−accessible :: A.Position -> Src.Expr -> Parser Src.Expr
81+accessible :: A.Position -> Src.Expr -> Parser E.Expr Src.Expr
9182accessible start expr =
92− oneOf E.XXX
93− [ do word1 0x2E {-.-} E.XXX
83+ oneOfWithFallback
84+ [ do word1 0x2E {-.-} E.Dot
9485 pos <- getPosition
95− field <- Var.lower
86+ field <- Var.lower E.Access
9687 end <- getPosition
97− let newExpr = A.at start end (Src.Access expr (A.at pos end field))
98− accessible start newExpr
99− , return expr
88+ accessible start $
89+ A.at start end (Src.Access expr (A.at pos end field))
10090 ]
91+ expr
10192
10293
10394
10495-- LISTS
10596
10697
107−list :: A.Position -> Parser Src.Expr
98+list :: A.Position -> Parser E.Expr Src.Expr
10899list start =
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 []))
100+ inContext E.List (word1 0x5B {-[-} E.Start) $
101+ do Space.chompAndCheckIndent E.ListSpace E.ListIndentOpen
102+ oneOf E.ListOpen
103+ [ do (entry, end) <- specialize E.ListExpr expression
104+ Space.checkIndent end E.ListIndentEnd
105+ chompListEnd start [entry]
106+ , do word1 0x5D {-]-} E.ListOpen
107+ addEnd start (Src.List [])
118108 ]
119109
120110
121−listHelp :: A.Position -> [Src.Expr] -> Parser Src.Expr
122−listHelp start entries =
123− oneOf E.XXX
124− [ do word1 0x2C {-,-} E.XXX
125− spaces
126− (entry, _, pos) <- expression
127− checkSpace pos
128− listHelp start (entry:entries)
129− , do word1 0x5D {-]-} E.XXX
130− end <- getPosition
131− return (A.at start end (Src.List (reverse entries)))
111+chompListEnd :: A.Position -> [Src.Expr] -> Parser E.List Src.Expr
112+chompListEnd start entries =
113+ oneOf E.ListEnd
114+ [ do word1 0x2C {-,-} E.ListEnd
115+ Space.chompAndCheckIndent E.ListSpace E.ListIndentExpr
116+ (entry, end) <- specialize E.ListExpr expression
117+ Space.checkIndent end E.ListIndentEnd
118+ chompListEnd start (entry:entries)
119+ , do word1 0x5D {-]-} E.ListEnd
120+ addEnd start (Src.List (reverse entries))
132121 ]
133122
134123
@@ -136,52 +125,55 @@ listHelp start entries =
136125-- TUPLES
137126
138127
139−tuple :: A.Position -> Parser Src.Expr
140−tuple start =
141− inContext E.ExprTuple (word1 0x28 {-(-} E.XXX) $
142− do pos <- getPosition
143− spos <- whitespace
144− oneOf E.XXX
145− [ do noSpace pos spos
146− word2 0x2D 0x29 {--)-} E.XXX
147− end <- getPosition
148− return $ A.at start end (Src.Op "-")
149−
150− , do checkSpace spos
151− (entry, _, spos2) <- expression
152− checkSpace spos2
153− tupleHelp start entry []
154−
155− , do noSpace pos spos
156− op <- Symbol.binop
157− word1 0x29 {-)-} E.XXX
158− end <- getPosition
159− return $ A.at start end (Src.Op op)
160−
161− , do noSpace pos spos
162− word1 0x29 {-)-} E.XXX
163− end <- getPosition
164− return (A.at start end Src.Unit)
165−
166− ]
167−
168−
169−tupleHelp :: A.Position -> Src.Expr -> [Src.Expr] -> Parser Src.Expr
170−tupleHelp start firstExpr revExprs =
171− oneOf E.XXX
172− [ do word1 0x2C {-,-} E.XXX
173− spaces
174− (entry, _, pos) <- expression
175− checkSpace pos
176− tupleHelp start firstExpr (entry : revExprs)
177− , do word1 0x29 {-)-} E.XXX
178− end <- getPosition
128+tuple :: A.Position -> Parser E.Expr Src.Expr
129+tuple start@(A.Position row col) =
130+ inContext E.Tuple (word1 0x28 {-(-} E.Start) $
131+ oneOf E.TupleOpen
132+ [
133+ do op <- Symbol.operator E.TupleOpen E.TupleOperatorReserved
134+ if op == "-"
135+ then
136+ oneOf E.TupleOperatorClose
137+ [
138+ do word1 0x29 {-)-} E.TupleOperatorClose
139+ addEnd start (Src.Op op)
140+ ,
141+ specialize E.TupleExpr $
142+ do negatedExpr@(A.At (A.Region _ end) _) <- term
143+ Space.chomp E.Space
144+ let exprStart = A.Position row (col + 2)
145+ let expr = A.at exprStart end (Src.Negate negatedExpr)
146+ fst <$> chompExprEnd exprStart (State [] expr [] end)
147+ ]
148+ else
149+ do word1 0x29 {-)-} E.TupleOperatorClose
150+ addEnd start (Src.Op op)
151+ ,
152+ do word1 0x29 {-)-} E.TupleOpen
153+ addEnd start Src.Unit
154+ ,
155+ do Space.chompAndCheckIndent E.TupleSpace E.TupleIndentExpr
156+ (entry, end) <- specialize E.TupleExpr expression
157+ Space.checkIndent end E.TupleIndentEnd
158+ chompTupleEnd start entry []
159+ ]
160+
161+
162+chompTupleEnd :: A.Position -> Src.Expr -> [Src.Expr] -> Parser E.Tuple Src.Expr
163+chompTupleEnd start firstExpr revExprs =
164+ oneOf E.TupleEnd
165+ [ do word1 0x2C {-,-} E.TupleEnd
166+ Space.chompAndCheckIndent E.TupleSpace E.TupleIndentExpr
167+ (entry, end) <- specialize E.TupleExpr expression
168+ Space.checkIndent end E.TupleIndentEnd
169+ chompTupleEnd start firstExpr (entry : revExprs)
170+ , do word1 0x29 {-)-} E.TupleEnd
179171 case reverse revExprs of
180172 [] ->
181173 return firstExpr
182174
183− secondExpr : others ->
184− return (A.at start end (Src.Tuple firstExpr secondExpr others))
175+ secondExpr : otherExprs ->
176+ addEnd start (Src.Tuple firstExpr secondExpr otherExprs)
185177 ]
186178
187179
@@ -189,30 +181,27 @@ tupleHelp start firstExpr revExprs =
189181-- RECORDS
190182
191183
192−record :: A.Position -> Parser Src.Expr
184+record :: A.Position -> Parser E.Expr Src.Expr
193185record start =
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
186+ inContext E.Record (word1 0x7B {- { -} E.Start) $
187+ do Space.chompAndCheckIndent E.RecordSpace E.RecordIndentOpen
188+ oneOf E.RecordOpen
189+ [ do word1 0x7D {-}-} E.RecordOpen
190+ addEnd start (Src.Record [])
191+ , do starter <- addLocation (Var.lower E.RecordField)
192+ Space.chompAndCheckIndent E.RecordSpace E.RecordIndentEquals
193+ oneOf E.RecordEquals
194+ [ do word1 0x7C {-|-} E.RecordEquals
195+ Space.chompAndCheckIndent E.RecordSpace E.RecordIndentField
205196 firstField <- chompField
206197 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
198+ addEnd start (Src.Update starter fields)
199+ , do word1 0x3D {-=-} E.RecordEquals
200+ Space.chompAndCheckIndent E.RecordSpace E.RecordIndentExpr
201+ (value, end) <- specialize E.RecordExpr expression
202+ Space.checkIndent end E.RecordIndentEnd
213203 fields <- chompFields [(starter, value)]
214− end <- getPosition
215− return (A.at start end (Src.Record fields))
204+ addEnd start (Src.Record fields)
216205 ]
217206 ]
218207
@@ -220,26 +209,26 @@ record start =
220209type Field = ( A.Located Name.Name, Src.Expr )
221210
222211
223−chompFields :: [Field] -> Parser [Field]
212+chompFields :: [Field] -> Parser E.Record [Field]
224213chompFields fields =
225− oneOf E.XXX
226− [ do word1 0x2C {-,-} E.XXX
227− spaces
214+ oneOf E.RecordEnd
215+ [ do word1 0x2C {-,-} E.RecordEnd
216+ Space.chompAndCheckIndent E.RecordSpace E.RecordField
228217 f <- chompField
229218 chompFields (f : fields)
230− , do word1 0x7D {-}-} E.XXX
219+ , do word1 0x7D {-}-} E.RecordEnd
231220 return (reverse fields)
232221 ]
233222
234223
235−chompField :: Parser Field
224+chompField :: Parser E.Record Field
236225chompField =
237− do key <- addLocation Var.lower
238− spaces
239− word1 0x3D {-=-} E.XXX
240− spaces
241− (value, _, pos) <- expression
242− checkSpace pos
226+ do key <- addLocation (Var.lower E.RecordField)
227+ Space.chompAndCheckIndent E.RecordSpace E.RecordIndentEquals
228+ word1 0x3D {-=-} E.RecordEquals
229+ Space.chompAndCheckIndent E.RecordSpace E.RecordIndentExpr
230+ (value, end) <- specialize E.RecordExpr expression
231+ Space.checkIndent end E.RecordIndentEnd
243232 return (key, value)
244233
245234
@@ -247,22 +236,18 @@ chompField =
247236-- EXPRESSIONS
248237
249238
250−type ExprParser =
251− SParser Src.Expr
252−
253−
254−expression :: ExprParser
239+expression :: Space.Parser E.Expr Src.Expr
255240expression =
256241 do start <- getPosition
257− oneOf E.XXX
242+ oneOf E.Start
258243 [ let_ start
259244 , if_ start
260245 , case_ start
261246 , function start
262247 , do expr <- possiblyNegativeTerm start
263248 end <- getPosition
264− space <- whitespace
265− exprHelp start (State [] expr [] end space)
249+ Space.chomp E.Space
250+ chompExprEnd start (State [] expr [] end)
266251 ]
267252
268253
@@ -272,77 +257,76 @@ data State =
272257 , _expr :: !Src.Expr
273258 , _args :: ![Src.Expr]
274259 , _end :: !A.Position
275− , _pos :: !SPos
276260 }
277261
278262
279−exprHelp :: A.Position -> State -> ExprParser
280−exprHelp start (State ops expr args end pos) =
281− oneOf E.XXX
263+chompExprEnd :: A.Position -> State -> Space.Parser E.Expr Src.Expr
264+chompExprEnd start (State ops expr args end) =
265+ oneOfWithFallback
282266 [ -- argument
283− do checkSpace pos
267+ do Space.checkIndent end E.IndentMoreExpr
284268 arg <- term
285269 newEnd <- getPosition
286− newPos <- whitespace
287− exprHelp start (State ops expr (arg:args) newEnd newPos)
288−
289− , -- infix operator
290− do checkSpace pos
291− opStart <- getPosition
292− opName <- Symbol.binop
293− opEnd <- getPosition
294− let op = A.at opStart opEnd opName
295− spos <- whitespace
296− checkSpace spos
270+ Space.chomp E.Space
271+ chompExprEnd start (State ops expr (arg:args) newEnd)
272+
273+ , -- operator
274+ do Space.checkIndent end E.IndentMoreExpr
275+ op@(A.At (A.Region opStart opEnd) opName) <- addLocation (Symbol.operator E.Start E.OperatorReserved)
276+ Space.chompAndCheckIndent E.Space E.IndentOperatorRight
297277 newStart <- getPosition
298278 if "-" == opName && end /= opStart && opEnd == newStart
299279 then
300280 -- negative terms
301− do rawTerm <- term
281+ do negatedExpr <- term
302282 newEnd <- getPosition
303− newPos <- whitespace
304− let arg = A.at opStart newEnd (Src.Negate rawTerm)
305− exprHelp start (State ops expr (arg:args) newEnd newPos)
283+ Space.chomp E.Space
284+ let arg = A.at opStart newEnd (Src.Negate negatedExpr)
285+ chompExprEnd start (State ops expr (arg:args) newEnd)
306286 else
307− oneOf E.XXX
287+ oneOf E.OperatorRight
308288 [ -- term
309289 do newExpr <- possiblyNegativeTerm newStart
310290 newEnd <- getPosition
311− newPos <- whitespace
291+ Space.chomp E.Space
312292 let newOps = (toCall expr args, op) : ops
313− exprHelp start (State newOps newExpr [] newEnd newPos)
293+ chompExprEnd start (State newOps newExpr [] newEnd)
314294
315295 , -- final term
316− do (newLast, newEnd, newPos) <-
317− oneOf E.XXX
296+ do (newLast, newEnd) <-
297+ oneOf E.OperatorRight
318298 [ let_ newStart
319299 , case_ newStart
320300 , if_ newStart
321301 , function newStart
322302 ]
323303 let newOps = (toCall expr args, op) : ops
324− let finalExpr = A.at start newEnd (Src.Binops (reverse newOps) newLast)
325− return ( finalExpr, newEnd, newPos )
304+ let finalExpr = Src.Binops (reverse newOps) newLast
305+ return ( A.at start newEnd finalExpr, newEnd )
326306 ]
327307
328− , -- done
329− let finalExpr = toCall expr args in
308+ ]
309+ -- done
310+ (
330311 case ops of
331312 [] ->
332− return ( finalExpr, end, pos )
313+ ( toCall expr args
314+ , end
315+ )
333316
334317 _ ->
335− return ( A.at start end (Src.Binops (reverse ops) finalExpr), end, pos )
336− ]
318+ ( A.at start end (Src.Binops (reverse ops) (toCall expr args))
319+ , end
320+ )
321+ )
337322
338323
339−possiblyNegativeTerm :: A.Position -> Parser Src.Expr
324+possiblyNegativeTerm :: A.Position -> Parser E.Expr Src.Expr
340325possiblyNegativeTerm start =
341− oneOf E.XXX
342− [ do word1 0x2D {---} E.XXX
326+ oneOf E.Start
327+ [ do word1 0x2D {---} E.Start
343328 expr <- term
344− end <- getPosition
345− return (A.at start end (Src.Negate expr))
329+ addEnd start (Src.Negate expr)
346330 , term
347331 ]
348332
@@ -361,30 +345,32 @@ toCall func revArgs =
361345-- IF EXPRESSION
362346
363347
364−if_ :: A.Position -> ExprParser
348+if_ :: A.Position -> Space.Parser E.Expr Src.Expr
365349if_ start =
366− inContext E.ExprIf Keyword.if_ $
367− ifHelp start []
368−
369−
370−ifHelp :: A.Position -> [(Src.Expr, Src.Expr)] -> ExprParser
371−ifHelp start branches =
372− do spaces
373− (condition, _, condPos) <- expression
374− checkSpace condPos
375− Keyword.then_
376− spaces
377− (thenBranch, _, thenPos) <- expression
378− checkSpace thenPos
379− Keyword.else_
380− spaces
350+ inContext E.If (Keyword.if_ E.Start) $
351+ chompIfEnd start []
352+
353+
354+chompIfEnd :: A.Position -> [(Src.Expr, Src.Expr)] -> Space.Parser E.If Src.Expr
355+chompIfEnd start branches =
356+ do Space.chompAndCheckIndent E.IfSpace E.IfIndentCondition
357+ (condition, condEnd) <- specialize E.IfCondition expression
358+ Space.checkIndent condEnd E.IfIndentThen
359+ Keyword.then_ E.IfThen
360+ Space.chompAndCheckIndent E.IfSpace E.IfIndentThenBranch
361+ (thenBranch, thenEnd) <- specialize E.IfThenBranch expression
362+ Space.checkIndent thenEnd E.IfIndentElse
363+ Keyword.else_ E.IfElse
364+ Space.chompAndCheckIndent E.IfSpace E.IfIndentElseBranch
381365 let newBranches = (condition, thenBranch) : branches
382− oneOf E.XXX
383− [ do Keyword.if_
384− ifHelp start newBranches
385− , do (elseBranch, elseEnd, elseSpace) <- expression
386− let ifExpr = A.at start elseEnd (Src.If (reverse newBranches) elseBranch)
387− return ( ifExpr, elseEnd, elseSpace )
366+ oneOf E.IfElseBranchStart
367+ [
368+ do Keyword.if_ E.IfElseBranchStart
369+ chompIfEnd start newBranches
370+ ,
371+ do (elseBranch, elseEnd) <- specialize E.IfElseBranch expression
372+ let ifExpr = Src.If (reverse newBranches) elseBranch
373+ return ( A.at start elseEnd ifExpr, elseEnd )
388374 ]
389375
390376
@@ -392,27 +378,27 @@ ifHelp start branches =
392378-- LAMBDA EXPRESSION
393379
394380
395−function :: A.Position -> ExprParser
381+function :: A.Position -> Space.Parser E.Expr Src.Expr
396382function start =
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 )
406−
407−
408−gatherArgs :: [Src.Pattern] -> Parser [Src.Pattern]
409−gatherArgs args =
410− oneOf E.XXX
411− [ do arg <- Pattern.term
412− spaces
413− gatherArgs (arg:args)
414− , do word2 0x2D 0x3E {-->-} E.XXX
415− return args
383+ inContext E.Func (word1 0x5C {-\-} E.Start) $
384+ do Space.chompAndCheckIndent E.FuncSpace E.FuncIndentArg
385+ arg <- specialize E.FuncArg Pattern.term
386+ Space.chompAndCheckIndent E.FuncSpace E.FuncIndentArrow
387+ revArgs <- chompArgs [arg]
388+ Space.chompAndCheckIndent E.FuncSpace E.FuncIndentBody
389+ (body, end) <- specialize E.FuncBody expression
390+ let funcExpr = Src.Lambda (reverse revArgs) body
391+ return (A.at start end funcExpr, end)
392+
393+
394+chompArgs :: [Src.Pattern] -> Parser E.Func [Src.Pattern]
395+chompArgs revArgs =
396+ oneOf E.FuncArrow
397+ [ do arg <- specialize E.FuncArg Pattern.term
398+ Space.chompAndCheckIndent E.FuncSpace E.FuncIndentArrow
399+ chompArgs (arg:revArgs)
400+ , do word2 0x2D 0x3E {-->-} E.FuncArrow
401+ return revArgs
416402 ]
417403
418404
@@ -420,90 +406,84 @@ gatherArgs args =
420406-- CASE EXPRESSIONS
421407
422408
423−case_ :: A.Position -> ExprParser
409+case_ :: A.Position -> Space.Parser E.Expr Src.Expr
424410case_ start =
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− )
442−
443−
444−branchHelp :: SParser (Src.Pattern, Src.Expr)
445−branchHelp =
446− do (pattern, patternPos) <- Pattern.expression
447− checkSpace patternPos
448− word2 0x2D 0x3E {-->-} E.XXX
449− spaces
450− (branchExpr, end, pos) <- expression
451− return ( (pattern, branchExpr), end, pos )
452−
453−
454−caseHelp :: [(Src.Pattern, Src.Expr)] -> A.Position -> SPos -> SParser [(Src.Pattern, Src.Expr)]
455−caseHelp branches end pos =
456− oneOf E.XXX
457− [ do checkAligned pos
458− (branch, newEnd, newPos) <- branchHelp
459− caseHelp (branch:branches) newEnd newPos
460− , return ( reverse branches, end, pos )
411+ inContext E.Case (Keyword.case_ E.Start) $
412+ do Space.chompAndCheckIndent E.CaseSpace E.CaseIndentExpr
413+ (expr, exprEnd) <- specialize E.CaseExpr expression
414+ Space.checkIndent exprEnd E.CaseIndentOf
415+ Keyword.of_ E.CaseOf
416+ Space.chompAndCheckIndent E.CaseSpace E.CaseIndentPattern
417+ withIndent $
418+ do (firstBranch, firstEnd) <- chompBranch
419+ (branches, end) <- chompCaseEnd [firstBranch] firstEnd
420+ return
421+ ( A.at start end (Src.Case expr branches)
422+ , end
423+ )
424+
425+
426+chompBranch :: Space.Parser E.Case (Src.Pattern, Src.Expr)
427+chompBranch =
428+ do (pattern, patternEnd) <- specialize E.CasePattern Pattern.expression
429+ Space.checkIndent patternEnd E.CaseIndentArrow
430+ word2 0x2D 0x3E {-->-} E.CaseArrow
431+ Space.chompAndCheckIndent E.CaseSpace E.CaseIndentBranch
432+ (branchExpr, end) <- specialize E.CaseBranch expression
433+ return ( (pattern, branchExpr), end )
434+
435+
436+chompCaseEnd :: [(Src.Pattern, Src.Expr)] -> A.Position -> Space.Parser E.Case [(Src.Pattern, Src.Expr)]
437+chompCaseEnd branches end =
438+ oneOfWithFallback
439+ [ do Space.checkAligned E.CasePatternAlignment
440+ (branch, newEnd) <- chompBranch
441+ chompCaseEnd (branch:branches) newEnd
461442 ]
443+ (reverse branches, end)
462444
463445
464446
465447-- LET EXPRESSION
466448
467449
468−let_ :: A.Position -> ExprParser
450+let_ :: A.Position -> Space.Parser E.Expr Src.Expr
469451let_ start =
470− do oldIndent <- getIndent
471− letIndent <- getCol
472− Keyword.let_
473− pushContext start E.ExprLet
474− setIndent letIndent
475− spaces
476− defIndent <- getCol
477− setIndent defIndent
478− (def, end, space) <- letDef
479− letHelp start oldIndent [def] end space
480−
481−
482−letHelp :: A.Position -> Word16 -> [A.Located Src.Def] -> A.Position -> SPos -> ExprParser
483−letHelp start oldIndent revDefs end pos =
484− oneOf E.XXX
485− [ do checkAligned pos
486− (def, newEnd, newPos) <- letDef
487− letHelp start oldIndent (def:revDefs) newEnd newPos
488−
489− , do setIndent oldIndent
490− checkSpace pos
491− Keyword.in_
492− popContext ()
493− spaces
494− (body, newEnd, newPos) <- expression
495− let letExpr = A.at start end (Src.Let (reverse revDefs) body)
496− return ( letExpr, newEnd, newPos )
452+ inContext E.Let (Keyword.let_ E.Start) $
453+ do (defs, defsEnd) <-
454+ withBacksetIndent 3 $
455+ do Space.chompAndCheckIndent E.LetSpace E.LetIndentDef
456+ withIndent $
457+ do (def, end) <- chompLetDef
458+ chompLetDefs [def] end
459+
460+ Space.checkIndent defsEnd E.LetIndentIn
461+ Keyword.in_ E.LetIn
462+ Space.chompAndCheckIndent E.LetSpace E.LetIndentBody
463+ (body, end) <- specialize E.LetBody expression
464+ return
465+ ( A.at start end (Src.Let defs body)
466+ , end
467+ )
468+
469+
470+chompLetDefs :: [A.Located Src.Def] -> A.Position -> Space.Parser E.Let [A.Located Src.Def]
471+chompLetDefs revDefs end =
472+ oneOfWithFallback
473+ [ do Space.checkAligned E.LetDefAlignment
474+ (def, newEnd) <- chompLetDef
475+ chompLetDefs (def:revDefs) newEnd
497476 ]
477+ (reverse revDefs, end)
498478
499479
500480
501481-- LET DEFINITIONS
502482
503483
504−letDef :: SParser (A.Located Src.Def)
505−letDef =
506− oneOf E.XXX
484+chompLetDef :: Space.Parser E.Let (A.Located Src.Def)
485+chompLetDef =
486+ oneOf E.LetDefName
507487 [ definition
508488 , destructure
509489 ]
@@ -513,61 +493,57 @@ letDef =
513493-- DEFINITION
514494
515495
516−definition :: SParser (A.Located Src.Def)
496+definition :: Space.Parser E.Let (A.Located Src.Def)
517497definition =
518− do start <- getPosition
519− name <- Var.lower
520− end <- getPosition
521− spaces
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
540− ]
541−
542−
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
547− spaces
548− definitionHelp start name tipe (arg : revArgs)
549− , do word1 0x3D {-=-} E.XXX
550− spaces
551− (body, end, space) <- expression
552− let def = A.at start end (Src.Define name (reverse revArgs) body tipe)
553− return ( def, end, space )
498+ do aname@(A.At (A.Region start _) name) <- addLocation (Var.lower E.LetDefName)
499+ specialize (E.LetDef name) $
500+ do Space.chompAndCheckIndent E.DefSpace E.DefIndentEquals
501+ oneOf E.DefEquals
502+ [
503+ do word1 0x3A {-:-} E.DefEquals
504+ Space.chompAndCheckIndent E.DefSpace E.DefIndentType
505+ (tipe, _) <- specialize E.DefType Type.expression
506+ Space.checkAligned E.DefAlignment
507+ defName <- chompMatchingName name
508+ Space.chompAndCheckIndent E.DefSpace E.DefIndentEquals
509+ chompDefArgsAndBody start defName (Just tipe) []
510+ ,
511+ chompDefArgsAndBody start aname Nothing []
512+ ]
513+
514+
515+chompDefArgsAndBody :: A.Position -> A.Located Name.Name -> Maybe Src.Type -> [Src.Pattern] -> Space.Parser E.Def (A.Located Src.Def)
516+chompDefArgsAndBody start name tipe revArgs =
517+ oneOf E.DefEquals
518+ [ do arg <- specialize E.DefArg Pattern.term
519+ Space.chompAndCheckIndent E.DefSpace E.DefIndentEquals
520+ chompDefArgsAndBody start name tipe (arg : revArgs)
521+ , do word1 0x3D {-=-} E.DefEquals
522+ Space.chompAndCheckIndent E.DefSpace E.DefIndentBody
523+ (body, end) <- specialize E.DefBody expression
524+ return
525+ ( A.at start end (Src.Define name (reverse revArgs) body tipe)
526+ , end
527+ )
554528 ]
555529
556530
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 ->
531+chompMatchingName :: Name.Name -> Parser E.Def (A.Located Name.Name)
532+chompMatchingName expectedName =
533+ let
534+ (P.Parser parserL) = Var.lower (E.DefNameRepeat expectedName)
535+ in
536+ P.Parser $ \state@(P.State _ _ _ sr sc) cok eok cerr eerr ->
561537 let
562− cokL name newState@(P.State _ _ _ er ec _) =
538+ cokL name newState@(P.State _ _ _ er ec) =
563539 if expectedName == name
564540 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)
541+ else cerr sr sc (E.DefNameMatch expectedName name)
566542
567− eokL name newState@(P.State _ _ _ er ec _) =
543+ eokL name newState@(P.State _ _ _ er ec) =
568544 if expectedName == name
569545 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)
546+ else eerr sr sc (E.DefNameMatch expectedName name)
571547 in
572548 parserL state cokL eokL cerr eerr
573549
@@ -577,12 +553,13 @@ matchingName expectedName =
577553-- DESTRUCTURE
578554
579555
580−destructure :: SParser (A.Located Src.Def)
556+destructure :: Space.Parser E.Let (A.Located Src.Def)
581557destructure =
558+ specialize E.LetDestruct $
582559 do start <- getPosition
583− pattern <- Pattern.term
584− spaces
585− word1 0x3D {-=-} E.XXX
586− spaces
587− (expr, end, space) <- expression
588− return ( A.at start end (Src.Destruct pattern expr), end, space )
560+ pattern <- specialize E.DestructPattern Pattern.term
561+ Space.chompAndCheckIndent E.DestructSpace E.DestructIndentEquals
562+ word1 0x3D {-=-} E.DestructEquals
563+ Space.chompAndCheckIndent E.DestructSpace E.DestructIndentBody
564+ (expr, end) <- specialize E.DestructBody expression
565+ return ( A.at start end (Src.Destruct pattern expr), end )
compiler/src/Parse/Keyword.hs+83−84
@@ -16,112 +16,111 @@ module Parse.Keyword
1616import Foreign.Ptr (plusPtr)
1717import Data.Word (Word8)
1818
19−import Parse.Utils (Parser)
19+import Parse.Primitives (Parser, Row, Col)
2020import qualified Parse.Variable as Var
2121import qualified Parse.Primitives as P
22−import qualified Reporting.Error.Syntax as E
2322
2423
2524
2625-- DECLARATIONS
2726
2827
29−type_ :: Parser ()
30−type_ = k4 0x74 0x79 0x70 0x65 E.KeywordType
28+type_ :: (Row -> Col -> x) -> Parser x ()
29+type_ tx = k4 0x74 0x79 0x70 0x65 tx
3130
32−alias_ :: Parser ()
33−alias_ = k5 0x61 0x6C 0x69 0x61 0x73 E.KeywordAlias
31+alias_ :: (Row -> Col -> x) -> Parser x ()
32+alias_ tx = k5 0x61 0x6C 0x69 0x61 0x73 tx
3433
35−port_ :: Parser ()
36−port_ = k4 0x70 0x6F 0x72 0x74 E.KeywordPort
34+port_ :: (Row -> Col -> x) -> Parser x ()
35+port_ tx = k4 0x70 0x6F 0x72 0x74 tx
3736
3837
3938
4039-- IF EXPRESSIONS
4140
4241
43−if_ :: Parser ()
44−if_ = k2 0x69 0x66 E.KeywordIf
42+if_ :: (Row -> Col -> x) -> Parser x ()
43+if_ tx = k2 0x69 0x66 tx
4544
46−then_ :: Parser ()
47−then_ = k4 0x74 0x68 0x65 0x6E E.KeywordThen
45+then_ :: (Row -> Col -> x) -> Parser x ()
46+then_ tx = k4 0x74 0x68 0x65 0x6E tx
4847
49−else_ :: Parser ()
50−else_ = k4 0x65 0x6C 0x73 0x65 E.KeywordElse
48+else_ :: (Row -> Col -> x) -> Parser x ()
49+else_ tx = k4 0x65 0x6C 0x73 0x65 tx
5150
5251
5352
5453-- CASE EXPRESSIONS
5554
5655
57−case_ :: Parser ()
58−case_ = k4 0x63 0x61 0x73 0x65 E.KeywordCase
56+case_ :: (Row -> Col -> x) -> Parser x ()
57+case_ tx = k4 0x63 0x61 0x73 0x65 tx
5958
60−of_ :: Parser ()
61−of_ = k2 0x6F 0x66 E.KeywordOf
59+of_ :: (Row -> Col -> x) -> Parser x ()
60+of_ tx = k2 0x6F 0x66 tx
6261
6362
6463
6564-- LET EXPRESSIONS
6665
6766
68−let_ :: Parser ()
69−let_ = k3 0x6C 0x65 0x74 E.KeywordLet
67+let_ :: (Row -> Col -> x) -> Parser x ()
68+let_ tx = k3 0x6C 0x65 0x74 tx
7069
71−in_ :: Parser ()
72−in_ = k2 0x69 0x6E E.KeywordIn
70+in_ :: (Row -> Col -> x) -> Parser x ()
71+in_ tx = k2 0x69 0x6E tx
7372
7473
7574
7675-- INFIXES
7776
7877
79−infix_ :: Parser ()
80−infix_ = k5 0x69 0x6E 0x66 0x69 0x78 E.KeywordInfix
78+infix_ :: (Row -> Col -> x) -> Parser x ()
79+infix_ tx = k5 0x69 0x6E 0x66 0x69 0x78 tx
8180
82−left_ :: Parser ()
83−left_ = k4 0x6C 0x65 0x66 0x74 E.Associativity
81+left_ :: (Row -> Col -> x) -> Parser x ()
82+left_ tx = k4 0x6C 0x65 0x66 0x74 tx
8483
85−right_ :: Parser ()
86−right_ = k5 0x72 0x69 0x67 0x68 0x74 E.Associativity
84+right_ :: (Row -> Col -> x) -> Parser x ()
85+right_ tx = k5 0x72 0x69 0x67 0x68 0x74 tx
8786
88−non_ :: Parser ()
89−non_ = k3 0x6E 0x6F 0x6E E.Associativity
87+non_ :: (Row -> Col -> x) -> Parser x ()
88+non_ tx = k3 0x6E 0x6F 0x6E tx
9089
9190
9291
9392-- IMPORTS
9493
9594
96−module_ :: Parser ()
97−module_ = k6 0x6D 0x6F 0x64 0x75 0x6C 0x65 E.KeywordModule
95+module_ :: (Row -> Col -> x) -> Parser x ()
96+module_ tx = k6 0x6D 0x6F 0x64 0x75 0x6C 0x65 tx
9897
99−import_ :: Parser ()
100−import_ = k6 0x69 0x6D 0x70 0x6F 0x72 0x74 E.KeywordImport
98+import_ :: (Row -> Col -> x) -> Parser x ()
99+import_ tx = k6 0x69 0x6D 0x70 0x6F 0x72 0x74 tx
101100
102−exposing_ :: Parser ()
103−exposing_ = k8 0x65 0x78 0x70 0x6F 0x73 0x69 0x6E 0x67 E.KeywordExposing
101+exposing_ :: (Row -> Col -> x) -> Parser x ()
102+exposing_ tx = k8 0x65 0x78 0x70 0x6F 0x73 0x69 0x6E 0x67 tx
104103
105−as_ :: Parser ()
106−as_ = k2 0x61 0x73 E.KeywordAs
104+as_ :: (Row -> Col -> x) -> Parser x ()
105+as_ tx = k2 0x61 0x73 tx
107106
108107
109108
110109-- EFFECTS
111110
112111
113−effect_ :: Parser ()
114−effect_ = k6 0x65 0x66 0x66 0x65 0x63 0x74 E.EffectStuff
112+effect_ :: (Row -> Col -> x) -> Parser x ()
113+effect_ tx = k6 0x65 0x66 0x66 0x65 0x63 0x74 tx
115114
116−where_ :: Parser ()
117−where_ = k5 0x77 0x68 0x65 0x72 0x65 E.EffectStuff
115+where_ :: (Row -> Col -> x) -> Parser x ()
116+where_ tx = k5 0x77 0x68 0x65 0x72 0x65 tx
118117
119−command_ :: Parser ()
120−command_ = k7 0x63 0x6F 0x6D 0x6D 0x61 0x6E 0x64 E.EffectStuff
118+command_ :: (Row -> Col -> x) -> Parser x ()
119+command_ tx = k7 0x63 0x6F 0x6D 0x6D 0x61 0x6E 0x64 tx
121120
122−subscription_ :: Parser ()
123−subscription_ =
124− P.Parser $ \(P.State pos end indent row col ctx) cok _ _ eerr ->
121+subscription_ :: (Row -> Col -> x) -> Parser x ()
122+subscription_ toError =
123+ P.Parser $ \(P.State pos end indent row col) cok _ _ eerr ->
125124 let !pos12 = plusPtr pos 12 in
126125 if pos12 <= end
127126 && P.unsafeIndex ( pos ) == 0x73
@@ -138,32 +137,32 @@ subscription_ =
138137 && P.unsafeIndex (plusPtr pos 11) == 0x6E
139138 && Var.getInnerWidth pos12 end == 0
140139 then
141− let !s = P.State pos12 end indent row (col + 12) ctx in cok () s
140+ let !s = P.State pos12 end indent row (col + 12) in cok () s
142141 else
143− eerr row col ctx E.EffectStuff
142+ eerr row col toError
144143
145144
146145
147146-- KEYWORDS
148147
149148
150−k2 :: Word8 -> Word8 -> x -> P.Parser c x ()
151−k2 w1 w2 x =
152− P.Parser $ \(P.State pos end indent row col ctx) cok _ _ eerr ->
149+k2 :: Word8 -> Word8 -> (Row -> Col -> x) -> Parser x ()
150+k2 w1 w2 toError =
151+ P.Parser $ \(P.State pos end indent row col) cok _ _ eerr ->
153152 let !pos2 = plusPtr pos 2 in
154153 if pos2 <= end
155154 && P.unsafeIndex ( pos ) == w1
156155 && P.unsafeIndex (plusPtr pos 1) == w2
157156 && Var.getInnerWidth pos2 end == 0
158157 then
159− let !s = P.State pos2 end indent row (col + 2) ctx in cok () s
158+ let !s = P.State pos2 end indent row (col + 2) in cok () s
160159 else
161− eerr row col ctx x
160+ eerr row col toError
162161
163162
164−k3 :: Word8 -> Word8 -> Word8 -> x -> P.Parser c x ()
165−k3 w1 w2 w3 x =
166− P.Parser $ \(P.State pos end indent row col ctx) cok _ _ eerr ->
163+k3 :: Word8 -> Word8 -> Word8 -> (Row -> Col -> x) -> Parser x ()
164+k3 w1 w2 w3 toError =
165+ P.Parser $ \(P.State pos end indent row col) cok _ _ eerr ->
167166 let !pos3 = plusPtr pos 3 in
168167 if pos3 <= end
169168 && P.unsafeIndex ( pos ) == w1
@@ -171,14 +170,14 @@ k3 w1 w2 w3 x =
171170 && P.unsafeIndex (plusPtr pos 2) == w3
172171 && Var.getInnerWidth pos3 end == 0
173172 then
174− let !s = P.State pos3 end indent row (col + 3) ctx in cok () s
173+ let !s = P.State pos3 end indent row (col + 3) in cok () s
175174 else
176− eerr row col ctx x
175+ eerr row col toError
177176
178177
179−k4 :: Word8 -> Word8 -> Word8 -> Word8 -> x -> P.Parser c x ()
180−k4 w1 w2 w3 w4 x =
181− P.Parser $ \(P.State pos end indent row col ctx) cok _ _ eerr ->
178+k4 :: Word8 -> Word8 -> Word8 -> Word8 -> (Row -> Col -> x) -> Parser x ()
179+k4 w1 w2 w3 w4 toError =
180+ P.Parser $ \(P.State pos end indent row col) cok _ _ eerr ->
182181 let !pos4 = plusPtr pos 4 in
183182 if pos4 <= end
184183 && P.unsafeIndex ( pos ) == w1
@@ -187,14 +186,14 @@ k4 w1 w2 w3 w4 x =
187186 && P.unsafeIndex (plusPtr pos 3) == w4
188187 && Var.getInnerWidth pos4 end == 0
189188 then
190− let !s = P.State pos4 end indent row (col + 4) ctx in cok () s
189+ let !s = P.State pos4 end indent row (col + 4) in cok () s
191190 else
192− eerr row col ctx x
191+ eerr row col toError
193192
194193
195−k5 :: Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> x -> P.Parser c x ()
196−k5 w1 w2 w3 w4 w5 x =
197− P.Parser $ \(P.State pos end indent row col ctx) cok _ _ eerr ->
194+k5 :: Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> (Row -> Col -> x) -> Parser x ()
195+k5 w1 w2 w3 w4 w5 toError =
196+ P.Parser $ \(P.State pos end indent row col) cok _ _ eerr ->
198197 let !pos5 = plusPtr pos 5 in
199198 if pos5 <= end
200199 && P.unsafeIndex ( pos ) == w1
@@ -204,14 +203,14 @@ k5 w1 w2 w3 w4 w5 x =
204203 && P.unsafeIndex (plusPtr pos 4) == w5
205204 && Var.getInnerWidth pos5 end == 0
206205 then
207− let !s = P.State pos5 end indent row (col + 5) ctx in cok () s
206+ let !s = P.State pos5 end indent row (col + 5) in cok () s
208207 else
209− eerr row col ctx x
208+ eerr row col toError
210209
211210
212−k6 :: Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> x -> P.Parser c x ()
213−k6 w1 w2 w3 w4 w5 w6 x =
214− P.Parser $ \(P.State pos end indent row col ctx) cok _ _ eerr ->
211+k6 :: Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> (Row -> Col -> x) -> Parser x ()
212+k6 w1 w2 w3 w4 w5 w6 toError =
213+ P.Parser $ \(P.State pos end indent row col) cok _ _ eerr ->
215214 let !pos6 = plusPtr pos 6 in
216215 if pos6 <= end
217216 && P.unsafeIndex ( pos ) == w1
@@ -222,14 +221,14 @@ k6 w1 w2 w3 w4 w5 w6 x =
222221 && P.unsafeIndex (plusPtr pos 5) == w6
223222 && Var.getInnerWidth pos6 end == 0
224223 then
225− let !s = P.State pos6 end indent row (col + 6) ctx in cok () s
224+ let !s = P.State pos6 end indent row (col + 6) in cok () s
226225 else
227− eerr row col ctx x
226+ eerr row col toError
228227
229228
230−k7 :: Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> x -> P.Parser c x ()
231−k7 w1 w2 w3 w4 w5 w6 w7 x =
232− P.Parser $ \(P.State pos end indent row col ctx) cok _ _ eerr ->
229+k7 :: Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> (Row -> Col -> x) -> Parser x ()
230+k7 w1 w2 w3 w4 w5 w6 w7 toError =
231+ P.Parser $ \(P.State pos end indent row col) cok _ _ eerr ->
233232 let !pos7 = plusPtr pos 7 in
234233 if pos7 <= end
235234 && P.unsafeIndex ( pos ) == w1
@@ -241,14 +240,14 @@ k7 w1 w2 w3 w4 w5 w6 w7 x =
241240 && P.unsafeIndex (plusPtr pos 6) == w7
242241 && Var.getInnerWidth pos7 end == 0
243242 then
244− let !s = P.State pos7 end indent row (col + 7) ctx in cok () s
243+ let !s = P.State pos7 end indent row (col + 7) in cok () s
245244 else
246− eerr row col ctx x
245+ eerr row col toError
247246
248247
249−k8 :: Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> x -> P.Parser c x ()
250−k8 w1 w2 w3 w4 w5 w6 w7 w8 x =
251− P.Parser $ \(P.State pos end indent row col ctx) cok _ _ eerr ->
248+k8 :: Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> (Row -> Col -> x) -> Parser x ()
249+k8 w1 w2 w3 w4 w5 w6 w7 w8 toError =
250+ P.Parser $ \(P.State pos end indent row col) cok _ _ eerr ->
252251 let !pos8 = plusPtr pos 8 in
253252 if pos8 <= end
254253 && P.unsafeIndex ( pos ) == w1
@@ -261,6 +260,6 @@ k8 w1 w2 w3 w4 w5 w6 w7 w8 x =
261260 && P.unsafeIndex (plusPtr pos 7) == w8
262261 && Var.getInnerWidth pos8 end == 0
263262 then
264− let !s = P.State pos8 end indent row (col + 8) ctx in cok () s
263+ let !s = P.State pos8 end indent row (col + 8) in cok () s
265264 else
266− eerr row col ctx x
265+ eerr row col toError
compiler/src/Parse/Number.hs+25−25
@@ -16,7 +16,7 @@ import Data.Word (Word8)
1616import Foreign.Ptr (Ptr, plusPtr, minusPtr)
1717
1818import qualified AST.Utils.Binop as Binop
19−import Parse.Utils (Parser)
19+import Parse.Primitives (Parser, Row, Col)
2020import qualified Parse.Variable as Var
2121import qualified Parse.Primitives as P
2222import qualified Reporting.Error.Syntax as E
@@ -46,16 +46,16 @@ data Number
4646 | Float (Utf8.Under256 Float)
4747
4848
49−number :: Parser Number
50−number =
51− P.Parser $ \(P.State pos end indent row col ctx) cok _ cerr eerr ->
49+number :: (Row -> Col -> x) -> (E.Number -> Row -> Col -> x) -> Parser x Number
50+number toExpectation toError =
51+ P.Parser $ \(P.State pos end indent row col) cok _ cerr eerr ->
5252 if pos >= end then
53− eerr row col ctx E.Number_Start
53+ eerr row col toExpectation
5454
5555 else
5656 let !word = P.unsafeIndex pos in
5757 if not (isDecimalDigit word) then
58− eerr row col ctx E.Number_Start
58+ eerr row col toExpectation
5959
6060 else
6161 let
@@ -70,13 +70,13 @@ number =
7070 let
7171 !newCol = col + fromIntegral (minusPtr newPos pos)
7272 in
73− cerr row newCol ctx problem
73+ cerr row newCol (toError problem)
7474
7575 OkInt newPos n ->
7676 let
7777 !newCol = col + fromIntegral (minusPtr newPos pos)
7878 !integer = Int n
79− !newState = P.State newPos end indent row newCol ctx
79+ !newState = P.State newPos end indent row newCol
8080 in
8181 cok integer newState
8282
@@ -85,7 +85,7 @@ number =
8585 !newCol = col + fromIntegral (minusPtr newPos pos)
8686 !copy = Utf8.fromPtr pos newPos
8787 !float = Float copy
88− !newState = P.State newPos end indent row newCol ctx
88+ !newState = P.State newPos end indent row newCol
8989 in
9090 cok float newState
9191
@@ -97,7 +97,7 @@ number =
9797-- first Int is newPos
9898--
9999data Outcome
100− = Err (Ptr Word8) E.Expectation
100+ = Err (Ptr Word8) E.Number
101101 | OkInt (Ptr Word8) Int
102102 | OkFloat (Ptr Word8)
103103
@@ -127,7 +127,7 @@ chompInt !pos end !n =
127127 chompExponent (plusPtr pos 1) end
128128
129129 else if isDirtyEnd pos end word then
130− Err pos E.Number_End
130+ Err pos E.NumberEnd
131131
132132 else
133133 OkInt pos n
@@ -140,13 +140,13 @@ chompInt !pos end !n =
140140chompFraction :: Ptr Word8 -> Ptr Word8 -> Int -> Outcome
141141chompFraction pos end n =
142142 if pos >= end then
143− Err pos (E.Number_Dot n)
143+ Err pos (E.NumberDot n)
144144
145145 else if isDecimalDigit (P.unsafeIndex pos) then
146146 chompFractionHelp (plusPtr pos 1) end
147147
148148 else
149− Err pos (E.Number_Dot n)
149+ Err pos (E.NumberDot n)
150150
151151
152152chompFractionHelp :: Ptr Word8 -> Ptr Word8 -> Outcome
@@ -163,7 +163,7 @@ chompFractionHelp pos end =
163163 chompExponent (plusPtr pos 1) end
164164
165165 else if isDirtyEnd pos end word then
166− Err pos E.Number_End
166+ Err pos E.NumberEnd
167167
168168 else
169169 OkFloat pos
@@ -176,7 +176,7 @@ chompFractionHelp pos end =
176176chompExponent :: Ptr Word8 -> Ptr Word8 -> Outcome
177177chompExponent pos end =
178178 if pos >= end then
179− Err pos E.Number_End
179+ Err pos E.NumberEnd
180180
181181 else
182182 let !word = P.unsafeIndex pos in
@@ -189,10 +189,10 @@ chompExponent pos end =
189189 if pos1 < end && isDecimalDigit (P.unsafeIndex pos1) then
190190 chompExponentHelp (plusPtr pos 2) end
191191 else
192− Err pos E.Number_End
192+ Err pos E.NumberEnd
193193
194194 else
195− Err pos E.Number_End
195+ Err pos E.NumberEnd
196196
197197
198198chompExponentHelp :: Ptr Word8 -> Ptr Word8 -> Outcome
@@ -225,10 +225,10 @@ chompZero pos end =
225225 chompFraction (plusPtr pos 1) end 0
226226
227227 else if isDecimalDigit word then
228− Err pos E.Number_NoLeadingZero
228+ Err pos E.NumberNoLeadingZero
229229
230230 else if isDirtyEnd pos end word then
231− Err pos E.Number_End
231+ Err pos E.NumberEnd
232232
233233 else
234234 OkInt pos 0
@@ -238,7 +238,7 @@ chompHexInt :: Ptr Word8 -> Ptr Word8 -> Outcome
238238chompHexInt pos end =
239239 let (# newPos, answer #) = chompHex pos end in
240240 if answer < 0 then
241− Err newPos E.Number_HexDigit
241+ Err newPos E.NumberHexDigit
242242 else
243243 OkInt newPos answer
244244
@@ -285,18 +285,18 @@ stepHex pos end word acc
285285-- PRECEDENCE
286286
287287
288−precedence :: Parser Binop.Precedence
288+precedence :: Parser E.Infix Binop.Precedence
289289precedence =
290− P.Parser $ \(P.State pos end indent row col ctx) cok _ _ eerr ->
290+ P.Parser $ \(P.State pos end indent row col) cok _ _ eerr ->
291291 if pos >= end then
292− eerr row col ctx E.Precedence
292+ eerr row col E.Precedence
293293
294294 else
295295 let !word = P.unsafeIndex pos in
296296 if isDecimalDigit word then
297297 cok
298298 (Binop.Precedence (fromIntegral (word - 0x30 {-0-})))
299− (P.State (plusPtr pos 1) end indent row (col + 1) ctx)
299+ (P.State (plusPtr pos 1) end indent row (col + 1))
300300
301301 else
302− eerr row col ctx E.Precedence
302+ eerr row col E.Precedence
compiler/src/Parse/Pattern.hs+103−120
@@ -9,16 +9,17 @@ module Parse.Pattern
99
1010import qualified Data.List as List
1111import qualified Data.Name as Name
12+import qualified Data.Utf8 as Utf8
1213
1314import qualified AST.Source as Src
14−import Parse.Utils (Parser, SParser, SPos, checkSpace, spaces, whitespace)
1515import qualified Parse.Keyword as Keyword
1616import qualified Parse.Number as Number
17+import qualified Parse.Space as Space
1718import qualified Parse.Symbol as Symbol
1819import qualified Parse.Utf8 as Utf8
1920import qualified Parse.Variable as Var
2021import qualified Parse.Primitives as P
21−import Parse.Primitives (addLocation, getPosition, inContext, oneOf, word1)
22+import Parse.Primitives (Parser, addLocation, addEnd, getPosition, inContext, oneOf, oneOfWithFallback, word1, word2)
2223import qualified Reporting.Annotation as A
2324import qualified Reporting.Error.Syntax as E
2425
@@ -27,10 +28,10 @@ import qualified Reporting.Error.Syntax as E
2728-- TERM
2829
2930
30−term :: Parser Src.Pattern
31+term :: Parser E.Pattern Src.Pattern
3132term =
3233 do start <- getPosition
33− oneOf E.XXX
34+ oneOf E.PStart
3435 [ record start
3536 , tuple start
3637 , list start
@@ -38,19 +39,17 @@ term =
3839 ]
3940
4041
41−termHelp :: A.Position -> Parser Src.Pattern
42+termHelp :: A.Position -> Parser E.Pattern Src.Pattern
4243termHelp start =
43− oneOf E.XXX
44+ oneOf E.PStart
4445 [
45− do Symbol.underscore
46− end <- getPosition
47− return (A.at start end Src.PAnything)
46+ do Symbol.wildcard
47+ addEnd start Src.PAnything
4848 ,
49− do name <- Var.lower
50− end <- getPosition
51− return (A.at start end (Src.PVar name))
49+ do name <- Var.lower E.PStart
50+ addEnd start (Src.PVar name)
5251 ,
53− do upper <- Var.foreignUpper
52+ do upper <- Var.foreignUpper E.PStart
5453 end <- getPosition
5554 let region = A.Region start end
5655 return $ A.at start end $
@@ -61,60 +60,51 @@ termHelp start =
6160 Var.Qualified home name ->
6261 Src.PCtorQual region home name []
6362 ,
64− do number <- Number.number
63+ do number <- Number.number E.PStart E.PNumber
6564 end <- getPosition
6665 case number of
6766 Number.Int int ->
6867 return (A.at start end (Src.PInt int))
6968
70− Number.Float _ ->
71− noFloatsAllowedInPatterns
69+ Number.Float float ->
70+ P.Parser $ \(P.State _ _ _ row col) _ _ cerr _ ->
71+ cerr row col (E.PFloat (Utf8.size float))
7272 ,
73− do str <- Utf8.string
74− end <- getPosition
75− return (A.at start end (Src.PStr str))
73+ do str <- Utf8.string E.PStart E.PString
74+ addEnd start (Src.PStr str)
7675 ,
77− do chr <- Utf8.character
78− end <- getPosition
79− return (A.at start end (Src.PChr chr))
76+ do chr <- Utf8.character E.PStart E.PChar
77+ addEnd start (Src.PChr chr)
8078 ]
8179
8280
83−noFloatsAllowedInPatterns :: Parser a
84−noFloatsAllowedInPatterns =
85− P.Parser $ \(P.State _ _ _ row col ctx) _ _ cerr _ ->
86− cerr row col ctx E.FloatInPattern
87−
88−
8981
9082-- RECORDS
9183
9284
93−record :: A.Position -> Parser Src.Pattern
85+record :: A.Position -> Parser E.Pattern Src.Pattern
9486record start =
95− inContext E.ExprRecord (word1 0x7B {- { -} E.XXX) $
96− do spaces
97− oneOf E.XXX
98− [ do var <- addLocation Var.lower
99− spaces
87+ inContext E.PRecord (word1 0x7B {- { -} E.PStart) $
88+ do Space.chompAndCheckIndent E.PRecordSpace E.PRecordIndentOpen
89+ oneOf E.PRecordOpen
90+ [ do var <- addLocation (Var.lower E.PRecordField)
91+ Space.chompAndCheckIndent E.PRecordSpace E.PRecordIndentEnd
10092 recordHelp start [var]
101− , do word1 0x7D {-}-} E.XXX
102− end <- getPosition
103− return (A.at start end (Src.PRecord []))
93+ , do word1 0x7D {-}-} E.PRecordEnd
94+ addEnd start (Src.PRecord [])
10495 ]
10596
10697
107−recordHelp :: A.Position -> [A.Located Name.Name] -> Parser Src.Pattern
98+recordHelp :: A.Position -> [A.Located Name.Name] -> Parser E.PRecord Src.Pattern
10899recordHelp start vars =
109− oneOf E.XXX
110− [ do word1 0x2C {-,-} E.XXX
111− spaces
112− var <- addLocation Var.lower
113− spaces
100+ oneOf E.PRecordEnd
101+ [ do word1 0x2C {-,-} E.PRecordEnd
102+ Space.chompAndCheckIndent E.PRecordSpace E.PRecordIndentField
103+ var <- addLocation (Var.lower E.PRecordField)
104+ Space.chompAndCheckIndent E.PRecordSpace E.PRecordIndentEnd
114105 recordHelp start (var:vars)
115− , do word1 0x7D {-}-} E.XXX
116− end <- getPosition
117− return (A.at start end (Src.PRecord vars))
106+ , do word1 0x7D {-}-} E.PRecordEnd
107+ addEnd start (Src.PRecord vars)
118108 ]
119109
120110
@@ -122,36 +112,34 @@ recordHelp start vars =
122112-- TUPLES
123113
124114
125−tuple :: A.Position -> Parser Src.Pattern
115+tuple :: A.Position -> Parser E.Pattern Src.Pattern
126116tuple start =
127− inContext E.ExprTuple (word1 0x28 {-(-} E.XXX) $
128− do spaces
129− oneOf E.XXX
130− [ do (pattern, sPos) <- expression
131− checkSpace sPos
117+ inContext E.PTuple (word1 0x28 {-(-} E.PStart) $
118+ do Space.chompAndCheckIndent E.PTupleSpace E.PTupleIndentOpen
119+ oneOf E.PTupleOpen
120+ [ do (pattern, end) <- P.specialize E.PTupleExpr expression
121+ Space.checkIndent end E.PTupleIndentEnd
132122 tupleHelp start pattern []
133− , do word1 0x29 {-)-} E.XXX
134− end <- getPosition
135− return (A.at start end Src.PUnit)
123+ , do word1 0x29 {-)-} E.PTupleEnd
124+ addEnd start Src.PUnit
136125 ]
137126
138127
139−tupleHelp :: A.Position -> Src.Pattern -> [Src.Pattern] -> Parser Src.Pattern
128+tupleHelp :: A.Position -> Src.Pattern -> [Src.Pattern] -> Parser E.PTuple Src.Pattern
140129tupleHelp start firstPattern revPatterns =
141− oneOf E.XXX
142− [ do word1 0x2C {-,-} E.XXX
143− spaces
144− (pattern, sPos) <- expression
145− checkSpace sPos
130+ oneOf E.PTupleEnd
131+ [ do word1 0x2C {-,-} E.PTupleEnd
132+ Space.chompAndCheckIndent E.PTupleSpace E.PTupleIndentExpr
133+ (pattern, end) <- P.specialize E.PTupleExpr expression
134+ Space.checkIndent end E.PTupleIndentEnd
146135 tupleHelp start firstPattern (pattern : revPatterns)
147− , do word1 0x29 {-)-} E.XXX
136+ , do word1 0x29 {-)-} E.PTupleEnd
148137 case reverse revPatterns of
149138 [] ->
150139 return firstPattern
151140
152141 secondPattern : otherPatterns ->
153− do end <- getPosition
154− return (A.at start end (Src.PTuple firstPattern secondPattern otherPatterns))
142+ addEnd start (Src.PTuple firstPattern secondPattern otherPatterns)
155143 ]
156144
157145
@@ -159,31 +147,29 @@ tupleHelp start firstPattern revPatterns =
159147-- LIST
160148
161149
162−list :: A.Position -> Parser Src.Pattern
150+list :: A.Position -> Parser E.Pattern Src.Pattern
163151list start =
164− inContext E.PatternList (word1 0x5B {-[-} E.XXX) $
165− do spaces
166− oneOf E.XXX
167− [ do (pattern, sPos) <- expression
168− checkSpace sPos
152+ inContext E.PList (word1 0x5B {-[-} E.PStart) $
153+ do Space.chompAndCheckIndent E.PListSpace E.PListIndentOpen
154+ oneOf E.PListOpen
155+ [ do (pattern, end) <- P.specialize E.PListExpr expression
156+ Space.checkIndent end E.PListIndentEnd
169157 listHelp start [pattern]
170− , do word1 0x5D {-]-} E.XXX
171− end <- getPosition
172− return (A.at start end (Src.PList []))
158+ , do word1 0x5D {-]-} E.PListEnd
159+ addEnd start (Src.PList [])
173160 ]
174161
175162
176−listHelp :: A.Position -> [Src.Pattern] -> Parser Src.Pattern
163+listHelp :: A.Position -> [Src.Pattern] -> Parser E.PList Src.Pattern
177164listHelp start patterns =
178− oneOf E.XXX
179− [ do word1 0x2C {-,-} E.XXX
180− spaces
181− (pattern, sPos) <- expression
182− checkSpace sPos
165+ oneOf E.PListEnd
166+ [ do word1 0x2C {-,-} E.PListEnd
167+ Space.chompAndCheckIndent E.PListSpace E.PListIndentExpr
168+ (pattern, end) <- P.specialize E.PListExpr expression
169+ Space.checkIndent end E.PListIndentEnd
183170 listHelp start (pattern:patterns)
184− , do word1 0x5D {-]-} E.XXX
185− end <- getPosition
186− return (A.at start end (Src.PList (reverse patterns)))
171+ , do word1 0x5D {-]-} E.PListEnd
172+ addEnd start (Src.PList (reverse patterns))
187173 ]
188174
189175
@@ -191,38 +177,37 @@ listHelp start patterns =
191177-- EXPRESSION
192178
193179
194−expression :: Parser (Src.Pattern, SPos)
180+expression :: Space.Parser E.Pattern Src.Pattern
195181expression =
196182 do start <- getPosition
197183 cTerm <- exprTerm
198184 exprHelp start [] cTerm
199185
200186
201−exprHelp :: A.Position -> [Src.Pattern] -> (Src.Pattern, A.Position, SPos) -> Parser (Src.Pattern, SPos)
202−exprHelp start patterns (pattern, _end, sPos) =
203− oneOf E.XXX
204− [ do checkSpace sPos
205− word1 0x3A {-:-} E.XXX
206− spaces
187+exprHelp :: A.Position -> [Src.Pattern] -> (Src.Pattern, A.Position) -> Space.Parser E.Pattern Src.Pattern
188+exprHelp start patterns (pattern, end) =
189+ oneOfWithFallback
190+ [ do Space.checkIndent end E.PIndentStart
191+ word2 0x3A 0x3A {-::-} E.PStart
192+ Space.chompAndCheckIndent E.PSpace E.PIndentStart
207193 cTerm <- exprTerm
208194 exprHelp start (pattern:patterns) cTerm
209− , do checkSpace sPos
210− Keyword.as_
211− spaces
195+ , do Space.checkIndent end E.PIndentStart
196+ Keyword.as_ E.PStart
197+ Space.chompAndCheckIndent E.PSpace E.PIndentAlias
212198 nameStart <- getPosition
213− name <- Var.lower
199+ name <- Var.lower E.PAlias
214200 newEnd <- getPosition
215− newSpace <- whitespace
201+ Space.chomp E.PSpace
216202 let alias = A.at nameStart newEnd name
217203 return
218204 ( A.at start newEnd (Src.PAlias (List.foldl' cons pattern patterns) alias)
219− , newSpace
205+ , newEnd
220206 )
221− , return
222− ( List.foldl' cons pattern patterns
223− , sPos
224− )
225207 ]
208+ ( List.foldl' cons pattern patterns
209+ , end
210+ )
226211
227212
228213cons :: Src.Pattern -> Src.Pattern -> Src.Pattern
@@ -234,38 +219,36 @@ cons tl hd =
234219-- EXPRESSION TERM
235220
236221
237−exprTerm :: SParser Src.Pattern
222+exprTerm :: Space.Parser E.Pattern Src.Pattern
238223exprTerm =
239− oneOf E.XXX
224+ oneOf E.PStart
240225 [
241226 do start <- getPosition
242− upper <- Var.foreignUpper
227+ upper <- Var.foreignUpper E.PStart
243228 end <- getPosition
244229 exprTermHelp (A.Region start end) upper start []
245230 ,
246− do t@(A.At (A.Region _ end) _) <- term
247− pos <- whitespace
248− return (t, end, pos)
231+ do eterm@(A.At (A.Region _ end) _) <- term
232+ Space.chomp E.PSpace
233+ return (eterm, end)
249234 ]
250235
251236
252−exprTermHelp :: A.Region -> Var.Upper -> A.Position -> [Src.Pattern] -> SParser Src.Pattern
237+exprTermHelp :: A.Region -> Var.Upper -> A.Position -> [Src.Pattern] -> Space.Parser E.Pattern Src.Pattern
253238exprTermHelp region upper start revArgs =
254239 do end <- getPosition
255− sPos <- whitespace
256− oneOf E.XXX
257− [ do checkSpace sPos
240+ Space.chomp E.PSpace
241+ oneOfWithFallback
242+ [ do Space.checkIndent end E.PIndentStart
258243 arg <- term
259244 exprTermHelp region upper start (arg:revArgs)
260− , return
261− ( A.at start end $
262− case upper of
263− Var.Unqualified name ->
264− Src.PCtor region name (reverse revArgs)
265−
266− Var.Qualified home name ->
267− Src.PCtorQual region home name (reverse revArgs)
268− , end
269− , sPos
270− )
271245 ]
246+ ( A.at start end $
247+ case upper of
248+ Var.Unqualified name ->
249+ Src.PCtor region name (reverse revArgs)
250+
251+ Var.Qualified home name ->
252+ Src.PCtorQual region home name (reverse revArgs)
253+ , end
254+ )
compiler/src/Parse/Shader.hs+17−17
@@ -10,8 +10,8 @@ import qualified Data.List as List
1010import qualified Data.Map as Map
1111import qualified Data.Name as Name
1212import qualified Data.Utf8 as Utf8
13−import Data.Word (Word8, Word16)
14−import Foreign.Ptr (Ptr, plusPtr, minusPtr)
13+import Data.Word (Word8)
14+import Foreign.Ptr (Ptr, plusPtr)
1515import qualified Language.GLSL.Parser as GLP
1616import qualified Language.GLSL.Syntax as GLS
1717import qualified Text.Parsec as Parsec
@@ -19,7 +19,7 @@ import qualified Text.Parsec.Error as Parsec
1919
2020import qualified AST.Source as Src
2121import qualified AST.Utils.Shader as Shader
22−import Parse.Utils (Parser)
22+import Parse.Primitives (Parser, Row, Col)
2323import qualified Parse.Primitives as P
2424import qualified Reporting.Annotation as A
2525import qualified Reporting.Error.Syntax as E
@@ -29,7 +29,7 @@ import qualified Reporting.Error.Syntax as E
2929-- SHADER
3030
3131
32−shader :: A.Position -> Parser Src.Expr
32+shader :: A.Position -> Parser E.Expr Src.Expr
3333shader start@(A.Position row col) =
3434 do block <- parseBlock
3535 shdr <- parseGlsl row col block
@@ -42,9 +42,9 @@ shader start@(A.Position row col) =
4242-- BLOCK
4343
4444
45−parseBlock :: Parser String
45+parseBlock :: Parser E.Expr String
4646parseBlock =
47− P.Parser $ \(P.State pos end indent row col ctx) cok _ cerr eerr ->
47+ P.Parser $ \(P.State pos end indent row col) cok _ cerr eerr ->
4848 let
4949 !pos6 = plusPtr pos 6
5050 in
@@ -63,17 +63,17 @@ parseBlock =
6363 case status of
6464 Good ->
6565 let
66− !size = minusPtr newPos pos
67− !block = error "TODO get a GLSL block" size
68− !newState = P.State (plusPtr newPos 2) end indent newRow newCol ctx
66+ !block = Utf8.fromPtr pos newPos
67+ !source = Utf8.toChars block
68+ !newState = P.State (plusPtr newPos 2) end indent newRow newCol
6969 in
70− cok block newState
70+ cok source newState
7171
7272 Unending ->
73− cerr row col ctx (E.ShaderEnd col (col + 6))
73+ cerr row col E.EndlessShader
7474
7575 else
76− eerr row col ctx E.ShaderStart
76+ eerr row col E.Start
7777
7878
7979data Status
@@ -81,7 +81,7 @@ data Status
8181 | Unending
8282
8383
84−eatShader :: Ptr Word8 -> Ptr Word8 -> Word16 -> Word16 -> (# Status, Ptr Word8, Word16, Word16 #)
84+eatShader :: Ptr Word8 -> Ptr Word8 -> Row -> Col -> (# Status, Ptr Word8, Row, Col #)
8585eatShader pos end row col =
8686 if pos >= end then
8787 (# Unending, pos, row, col #)
@@ -103,7 +103,7 @@ eatShader pos end row col =
103103-- GLSL
104104
105105
106−parseGlsl :: Word16 -> Word16 -> String -> Parser Shader.Types
106+parseGlsl :: Row -> Col -> String -> Parser E.Expr Shader.Types
107107parseGlsl startRow startCol src =
108108 case GLP.parse src of
109109 Right (GLS.TranslationUnit decls) ->
@@ -128,10 +128,10 @@ parseGlsl startRow startCol src =
128128 else failure (startRow + row - 1) col msg
129129
130130
131−failure :: Word16 -> Word16 -> String -> Parser a
131+failure :: Row -> Col -> String -> Parser E.Expr a
132132failure row col msg =
133− P.Parser $ \(P.State _ _ _ _ _ ctx) _ _ cerr _ ->
134− cerr row col ctx (E.ShaderProblem msg)
133+ P.Parser $ \(P.State _ _ _ _ _) _ _ cerr _ ->
134+ cerr row col (E.ShaderProblem msg)
135135
136136
137137
compiler/src/Parse/Symbol.hs+18−18
@@ -2,7 +2,7 @@
22{-# LANGUAGE BangPatterns, UnboxedTuples, OverloadedStrings #-}
33module Parse.Symbol
44 ( wildcard
5− , binop
5+ , operator
66 )
77 where
88
@@ -14,7 +14,7 @@ import qualified Data.Vector as Vector
1414import Foreign.Ptr (Ptr, plusPtr, minusPtr)
1515import GHC.Word (Word8)
1616
17−import Parse.Utils
17+import Parse.Primitives (Parser, Row, Col)
1818import qualified Parse.Variable as Var
1919import qualified Parse.Primitives as P
2020import qualified Reporting.Error.Syntax as E
@@ -24,11 +24,11 @@ import qualified Reporting.Error.Syntax as E
2424-- UNDERSCORE
2525
2626
27−wildcard :: Parser ()
27+wildcard :: Parser E.Pattern ()
2828wildcard =
29− P.Parser $ \(P.State pos end indent row col ctx) cok _ cerr eerr ->
29+ P.Parser $ \(P.State pos end indent row col) cok _ cerr eerr ->
3030 if pos == end || P.unsafeIndex pos /= 0x5F {- _ -} then
31− eerr row col ctx E.Wildcard
31+ eerr row col E.PStart
3232 else
3333 let
3434 !newPos = plusPtr pos 1
@@ -36,34 +36,34 @@ wildcard =
3636 in
3737 if Var.getInnerWidth newPos end > 0 then
3838 let (# _, badCol #) = Var.chompInnerChars newPos end newCol in
39− cerr row col ctx (E.WildcardNotVar newCol badCol)
39+ cerr row col (E.PWildcardNotVar (fromIntegral (badCol - col)))
4040 else
41− let !newState = P.State newPos end indent row newCol ctx in
41+ let !newState = P.State newPos end indent row newCol in
4242 cok () newState
4343
4444
4545
46−-- BINOP
46+-- OPERATOR
4747
4848
49−binop :: Parser Name.Name
50−binop =
51− P.Parser $ \(P.State pos end indent row col ctx) cok _ cerr eerr ->
49+operator :: (Row -> Col -> x) -> (E.Operator -> Row -> Col -> x) -> Parser x Name.Name
50+operator toExpectation toError =
51+ P.Parser $ \(P.State pos end indent row col) cok _ cerr eerr ->
5252 let !newPos = chompOps pos end in
5353 if pos == newPos then
54− eerr row col ctx E.XXX
54+ eerr row col toExpectation
5555
5656 else
5757 case Name.fromPtr pos newPos of
58− "." -> cerr row col ctx (E.ReservedOperator E.Dot)
59− "|" -> cerr row col ctx (E.ReservedOperator E.Pipe)
60− "->" -> cerr row col ctx (E.ReservedOperator E.Arrow)
61− "=" -> cerr row col ctx (E.ReservedOperator E.Equals)
62− ":" -> cerr row col ctx (E.ReservedOperator E.HasType)
58+ "." -> cerr row col (toError E.OpDot)
59+ "|" -> cerr row col (toError E.OpPipe)
60+ "->" -> cerr row col (toError E.OpArrow)
61+ "=" -> cerr row col (toError E.OpEquals)
62+ ":" -> cerr row col (toError E.OpHasType)
6363 op ->
6464 let
6565 !newCol = col + fromIntegral (minusPtr newPos pos)
66− !newState = P.State newPos end indent row newCol ctx
66+ !newState = P.State newPos end indent row newCol
6767 in
6868 cok op newState
6969
compiler/src/Parse/Type.hs+106−103
@@ -2,7 +2,7 @@
22{-# LANGUAGE OverloadedStrings #-}
33module Parse.Type
44 ( expression
5− , unionConstructor
5+ , variant
66 )
77 where
88
@@ -10,8 +10,8 @@ module Parse.Type
1010import qualified Data.Name as Name
1111
1212import qualified AST.Source as Src
13−import Parse.Primitives (addLocation, getPosition, inContext, oneOf, word1, word2)
14−import Parse.Utils (Parser, SParser, SPos, checkSpace, spaces, whitespace)
13+import Parse.Primitives (Parser, addLocation, addEnd, getPosition, inContext, specialize, oneOf, oneOfWithFallback, word1, word2)
14+import qualified Parse.Space as Space
1515import qualified Parse.Variable as Var
1616import qualified Reporting.Annotation as A
1717import qualified Reporting.Error.Syntax as E
@@ -21,13 +21,13 @@ import qualified Reporting.Error.Syntax as E
2121-- TYPE TERMS
2222
2323
24−term :: Parser Src.Type
24+term :: Parser E.Type Src.Type
2525term =
2626 do start <- getPosition
27− oneOf E.XXX
27+ oneOf E.TStart
2828 [
2929 -- types with no arguments (Int, Float, etc.)
30− do upper <- Var.foreignUpper
30+ do upper <- Var.foreignUpper E.TStart
3131 end <- getPosition
3232 let region = A.Region start end
3333 return $ A.At region $
@@ -39,45 +39,40 @@ term =
3939 Src.TTypeQual region home name []
4040 ,
4141 -- type variables
42− do var <- Var.lower
43− end <- getPosition
44− return (A.at start end (Src.TVar var))
42+ do var <- Var.lower E.TStart
43+ addEnd start (Src.TVar var)
4544 ,
4645 -- tuples
47− inContext E.TypeTuple (word1 0x28 {-(-} E.XXX) $
48− oneOf E.XXX
49− [ do word1 0x29 {-)-} E.XXX
50− end <- getPosition
51− return (A.at start end Src.TUnit)
52− , do spaces
53− (tipe, _, pos) <- expression
54− checkSpace pos
55− tupleEnding start tipe []
46+ inContext E.TTuple (word1 0x28 {-(-} E.TStart) $
47+ oneOf E.TTupleOpen
48+ [ do word1 0x29 {-)-} E.TTupleOpen
49+ addEnd start Src.TUnit
50+ , do Space.chompAndCheckIndent E.TTupleSpace E.TTupleIndentType
51+ (tipe, end) <- specialize E.TTupleType expression
52+ Space.checkIndent end E.TTupleIndentEnd
53+ chompTupleEnd start tipe []
5654 ]
5755 ,
5856 -- records
59− inContext E.TypeRecord (word1 0x7B {- { -} E.XXX) $
60− do spaces
61− oneOf E.XXX
62− [ do word1 0x7D {-}-} E.XXX
63− end <- getPosition
64− return (A.at start end (Src.TRecord [] Nothing))
65− , do var <- addLocation Var.lower
66− spaces
67− oneOf E.XXX
68− [ do word1 0x7C {-|-} E.XXX
69− spaces
70− firstField <- field
71− fields <- chompFields [firstField]
72− end <- getPosition
73− return (A.at start end (Src.TRecord fields (Just var)))
74− , do word1 0x3A {-:-} E.XXX
75− spaces
76− (tipe, _, nextPos) <- expression
77− checkSpace nextPos
78− fields <- chompFields [(var, tipe)]
79− end <- getPosition
80− return (A.at start end (Src.TRecord fields Nothing))
57+ inContext E.TRecord (word1 0x7B {- { -} E.TStart) $
58+ do Space.chompAndCheckIndent E.TRecordSpace E.TRecordIndentOpen
59+ oneOf E.TRecordOpen
60+ [ do word1 0x7D {-}-} E.TRecordEnd
61+ addEnd start (Src.TRecord [] Nothing)
62+ , do name <- addLocation (Var.lower E.TRecordField)
63+ Space.chompAndCheckIndent E.TRecordSpace E.TRecordIndentColon
64+ oneOf E.TRecordColon
65+ [ do word1 0x7C {-|-} E.TRecordColon
66+ Space.chompAndCheckIndent E.TRecordSpace E.TRecordIndentField
67+ field <- chompField
68+ fields <- chompRecordEnd [field]
69+ addEnd start (Src.TRecord fields (Just name))
70+ , do word1 0x3A {-:-} E.TRecordColon
71+ Space.chompAndCheckIndent E.TRecordSpace E.TRecordIndentType
72+ (tipe, end) <- specialize E.TRecordType expression
73+ Space.checkIndent end E.TRecordIndentEnd
74+ fields <- chompRecordEnd [(name, tipe)]
75+ addEnd start (Src.TRecord fields Nothing)
8176 ]
8277 ]
8378 ]
@@ -87,37 +82,40 @@ term =
8782-- TYPE EXPRESSIONS
8883
8984
90−expression :: SParser Src.Type
85+expression :: Space.Parser E.Type Src.Type
9186expression =
9287 do start <- getPosition
93− (tipe1, end1, pos1) <-
94− oneOf E.XXX
88+ term1@(tipe1, end1) <-
89+ oneOf E.TStart
9590 [ app start
96− , (,,) <$> term <*> getPosition <*> whitespace
91+ , do eterm <- term
92+ end <- getPosition
93+ Space.chomp E.TSpace
94+ return (eterm, end)
9795 ]
98− oneOf E.XXX
99− [ do checkSpace pos1
100− word2 0x2D 0x3E {-->-} E.XXX
101− spaces
102− (tipe2, end2, pos2) <- expression
96+ oneOfWithFallback
97+ [ do Space.checkIndent end1 E.TIndentStart -- should never trigger
98+ word2 0x2D 0x3E {-->-} E.TArrow
99+ Space.chompAndCheckIndent E.TSpace E.TIndentStart
100+ (tipe2, end2) <- expression
103101 let tipe = A.at start end2 (Src.TLambda tipe1 tipe2)
104− return ( tipe, end2, pos2 )
105− , return ( tipe1, end1, pos1 )
102+ return ( tipe, end2 )
106103 ]
104+ term1
107105
108106
109107
110108-- TYPE CONSTRUCTORS
111109
112110
113−app :: A.Position -> SParser Src.Type
111+app :: A.Position -> Space.Parser E.Type Src.Type
114112app start =
115− do upper <- Var.foreignUpper
116− nameEnd <- getPosition
117− namePos <- whitespace
118− (args, end, pos) <- eatArgs [] nameEnd namePos
113+ do upper <- Var.foreignUpper E.TStart
114+ upperEnd <- getPosition
115+ Space.chomp E.TSpace
116+ (args, end) <- chompArgs [] upperEnd
119117
120− let region = A.Region start nameEnd
118+ let region = A.Region start upperEnd
121119 let tipe =
122120 case upper of
123121 Var.Unqualified name ->
@@ -126,52 +124,40 @@ app start =
126124 Var.Qualified home name ->
127125 Src.TTypeQual region home name args
128126
129− return ( A.at start end tipe, end, pos )
127+ return ( A.at start end tipe, end )
130128
131129
132−unionConstructor :: SParser (A.Located Name.Name, [Src.Type])
133−unionConstructor =
134− do start <- getPosition
135− name <- Var.upper
136− nameEnd <- getPosition
137− namePos <- whitespace
138− (args, end, pos) <- eatArgs [] nameEnd namePos
139− return ( (A.at start nameEnd name, args), end, pos )
140−
141−
142−eatArgs :: [Src.Type] -> A.Position -> SPos -> SParser [Src.Type]
143−eatArgs args end pos =
144− oneOf E.XXX
145− [ do checkSpace pos
130+chompArgs :: [Src.Type] -> A.Position -> Space.Parser E.Type [Src.Type]
131+chompArgs args end =
132+ oneOfWithFallback
133+ [ do Space.checkIndent end E.TIndentStart
146134 arg <- term
147135 newEnd <- getPosition
148− newSpace <- whitespace
149− eatArgs (arg:args) newEnd newSpace
150− , return ( reverse args, end, pos )
136+ Space.chomp E.TSpace
137+ chompArgs (arg:args) newEnd
151138 ]
139+ (reverse args, end)
152140
153141
154142
155143-- TUPLES
156144
157145
158−tupleEnding :: A.Position -> Src.Type -> [Src.Type] -> Parser Src.Type
159−tupleEnding start firstType revTypes =
160− oneOf E.XXX
161− [ do word1 0x2C {-,-} E.XXX
162− spaces
163− (tipe, _, pos) <- expression
164− checkSpace pos
165− tupleEnding start firstType (tipe : revTypes)
166− , do word1 0x29 {-)-} E.XXX
167− end <- getPosition
146+chompTupleEnd :: A.Position -> Src.Type -> [Src.Type] -> Parser E.TTuple Src.Type
147+chompTupleEnd start firstType revTypes =
148+ oneOf E.TTupleEnd
149+ [ do word1 0x2C {-,-} E.TTupleEnd
150+ Space.chompAndCheckIndent E.TTupleSpace E.TTupleIndentType
151+ (tipe, end) <- specialize E.TTupleType expression
152+ Space.checkIndent end E.TTupleIndentEnd
153+ chompTupleEnd start firstType (tipe : revTypes)
154+ , do word1 0x29 {-)-} E.TTupleEnd
168155 case reverse revTypes of
169156 [] ->
170157 return firstType
171158
172159 secondType : otherTypes ->
173− return $ A.at start end $
174− Src.TTuple firstType secondType otherTypes
160+ addEnd start (Src.TTuple firstType secondType otherTypes)
175161 ]
176162
177163
@@ -182,24 +168,41 @@ tupleEnding start firstType revTypes =
182168type Field = ( A.Located Name.Name, Src.Type )
183169
184170
185−chompFields :: [Field] -> Parser [Field]
186−chompFields fields =
187− oneOf E.XXX
188− [ do word1 0x2C {-,-} E.XXX
189− spaces
190− f <- field
191− chompFields (f : fields)
192− , do word1 0x7D {-}-} E.XXX
171+chompRecordEnd :: [Field] -> Parser E.TRecord [Field]
172+chompRecordEnd fields =
173+ oneOf E.TRecordEnd
174+ [ do word1 0x2C {-,-} E.TRecordEnd
175+ Space.chompAndCheckIndent E.TRecordSpace E.TRecordIndentField
176+ field <- chompField
177+ chompRecordEnd (field : fields)
178+ , do word1 0x7D {-}-} E.TRecordEnd
193179 return (reverse fields)
194180 ]
195181
196182
197−field :: Parser Field
198−field =
199− do name <- addLocation Var.lower
200− spaces
201− word1 0x3A {-:-} E.XXX
202− spaces
203− (tipe, _, endPos) <- expression
204− checkSpace endPos
183+chompField :: Parser E.TRecord Field
184+chompField =
185+ do name <- addLocation (Var.lower E.TRecordField)
186+ Space.chompAndCheckIndent E.TRecordSpace E.TRecordIndentColon
187+ word1 0x3A {-:-} E.TRecordColon
188+ Space.chompAndCheckIndent E.TRecordSpace E.TRecordIndentType
189+ (tipe, end) <- specialize E.TRecordType expression
190+ Space.checkIndent end E.TRecordIndentEnd
205191 return (name, tipe)
192+
193+
194+
195+-- VARIANT
196+
197+
198+variant :: Space.Parser E.CustomType (A.Located Name.Name, [Src.Type])
199+variant =
200+ do start <- getPosition
201+ name <- Var.upper E.CT_Variant
202+ nameEnd <- getPosition
203+ Space.chomp E.CT_Space
204+ (args, end) <- specialize E.CT_Type (chompArgs [] nameEnd)
205+ return
206+ ( (A.at start nameEnd name, args)
207+ , end
208+ )
compiler/src/Parse/Utf8.hs+57−45
@@ -11,7 +11,7 @@ import qualified Data.Utf8 as Utf8
1111import Data.Word (Word8, Word16)
1212import Foreign.Ptr (Ptr, plusPtr, minusPtr)
1313
14−import Parse.Utils (Parser)
14+import Parse.Primitives (Parser, Row, Col)
1515import qualified Parse.Number as Number
1616import qualified Parse.Primitives as P
1717import qualified Reporting.Error.Syntax as E
@@ -21,37 +21,41 @@ import qualified Reporting.Error.Syntax as E
2121-- CHARACTER
2222
2323
24−character :: Parser Utf8.String
25−character =
26− P.Parser $ \(P.State pos end indent row col ctx) cok _ cerr eerr ->
24+character :: (Row -> Col -> x) -> (E.Char -> Row -> Col -> x) -> Parser x Utf8.String
25+character toExpectation toError =
26+ P.Parser $ \(P.State pos end indent row col) cok _ cerr eerr ->
2727 if pos >= end || P.unsafeIndex pos /= 0x27 {- ' -} then
28− eerr row col ctx E.CharStart
28+ eerr row col toExpectation
2929
3030 else
3131 case chompChar (plusPtr pos 1) end (col + 1) 0 placeholder of
3232 Good newPos newCol numChars mostRecent ->
3333 if numChars /= 1 then
34− cerr row col ctx (E.CharNotString col newCol)
34+ cerr row col (toError (E.CharNotString (fromIntegral (newCol - col))))
3535 else
3636 let
37− !newState = P.State newPos end indent row newCol ctx
37+ !newState = P.State newPos end indent row newCol
3838 !char = Utf8.fromChunks [mostRecent]
3939 in
4040 cok char newState
4141
42− Bad newCol x ->
43− cerr row newCol ctx x
42+ CharEndless newCol ->
43+ cerr row newCol (toError E.CharEndless)
44+
45+ CharEscape newCol escape ->
46+ cerr row newCol (toError (E.CharEscape escape))
4447
4548
4649data CharResult
47− = Good (Ptr Word8) Word16 Int Utf8.Chunk
48− | Bad Word16 E.Expectation
50+ = Good (Ptr Word8) Col Word16 Utf8.Chunk
51+ | CharEndless Col
52+ | CharEscape Col E.Escape
4953
5054
51−chompChar :: Ptr Word8 -> Ptr Word8 -> Word16 -> Int -> Utf8.Chunk -> CharResult
55+chompChar :: Ptr Word8 -> Ptr Word8 -> Col -> Word16 -> Utf8.Chunk -> CharResult
5256chompChar pos end col numChars mostRecent =
5357 if pos >= end then
54− Bad col E.CharEnd
58+ CharEndless col
5559
5660 else
5761 let
@@ -61,7 +65,7 @@ chompChar pos end col numChars mostRecent =
6165 Good (plusPtr pos 1) (col + 1) numChars mostRecent
6266
6367 else if word == 0x0A {- \n -} then
64− Bad col E.CharEnd
68+ CharEndless col
6569
6670 else if word == 0x22 {- " -} then
6771 chompChar (plusPtr pos 1) end (col + 1) (numChars + 1) doubleQuote
@@ -74,11 +78,11 @@ chompChar pos end col numChars mostRecent =
7478 EscapeUnicode delta code ->
7579 chompChar (plusPtr pos delta) end (col + fromIntegral delta) (numChars + 1) (Utf8.CodePoint code)
7680
77− EscapeProblem x ->
78− Bad col x
81+ EscapeProblem badEscape ->
82+ CharEscape col badEscape
7983
8084 EscapeEndOfFile ->
81− Bad (col + 1) E.CharEnd
85+ CharEndless col
8286
8387 else
8488 let
@@ -92,32 +96,40 @@ chompChar pos end col numChars mostRecent =
9296-- STRINGS
9397
9498
95−string :: Parser Utf8.String
96−string =
97− P.Parser $ \(P.State pos end indent row col ctx) cok _ cerr eerr ->
99+string :: (Row -> Col -> x) -> (E.String -> Row -> Col -> x) -> Parser x Utf8.String
100+string toExpectation toError =
101+ P.Parser $ \(P.State pos end indent row col) cok _ cerr eerr ->
98102 if isDoubleQuote pos end then
99103
100104 let
101105 !pos1 = plusPtr pos 1
102− result =
103− if isDoubleQuote pos1 end && isDoubleQuote (plusPtr pos 2) end then
104− multiString (plusPtr pos 3) end row (col + 3) (plusPtr pos 3) row col mempty
105− else
106− singleString pos1 end row (col + 1) pos1 mempty
107106 in
108− case result of
109− Ok newPos newRow newCol utf8 ->
107+ case
108+ if isDoubleQuote pos1 end then
109+ let !pos2 = plusPtr pos 2 in
110+ if isDoubleQuote pos2 end then
110111 let
111− !newState =
112− P.State newPos end indent newRow newCol ctx
112+ !pos3 = plusPtr pos 3
113+ !col3 = col + 3
113114 in
114− cok utf8 newState
115−
116− Err r c x ->
117− cerr r c ctx x
115+ multiString pos3 end row col3 pos3 row col mempty
116+ else
117+ Ok pos2 row (col + 2) Utf8.empty
118+ else
119+ singleString pos1 end row (col + 1) pos1 mempty
120+ of
121+ Ok newPos newRow newCol utf8 ->
122+ let
123+ !newState =
124+ P.State newPos end indent newRow newCol
125+ in
126+ cok utf8 newState
127+
128+ Err r c x ->
129+ cerr r c (toError x)
118130
119131 else
120− eerr row col ctx E.StringStart
132+ eerr row col toExpectation
121133
122134
123135{-# INLINE isDoubleQuote #-}
@@ -127,8 +139,8 @@ isDoubleQuote pos end =
127139
128140
129141data StringResult
130− = Ok (Ptr Word8) Word16 Word16 Utf8.String
131− | Err Word16 Word16 E.Expectation
142+ = Ok (Ptr Word8) Row Col !Utf8.String
143+ | Err Row Col E.String
132144
133145
134146finalize :: Ptr Word8 -> Ptr Word8 -> [Utf8.Chunk] -> Utf8.String
@@ -155,7 +167,7 @@ addEscape chunk start end revChunks =
155167singleString :: Ptr Word8 -> Ptr Word8 -> Word16 -> Word16 -> Ptr Word8 -> [Utf8.Chunk] -> StringResult
156168singleString pos end row col initialPos revChunks =
157169 if pos >= end then
158− Err row col E.StringEnd_Single
170+ Err row col E.StringEndless_Single
159171
160172 else
161173 let
@@ -166,7 +178,7 @@ singleString pos end row col initialPos revChunks =
166178 finalize initialPos pos revChunks
167179
168180 else if word == 0x0A {- \n -} then
169− Err row col E.StringEnd_Single
181+ Err row col E.StringEndless_Single
170182
171183 else if word == 0x27 {- ' -} then
172184 let !newPos = plusPtr pos 1 in
@@ -184,10 +196,10 @@ singleString pos end row col initialPos revChunks =
184196 addEscape (Utf8.CodePoint code) initialPos pos revChunks
185197
186198 EscapeProblem x ->
187− Err row col x
199+ Err row col (E.StringEscape x)
188200
189201 EscapeEndOfFile ->
190− Err row (col + 1) E.StringEnd_Single
202+ Err row (col + 1) E.StringEndless_Single
191203
192204 else
193205 let !newPos = plusPtr pos (P.getCharWidth pos end word) in
@@ -201,7 +213,7 @@ singleString pos end row col initialPos revChunks =
201213multiString :: Ptr Word8 -> Ptr Word8 -> Word16 -> Word16 -> Ptr Word8 -> Word16 -> Word16 -> [Utf8.Chunk] -> StringResult
202214multiString pos end row col initialPos sr sc revChunks =
203215 if pos >= end then
204− Err row col (E.StringEnd_Multi sr sc)
216+ Err sr sc E.StringEndless_Multi
205217
206218 else
207219 let !word = P.unsafeIndex pos in
@@ -235,10 +247,10 @@ multiString pos end row col initialPos sr sc revChunks =
235247 addEscape (Utf8.CodePoint code) initialPos pos revChunks
236248
237249 EscapeProblem x ->
238− Err row col x
250+ Err row col (E.StringEscape x)
239251
240252 EscapeEndOfFile ->
241− Err row (col + 1) (E.StringEnd_Multi sr sc)
253+ Err sr sc E.StringEndless_Multi
242254
243255 else
244256 let !newPos = plusPtr pos (P.getCharWidth pos end word) in
@@ -253,7 +265,7 @@ data Escape
253265 = EscapeNormal
254266 | EscapeUnicode !Int !Int
255267 | EscapeEndOfFile
256− | EscapeProblem E.Expectation
268+ | EscapeProblem E.Escape
257269
258270
259271eatEscape :: Ptr Word8 -> Ptr Word8 -> Word16 -> Escape
@@ -297,7 +309,7 @@ eatUnicode pos end startCol =
297309 startCol
298310 (startCol + fromIntegral (minusPtr newPos pos) + 1)
299311 numDigits
300− (Utf8.fromPtr digitPos newPos)
312+ code
301313
302314 else
303315 EscapeUnicode (numDigits + 4) code
compiler/src/Parse/Variable.hs+36−38
@@ -17,57 +17,55 @@ module Parse.Variable
1717import qualified Data.Char as Char
1818import qualified Data.Name as Name
1919import qualified Data.Set as Set
20−import Data.Word (Word8, Word16)
20+import Data.Word (Word8)
2121import Foreign.Ptr (Ptr, plusPtr)
2222import GHC.Exts (Char(C#), Int#, (+#), (-#), chr#, uncheckedIShiftL#, word2Int#)
2323import GHC.Word (Word8(W8#))
2424
2525import qualified AST.Source as Src
26−import Parse.Utils (Parser)
27−import Parse.Primitives (unsafeIndex)
26+import Parse.Primitives (Parser, Row, Col, unsafeIndex)
2827import qualified Parse.Primitives as P
29−import qualified Reporting.Error.Syntax as E
3028
3129
3230
3331-- LOCAL UPPER
3432
3533
36−upper :: Parser Name.Name
37−upper =
38− P.Parser $ \(P.State pos end indent row col ctx) cok _ _ eerr ->
34+upper :: (Row -> Col -> x) -> Parser x Name.Name
35+upper toError =
36+ P.Parser $ \(P.State pos end indent row col) cok _ _ eerr ->
3937 let (# newPos, newCol #) = chompUpper pos end col in
4038 if pos == newPos then
41− eerr row col ctx E.Upper
39+ eerr row col toError
4240 else
4341 let !name = Name.fromPtr pos newPos in
44− cok name (P.State newPos end indent row newCol ctx)
42+ cok name (P.State newPos end indent row newCol)
4543
4644
4745
4846-- LOCAL LOWER
4947
5048
51−lower :: Parser Name.Name
52−lower =
53− P.Parser $ \(P.State pos end indent row col ctx) cok _ _ eerr ->
49+lower :: (Row -> Col -> x) -> Parser x Name.Name
50+lower toError =
51+ P.Parser $ \(P.State pos end indent row col) cok _ _ eerr ->
5452 let (# newPos, newCol #) = chompLower pos end col in
5553 if pos == newPos then
56− eerr row col ctx E.Lower
54+ eerr row col toError
5755 else
5856 let !name = Name.fromPtr pos newPos in
5957 if Set.member name reservedWords then
60− eerr row col ctx E.Lower
58+ eerr row col toError
6159 else
6260 let
6361 !newState =
64− P.State newPos end indent row newCol ctx
62+ P.State newPos end indent row newCol
6563 in
6664 cok name newState
6765
6866
6967{-# NOINLINE reservedWords #-}
70−reservedWords :: Set.Set Name.Name
68+reservedWords :: Set.Set Name.Name -- TODO try using a trie instead
7169reservedWords =
7270 Set.fromList
7371 [ "if", "then", "else"
@@ -85,9 +83,9 @@ reservedWords =
8583-- MODULE NAME
8684
8785
88−moduleName :: Parser Name.Name
89−moduleName =
90− P.Parser $ \(P.State pos end indent row col ctx) cok _ _ eerr ->
86+moduleName :: (Row -> Col -> x) -> Parser x Name.Name
87+moduleName toError =
88+ P.Parser $ \(P.State pos end indent row col) cok _ _ eerr ->
9189 let
9290 (# pos1, col1 #) = chompUpper pos end col
9391 (# status, newPos, newCol #) = moduleNameHelp pos1 end col1
@@ -96,12 +94,12 @@ moduleName =
9694 Good ->
9795 let
9896 !name = Name.fromPtr pos newPos
99− !newState = P.State newPos end indent row newCol ctx
97+ !newState = P.State newPos end indent row newCol
10098 in
10199 cok name newState
102100
103101 Bad ->
104− eerr row newCol ctx E.ModuleName
102+ eerr row newCol toError
105103
106104
107105data ModuleNameStatus
@@ -109,7 +107,7 @@ data ModuleNameStatus
109107 | Bad
110108
111109
112−moduleNameHelp :: Ptr Word8 -> Ptr Word8 -> Word16 -> (# ModuleNameStatus, Ptr Word8, Word16 #)
110+moduleNameHelp :: Ptr Word8 -> Ptr Word8 -> Col -> (# ModuleNameStatus, Ptr Word8, Col #)
113111moduleNameHelp pos end col =
114112 if isDot pos end then
115113 let
@@ -134,15 +132,15 @@ data Upper
134132 | Qualified Name.Name Name.Name
135133
136134
137−foreignUpper :: Parser Upper
138−foreignUpper =
139− P.Parser $ \(P.State pos end indent row col ctx) cok _ _ eerr ->
135+foreignUpper :: (Row -> Col -> x) -> Parser x Upper
136+foreignUpper toError =
137+ P.Parser $ \(P.State pos end indent row col) cok _ _ eerr ->
140138 let (# upperStart, upperEnd, newCol #) = foreignUpperHelp pos end col in
141139 if upperStart == upperEnd then
142− eerr row newCol ctx E.Upper
140+ eerr row newCol toError
143141 else
144142 let
145− !newState = P.State upperEnd end indent row newCol ctx
143+ !newState = P.State upperEnd end indent row newCol
146144 !name = Name.fromPtr upperStart upperEnd
147145 !foreign =
148146 if upperStart == pos then
@@ -154,7 +152,7 @@ foreignUpper =
154152 cok foreign newState
155153
156154
157−foreignUpperHelp :: Ptr Word8 -> Ptr Word8 -> Word16 -> (# Ptr Word8, Ptr Word8, Word16 #)
155+foreignUpperHelp :: Ptr Word8 -> Ptr Word8 -> Col -> (# Ptr Word8, Ptr Word8, Col #)
158156foreignUpperHelp pos end col =
159157 let
160158 (# newPos, newCol #) = chompUpper pos end col
@@ -173,20 +171,20 @@ foreignUpperHelp pos end col =
173171-- FOREIGN ALPHA
174172
175173
176−foreignAlpha :: Parser Src.Expr_
177−foreignAlpha =
178− P.Parser $ \(P.State pos end indent row col ctx) cok _ _ eerr ->
174+foreignAlpha :: (Row -> Col -> x) -> Parser x Src.Expr_
175+foreignAlpha toError =
176+ P.Parser $ \(P.State pos end indent row col) cok _ _ eerr ->
179177 let (# alphaStart, alphaEnd, newCol, varType #) = foreignAlphaHelp pos end col in
180178 if alphaStart == alphaEnd then
181− eerr row newCol ctx E.Alpha
179+ eerr row newCol toError
182180 else
183181 let
184− !newState = P.State alphaEnd end indent row newCol ctx
182+ !newState = P.State alphaEnd end indent row newCol
185183 !name = Name.fromPtr alphaStart alphaEnd
186184 in
187185 if alphaStart == pos then
188186 if Set.member name reservedWords then
189− eerr row col ctx E.Alpha
187+ eerr row col toError
190188 else
191189 cok (Src.Var varType name) newState
192190 else
@@ -194,7 +192,7 @@ foreignAlpha =
194192 cok (Src.VarQual varType home name) newState
195193
196194
197−foreignAlphaHelp :: Ptr Word8 -> Ptr Word8 -> Word16 -> (# Ptr Word8, Ptr Word8, Word16, Src.VarType #)
195+foreignAlphaHelp :: Ptr Word8 -> Ptr Word8 -> Col -> (# Ptr Word8, Ptr Word8, Col, Src.VarType #)
198196foreignAlphaHelp pos end col =
199197 let
200198 (# lowerPos, lowerCol #) = chompLower pos end col
@@ -234,7 +232,7 @@ isDot pos end =
234232-- UPPER CHARS
235233
236234
237−chompUpper :: Ptr Word8 -> Ptr Word8 -> Word16 -> (# Ptr Word8, Word16 #)
235+chompUpper :: Ptr Word8 -> Ptr Word8 -> Col -> (# Ptr Word8, Col #)
238236chompUpper pos end col =
239237 let !width = getUpperWidth pos end in
240238 if width == 0 then
@@ -267,7 +265,7 @@ getUpperWidthHelp pos _ word
267265-- LOWER CHARS
268266
269267
270−chompLower :: Ptr Word8 -> Ptr Word8 -> Word16 -> (# Ptr Word8, Word16 #)
268+chompLower :: Ptr Word8 -> Ptr Word8 -> Col -> (# Ptr Word8, Col #)
271269chompLower pos end col =
272270 let !width = getLowerWidth pos end in
273271 if width == 0 then
@@ -300,7 +298,7 @@ getLowerWidthHelp pos _ word
300298-- INNER CHARS
301299
302300
303−chompInnerChars :: Ptr Word8 -> Ptr Word8 -> Word16 -> (# Ptr Word8, Word16 #)
301+chompInnerChars :: Ptr Word8 -> Ptr Word8 -> Col -> (# Ptr Word8, Col #)
304302chompInnerChars !pos end !col =
305303 let !width = getInnerWidth pos end in
306304 if width == 0 then