320 lines
7.2 KiB
Haskell
Raw Normal View History

module AST.Parser (example, contract) where
import Data.Text (Text)
import AST.Types hiding (tuple)
import Parser
import Range
import Debug.Trace
name :: Parser (Name Range)
name = do
(raw, info) <- range (token "Name")
return Name {info, raw}
capitalName :: Parser (Name Range)
capitalName = do
(raw, info) <- range (token "Name_Capital")
return Name {info, raw}
contract :: Parser (Contract Range)
contract = subtree "contract" do
(decls, info) <- range do
many "declaration" do
inside "declaration:" do
declaration
return (Contract info decls)
declaration :: Parser (Declaration Range)
declaration = do
(b, info) <- range binding
return (ValueDecl info b)
<|> do
(b, info) <- range vardecl
return (ValueDecl info b)
<|> do
(b, info) <- range constdecl
return (ValueDecl info b)
<|>
typedecl
typedecl :: Parser (Declaration Range)
typedecl = do
subtree "type_decl" do
r <- getRange
n <- inside "typeName:" name
t <- inside "typeValue:" newtype_
return $ TypeDecl r n t
vardecl :: Parser (Binding Range)
vardecl = do
subtree "var_decl" do
r <- getRange
n <- inside "name:" name
ty <- inside "type:" type_
b <- inside "value:" expr
return (Var r n ty b)
constdecl :: Parser (Binding Range)
constdecl = do
subtree "const_decl" do
r <- getRange
n <- inside "name" name
ty <- inside "type" type_
b <- inside "value" expr
return (Const r n ty b)
par x = do
consume "("
a <- x
consume ")"
return a
binding :: Parser (Binding Range)
binding = do
info <- getRange
inside ":fun_decl" do
recur <- optional $ inside "recursive" $ token "recursive"
name <- inside "name:" name
params <-
inside "parameters:parameters" do
many "param" do
notFollowedBy do
consumeOrDie ")"
stubbed "parameters" paramDecl
ty <- inside "type:" type_
exp <- inside "body:" letExpr
return (Function info (recur == Just "recursive") name params ty exp)
expr :: Parser (Expr Range)
expr = stubbed "expr" do
select
[ Ident <$> getRange <*> do
r <- getRange
n <- name
return $ QualifiedName r n []
, opCall
, fun_call
, record_expr
, int_literal
, par_call
, method_call
-- , if_expr
-- , constant
]
2020-05-01 22:41:07 +04:00
where
-- $.case_expr,
-- $.cond_expr,
-- $.disj_expr,
-- $.fun_expr,
method_call :: Parser (Expr Range)
method_call = do
subtree "projection_call" do
r <- getRange
(f, r') <- field "f" $ range projection
xs <- inside "arguments" arguments
return $ Apply r (Ident r' f) xs
projection :: Parser (QualifiedName Range)
projection = do
subtree "data_projection" do
r <- getRange
s <- inside "struct" name
is <- many "selection" selection
return $ QualifiedName r s is
selection :: Parser (Path Range)
selection = do
inside "index:selection" $ do
r <- getRange
n <- name
return $ At r n
<|> do
r <- getRange
n <- token "Int"
return $ Ix r n
par_call :: Parser (Expr Range)
par_call = do
subtree "par_call" do
r <- getRange
f <- inside "f" expr
az <- inside "arguments" arguments
return $ Apply r f az
int_literal :: Parser (Expr Range)
int_literal = do
r <- getRange
i <- token "Int"
return $ Constant r (Int r i)
record_expr :: Parser (Expr Range)
record_expr = do
subtree "record_expr" do
r <- getRange
az <- many "assignment" do
inside "assignment:field_assignment" do
r <- getRange
n <- inside "name" name
e <- inside "_rhs" expr
return $ Assignment r n e
return $ Record r az
fun_call :: Parser (Expr Range)
fun_call = do
subtree "fun_call" do
r <- getRange
(f, r') <- range $ inside "f" function_id
xs <- inside "arguments" do
arguments
return $ Apply r (Ident r' f) xs
arguments =
subtree "arguments" do
many "argument" do
inside "argument" expr
function_id :: Parser (QualifiedName Range)
function_id = select
[ do
r <- getRange
n <- name
return $ QualifiedName r n []
, do
subtree "module_field" do
r <- getRange
whole <- inside "module" capitalName
path <- inside "method" name
return $ QualifiedName r whole [At r path]
]
opCall :: Parser (Expr Range)
opCall = do
subtree "op_expr" $ do
inside "the" do
expr
<|> do
i <- getRange
l <- inside "arg1" expr
o <- inside "op" anything
r <- inside "arg2" expr
return $ BinOp i l o r
2020-05-01 22:41:07 +04:00
letExpr = do
subtree "let_expr" do
r <- getRange
decls <- optional do
inside "locals:block" do
many "decl" do
inside "statement" do
declaration <|> statement
body <- inside "body"expr
2020-05-01 22:41:07 +04:00
return case decls of
Just them -> Let r them body
Nothing -> body
statement :: Parser (Declaration Range)
statement = do
r <- getRange
e <- expr
return $ Action r e
paramDecl :: Parser (VarDecl Range)
paramDecl = do
info <- getRange
inside "parameter:param_decl" do
info' <- getRange
mutable <- do
inside ":access" do
select
[ consume "var" >> return (Mutable info')
, consume "const" >> return (Immutable info')
]
name <- inside "name" name
ty <- inside "type" type_
return (Decl info mutable name ty)
newtype_ = select
[ record_type
, type_
-- , sum_type
]
record_type = do
subtree "record_type" do
r <- getRange
fs <- many "field" do
inside "field" do
field_decl
traceShowM fs
return $ TRecord r fs
field_decl = do
subtree "field_decl" do
r <- getRange
n <- inside "fieldName" name
t <- inside "fieldType" type_
return $ TField r n t
type_ :: Parser (Type Range)
type_ =
fun_type
where
fun_type :: Parser (Type Range)
fun_type = do
inside ":fun_type" do
info <- getRange
domain <- inside "domain" cartesian
codomain <- optional do
consume "->"
fun_type
return case codomain of
Just co -> TArrow info domain co
Nothing -> domain
cartesian = do
inside ":cartesian" do
info <- getRange
TProduct info <$> some "corety" do
inside "element" do
core_type
core_type = do
info <- getRange
select
[ TVar info <$> typename
, subtree "invokeBinary" do
r <- getRange
f <- inside "typeConstr" name
xs <- inside "arguments" typeTuple
return $ TApply r f xs
]
typename = name
typeTuple :: Parser [Type Range]
typeTuple = do
subtree "type_tuple" do
many "type tuple element" do
inside "element" type_
tuple :: Text -> Parser a -> Parser [a]
tuple msg = par . some msg
-- example = "../../../src/test/contracts/application.ligo"
-- example = "../../../src/test/contracts/address.ligo"
example = "../../../src/test/contracts/amount.ligo"
-- example = "../../../src/test/contracts/application.ligo"
-- example = "../../../src/test/contracts/application.ligo"
-- example = "../../../src/test/contracts/application.ligo"
-- example = "../../../src/test/contracts/application.ligo"
-- example = "../../../src/test/contracts/application.ligo"