927 lines
22 KiB
Haskell
Raw Normal View History

2020-06-04 17:40:38 +04:00
{- | Parser for a contract.
2020-05-08 01:18:26 +04:00
-}
2020-07-10 15:11:49 +04:00
module AST.Parser (example, contract, sample) where
import Data.Text (Text)
import qualified Data.Text as Text
2020-07-10 15:11:49 +04:00
import Data.Sum (Element)
2020-06-04 17:16:04 +04:00
import AST.Types
import Parser
2020-07-09 18:59:38 +04:00
import Range
import Product
2020-06-04 17:40:38 +04:00
import Tree hiding (skip)
2020-07-10 16:13:39 +04:00
import Pretty
import Debug.Trace
2020-06-01 18:17:33 +04:00
ranged
:: ( Functor f
2020-06-08 01:16:33 +04:00
, Element f fs
2020-06-01 18:17:33 +04:00
)
=> Parser (f (Tree fs ASTInfo))
-> Parser (Tree fs ASTInfo)
2020-06-01 18:17:33 +04:00
ranged p = do
r <- getInfo
a <- p
return $ mk r a
2020-06-04 17:40:38 +04:00
-- | The entrypoint.
2020-06-01 18:17:33 +04:00
contract :: Parser (Pascal ASTInfo)
contract =
2020-07-09 18:59:38 +04:00
pure contract'
<*> getInfo
2020-06-01 18:17:33 +04:00
<*> subtree "contract" do
many do
inside "declaration:" do
declaration
2020-07-09 18:59:38 +04:00
where
contract'
:: ASTInfo
-> [Pascal ASTInfo]
-> Pascal ASTInfo
contract' r = foldr (contract'' $ getElem r) (mk r ContractEnd)
contract''
:: Range
-> Pascal ASTInfo
-> Pascal ASTInfo
-> Pascal ASTInfo
contract'' r x xs = mk (Cons r' rest) $ ContractCons x xs
where
r' = Range start end f
Range _ end f = r
Cons (Range start _ _) rest = infoOf x
2020-06-01 18:17:33 +04:00
name :: Parser (Pascal ASTInfo)
name = ranged do pure Name <*> token "Name"
2020-05-08 01:18:26 +04:00
2020-07-08 20:31:42 +04:00
typeName :: Parser (Pascal ASTInfo)
typeName = ranged do pure TypeName <*> token "TypeName"
fieldName :: Parser (Pascal ASTInfo)
fieldName = ranged do pure FieldName <*> token "FieldName"
2020-06-01 18:17:33 +04:00
capitalName :: Parser (Pascal ASTInfo)
capitalName = ranged do pure Name <*> token "Name_Capital"
2020-05-08 01:18:26 +04:00
2020-06-01 18:17:33 +04:00
declaration :: Parser (Pascal ASTInfo)
declaration
2020-06-01 18:17:33 +04:00
= do ranged do pure ValueDecl <*> binding
<|> do ranged do pure ValueDecl <*> vardecl
<|> do ranged do pure ValueDecl <*> constdecl
<|> do ranged do pure Action <*> attributes
<|> do typedecl
<|> do include
2020-06-04 17:16:04 +04:00
include :: Parser (Pascal ASTInfo)
include = do
subtree "include" do
inside "filename" do
ranged do
f <- token "String"
t <- restart contract (init $ tail $ Text.unpack f)
return $ Include f t
2020-06-01 18:17:33 +04:00
typedecl :: Parser (Pascal ASTInfo)
typedecl = do
subtree "type_decl" do
2020-06-01 18:17:33 +04:00
ranged do
pure TypeDecl
2020-07-08 20:31:42 +04:00
<*> inside "typeName:" typeName
2020-06-01 18:17:33 +04:00
<*> inside "typeValue:" newtype_
2020-06-01 18:17:33 +04:00
vardecl :: Parser (Pascal ASTInfo)
vardecl = do
subtree "var_decl" do
2020-06-01 18:17:33 +04:00
ranged do
pure Var
<*> inside "name" name
<*> inside "type" type_
<*> inside "value" expr
2020-06-01 18:17:33 +04:00
constdecl :: Parser (Pascal ASTInfo)
constdecl = do
subtree "const_decl" do
2020-06-01 18:17:33 +04:00
ranged do
pure Const
<*> inside "name" name
<*> inside "type" type_
<*> inside "value" expr
2020-06-01 18:17:33 +04:00
binding :: Parser (Pascal ASTInfo)
binding = do
inside ":fun_decl" do
2020-06-01 18:17:33 +04:00
ranged do
pure Function
<*> recursive
<*> inside "name:" name
<*> inside "parameters:parameters" do
many do
inside "parameter" paramDecl
<*> inside "type:" type_
<*> inside "body:" letExpr
2020-06-04 17:16:04 +04:00
recursive :: Parser Bool
recursive = do
mr <- optional do
inside "recursive" do
token "recursive"
return $ maybe False (== "recursive") mr
2020-06-01 18:17:33 +04:00
expr :: Parser (Pascal ASTInfo)
expr = stubbed "expr" do
select
2020-05-08 01:18:26 +04:00
[ -- Wait, isn't it `qname`? TODO: replace.
2020-06-01 18:17:33 +04:00
ranged do
pure Ident <*> do
ranged do
pure 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
]
2020-06-01 18:17:33 +04:00
set_remove :: Parser (Pascal ASTInfo)
set_remove = do
subtree "set_remove" do
2020-06-01 18:17:33 +04:00
ranged do
pure SetRemove
<*> inside "key" expr
<*> inside "container" do
inside ":path" do
qname <|> projection
2020-06-01 18:17:33 +04:00
set_patch :: Parser (Pascal ASTInfo)
set_patch = do
subtree "set_patch" do
2020-06-01 18:17:33 +04:00
ranged do
pure SetPatch
<*> inside "container:path" (qname <|> projection)
<*> many do inside "key" expr
2020-06-04 17:16:04 +04:00
record_update :: Parser (Pascal ASTInfo)
record_update = do
subtree "update_record" do
2020-06-01 18:17:33 +04:00
ranged do
pure RecordUpd
<*> inside "record:path" do qname <|> projection
<*> many do inside "assignment" field_path_assignment
2020-06-04 17:16:04 +04:00
field_path_assignment :: Parser (Pascal ASTInfo)
field_path_assignment = do
subtree "field_path_assignment" do
2020-06-01 18:17:33 +04:00
ranged do
pure FieldAssignment
2020-07-08 20:31:42 +04:00
<*> inside "lhs:fpath" do fqname <|> projection
2020-06-01 18:17:33 +04:00
<*> inside "_rhs" expr
2020-06-04 17:16:04 +04:00
map_patch :: Parser (Pascal ASTInfo)
map_patch = do
subtree "map_patch" do
2020-06-01 18:17:33 +04:00
ranged do
pure MapPatch
<*> inside "container:path" (qname <|> projection)
<*> many do inside "binding" map_binding
2020-06-01 18:17:33 +04:00
set_expr :: Parser (Pascal ASTInfo)
set_expr = do
subtree "set_expr" do
2020-06-01 18:17:33 +04:00
ranged do
pure List <*> many do
inside "element" expr
2020-06-04 17:16:04 +04:00
lambda_expr :: Parser (Pascal ASTInfo)
lambda_expr = do
subtree "fun_expr" do
2020-06-01 18:17:33 +04:00
ranged do
pure Lambda
<*> inside "parameters:parameters" do
many do inside "parameter" paramDecl
<*> inside "type" newtype_
<*> inside "body" expr
2020-06-04 17:16:04 +04:00
seq_expr :: Parser (Pascal ASTInfo)
seq_expr = do
subtree "block" do
2020-06-01 18:17:33 +04:00
ranged do
pure Seq <*> many do
inside "statement" do
declaration <|> statement
2020-06-04 17:16:04 +04:00
loop :: Parser (Pascal ASTInfo)
loop = do
subtree "loop" do
for_loop <|> while_loop <|> for_container
2020-06-04 17:16:04 +04:00
for_container :: Parser (Pascal ASTInfo)
for_container = do
subtree "for_loop" do
2020-06-01 18:17:33 +04:00
ranged do
pure ForBox
<*> inside "key" name
<*> optional do inside "value" name
<*> inside "kind" anything
<*> inside "collection" expr
<*> inside "body" (expr <|> seq_expr)
2020-06-04 17:16:04 +04:00
while_loop :: Parser (Pascal ASTInfo)
while_loop = do
subtree "while_loop" do
2020-06-01 18:17:33 +04:00
ranged do
pure WhileLoop
<*> inside "breaker" expr
<*> inside "body" expr
2020-06-04 17:16:04 +04:00
for_loop :: Parser (Pascal ASTInfo)
for_loop = do
subtree "for_loop" do
2020-06-01 18:17:33 +04:00
ranged do
pure ForLoop
<*> inside "name" name
<*> inside "begin" expr
<*> inside "end" expr
<*> inside "body" expr
2020-06-04 17:16:04 +04:00
clause_block :: Parser (Pascal ASTInfo)
clause_block = do
subtree "clause_block" do
inside "block:block" do
2020-06-01 18:17:33 +04:00
ranged do
pure Seq <*> many do
inside "statement" (declaration <|> statement)
<|> do
subtree "clause_block" do
2020-06-01 18:17:33 +04:00
ranged do
pure Seq <*> many do
inside "statement" (declaration <|> statement)
2020-06-01 18:17:33 +04:00
skip :: Parser (Pascal ASTInfo)
skip = do
2020-06-01 18:17:33 +04:00
ranged do
pure Skip
<* token "skip"
2020-06-01 18:17:33 +04:00
case_action :: Parser (Pascal ASTInfo)
case_action = do
subtree "case_instr" do
2020-06-01 18:17:33 +04:00
ranged do
pure Case
<*> inside "subject" expr
<*> many do
inside "case" alt_action
2020-06-01 18:17:33 +04:00
alt_action :: Parser (Pascal ASTInfo)
alt_action = do
subtree "case_clause_instr" do
2020-06-01 18:17:33 +04:00
ranged do
pure Alt
<*> inside "pattern" pattern
<*> inside "body:if_clause" expr
2020-06-01 18:17:33 +04:00
case_expr :: Parser (Pascal ASTInfo)
case_expr = do
subtree "case_expr" do
2020-06-01 18:17:33 +04:00
ranged do
pure Case
<*> inside "subject" expr
<*> many do
inside "case" alt
2020-06-01 18:17:33 +04:00
alt :: Parser (Pascal ASTInfo)
alt = do
subtree "case_clause_expr" do
2020-06-01 18:17:33 +04:00
ranged do
pure Alt
<*> inside "pattern" pattern
<*> inside "body" expr
2020-06-01 18:17:33 +04:00
pattern :: Parser (Pascal ASTInfo)
pattern = do
subtree "pattern" $ do
inside "the" core_pattern
<|>
2020-06-01 18:17:33 +04:00
do ranged do
pure IsCons
<*> inside "head" core_pattern
<*> inside "tail" pattern
2020-06-01 18:17:33 +04:00
core_pattern :: Parser (Pascal ASTInfo)
core_pattern
2020-05-08 01:18:26 +04:00
= constr_pattern
<|> string_pattern
<|> int_pattern
<|> nat_pattern
<|> tuple_pattern
<|> list_pattern
<|> some_pattern
<|> var_pattern
2020-06-01 18:17:33 +04:00
var_pattern :: Parser (Pascal ASTInfo)
var_pattern =
2020-06-01 18:17:33 +04:00
ranged do
pure IsVar <*> name
2020-06-01 18:17:33 +04:00
some_pattern :: Parser (Pascal ASTInfo)
some_pattern = do
subtree "Some_pattern" do
2020-06-01 18:17:33 +04:00
ranged do
pure IsConstr
<*> inside "constr" do
ranged do
pure Name <*> token "Some"
2020-06-01 18:17:33 +04:00
<*> do Just <$> inside "arg" pattern
string_pattern :: Parser (Pascal ASTInfo)
string_pattern =
2020-06-01 18:17:33 +04:00
ranged do
pure IsConstant <*> do
ranged do
pure String <*> token "String"
2020-06-01 18:17:33 +04:00
nat_pattern :: Parser (Pascal ASTInfo)
nat_pattern =
2020-06-01 18:17:33 +04:00
ranged do
pure IsConstant <*> do
ranged do
pure Nat <*> token "Nat"
2020-06-01 18:17:33 +04:00
int_pattern :: Parser (Pascal ASTInfo)
int_pattern =
2020-06-01 18:17:33 +04:00
ranged do
pure IsConstant <*> do
ranged do
pure Int <*> token "Int"
2020-06-01 18:17:33 +04:00
constr_pattern :: Parser (Pascal ASTInfo)
constr_pattern =
do
subtree "user_constr_pattern" do
2020-06-01 18:17:33 +04:00
ranged do
pure IsConstr
<*> inside "constr:constr" capitalName
<*> optional do
inside "arguments" tuple_pattern
<|>
do
2020-06-01 18:17:33 +04:00
ranged do
pure IsConstr
<*> ranged do
pure Name <*> do
true <|> false <|> none <|> unit
<*> pure Nothing
tuple_pattern :: Parser (Pascal ASTInfo)
tuple_pattern = do
subtree "tuple_pattern" do
2020-06-01 18:17:33 +04:00
ranged do
pure IsTuple <*> many do
inside "element" pattern
2020-06-01 18:17:33 +04:00
list_pattern :: Parser (Pascal ASTInfo)
list_pattern = do
subtree "list_pattern" do
2020-06-01 18:17:33 +04:00
ranged do
pure IsList <*> many do
inside "element" pattern
2020-06-01 18:17:33 +04:00
nullary_ctor :: Parser (Pascal ASTInfo)
nullary_ctor = do
2020-06-01 18:17:33 +04:00
ranged do
pure Ident <*> do
ranged do
pure QualifiedName
<*> ranged do
pure Name <*> do
true <|> false <|> none <|> unit
<*> pure []
2020-06-04 17:16:04 +04:00
true, false, none, unit :: Parser Text
true = token "True"
false = token "False"
none = token "None"
unit = token "Unit"
2020-06-01 18:17:33 +04:00
nat_literal :: Parser (Pascal ASTInfo)
nat_literal = do
2020-06-01 18:17:33 +04:00
ranged do
pure Constant <*> do
ranged do
pure Nat <*> token "Nat"
2020-06-01 18:17:33 +04:00
bytes_literal :: Parser (Pascal ASTInfo)
bytes_literal = do
2020-06-01 18:17:33 +04:00
ranged do
pure Constant <*> do
ranged do
pure Bytes <*> token "Bytes"
2020-06-01 18:17:33 +04:00
constr_call :: Parser (Pascal 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
2020-06-01 18:17:33 +04:00
ranged do
pure Apply
<*> ranged do
pure Ident <*> inside "constr" qname'
<*> inside "arguments:arguments" do
many do inside "argument" expr
user_constr_call = do
subtree "constr_call" do
2020-06-01 18:17:33 +04:00
ranged do
pure Apply
<*> inside "constr:constr" do
ranged do
pure Ident <*> do
ranged do
pure QualifiedName
<*> capitalName
<*> pure []
<*> inside "arguments:arguments" do
many do
inside "argument" expr
indexing :: Parser (Pascal ASTInfo)
indexing = do
subtree "map_lookup" do
2020-06-01 18:17:33 +04:00
ranged do
pure Indexing
<*> inside "container:path" do
qname <|> projection
<*> inside "index" expr
2020-05-01 22:41:07 +04:00
2020-06-01 18:17:33 +04:00
map_remove :: Parser (Pascal ASTInfo)
map_remove = do
subtree "map_remove" do
2020-06-01 18:17:33 +04:00
ranged do
pure MapRemove
<*> inside "key" expr
<*> inside "container" do
inside ":path" do
qname <|> projection
2020-06-01 18:17:33 +04:00
big_map_expr :: Parser (Pascal ASTInfo)
big_map_expr = do
subtree "big_map_injection" do
2020-06-01 18:17:33 +04:00
ranged do
pure BigMap <*> many do
inside "binding" do
map_binding
2020-06-01 18:17:33 +04:00
map_expr :: Parser (Pascal ASTInfo)
map_expr = do
subtree "map_injection" do
2020-06-01 18:17:33 +04:00
ranged do
pure Map <*> many do
inside "binding" do
map_binding
2020-06-01 18:17:33 +04:00
map_binding :: Parser (Pascal ASTInfo)
map_binding = do
subtree "binding" do
2020-06-01 18:17:33 +04:00
ranged do
pure MapBinding
<*> inside "key" expr
<*> inside "value" expr
2020-06-01 18:17:33 +04:00
moduleQualified :: Parser (Pascal ASTInfo)
moduleQualified = do
subtree "module_field" do
2020-06-01 18:17:33 +04:00
ranged do
pure Ident <*> do
ranged do
pure QualifiedName
<*> inside "module" capitalName
<*> do pure <$> ranged do
pure At <*> inside "method" do name <|> name'
tuple_expr :: Parser (Pascal ASTInfo)
tuple_expr = do
subtree "tuple_expr" do
2020-06-01 18:17:33 +04:00
ranged do
pure Tuple <*> many do
inside "element" expr
2020-06-01 18:17:33 +04:00
attributes :: Parser (Pascal ASTInfo)
2020-05-06 23:19:28 +04:00
attributes = do
subtree "attr_decl" do
2020-06-01 18:17:33 +04:00
ranged do
pure Attrs <*> many do
inside "attribute" do
token "String"
2020-05-06 23:19:28 +04:00
2020-06-01 18:17:33 +04:00
string_literal :: Parser (Pascal ASTInfo)
string_literal = do
2020-06-01 18:17:33 +04:00
ranged do
pure Constant <*> do
ranged do
pure String <*> do
token "String"
2020-06-01 18:17:33 +04:00
has_type :: Parser (Pascal ASTInfo)
has_type = do
subtree "annot_expr" do
2020-06-01 18:17:33 +04:00
ranged do
pure Annot
<*> inside "subject" expr
<*> inside "type" type_
2020-06-01 18:17:33 +04:00
list_expr :: Parser (Pascal ASTInfo)
list_expr = do
subtree "list_expr" do
2020-06-01 18:17:33 +04:00
ranged do
pure List <*> many do
inside "element" expr
2020-06-01 18:17:33 +04:00
qname :: Parser (Pascal ASTInfo)
qname = do
2020-06-01 18:17:33 +04:00
ranged do
pure QualifiedName
<*> name
<*> pure []
2020-07-08 20:31:42 +04:00
fqname :: Parser (Pascal ASTInfo)
fqname = do
ranged do
pure QualifiedName
<*> fieldName
<*> pure []
2020-06-01 18:17:33 +04:00
qname' :: Parser (Pascal ASTInfo)
qname' = do
2020-06-01 18:17:33 +04:00
ranged do
pure QualifiedName
<*> name'
<*> pure []
2020-06-01 18:17:33 +04:00
assign :: Parser (Pascal ASTInfo)
assign = do
subtree "assignment" do
2020-06-01 18:17:33 +04:00
ranged do
pure Assign
<*> inside "LHS" lhs
<*> inside "RHS" expr
2020-06-01 18:17:33 +04:00
lhs :: Parser (Pascal ASTInfo)
lhs =
2020-06-01 18:17:33 +04:00
ranged do
pure LHS
<*> inside "container:path" do
qname <|> projection
<*> pure Nothing
<|>
2020-06-01 18:17:33 +04:00
ranged do
pure LHS
<*> subtree "path" do
qname <|> projection
<*> pure Nothing
<|>
2020-06-01 18:17:33 +04:00
subtree "map_lookup" do
ranged do
pure LHS
<*> inside "container:path" do
qname <|> projection
<*> inside "index" do
Just <$> expr
2020-06-01 18:17:33 +04:00
tez_literal :: Parser (Pascal ASTInfo)
tez_literal = do
2020-06-01 18:17:33 +04:00
ranged do
pure Constant <*> do
ranged do
pure Tez <*> token "Tez"
2020-06-01 18:17:33 +04:00
if_expr :: Parser (Pascal ASTInfo)
if_expr = do
subtree "conditional" do
2020-06-01 18:17:33 +04:00
ranged do
pure If
<*> inside "selector" expr
<*> inside "then:if_clause" expr
<*> inside "else:if_clause" expr
<|> do
subtree "cond_expr" do
2020-06-01 18:17:33 +04:00
ranged do
pure If
<*> inside "selector" expr
<*> inside "then" expr
<*> inside "else" expr
2020-06-01 18:17:33 +04:00
method_call :: Parser (Pascal ASTInfo)
method_call = do
subtree "projection_call" do
2020-06-01 18:17:33 +04:00
ranged do
pure apply'
<*> getInfo
<*> inside "f" projection
<*> optional do inside "arguments" arguments
where
2020-06-01 18:17:33 +04:00
apply' i f (Just xs) = Apply (mk i $ Ident f) xs
2020-06-04 17:16:04 +04:00
apply' _ f _ = Ident f
2020-06-01 18:17:33 +04:00
projection :: Parser (Pascal ASTInfo)
projection = do
subtree "data_projection" do
2020-06-01 18:17:33 +04:00
ranged do
pure QualifiedName
<*> inside "struct" name
<*> many selection
2020-06-01 18:17:33 +04:00
selection :: Parser (Pascal ASTInfo)
selection = do
inside "index:selection"
2020-07-08 20:31:42 +04:00
$ ranged do pure At <*> fieldName
2020-06-01 18:17:33 +04:00
<|> ranged do pure Ix <*> token "Int"
<|>
inside "index" do
2020-06-01 18:17:33 +04:00
ranged do pure Ix <*> token "Int"
2020-06-01 18:17:33 +04:00
par_call :: Parser (Pascal ASTInfo)
par_call = do
subtree "par_call" do
2020-06-01 18:17:33 +04:00
pure apply'
<*> getInfo
<*> inside "f" expr
<*> optional do inside "arguments" arguments
where
2020-06-01 18:17:33 +04:00
apply'
:: ASTInfo
-> Pascal ASTInfo
-> Maybe [Pascal ASTInfo]
-> Pascal ASTInfo
apply' i f (Just xs) = mk i $ Apply f xs
2020-06-04 17:16:04 +04:00
apply' _ f _ = f
2020-06-01 18:17:33 +04:00
int_literal :: Parser (Pascal ASTInfo)
int_literal = do
2020-06-01 18:17:33 +04:00
ranged do
pure Constant
<*> ranged do
pure Int <*> token "Int"
2020-06-01 18:17:33 +04:00
record_expr :: Parser (Pascal ASTInfo)
record_expr = do
subtree "record_expr" do
2020-06-01 18:17:33 +04:00
ranged do
pure Record <*> many do
inside "assignment:field_assignment" do
ranged do
pure Assignment
2020-07-08 20:31:42 +04:00
<*> inside "name" fieldName
2020-06-01 18:17:33 +04:00
<*> inside "_rhs" expr
fun_call :: Parser (Pascal ASTInfo)
fun_call = do
subtree "fun_call" do
2020-06-01 18:17:33 +04:00
ranged do
pure Apply
2020-07-08 18:55:11 +04:00
<*> inside "f" function_id
2020-06-01 18:17:33 +04:00
<*> inside "arguments" arguments
2020-06-04 17:16:04 +04:00
arguments :: Parser [Pascal ASTInfo]
arguments =
subtree "arguments" do
many do inside "argument" expr
2020-06-01 18:17:33 +04:00
function_id :: Parser (Pascal ASTInfo)
2020-07-08 18:55:11 +04:00
function_id = ranged do
pure Ident <*> select
[ qname
, do
subtree "module_field" do
ranged do
pure QualifiedName
<*> inside "module" capitalName
<*> do pure <$> ranged do
pure At <*> inside "method" do name <|> name'
]
2020-06-01 18:17:33 +04:00
opCall :: Parser (Pascal ASTInfo)
opCall = do
subtree "op_expr"
$ do inside "the" expr
2020-06-01 18:17:33 +04:00
<|> ranged do
pure BinOp
<*> inside "arg1" expr
<*> inside "op" anything
<*> inside "arg2" expr
<|> ranged do
pure UnOp
<*> inside "negate" anything
<*> inside "arg" expr
2020-06-04 17:16:04 +04:00
letExpr :: Parser (Pascal ASTInfo)
2020-05-01 22:41:07 +04:00
letExpr = do
subtree "let_expr" do
2020-06-01 18:17:33 +04:00
pure let'
<*> getInfo
<*> optional do
inside "locals:block" do
many do
inside "statement" do
declaration <|> statement
<*> inside "body"expr
where
2020-07-09 18:59:38 +04:00
let'
:: ASTInfo
-> (Maybe [Pascal ASTInfo])
-> Pascal ASTInfo
-> Pascal ASTInfo
let' r decls body = case decls of
2020-07-09 18:59:38 +04:00
Just them -> foldr (let'' $ getElem r) body them
2020-05-01 22:41:07 +04:00
Nothing -> body
2020-07-09 18:59:38 +04:00
let''
:: Range
-> Pascal ASTInfo
-> Pascal ASTInfo
-> Pascal ASTInfo
2020-07-10 16:13:39 +04:00
let'' r decl b =
mk (Cons r' rest) $ Let decl b
2020-07-09 18:59:38 +04:00
where
r' = Range start end f
Range _ end f = r
2020-07-10 16:13:39 +04:00
Cons (Range start _ _) rest = infoOf decl
2020-07-09 18:59:38 +04:00
2020-06-01 18:17:33 +04:00
statement :: Parser (Pascal ASTInfo)
statement = ranged do pure Action <*> expr
2020-06-01 18:17:33 +04:00
paramDecl :: Parser (Pascal ASTInfo)
paramDecl = do
subtree "param_decl" do
2020-06-01 18:17:33 +04:00
ranged do
pure Decl
<*> inside "access" do
ranged do
2020-06-04 17:16:04 +04:00
access' =<< anything
2020-06-01 18:17:33 +04:00
<*> inside "name" name
<*> inside "type" type_
2020-05-08 20:38:41 +04:00
where
2020-06-04 17:16:04 +04:00
access' "var" = pure Mutable
access' "const" = pure Immutable
access' _ = die "`var` or `const`"
2020-06-04 17:16:04 +04:00
newtype_ :: Parser (Pascal ASTInfo)
newtype_ = select
[ record_type
, type_
, sum_type
]
2020-06-04 17:16:04 +04:00
sum_type :: Parser (Pascal ASTInfo)
sum_type = do
subtree "sum_type" do
2020-06-01 18:17:33 +04:00
ranged do
pure TSum <*> many do
inside "variant" variant
2020-06-04 17:16:04 +04:00
variant :: Parser (Pascal ASTInfo)
variant = do
subtree "variant" do
2020-06-01 18:17:33 +04:00
ranged do
pure Variant
<*> inside "constructor:constr" capitalName
<*> optional do inside "arguments" type_
2020-06-04 17:16:04 +04:00
record_type :: Parser (Pascal ASTInfo)
record_type = do
subtree "record_type" do
2020-06-01 18:17:33 +04:00
ranged do
pure TRecord <*> many do
inside "field" do
field_decl
2020-06-04 17:16:04 +04:00
field_decl :: Parser (Pascal ASTInfo)
field_decl = do
subtree "field_decl" do
2020-06-01 18:17:33 +04:00
ranged do
pure TField
2020-07-08 20:31:42 +04:00
<*> inside "fieldName" fieldName
2020-06-01 18:17:33 +04:00
<*> inside "fieldType" newtype_
2020-06-01 18:17:33 +04:00
type_ :: Parser (Pascal ASTInfo)
type_ =
fun_type
where
2020-06-01 18:17:33 +04:00
fun_type :: Parser (Pascal ASTInfo)
fun_type = do
inside ":fun_type" do
2020-06-01 18:17:33 +04:00
pure tarrow
<*> getInfo
<*> inside "domain" cartesian
<*> optional do inside "codomain" fun_type
where
2020-06-01 18:17:33 +04:00
tarrow i domain codomain =
case codomain of
2020-06-01 18:17:33 +04:00
Just co -> mk i $ TArrow domain co
Nothing -> domain
cartesian = do
inside ":cartesian" do
2020-06-01 18:17:33 +04:00
ranged do
pure TProduct <*> some do
inside "element" do
core_type
core_type = do
select
2020-07-08 20:31:42 +04:00
[ ranged do pure TVar <*> typeName
, subtree "invokeBinary" do
2020-06-01 18:17:33 +04:00
ranged do
pure TApply
<*> inside "typeConstr" name'
<*> inside "arguments" typeTuple
, subtree "invokeUnary" do
2020-06-01 18:17:33 +04:00
ranged do
pure TApply
<*> inside "typeConstr" name'
<*> do pure <$> inside "arguments" type_
, subtree "type_expr" newtype_
]
2020-06-01 18:17:33 +04:00
name' :: Parser (Pascal ASTInfo)
name' = do
2020-06-01 18:17:33 +04:00
ranged do pure Name <*> anything
2020-06-01 18:17:33 +04:00
typeTuple :: Parser [Pascal ASTInfo]
typeTuple = do
subtree "type_tuple" do
many do inside "element" type_
2020-07-10 15:11:49 +04:00
sample :: IO (Pascal ASTInfo)
sample = runParser' contract (Path example)
example :: FilePath
-- 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"
2020-06-17 22:05:44 +04:00
-- example = "../../../src/test/contracts/arithmetic.ligo"
2020-07-08 20:31:42 +04:00
-- 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"
2020-07-10 16:13:39 +04:00
example = "../../../src/test/contracts/coase.ligo"
2020-05-08 20:38:41 +04:00
-- example = "../../../src/test/contracts/failwith.ligo"
2020-05-08 21:30:19 +04:00
-- example = "../../../src/test/contracts/loop.ligo"
2020-06-17 22:05:44 +04:00
-- example = "../../../src/test/contracts/redeclaration.ligo"
2020-07-08 18:55:11 +04:00
-- example = "../../../src/test/contracts/includer.ligo"
2020-07-10 15:11:49 +04:00
-- example = "../../../src/test/contracts/namespaces.ligo"
2020-07-10 16:13:39 +04:00
-- example = "../../../src/test/contracts/blocks.ligo"
-- example = "../../../src/test/contracts/application.ligo"
-- example = "../../../src/test/contracts/application.ligo"