0.2.0
Includes better error handling, additional tests, parsing and lexing fixes to match the desired behavior defined by the new tests, and a very basic REPL implementation.
This commit is contained in:
22
src/Lexer.hs
22
src/Lexer.hs
@ -4,7 +4,9 @@ import Research
|
||||
import Text.Megaparsec
|
||||
import Text.Megaparsec.Char
|
||||
import Data.Void
|
||||
import qualified Data.Set as Set
|
||||
|
||||
-- Lexer type and tokens
|
||||
type Lexer = Parsec Void String
|
||||
data LToken
|
||||
= LKeywordT
|
||||
@ -19,6 +21,7 @@ data LToken
|
||||
| LNewline
|
||||
deriving (Show, Eq, Ord)
|
||||
|
||||
-- Lexical rules
|
||||
keywordT :: Lexer LToken
|
||||
keywordT = string "t" *> notFollowedBy alphaNumChar *> pure LKeywordT
|
||||
|
||||
@ -38,8 +41,11 @@ stringLiteral :: Lexer LToken
|
||||
stringLiteral = do
|
||||
char '"'
|
||||
content <- many (noneOf ['"'])
|
||||
char '"' --"
|
||||
return (LStringLiteral content)
|
||||
if null content
|
||||
then fail "Empty string literals are not allowed"
|
||||
else do
|
||||
char '"' -- "
|
||||
return (LStringLiteral content)
|
||||
|
||||
assign :: Lexer LToken
|
||||
assign = char '=' *> pure LAssign
|
||||
@ -59,13 +65,15 @@ closeBracket = char ']' *> pure LCloseBracket
|
||||
lnewline :: Lexer LToken
|
||||
lnewline = char '\n' *> pure LNewline
|
||||
|
||||
-- Whitespace consumer
|
||||
sc :: Lexer ()
|
||||
sc = skipMany (char ' ' <|> char '\t')
|
||||
|
||||
-- Lexer definition
|
||||
saplingLexer :: Lexer [LToken]
|
||||
saplingLexer = many (sc *> choice
|
||||
[ try keywordT
|
||||
, try identifier
|
||||
[ try identifier
|
||||
, try keywordT
|
||||
, try integerLiteral
|
||||
, try stringLiteral
|
||||
, assign
|
||||
@ -74,8 +82,10 @@ saplingLexer = many (sc *> choice
|
||||
, openBracket
|
||||
, closeBracket
|
||||
, lnewline
|
||||
]) <* eof
|
||||
] <* sc) <* eof
|
||||
|
||||
-- Lexing function with enhanced error handling
|
||||
lexSapling :: String -> [LToken]
|
||||
lexSapling input = case runParser saplingLexer "" input of
|
||||
Left err -> error "Failed to lex input"
|
||||
Left err -> error $ "Lexical error:\n" ++ errorBundlePretty err
|
||||
Right tokens -> tokens
|
||||
|
Reference in New Issue
Block a user