Skip to content

Commit

Permalink
Add support for python-style class methods
Browse files Browse the repository at this point in the history
  • Loading branch information
flbulgarelli committed Apr 14, 2022
1 parent a585df1 commit 70707cc
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 8 deletions.
16 changes: 14 additions & 2 deletions spec/PythonSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,21 @@ spec = do
(SimpleMethod "foo" [VariablePattern "self", VariablePattern "x"] (Return (Reference "x")))
]))

it "doesn't parse methods without self" $ do
it "parses classes with static methods" $ do
py "class Something:\n @staticmethod\n def foo(x): return x" `shouldBe` (
Class "Something" Nothing (Decorator [Static]
(SimpleMethod "foo" [VariablePattern "x"] (Return (Reference "x")))
))

it "parses classes with class methods" $ do
py "class Something:\n @classmethod\n def foo(cls, x): return x" `shouldBe` (
Class "Something" Nothing (Decorator [Classy]
(SimpleMethod "foo" [VariablePattern "cls", VariablePattern "x"] (Return (Reference "x")))
))

it "does parse methods without self" $ do
py "class Something:\n def bar(): return None\n" `shouldBe` (
Class "Something" Nothing (SimpleFunction "bar" [] (Return MuNil)))
Class "Something" Nothing (SimpleMethod "bar" [] (Return MuNil)))

it "doesn't parse methods pseudo-methods outside a class" $ do
py "def bar(self): return None\n" `shouldBe` (SimpleFunction "bar" [VariablePattern "self"] (Return MuNil))
Expand Down
1 change: 1 addition & 0 deletions src/Language/Mulang/Ast.hs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ data Type
data Modifier
= Abstract
| Static
| Classy
| Private
| Protected
| Annotation Expression
Expand Down
17 changes: 11 additions & 6 deletions src/Language/Mulang/Parsers/Python.hs
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,15 @@ muModule :: ModuleSpan -> M.Expression
muModule (Module statements) = compactMap muStatement statements

muClassStatement :: StatementSpan -> M.Expression
muClassStatement (Fun name args@((Param (Ident "self" _) _ _ _):_) _ body _) =
M.SimpleMethod (muIdent name) (map muParameter args) (muSuite body)
muClassStatement (Fun name args _ body _) = M.SimpleMethod (muIdent name) (map muParameter args) (muSuite body)
muClassStatement (Decorated ds statement _) = M.Decorator (map muDecorator ds) (muClassStatement statement)
muClassStatement other = muStatement other

muDecorator (Decorator [Ident "staticmethod" _] [] _) = M.Static
muDecorator (Decorator [Ident "classmethod" _] [] _) = M.Classy
muDecorator (Decorator [Ident name _] [] _) = M.Annotation (M.Reference name)
muDecorator other = M.debugModifier other

muStatement :: StatementSpan -> M.Expression
muStatement (While cond body _ _) = M.While (muExpr cond) (muSuite body)
muStatement (For targets generator body _ _) = M.For [M.Generator (M.TuplePattern (map (M.VariablePattern . muVariable) targets)) (muExpr generator)] (muSuite body)
Expand Down Expand Up @@ -98,10 +103,10 @@ muClass parent name body = M.Class name parent body
normalizeTests (M.Sequence exprs) = M.Sequence $ map normalizeTest exprs
normalizeTests expr = normalizeTest expr

normalizeTest func@(M.SimpleProcedure name _ body) = if isPrefixOf "test_" name
then M.Test (M.MuString name) body
else func
normalizeTest e = e
normalizeTest func@(M.SimpleMethod name _ body) = if isPrefixOf "test_" name
then M.Test (M.MuString name) body
else func
normalizeTest e = e

muIf (condition, body) otherwise = M.If (muExpr condition) (muSuite body) otherwise

Expand Down

0 comments on commit 70707cc

Please sign in to comment.