From 78d2b3acf77dc0500d27836915dce99a9c368b53 Mon Sep 17 00:00:00 2001 From: Arnaud Bailly Date: Fri, 17 Oct 2025 16:36:40 +0200 Subject: feat: can parse a simple λ-expression MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../haskell/src/Minilang/Lambda/Parser.hs | 31 +++++++++++++++++++--- .../haskell/test/Minilang/Lambda/ParserSpec.hs | 2 ++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/lambda-calcul/haskell/src/Minilang/Lambda/Parser.hs b/lambda-calcul/haskell/src/Minilang/Lambda/Parser.hs index da590ad..545536d 100644 --- a/lambda-calcul/haskell/src/Minilang/Lambda/Parser.hs +++ b/lambda-calcul/haskell/src/Minilang/Lambda/Parser.hs @@ -13,15 +13,38 @@ type Parser = Parsec Void Text data ParseError = ParseError Text deriving (Eq, Show) -data AST = Sym Text +data AST = Sym Text | Abs Text AST deriving (Eq, Show) parse :: Text -> Either ParseError AST parse = - first (ParseError . pack . errorBundlePretty) . Text.Megaparsec.parse symbol "" + first (ParseError . pack . errorBundlePretty) . Text.Megaparsec.parse ast "" -symbol :: Parser AST -symbol = Sym . pack <$> identifier +ast :: Parser AST +ast = try lambda <|> try sym + +lambda :: Parser AST +lambda = + between + lpar + rpar + ( do + lexeme "lam" + binding <- pack <$> between lpar rpar identifier + Abs binding <$> ast + ) + +lpar :: Parser Text +lpar = symbol "(" + +rpar :: Parser Text +rpar = symbol ")" + +symbol :: Text -> Parser Text +symbol = L.symbol spaceConsumer + +sym :: Parser AST +sym = Sym . pack <$> identifier identifier :: Parser String identifier = diff --git a/lambda-calcul/haskell/test/Minilang/Lambda/ParserSpec.hs b/lambda-calcul/haskell/test/Minilang/Lambda/ParserSpec.hs index 4d6f6e0..c1eab27 100644 --- a/lambda-calcul/haskell/test/Minilang/Lambda/ParserSpec.hs +++ b/lambda-calcul/haskell/test/Minilang/Lambda/ParserSpec.hs @@ -10,6 +10,8 @@ spec :: Spec spec = parallel $ do prop "parses an identifier as a variable" $ \(Identifier ident) -> parse ident `shouldBe` Right (Sym ident) + prop "parses a lambda-expression as an abstraction" $ \(Identifier ident) (Identifier body) -> + parse ("(lam (" <> ident <> ") " <> body <> ")") `shouldBe` Right (Abs ident (Sym body)) newtype Identifier = Identifier Text deriving (Eq, Show) -- cgit v1.2.3