745 lines
18 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 ASTInfo)
name = ctor Name <*> token "Name"
capitalName :: Parser (Name ASTInfo)
capitalName = ctor Name <*> token "Name_Capital"
contract :: Parser (Contract ASTInfo)
contract =
ctor Contract
<*> subtree "contract" do
many "declaration" do
inside "declaration:" do
declaration
declaration :: Parser (Declaration ASTInfo)
declaration
= do ctor ValueDecl <*> binding
<|> do ctor ValueDecl <*> vardecl
<|> do ctor ValueDecl <*> constdecl
<|> do typedecl
2020-05-06 23:19:28 +04:00
<|> do ctor Action <*> attributes
<|> do include
include = do
subtree "include" do
ctor Include
<*> inside "filename" do token "String"
typedecl :: Parser (Declaration ASTInfo)
typedecl = do
subtree "type_decl" do
ctor TypeDecl
<*> inside "typeName:" name
<*> inside "typeValue:" newtype_
vardecl :: Parser (Binding ASTInfo)
vardecl = do
subtree "var_decl" do
ctor Var
<*> inside "name" name
<*> inside "type" type_
<*> inside "value" expr
constdecl :: Parser (Binding ASTInfo)
constdecl = do
subtree "const_decl" do
ctor Const
<*> inside "name" name
<*> inside "type" type_
<*> inside "value" expr
binding :: Parser (Binding ASTInfo)
binding = do
inside ":fun_decl" do
ctor Function
<*> recursive
<*> inside "name:" name
<*> inside "parameters:parameters" do
many "param" do
inside "parameter" paramDecl
<*> inside "type:" type_
<*> inside "body:" letExpr
recursive = do
mr <- optional do
inside "recursive" do
token "recursive"
return $ maybe False (== "recursive") mr
expr :: Parser (Expr ASTInfo)
expr = stubbed "expr" do
select
[ ctor Ident <*> do
ctor QualifiedName
<*> name
<*> pure []
, opCall
, fun_call
, record_expr
, int_literal
, tez_literal
, par_call
, method_call
, if_expr
, assign
, list_expr
, has_type
, string_literal
2020-05-06 23:19:28 +04:00
, attributes
, tuple_expr
, moduleQualified
, big_map_expr
, map_expr
, map_remove
, indexing
, constr_call
, nat_literal
, nullary_ctor
, bytes_literal
, case_expr
, skip
, case_action
, clause_block
, loop
, seq_expr
, lambda_expr
, set_expr
, map_patch
, record_update
, set_patch
, set_remove
]
set_remove :: Parser (Expr ASTInfo)
set_remove = do
subtree "set_remove" do
ctor SetRemove
<*> inside "key" expr
<*> inside "container" do
inside ":path" do
qname <|> projection
set_patch = do
subtree "set_patch" do
ctor SetPatch
<*> inside "container:path" (qname <|> projection)
<*> many "key" do
inside "key" expr
record_update = do
subtree "update_record" do
ctor RecordUpd
<*> inside "record:path" do qname <|> projection
<*> many "field" do
inside "assignment" field_path_assignment
field_path_assignment = do
subtree "field_path_assignment" do
ctor FieldAssignment
<*> inside "lhs:path" do qname <|> projection
<*> inside "_rhs" expr
map_patch = do
subtree "map_patch" do
ctor MapPatch
<*> inside "container:path" (qname <|> projection)
<*> many "binding" do
inside "binding" map_binding
set_expr :: Parser (Expr ASTInfo)
set_expr = do
subtree "set_expr" do
ctor List <*> do
many "list elem" do
inside "element" expr
lambda_expr = do
subtree "fun_expr" do
ctor Lambda
<*> inside "parameters:parameters" do
many "param" do
inside "parameter" paramDecl
<*> inside "type" newtype_
<*> inside "body" expr
seq_expr = do
subtree "block" do
ctor Seq <*> do
many "statement" do
inside "statement" do
declaration <|> statement
loop = do
subtree "loop" do
for_loop <|> while_loop <|> for_container
for_container = do
subtree "for_loop" do
ctor ForBox
<*> inside "key" name
<*> optional do inside "value" name
<*> inside "kind" anything
<*> inside "collection" expr
<*> inside "body" (expr <|> seq_expr)
while_loop = do
subtree "while_loop" do
ctor WhileLoop
<*> inside "breaker" expr
<*> inside "body" expr
for_loop = do
subtree "for_loop" do
ctor ForLoop
<*> inside "name" name
<*> inside "begin" expr
<*> inside "end" expr
<*> inside "body" expr
clause_block = do
subtree "clause_block" do
inside "block:block" do
ctor Seq <*> many "statement" do
inside "statement" (declaration <|> statement)
<|> do
subtree "clause_block" do
ctor Seq <*> many "statement" do
inside "statement" (declaration <|> statement)
skip :: Parser (Expr ASTInfo)
skip = do
ctor Skip <* token "skip"
case_action :: Parser (Expr ASTInfo)
case_action = do
subtree "case_instr" do
ctor Case
<*> inside "subject" expr
<*> many "case" do
inside "case" alt_action
alt_action :: Parser (Alt ASTInfo)
alt_action = do
subtree "case_clause_instr" do
ctor Alt
<*> inside "pattern" pattern
<*> inside "body:if_clause" expr
case_expr :: Parser (Expr ASTInfo)
case_expr = do
subtree "case_expr" do
ctor Case
<*> inside "subject" expr
<*> many "case" do
inside "case" alt
alt :: Parser (Alt ASTInfo)
alt = do
subtree "case_clause_expr" do
ctor Alt
<*> inside "pattern" pattern
<*> inside "body" expr
pattern :: Parser (Pattern ASTInfo)
pattern = do
subtree "pattern" $ do
inside "the" core_pattern
<|>
do ctor IsCons
<*> inside "head" core_pattern
<*> inside "tail" pattern
core_pattern :: Parser (Pattern ASTInfo)
core_pattern
= -- int_pattern
-- <|> nat_pattern
-- <|> var_pattern
-- <|> list_pattern
-- <|> tuple_pattern
-- <|>
constr_pattern
<|> string_pattern
<|> int_pattern
<|> nat_pattern
<|> tuple_pattern
<|> list_pattern
<|> some_pattern
<|> var_pattern
var_pattern :: Parser (Pattern ASTInfo)
var_pattern =
ctor IsVar <*> name
some_pattern :: Parser (Pattern ASTInfo)
some_pattern = do
subtree "Some_pattern" do
ctor IsConstr
<*> do inside "constr" do ctor Name <*> token "Some"
<*> do Just <$> inside "arg" pattern
string_pattern :: Parser (Pattern ASTInfo)
string_pattern =
ctor IsConstant <*> do
ctor String <*> token "String"
nat_pattern :: Parser (Pattern ASTInfo)
nat_pattern =
ctor IsConstant <*> do
ctor Nat <*> token "Nat"
int_pattern :: Parser (Pattern ASTInfo)
int_pattern =
ctor IsConstant <*> do
ctor Int <*> token "Int"
constr_pattern :: Parser (Pattern ASTInfo)
constr_pattern =
do
subtree "user_constr_pattern" do
ctor IsConstr
<*> inside "constr:constr" capitalName
<*> optional do
inside "arguments" tuple_pattern
<|>
do
ctor IsConstr
<*> do ctor Name <*> do token "True" <|> token "False" <|> token "None" <|> token "Unit"
<*> pure Nothing
tuple_pattern :: Parser (Pattern ASTInfo)
tuple_pattern = do
subtree "tuple_pattern" do
ctor IsTuple <*> do
many "element" do
inside "element" pattern
list_pattern :: Parser (Pattern ASTInfo)
list_pattern = do
subtree "list_pattern" do
ctor IsList <*> do
many "element" do
inside "element" pattern
nullary_ctor :: Parser (Expr ASTInfo)
nullary_ctor = do
ctor Ident <*> do
ctor QualifiedName
<*> do ctor Name <*> do
true <|> false <|> none <|> unit
<*> pure []
where
true = token "True"
false = token "False"
none = token "None"
unit = token "Unit"
nat_literal :: Parser (Expr ASTInfo)
nat_literal = do
ctor Constant <*> do
ctor Nat <*> token "Nat"
bytes_literal :: Parser (Expr ASTInfo)
bytes_literal = do
ctor Constant <*> do
ctor Bytes <*> token "Bytes"
constr_call :: Parser (Expr ASTInfo)
constr_call = do
some_call <|> user_constr_call
2020-05-01 22:41:07 +04:00
where
some_call = do
subtree "Some_call" do
ctor Apply
<*> do ctor Ident <*> inside "constr" qname'
<*> inside "arguments:arguments" do
many "argument" do
inside "argument" expr
user_constr_call = do
subtree "constr_call" do
ctor Apply
<*> inside "constr:constr" do
ctor Ident <*> do
ctor QualifiedName
<*> capitalName
<*> pure []
<*> inside "arguments:arguments" do
many "argument" do
inside "argument" expr
indexing :: Parser (Expr ASTInfo)
indexing = do
subtree "map_lookup" do
ctor Indexing
<*> inside "container:path" do
qname <|> projection
<*> inside "index" expr
2020-05-01 22:41:07 +04:00
map_remove :: Parser (Expr ASTInfo)
map_remove = do
subtree "map_remove" do
ctor MapRemove
<*> inside "key" expr
<*> inside "container" do
inside ":path" do
qname <|> projection
big_map_expr :: Parser (Expr ASTInfo)
big_map_expr = do
subtree "big_map_injection" do
ctor BigMap <*> do
many "binding" do
inside "binding" do
map_binding
map_expr :: Parser (Expr ASTInfo)
map_expr = do
subtree "map_injection" do
ctor Map <*> do
many "binding" do
inside "binding" do
map_binding
map_binding :: Parser (MapBinding ASTInfo)
map_binding = do
subtree "binding" do
ctor MapBinding
<*> inside "key" expr
<*> inside "value" expr
moduleQualified :: Parser (Expr ASTInfo)
moduleQualified = do
subtree "module_field" do
ctor Ident <*> do
ctor QualifiedName
<*> inside "module" capitalName
<*> do pure <$> do ctor At <*> inside "method" do name <|> name'
tuple_expr :: Parser (Expr ASTInfo)
tuple_expr = do
subtree "tuple_expr" do
ctor Tuple <*> do
many "tuple element" do
inside "element" expr
2020-05-06 23:19:28 +04:00
attributes :: Parser (Expr ASTInfo)
attributes = do
subtree "attr_decl" do
ctor Attrs <*> do
many "attribute" do
inside "attribute" do
token "String"
string_literal :: Parser (Expr ASTInfo)
string_literal = do
ctor Constant <*> do
ctor String <*>
token "String"
has_type :: Parser (Expr ASTInfo)
has_type = do
subtree "annot_expr" do
ctor Annot
<*> inside "subject" expr
<*> inside "type" type_
list_expr :: Parser (Expr ASTInfo)
list_expr = do
subtree "list_expr" do
ctor List <*> do
many "list elem" do
inside "element" expr
qname :: Parser (QualifiedName ASTInfo)
qname = do
ctor QualifiedName
<*> name
<*> pure []
qname' :: Parser (QualifiedName ASTInfo)
qname' = do
ctor QualifiedName
<*> name'
<*> pure []
assign :: Parser (Expr ASTInfo)
assign = do
subtree "assignment" do
ctor Assign
<*> inside "LHS" lhs
<*> inside "RHS" expr
lhs :: Parser (LHS ASTInfo)
lhs =
do ctor LHS
<*> inside "container:path" do
qname <|> projection
<*> pure Nothing
<|>
do ctor LHS
<*> subtree "path" do
qname <|> projection
<*> pure Nothing
<|>
do subtree "map_lookup" do
ctor LHS
<*> inside "container:path" do
qname <|> projection
<*> inside "index" do
Just <$> expr
tez_literal :: Parser (Expr ASTInfo)
tez_literal = do
ctor Constant <*> do
ctor Tez <*> token "Tez"
if_expr :: Parser (Expr ASTInfo)
if_expr = do
subtree "conditional" do
ctor If
<*> inside "selector" expr
<*> inside "then:if_clause" expr
<*> inside "else:if_clause" expr
<|> do
subtree "cond_expr" do
ctor If
<*> inside "selector" expr
<*> inside "then" expr
<*> inside "else" expr
method_call :: Parser (Expr ASTInfo)
method_call = do
subtree "projection_call" do
ctor apply'
<*> field "f" projection
<*> optional do inside "arguments" arguments
where
apply' r f (Just xs) = Apply r (Ident r f) xs
apply' r f _ = Ident r f
projection :: Parser (QualifiedName ASTInfo)
projection = do
subtree "data_projection" do
ctor QualifiedName
<*> inside "struct" name
<*> many "selection" selection
selection :: Parser (Path ASTInfo)
selection = do
inside "index:selection"
$ do ctor At <*> name
<|> do ctor Ix <*> token "Int"
<|>
inside "index" do
do ctor Ix <*> token "Int"
par_call :: Parser (Expr ASTInfo)
par_call = do
subtree "par_call" do
ctor apply'
<*> inside "f" expr
<*> optional do inside "arguments" arguments
where
apply' r f (Just xs) = Apply r f xs
apply' _ f _ = f
int_literal :: Parser (Expr ASTInfo)
int_literal = do
ctor Constant
<*> do ctor Int <*> token "Int"
record_expr :: Parser (Expr ASTInfo)
record_expr = do
subtree "record_expr" do
ctor Record <*> do
many "assignment" do
inside "assignment:field_assignment" do
ctor Assignment
<*> inside "name" name
<*> inside "_rhs" expr
fun_call :: Parser (Expr ASTInfo)
fun_call = do
subtree "fun_call" do
ctor Apply
<*> do ctor Ident <*> inside "f" function_id
<*> inside "arguments" arguments
arguments =
subtree "arguments" do
many "argument" do
inside "argument" expr
function_id :: Parser (QualifiedName ASTInfo)
function_id = select
[ qname
, do
subtree "module_field" do
ctor QualifiedName
<*> inside "module" capitalName
<*> do pure <$> do ctor At <*> inside "method" do name <|> name'
]
opCall :: Parser (Expr ASTInfo)
opCall = do
subtree "op_expr"
$ do inside "the" expr
<|> do ctor BinOp
<*> inside "arg1" expr
<*> inside "op" anything
<*> inside "arg2" expr
2020-05-06 23:19:28 +04:00
<|> do ctor UnOp
<*> inside "negate" anything
<*> inside "arg" expr
2020-05-01 22:41:07 +04:00
letExpr = do
subtree "let_expr" do
ctor let'
<*> optional do
inside "locals:block" do
many "decl" do
inside "statement" do
declaration <|> statement
<*> inside "body"expr
where
let' r decls body = case decls of
2020-05-01 22:41:07 +04:00
Just them -> Let r them body
Nothing -> body
statement :: Parser (Declaration ASTInfo)
statement = ctor Action <*> expr
paramDecl :: Parser (VarDecl ASTInfo)
paramDecl = do
subtree "param_decl" do
ctor Decl
<*> do inside ":access" do
select
[ ctor Mutable <* consumeOrDie "var"
, ctor Immutable <* consumeOrDie "const"
]
<*> inside "name" name
<*> inside "type" type_
newtype_ = select
[ record_type
, type_
, sum_type
]
sum_type = do
subtree "sum_type" do
ctor TSum <*> do
many "variant" do
inside "variant" variant
variant = do
subtree "variant" do
ctor Variant
<*> inside "constructor:constr" capitalName
<*> optional do inside "arguments" type_
record_type = do
subtree "record_type" do
ctor TRecord
<*> many "field" do
inside "field" do
field_decl
field_decl = do
subtree "field_decl" do
ctor TField
<*> inside "fieldName" name
<*> inside "fieldType" newtype_
type_ :: Parser (Type ASTInfo)
type_ =
fun_type
where
fun_type :: Parser (Type ASTInfo)
fun_type = do
inside ":fun_type" do
ctor tarrow
<*> inside "domain" cartesian
<*> optional do inside "codomain" fun_type
where
tarrow info domain codomain =
case codomain of
Just co -> TArrow info domain co
Nothing -> domain
cartesian = do
inside ":cartesian" do
ctor TProduct <*> some "corety" do
inside "element" do
core_type
core_type = do
select
[ ctor TVar <*> name
, subtree "invokeBinary" do
ctor TApply
<*> inside "typeConstr" name'
<*> inside "arguments" typeTuple
, subtree "invokeUnary" do
ctor TApply
<*> inside "typeConstr" name'
<*> do pure <$> inside "arguments" type_
, subtree "type_expr" newtype_
]
name' :: Parser (Name ASTInfo)
name' = do
ctor Name <*> anything
typeTuple :: Parser [Type ASTInfo]
typeTuple = do
subtree "type_tuple" do
many "type tuple element" do
inside "element" type_
-- example = "../../../src/test/contracts/application.ligo"
-- example = "../../../src/test/contracts/address.ligo"
-- example = "../../../src/test/contracts/amount.ligo"
2020-05-06 23:19:28 +04:00
-- example = "../../../src/test/contracts/annotation.ligo"
-- example = "../../../src/test/contracts/arithmetic.ligo"
-- example = "../../../src/test/contracts/assign.ligo"
-- example = "../../../src/test/contracts/attributes.ligo"
-- example = "../../../src/test/contracts/bad_timestamp.ligo"
-- example = "../../../src/test/contracts/bad_type_operator.ligo"
-- example = "../../../src/test/contracts/balance_constant.ligo"
-- example = "../../../src/test/contracts/big_map.ligo"
-- example = "../../../src/test/contracts/bitwise_arithmetic.ligo"
-- example = "../../../src/test/contracts/blockless.ligo"
-- example = "../../../src/test/contracts/boolean_operators.ligo"
-- example = "../../../src/test/contracts/bytes_arithmetic.ligo"
-- example = "../../../src/test/contracts/bytes_unpack.ligo"
-- example = "../../../src/test/contracts/chain_id.ligo"
-- example = "../../../src/test/contracts/coase.ligo"
example = "../../../src/test/contracts/failwith.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"
-- example = "../../../src/test/contracts/application.ligo"
-- example = "../../../src/test/contracts/application.ligo"