Add some more documentation
This commit is contained in:
parent
eace901195
commit
b62cd58add
@ -1,4 +1,12 @@
|
|||||||
|
|
||||||
|
{-
|
||||||
|
Parser for a contract. The `example` is exported to run on current debug target.
|
||||||
|
|
||||||
|
TODO: prune some "path" and alike stuff from grammar, refactor common things.
|
||||||
|
|
||||||
|
TODO: break <*>/do ladders onto separate named parsers.
|
||||||
|
-}
|
||||||
|
|
||||||
module AST.Parser (example, contract) where
|
module AST.Parser (example, contract) where
|
||||||
|
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
@ -10,12 +18,6 @@ import Range
|
|||||||
|
|
||||||
import Debug.Trace
|
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 :: Parser (Contract ASTInfo)
|
||||||
contract =
|
contract =
|
||||||
ctor Contract
|
ctor Contract
|
||||||
@ -24,6 +26,12 @@ contract =
|
|||||||
inside "declaration:" do
|
inside "declaration:" do
|
||||||
declaration
|
declaration
|
||||||
|
|
||||||
|
name :: Parser (Name ASTInfo)
|
||||||
|
name = ctor Name <*> token "Name"
|
||||||
|
|
||||||
|
capitalName :: Parser (Name ASTInfo)
|
||||||
|
capitalName = ctor Name <*> token "Name_Capital"
|
||||||
|
|
||||||
declaration :: Parser (Declaration ASTInfo)
|
declaration :: Parser (Declaration ASTInfo)
|
||||||
declaration
|
declaration
|
||||||
= do ctor ValueDecl <*> binding
|
= do ctor ValueDecl <*> binding
|
||||||
@ -83,7 +91,8 @@ recursive = do
|
|||||||
expr :: Parser (Expr ASTInfo)
|
expr :: Parser (Expr ASTInfo)
|
||||||
expr = stubbed "expr" do
|
expr = stubbed "expr" do
|
||||||
select
|
select
|
||||||
[ ctor Ident <*> do
|
[ -- Wait, isn't it `qname`? TODO: replace.
|
||||||
|
ctor Ident <*> do
|
||||||
ctor QualifiedName
|
ctor QualifiedName
|
||||||
<*> name
|
<*> name
|
||||||
<*> pure []
|
<*> pure []
|
||||||
@ -265,13 +274,7 @@ pattern = do
|
|||||||
|
|
||||||
core_pattern :: Parser (Pattern ASTInfo)
|
core_pattern :: Parser (Pattern ASTInfo)
|
||||||
core_pattern
|
core_pattern
|
||||||
= -- int_pattern
|
= constr_pattern
|
||||||
-- <|> nat_pattern
|
|
||||||
-- <|> var_pattern
|
|
||||||
-- <|> list_pattern
|
|
||||||
-- <|> tuple_pattern
|
|
||||||
-- <|>
|
|
||||||
constr_pattern
|
|
||||||
<|> string_pattern
|
<|> string_pattern
|
||||||
<|> int_pattern
|
<|> int_pattern
|
||||||
<|> nat_pattern
|
<|> nat_pattern
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
|
|
||||||
{- TODO(kirill.andreev): add offsets to ranges, store verbatim in Wrong* -}
|
{-
|
||||||
|
The AST and auxillary types along with their pretty-printers.
|
||||||
|
|
||||||
|
TODO: Untangle pretty-printing mess into combinators.
|
||||||
|
TODO: Store offending text verbatim in Wrong*.
|
||||||
|
-}
|
||||||
|
|
||||||
module AST.Types where
|
module AST.Types where
|
||||||
|
|
||||||
@ -15,8 +20,6 @@ import Pretty
|
|||||||
|
|
||||||
import Debug.Trace
|
import Debug.Trace
|
||||||
|
|
||||||
type TODO = Text
|
|
||||||
|
|
||||||
data Contract info
|
data Contract info
|
||||||
= Contract info [Declaration info]
|
= Contract info [Declaration info]
|
||||||
| WrongContract Error
|
| WrongContract Error
|
||||||
@ -86,6 +89,7 @@ data TField info
|
|||||||
|
|
||||||
instance Stubbed (TField info) where stub = WrongTField
|
instance Stubbed (TField info) where stub = WrongTField
|
||||||
|
|
||||||
|
-- | TODO: break onto smaller types? Literals -> Constannt; mapOps; mmove Annots to Decls.
|
||||||
data Expr info
|
data Expr info
|
||||||
= Let info [Declaration info] (Expr info)
|
= Let info [Declaration info] (Expr info)
|
||||||
| Apply info (Expr info) [Expr info]
|
| Apply info (Expr info) [Expr info]
|
||||||
@ -295,6 +299,7 @@ instance Pretty (Variant i) where
|
|||||||
Variant _ ctor _ -> "|" <+> pp ctor
|
Variant _ ctor _ -> "|" <+> pp ctor
|
||||||
WrongVariant err -> pp err
|
WrongVariant err -> pp err
|
||||||
|
|
||||||
|
-- My eyes.
|
||||||
instance Pretty (Expr i) where
|
instance Pretty (Expr i) where
|
||||||
pp = \case
|
pp = \case
|
||||||
Let _ decls body -> "block {" $$ (nest 2 $ vcat $ punctuate "\n" $ map pp decls) $$ "}" $$ "with" $$ nest 2 (pp body)
|
Let _ decls body -> "block {" $$ (nest 2 $ vcat $ punctuate "\n" $ map pp decls) $$ "}" $$ "with" $$ nest 2 (pp body)
|
||||||
@ -396,5 +401,6 @@ instance Pretty (LHS i) where
|
|||||||
LHS _ qn mi -> pp qn <> foldMap (brackets . pp) mi
|
LHS _ qn mi -> pp qn <> foldMap (brackets . pp) mi
|
||||||
WrongLHS err -> pp err
|
WrongLHS err -> pp err
|
||||||
|
|
||||||
|
-- TODO: Use it, make more alike.
|
||||||
tuple :: Pretty p => [p] -> Doc
|
tuple :: Pretty p => [p] -> Doc
|
||||||
tuple xs = parens (fsep $ punctuate "," $ map pp xs)
|
tuple xs = parens (fsep $ punctuate "," $ map pp xs)
|
@ -1,4 +1,42 @@
|
|||||||
|
|
||||||
|
{-
|
||||||
|
The thing that can untangle the mess that tree-sitter produced.
|
||||||
|
|
||||||
|
If there be errors, it /will/ be a mess.
|
||||||
|
|
||||||
|
The AST you are building must:
|
||||||
|
1) Have first field with type `ASTInfo` in each non-error constructor at each
|
||||||
|
type.
|
||||||
|
2) Have `Error`-only constructor to represent failure and implement `Stubbed`.
|
||||||
|
|
||||||
|
I recommend parametrising your `AST` with some `info` typevar to be
|
||||||
|
`ASTInfo` in the moment of parsing.
|
||||||
|
|
||||||
|
I also recomment, in your tree-sitter grammar, to add `field("foo", ...)`
|
||||||
|
to each sub-rule, that has `$.` in front of it - in a rule, that doesn't
|
||||||
|
start with `_` in its name.
|
||||||
|
|
||||||
|
As a general rule of thumb, make each significant part a separate rule,
|
||||||
|
even if it is a keyword. Then, apply previous advice.
|
||||||
|
|
||||||
|
Only make rule start with `_` if it is a pure choice.
|
||||||
|
|
||||||
|
('block'
|
||||||
|
...
|
||||||
|
a: <a>
|
||||||
|
...
|
||||||
|
b: <b>
|
||||||
|
...)
|
||||||
|
|
||||||
|
->
|
||||||
|
|
||||||
|
block = do
|
||||||
|
subtree "block" do
|
||||||
|
ctor Block
|
||||||
|
<*> inside "a" a
|
||||||
|
<*> inside "b" b
|
||||||
|
-}
|
||||||
|
|
||||||
module Parser (module Parser, gets, pfGrove) where
|
module Parser (module Parser, gets, pfGrove) where
|
||||||
|
|
||||||
import Control.Monad.State
|
import Control.Monad.State
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
{-
|
||||||
|
Pretty printer, based on GHC one.
|
||||||
|
-}
|
||||||
|
|
||||||
module Pretty
|
module Pretty
|
||||||
( module Pretty
|
( module Pretty
|
||||||
@ -9,15 +12,19 @@ import Data.Text
|
|||||||
|
|
||||||
import Text.PrettyPrint hiding ((<>))
|
import Text.PrettyPrint hiding ((<>))
|
||||||
|
|
||||||
|
-- | With this, one can `data X = ...; derive Show via PP X`
|
||||||
newtype PP a = PP { unPP :: a }
|
newtype PP a = PP { unPP :: a }
|
||||||
|
|
||||||
instance Pretty a => Show (PP a) where
|
instance Pretty a => Show (PP a) where
|
||||||
show = show . pp . unPP
|
show = show . pp . unPP
|
||||||
|
|
||||||
|
-- | Pretty-printable types.
|
||||||
class Pretty p where
|
class Pretty p where
|
||||||
pp :: p -> Doc
|
pp :: p -> Doc
|
||||||
|
|
||||||
|
-- | Common instance.
|
||||||
instance Pretty Text where
|
instance Pretty Text where
|
||||||
pp = text . unpack
|
pp = text . unpack
|
||||||
|
|
||||||
|
-- | TODO: tuple, not list; actually /use/ it.
|
||||||
wrap [l, r] a = hang (hang l 2 r) 0 r
|
wrap [l, r] a = hang (hang l 2 r) 0 r
|
@ -3,12 +3,14 @@ module Range where
|
|||||||
|
|
||||||
import Pretty
|
import Pretty
|
||||||
|
|
||||||
|
-- | A continuous location in text.
|
||||||
data Range = Range
|
data Range = Range
|
||||||
{ rStart :: (Int, Int, Int)
|
{ rStart :: (Int, Int, Int) -- ^ [Start: line, col, byte-offset...
|
||||||
, rFinish :: (Int, Int, Int)
|
, rFinish :: (Int, Int, Int) -- ^ ... End: line, col, byte-offset).
|
||||||
}
|
}
|
||||||
deriving (Show) via PP Range
|
deriving (Show) via PP Range
|
||||||
|
|
||||||
|
-- | TODO: Ugh. Purge it.
|
||||||
diffRange :: Range -> Range -> Range
|
diffRange :: Range -> Range -> Range
|
||||||
diffRange (Range ws wf) (Range ps _) = Range (max ws ps) wf
|
diffRange (Range ws wf) (Range ps _) = Range (max ws ps) wf
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user