@@ -291,6 +291,17 @@ export
291spaces : Lexer
291spaces : Lexer
292spaces = some space
292spaces = some space
294+||| Recognise a single newline sequence. Understands CRLF, CR, and LF
297+newline = let crlf = "\r\n" in
298+ exact crlf <|> oneOf crlf
300+||| Recognise one or more newline sequences. Understands CRLF, CR, and LF
303+newlines = some newline
294||| Recognise a single non-whitespace, non-alphanumeric character
305||| Recognise a single non-whitespace, non-alphanumeric character
296symbol : Lexer
307symbol : Lexer
@@ -341,6 +352,25 @@ export
341hexLit : Lexer
352hexLit : Lexer
342hexLit = approx "0x" <+> hexDigits
353hexLit = approx "0x" <+> hexDigits
355+||| Recognise `start`, then recognise all input until a newline is encountered,
356+||| and consume the newline. Will succeed if end-of-input is encountered before
359+lineComment : (start : Lexer) -> Lexer
360+lineComment start = start <+> manyUntil newline any <+> opt newline
362+||| Recognise all input between `start` and `end` lexers.
363+||| Supports balanced nesting.
365+||| For block comments that don't support nesting (such as C-style comments),
368+blockComment : (start : Lexer) -> (end : Lexer) -> Lexer
369+blockComment start end = start <+> middle <+> end
371+ middle : Recognise False
372+ middle = manyUntil end (blockComment start end <|> any)
344||| A mapping from lexers to the tokens they produce.
374||| A mapping from lexers to the tokens they produce.
345||| This is a list of pairs `(Lexer, String -> tokenType)`
375||| This is a list of pairs `(Lexer, String -> tokenType)`
346||| For each Lexer in the list, if a substring in the input matches, run
376||| For each Lexer in the list, if a substring in the input matches, run