-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rework AST #3
Rework AST #3
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,39 @@ | ||
module Main (main) where | ||
|
||
import Syntax | ||
import Ast | ||
import Data.Map.Strict as Map | ||
import Text.PrettyPrint.Leijen.Text (pretty) | ||
|
||
{- | ||
append xs ys = λ xs . λ ys . case xs of | ||
Nil => ys | ||
Cons x' xs' => Cons x' (append xs' ys) | ||
-} | ||
|
||
bodyOfAppend :: Expression | ||
bodyOfAppend :: Expr | ||
bodyOfAppend = | ||
Case | ||
(Variable "xs") | ||
[ (Pat "Nil" [], Variable "ys") | ||
, | ||
( Pat "Cons" ["x'", "xs'"] | ||
, Constructor "Cons" [Variable "x'", Application (Application (Function "append") (Variable "xs'")) (Variable "ys")] | ||
) | ||
] | ||
(Var $ VarName "xs") | ||
$ Map.fromList | ||
[ (ConName "Nil", Alt [] (Var $ VarName "ys")) | ||
, | ||
( ConName "Cons" | ||
, Alt | ||
[VarName "x'", VarName "xs'"] | ||
( Con (ConName "Cons") [Var $ VarName "x'", App (App (Fun $ FunName "append") (Var $ VarName "xs'")) (Var $ VarName "ys")] | ||
) | ||
) | ||
] | ||
|
||
appendInExp :: FunctionHeader | ||
appendInExp :: Expr | ||
appendInExp = | ||
Header | ||
"append" | ||
["xs", "ys"] | ||
(Lambda "xs" (Lambda "ys" bodyOfAppend)) | ||
App | ||
( Fun | ||
(FunName "append") | ||
) | ||
(Lam (VarName "xs") (Lam (VarName "ys") bodyOfAppend)) | ||
|
||
main :: IO () | ||
main = print appendInExp | ||
main = do | ||
print appendInExp | ||
print $ pretty appendInExp |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
{-# LANGUAGE InstanceSigs #-} | ||
|
||
{- | Basic IL datatypes | ||
|
||
The grammar is based on [A Hierarchy of Program Transformers](https://www.researchgate.net/publication/229062264_A_Hierarchy_of_Program_Transformers). | ||
-} | ||
module Ast ( | ||
Expr (Var, Con, Lam, Fun, App, Case, Let), | ||
Fun (FunName, funName), | ||
Var (VarName, varName), | ||
Con (ConName, conName), | ||
Alt (Alt), | ||
) where | ||
|
||
import Data.Map.Strict (Map) | ||
import Data.Map.Strict qualified as Map | ||
import Data.Text (Text) | ||
|
||
import Text.PrettyPrint.Leijen.Text ( | ||
Doc, | ||
Pretty, | ||
align, | ||
hsep, | ||
parens, | ||
pretty, | ||
text, | ||
textStrict, | ||
vsep, | ||
(<+>), | ||
) | ||
|
||
-- | Function name, must be lowercase | ||
newtype Fun = FunName {funName :: Text} | ||
deriving (Show) | ||
|
||
instance Pretty Fun where | ||
pretty :: Fun -> Doc | ||
pretty (FunName fun) = textStrict fun | ||
|
||
-- | Variable name, must be lowercase | ||
newtype Var = VarName {varName :: Text} | ||
deriving (Show) | ||
|
||
instance Pretty Var where | ||
pretty :: Var -> Doc | ||
pretty (VarName var) = textStrict var | ||
|
||
-- | Constructor name, must start with uppercase letter | ||
newtype Con = ConName {conName :: Text} | ||
deriving (Show, Ord, Eq) | ||
|
||
instance Pretty Con where | ||
pretty :: Con -> Doc | ||
pretty (ConName con) = textStrict con | ||
|
||
-- | Case pattern-matching alternatives map | ||
type Alts = Map Con Alt | ||
|
||
instance Pretty Alts where | ||
pretty :: Alts -> Doc | ||
pretty alts = vsep $ map (\(con, alt) -> pretty con <+> pretty alt) list | ||
where | ||
list = Map.toList alts | ||
|
||
-- | Case pattern-matching alternative | ||
data Alt = Alt [Var] Expr | ||
deriving (Show) | ||
|
||
instance Pretty Alt where | ||
pretty :: Alt -> Doc | ||
pretty (Alt vars expr) = hsep (fmap pretty vars) <+> text "=>" <+> pretty expr | ||
|
||
-- | IL expression type | ||
data Expr | ||
= -- | Variable | ||
Var Var | ||
| -- | Sum type constructor with arbitrary expression inside | ||
Con Con [Expr] | ||
| -- | Lambda abstraction | ||
Lam Var Expr | ||
| -- | Function call | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. А можно для дебилов: чем вызов функции от применения отличется? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Как я понимаю, узел Fun просто висит слева в аппликации и хранит в себе имя функции. Всё. Вероятно так удобнее для дистилляции :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Да, всё вроде так. |
||
Fun Fun | ||
| -- | Expressions' application | ||
App Expr Expr | ||
| -- | Pattern-matching using case, patterns must be non-overlapping and exhaustive | ||
Case Expr Alts | ||
| -- | Simple let expression, can be introduced only by distillation | ||
Let Var Expr Expr | ||
deriving (Show) | ||
|
||
{- | PPrinting currently is very simple and only used for debugging. | ||
Most probably will change after source language design. | ||
-} | ||
instance Pretty Expr where | ||
pretty :: Expr -> Doc | ||
pretty (Var var) = pretty var | ||
pretty (Con con exprs) = pretty con <+> hsep (fmap pretty exprs) | ||
pretty (Lam var expr) = text "\\" <> pretty var <> text "." <> pretty expr | ||
pretty (Fun fun) = pretty fun | ||
pretty (App expr1 expr2) = parens (pretty expr1) <+> parens (pretty expr2) | ||
pretty (Case expr alts) = text "case" <+> pretty expr <+> text "of" <+> align (pretty alts) | ||
pretty (Let var varExpr expr) = text "let" <+> pretty var <+> text "=" <+> pretty varExpr <+> text "in" <+> pretty expr |
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А почему не
type Fun = Text
? Просто тут как будто избыточность какая-то возникаетThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
У нас вырисовываются три раздельных пространства имён: функции, переменные и конструкторы. Разделение на три точно разных типа выглядит очень даже оправданно в данном случае