2020-04-30 17:58:35 +04:00
|
|
|
|
2020-05-01 19:04:29 +04:00
|
|
|
module AST.Parser (example, contract) where
|
2020-04-30 17:58:35 +04:00
|
|
|
|
|
|
|
import Data.Text (Text)
|
|
|
|
|
2020-05-06 21:26:00 +04:00
|
|
|
import AST.Types hiding (tuple)
|
2020-04-30 17:58:35 +04:00
|
|
|
|
|
|
|
import Parser
|
|
|
|
import Range
|
|
|
|
|
|
|
|
import Debug.Trace
|
|
|
|
|
|
|
|
name :: Parser (Name Range)
|
|
|
|
name = do
|
|
|
|
(raw, info) <- range (token "Name")
|
|
|
|
return Name {info, raw}
|
|
|
|
|
2020-05-06 21:26:00 +04:00
|
|
|
capitalName :: Parser (Name Range)
|
|
|
|
capitalName = do
|
|
|
|
(raw, info) <- range (token "Name_Capital")
|
|
|
|
return Name {info, raw}
|
|
|
|
|
2020-04-30 17:58:35 +04:00
|
|
|
contract :: Parser (Contract Range)
|
|
|
|
contract = subtree "contract" do
|
|
|
|
(decls, info) <- range do
|
2020-05-06 21:26:00 +04:00
|
|
|
many "declaration" do
|
|
|
|
inside "declaration:" do
|
|
|
|
declaration
|
2020-05-01 19:04:29 +04:00
|
|
|
|
2020-04-30 17:58:35 +04:00
|
|
|
return (Contract info decls)
|
|
|
|
|
|
|
|
declaration :: Parser (Declaration Range)
|
2020-05-06 21:26:00 +04:00
|
|
|
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)
|
2020-04-30 17:58:35 +04:00
|
|
|
|
|
|
|
par x = do
|
|
|
|
consume "("
|
|
|
|
a <- x
|
|
|
|
consume ")"
|
|
|
|
return a
|
|
|
|
|
|
|
|
binding :: Parser (Binding Range)
|
|
|
|
binding = do
|
|
|
|
info <- getRange
|
2020-05-06 21:26:00 +04:00
|
|
|
inside ":fun_decl" do
|
|
|
|
recur <- optional $ inside "recursive" $ token "recursive"
|
|
|
|
name <- inside "name:" name
|
2020-04-30 17:58:35 +04:00
|
|
|
params <-
|
2020-05-06 21:26:00 +04:00
|
|
|
inside "parameters:parameters" do
|
|
|
|
many "param" do
|
|
|
|
notFollowedBy do
|
|
|
|
consumeOrDie ")"
|
|
|
|
|
|
|
|
stubbed "parameters" paramDecl
|
|
|
|
ty <- inside "type:" type_
|
|
|
|
exp <- inside "body:" letExpr
|
2020-04-30 21:46:37 +04:00
|
|
|
return (Function info (recur == Just "recursive") name params ty exp)
|
|
|
|
|
|
|
|
expr :: Parser (Expr Range)
|
2020-05-06 21:26:00 +04:00
|
|
|
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,
|
|
|
|
|
2020-05-06 21:26:00 +04:00
|
|
|
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
|
2020-05-06 21:26:00 +04:00
|
|
|
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
|
2020-04-30 17:58:35 +04:00
|
|
|
|
2020-05-06 21:26:00 +04:00
|
|
|
statement :: Parser (Declaration Range)
|
|
|
|
statement = do
|
|
|
|
r <- getRange
|
|
|
|
e <- expr
|
|
|
|
return $ Action r e
|
|
|
|
|
2020-04-30 17:58:35 +04:00
|
|
|
paramDecl :: Parser (VarDecl Range)
|
|
|
|
paramDecl = do
|
|
|
|
info <- getRange
|
2020-05-06 21:26:00 +04:00
|
|
|
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
|
2020-04-30 17:58:35 +04:00
|
|
|
|
|
|
|
type_ :: Parser (Type Range)
|
|
|
|
type_ =
|
|
|
|
fun_type
|
|
|
|
where
|
|
|
|
fun_type :: Parser (Type Range)
|
|
|
|
fun_type = do
|
2020-05-06 21:26:00 +04:00
|
|
|
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
|
2020-04-30 17:58:35 +04:00
|
|
|
|
|
|
|
cartesian = do
|
2020-05-06 21:26:00 +04:00
|
|
|
inside ":cartesian" do
|
|
|
|
info <- getRange
|
|
|
|
TProduct info <$> some "corety" do
|
|
|
|
inside "element" do
|
|
|
|
core_type
|
2020-04-30 17:58:35 +04:00
|
|
|
|
|
|
|
core_type = do
|
|
|
|
info <- getRange
|
|
|
|
select
|
|
|
|
[ TVar info <$> typename
|
2020-05-06 21:26:00 +04:00
|
|
|
, subtree "invokeBinary" do
|
|
|
|
r <- getRange
|
|
|
|
f <- inside "typeConstr" name
|
|
|
|
xs <- inside "arguments" typeTuple
|
|
|
|
return $ TApply r f xs
|
2020-04-30 17:58:35 +04:00
|
|
|
]
|
|
|
|
|
|
|
|
typename = name
|
|
|
|
|
2020-05-06 21:26:00 +04:00
|
|
|
typeTuple :: Parser [Type Range]
|
|
|
|
typeTuple = do
|
|
|
|
subtree "type_tuple" do
|
|
|
|
many "type tuple element" do
|
|
|
|
inside "element" type_
|
|
|
|
|
2020-04-30 17:58:35 +04:00
|
|
|
tuple :: Text -> Parser a -> Parser [a]
|
|
|
|
tuple msg = par . some msg
|
|
|
|
|
2020-05-06 21:26:00 +04:00
|
|
|
-- 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"
|