From 61a467c1be9895cc8c22b73ac0ff4350047d43e6 Mon Sep 17 00:00:00 2001 From: Kleidi Bujari Date: Tue, 13 Oct 2026 23:44:16 -0700 Subject: baseline parsing/eval --- src/Hint/Parser.hs | 117 ++++++++++++++++++++++++++++------------------------- 1 file changed, 62 insertions(+), 55 deletions(-) (limited to 'src/Hint/Parser.hs') 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) - -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 +parseBinding = do + void $ token KeywordLet + name <- parseIdentifier + void $ token TEquals + value <- expr + void $ token KeywordIn + body <- expr + pure $ Bind name value body + +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 -- cgit v1.3.1