summaryrefslogtreecommitdiff
path: root/src/Hint/Parser.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Hint/Parser.hs')
-rw-r--r--src/Hint/Parser.hs115
1 files changed, 61 insertions, 54 deletions
diff --git a/src/Hint/Parser.hs b/src/Hint/Parser.hs
index 28301e5..c5d23a2 100644
--- a/src/Hint/Parser.hs
+++ b/src/Hint/Parser.hs
@@ -1,7 +1,10 @@
module Hint.Parser where
-import Control.Applicative (Alternative (..), many)
+import Control.Applicative (Alternative (..))
+import Control.Monad (void)
import Data.Either (fromRight)
+import qualified Data.Text as T
+import Hint.Data
import Hint.Lexer (Input, Token (..), TokenKind (..),
runProd)
@@ -10,17 +13,9 @@ data ParseError
| NoParse
deriving (Show, Eq)
-data Value
- = VInt Int
- | VString String
- | VList Value
- deriving (Show, Eq)
-
-data Expr
- = EVar String
- | EValue Value
- | EBinding String Expr
- | EFunc String [String] Expr
+data BinOp
+ = Add
+ | Mult
deriving (Show, Eq)
newtype Parser a = Parser
@@ -56,6 +51,32 @@ instance Alternative Parser where
runParser :: Parser a -> Input -> Either ParseError (a, [Token])
runParser p = unParser p . fromRight [] . runProd
+token :: TokenKind -> Parser Token
+token t = sat (== t)
+
+sat :: (TokenKind -> Bool) -> Parser Token
+sat p = Parser parse
+ where
+ parse [] = Left $ UnexpectedToken [TEof]
+ parse (t@(Token kind _) : ts)
+ | p kind = Right (t, ts)
+ | otherwise = Left $ UnexpectedToken [kind]
+
+pStr :: Parser Literal
+pStr = String . T.pack <$> Parser parseString
+ where
+ parseString (Token (TString s) _ : ts) = pure (s, ts)
+ parseString _ = Left NoParse
+
+pBool :: Parser Literal
+pBool = (Boolean False <$ sat (== KeywordFalse)) <|> (Boolean True <$ sat (== KeywordTrue))
+
+pNumeric :: Parser Literal
+pNumeric = Int <$> Parser p
+ where
+ p (Token (TInt i) _ : ts) = pure (i, ts)
+ p _ = Left NoParse
+
parseWord :: String -> Parser Token
parseWord name = Parser parse
where
@@ -64,51 +85,37 @@ parseWord name = Parser parse
| name == n = Right (t, ts)
parse _ = Left NoParse
-parseValue :: Parser Expr
-parseValue = EValue <$> Parser parse
+parseLiteral :: Parser Expr
+parseLiteral = Literal <$> (pStr <|> pBool <|> pNumeric)
+
+parseIdentifier :: Parser Identifier
+parseIdentifier = Parser p
where
- parse ((Token (TInt n) _) : ts) = pure (VInt n, ts)
- parse ((Token (TString s) _) : ts) = pure (VString s, ts)
- parse _ = Left $ UnexpectedToken []
+ p (Token (TIdent s) _ : ts) = pure (Identifier $ T.pack s, ts)
+ p _ = Left NoParse
parseBinding :: Parser Expr
-parseBinding = EBinding
- <$> phrase
- <*> expr <* sat (== KeywordIn)
- where
- phrase = sat (== KeywordLet) *> ident <* sat (== TEquals)
- ident = Parser $ \((Token (TIdent name) _) : ts) -> pure (name, ts)
+parseBinding = do
+ void $ token KeywordLet
+ name <- parseIdentifier
+ void $ token TEquals
+ value <- expr
+ void $ token KeywordIn
+ body <- expr
+ pure $ Bind name value body
-parseFunc :: Parser Expr
-parseFunc = EFunc
- <$> ident
- <*> many ident <* sat (== TEquals)
- <*> parseValue
- where
- parse ((Token (TIdent name) _) : ts) = pure (name, ts)
- parse _ = Left NoParse
- ident = Parser parse
+parseIf :: Parser Expr
+parseIf = do
+ void $ token KeywordIf
+ cond <- expr
+ void $ token KeywordThen
+ a <- expr
+ void $ token KeywordElse
+ b <- expr
+ pure $ If cond a b
expr :: Parser Expr
-expr = parseValue <|> parseBinding
-
-sat :: (TokenKind -> Bool) -> Parser Token
-sat p = Parser parse
- where
- parse [] = Left $ UnexpectedToken [TEof]
- parse (t@(Token kind _) : ts)
- | p kind = Right (t, ts)
- | otherwise = Left $ UnexpectedToken [kind]
-
--- parseBind :: Parser Expr
--- parseBind = EBinding <$> name <*> result
--- where
--- name = Parser $ \(t : ts) ->
--- case t of
--- (Token (TIdent s) _) -> pure (s, ts)
--- _ -> Left $ UnexpectedToken $ [TIdent ""]
-
--- result = Parser $ \(t : ts) ->
--- case t of
--- (Token (TInt n) _) -> pure (ELit n, ts)
--- _ -> Left $ UnexpectedToken $ [TIdent ""]
+expr = parseLiteral
+ <|> parseIf
+ <|> parseBinding
+ <|> Ident <$> parseIdentifier