{-# language OverloadedStrings #-} {-# language FlexibleContexts #-} module Programs where import Control.Lens.Getter ((^.)) import Control.Lens.Iso (from) import Data.Function ((&)) import Data.List.NonEmpty (NonEmpty(..)) import Language.Python.DSL import Language.Python.Syntax -- | -- @ -- def append_to(element, to=[]): -- to.append(element) -- return to -- @ -- -- Written without the DSL (not recommended!) append_to :: Raw Statement append_to = CompoundStatement $ Fundef (Ann ()) [] (Indents [] (Ann ())) Nothing (Space :| []) "append_to" [] ( CommaSepMany (PositionalParam (Ann ()) "element" Nothing) (MkComma [Space]) $ CommaSepOne (KeywordParam (Ann ()) "to" Nothing [] (List (Ann ()) [] Nothing [])) ) [] Nothing (SuiteMany (Ann ()) (MkColon []) Nothing LF $ Block [] ( SmallStatement (Indents [replicate 4 Space ^. from indentWhitespaces] (Ann ())) (MkSmallStatement (Expr (Ann ()) $ Call (Ann ()) (Deref (Ann ()) (Ident (Ann ()) "to") [] "append") [] (Just $ CommaSepOne1' (PositionalArg (Ann ()) (Ident (Ann ()) "element")) Nothing) []) [] Nothing Nothing (Just LF)) ) [ Right $ SmallStatement (Indents [replicate 4 Space ^. from indentWhitespaces] (Ann ())) (MkSmallStatement (Return (Ann ()) [Space] (Just $ Ident (Ann ()) "to")) [] Nothing Nothing (Just LF)) ]) -- | -- @ -- def append_to(element, to=[]): -- to.append(element) -- return to -- @ -- -- Written with the DSL append_to' :: Raw Fundef append_to' = def_ "append_to" [ p_ "element", k_ "to" (list_ []) ] [ line_ $ call_ ("to" /> "append") [ "element" ] , line_ $ return_ "to" ] -- | -- @ -- def fact(n) -- def go(n, acc) -- if n == 0: -- return acc -- else: -- go(n-1, n*acc) -- return go(n, 1) -- @ fact_tr :: Raw Fundef fact_tr = def_ "fact" [p_ "n"] [ line_ $ def_ "go" [p_ "n", p_ "acc"] [ line_ $ if_ ("n" .== 0) [line_ $ return_ (var_ "acc")] & else_ [line_ . return_ $ call_ "go" [p_ $ "n" .- 1, p_ $ "n" .* "acc"]] ] , line_ . return_ $ call_ "go" [p_ "n", p_ 1] ] -- | -- @ -- def spin(): -- spin() -- @ spin :: Raw Fundef spin = def_ "spin" [] [line_ $ call_ "spin" []] -- | -- @ -- def yes() -- print("yes") -- yes() -- @ yes :: Raw Fundef yes = def_ "yes" [] [ line_ $ call_ "print" [p_ $ str_ "yes"] , line_ $ call_ "yes" [] ] counter :: Raw ClassDef counter = class_ "Counter" [] [ line_ $ def_ "__init__" ["self"] [line_ ("self" /> "x" .= 0)] , blank_ , line_ $ def_ "incr" ["self"] [line_ ("self" /> "x" .+= 1)] , blank_ , line_ $ def_ "reset" ["self"] [line_ ("self" /> "x" .= 0)] , blank_ , line_ $ def_ "get" ["self"] [line_ $ return_ ("self" /> "x")] ] exceptions :: Raw Fundef exceptions = def_ "exceptions" [] [ line_ $ tryE_ [line_ pass_] & except_ [line_ pass_] , blank_ , line_ $ tryE_ [line_ pass_] & exceptAs_ (var_ "a" `as_` id_ "b") [line_ pass_] , blank_ , line_ $ tryE_ [line_ pass_] & exceptAs_ (var_ "a" `as_` id_ "b") [line_ pass_] & finally_ [line_ pass_] , blank_ , line_ $ tryE_ [line_ pass_] & exceptAs_ (var_ "a" `as_` id_ "b") [line_ pass_] & else_ [line_ pass_] & finally_ [line_ pass_] , blank_ , line_ $ tryF_ [line_ pass_] [line_ pass_] , blank_ , line_ $ tryF_ [line_ pass_] & finally_ [line_ pass_] , blank_ , line_ $ tryF_ [line_ pass_] [line_ pass_] & exceptAs_ (var_ "a" `as_` id_ "b") [line_ pass_] & else_ [line_ pass_] ] everything :: Raw Module everything = module_ [ line_ append_to , blank_ , line_ append_to' , blank_ , line_ fact_tr , blank_ , line_ spin , blank_ , line_ yes , blank_ , line_ counter , blank_ , line_ exceptions ]