Skip to content

Commit

Permalink
feature: support to parse a whole sol file
Browse files Browse the repository at this point in the history
* refactor: export functions to avoid getting disturbing outside
* feature: support parse comments when parsing statements
  • Loading branch information
xieyuschen committed Aug 13, 2024
1 parent a6f2d9a commit 3ed3a23
Show file tree
Hide file tree
Showing 16 changed files with 475 additions and 198 deletions.
4 changes: 2 additions & 2 deletions slinter.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ common common-depends
library internallib
import: common-depends
exposed-modules:
Lib.AST.File,
Lib.AST.Function,
Lib.AST.Contract,
Lib.AST.Pragma,
Lib.AST.Model,
Lib.AST.Type,
Expand Down Expand Up @@ -76,8 +76,8 @@ test-suite tests
hs-source-dirs: tests
default-language: Haskell2010
other-modules:
Lib.AST.FileSpec,
Lib.AST.FunctionSpec,
Lib.AST.ContractSpec,
Lib.AST.PragmaSpec,
Lib.AST.TypeSpec,
Lib.AST.ExprSpec,
Expand Down
58 changes: 0 additions & 58 deletions src/Lib/AST/Contract.hs

This file was deleted.

151 changes: 111 additions & 40 deletions src/Lib/AST/Definition.hs
Original file line number Diff line number Diff line change
@@ -1,13 +1,49 @@
{-# LANGUAGE OverloadedStrings #-}

module Lib.AST.Definition where
module Lib.AST.Definition
( pModifierDefinition,
pEventDefinition,
pErrorDefinition,
pConstructorDefinition,
pInterfaceDefinition,
pLibraryDefinition,
pContractDefinition,
pContractBody,
)
where

import Control.Monad (when)
import Data.Either
import Data.Functor (($>))
import Data.Maybe (fromMaybe, listToMaybe)
import Data.Maybe (fromMaybe, isJust, listToMaybe)
import Lib.AST.Expr (pFnCallArgs)
import Lib.AST.Function (pFnDeclModifierInvocation, pFunctionDefinition)
import Lib.AST.Model (ConstructorDefinition (..), ConstructorMutability (..), ContractBody (..), ErrorDefinition (..), ErrorParameter (ErrorParameter, errParamName, errParamType), EventDefinition (..), EventParameter (..), FnDecorator (..), FnModifierInvocation, FnName (..), FunctionDefinition (fnDefName), InheritanceSpecifier (..), InterfaceDefinition (..), LibraryDefinition (..), ModifierDefinition (..), extractFnDecOs, leftCurlyBrace, leftParenthesis, rightCurlyBrace, rightParenthesis, semicolon, CBFSSum (..))
import Lib.AST.Model
( CBFSSum (..),
ConstructorDefinition (..),
ConstructorMutability (..),
ContractBody (..),
ContractDefinition (..),
ErrorDefinition (..),
ErrorParameter (ErrorParameter, errParamName, errParamType),
EventDefinition (..),
EventParameter (..),
FnDecorator (..),
FnModifierInvocation,
FnName (..),
FunctionDefinition (fnDefName),
InheritanceSpecifier (..),
InterfaceDefinition (..),
LibraryDefinition (..),
ModifierDefinition (..),
extractFnDecOs,
keywordContract,
leftCurlyBrace,
leftParenthesis,
rightCurlyBrace,
rightParenthesis,
semicolon,
)
import Lib.AST.Pragma (pComment, pUsingDirective)
import Lib.AST.Stat (pState, pStateVariable)
import Lib.AST.Type (pInt, pType, pTypeEnum, pTypeStruct, pUserDefinedValueTypeDefinition)
Expand Down Expand Up @@ -165,43 +201,6 @@ pConstructorDefinition = do
constructorParamList = parameters
}

-- pContractBody parses the contract body quoted with '{}'
pContractBody :: Parser ContractBody
pContractBody = do
all <-
sepEndBy
( CBFSSumComment <$> try pComment
<|> CBFSSumUsingDirective <$> try pUsingDirective
<|> CBFSSumConstructorDefinition <$> try pConstructorDefinition
<|> CBFSSumFunctionDefinition <$> try pFunctionDefinition
<|> CBFSSumModifierDefinition <$> try pModifierDefinition
<|> CBFSSumStructure <$> try pTypeStruct
<|> CBFSSumSTypeEnum <$> try pTypeEnum
<|> CBFSSumUserDefinedValueTypeDefinition <$> try pUserDefinedValueTypeDefinition
<|> CBFSSumEventDefinition <$> try pEventDefinition
<|> CBFSSumErrorDefinition <$> try pErrorDefinition
-- the state variable parser should be put at last to avoid parse the other keyword as a type
<|> CBFSSumStateVariable <$> try pStateVariable
)
pManySpaces

return $
ContractBody
{ ctBodyConstructor = Nothing,
ctBodyFunctions = [v | CBFSSumFunctionDefinition v <- all],
ctBodyModifiers = [v | CBFSSumModifierDefinition v <- all],
ctBodyStructDefinitions = [v | CBFSSumStructure v <- all],
ctBodyEnumDefinitions = [v | CBFSSumSTypeEnum v <- all],
ctBodyUserDefinedValueTypeDefinition = [v | CBFSSumUserDefinedValueTypeDefinition v <- all],
ctBodyStateVariables = [v | CBFSSumStateVariable v <- all],
ctBodyEventDefinitions = [v | CBFSSumEventDefinition v <- all],
ctBodyErrorDefinitions = [v | CBFSSumErrorDefinition v <- all],
ctBodyUsingDirectives = [v | CBFSSumUsingDirective v <- all],
ctBodyReceiveFunctions = filter (\f -> fnDefName f == FnReceive) [v | CBFSSumFunctionDefinition v <- all],
ctBodyFallbackFunctions = filter (\f -> fnDefName f == FnFallback) [v | CBFSSumFunctionDefinition v <- all]
-- ctBodyAllFields = all
}

pInterfaceDefinition :: Parser InterfaceDefinition
pInterfaceDefinition = do
name <-
Expand Down Expand Up @@ -256,3 +255,75 @@ pLibraryDefinition = do
{ libraryBody = body,
libraryName = name
}

pContractDefinition :: Parser ContractDefinition
pContractDefinition = do
-- if the abstract keyword exist, we must consume at least 1 space
abs <-
pManySpaces
*> optionMaybe (try $ pOneKeyword "abstract")
when (isJust abs) pMany1Spaces
contractName <-
pOneKeyword keywordContract
>> pMany1Spaces
*> pIdentifier
<* pManySpaces
inherSpecifiers <-
optionMaybe $
pOneKeyword "is"
*> pMany1Spaces
*> sepBy
(pManySpaces *> pInheritanceSpecifier <* pManySpaces)
(char ',')

body <-
pManySpaces
*> between
(pManySpaces >> pOneKeyword leftCurlyBrace >> pManySpaces)
(pManySpaces >> pOneKeyword rightCurlyBrace >> pManySpaces)
pContractBody
return
ContractDefinition
{ contractName = contractName,
contractIsAbstract = isJust abs,
contractInheritanceSpecifiers = fromMaybe [] inherSpecifiers,
contractBody = body
}

-- pContractBody parses the contract body quoted with '{}'
pContractBody :: Parser ContractBody
pContractBody = do
all <-
pManySpaces
*> sepEndBy
( CBFSSumComment <$> try pComment
<|> CBFSSumUsingDirective <$> try pUsingDirective
<|> CBFSSumConstructorDefinition <$> try pConstructorDefinition
<|> CBFSSumFunctionDefinition <$> try pFunctionDefinition
<|> CBFSSumModifierDefinition <$> try pModifierDefinition
<|> CBFSSumStructure <$> try pTypeStruct
<|> CBFSSumSTypeEnum <$> try pTypeEnum
<|> CBFSSumUserDefinedValueTypeDefinition <$> try pUserDefinedValueTypeDefinition
<|> CBFSSumEventDefinition <$> try pEventDefinition
<|> CBFSSumErrorDefinition <$> try pErrorDefinition
-- the state variable parser should be put at last to avoid parse the other keyword as a type
<|> CBFSSumStateVariable <$> try pStateVariable
)
pManySpaces

return $
ContractBody
{ ctBodyConstructor = Nothing,
ctBodyFunctions = [v | CBFSSumFunctionDefinition v <- all],
ctBodyModifiers = [v | CBFSSumModifierDefinition v <- all],
ctBodyStructDefinitions = [v | CBFSSumStructure v <- all],
ctBodyEnumDefinitions = [v | CBFSSumSTypeEnum v <- all],
ctBodyUserDefinedValueTypeDefinition = [v | CBFSSumUserDefinedValueTypeDefinition v <- all],
ctBodyStateVariables = [v | CBFSSumStateVariable v <- all],
ctBodyEventDefinitions = [v | CBFSSumEventDefinition v <- all],
ctBodyErrorDefinitions = [v | CBFSSumErrorDefinition v <- all],
ctBodyUsingDirectives = [v | CBFSSumUsingDirective v <- all],
ctBodyReceiveFunctions = filter (\f -> fnDefName f == FnReceive) [v | CBFSSumFunctionDefinition v <- all],
ctBodyFallbackFunctions = filter (\f -> fnDefName f == FnFallback) [v | CBFSSumFunctionDefinition v <- all]
-- ctBodyAllFields = all
}
73 changes: 54 additions & 19 deletions src/Lib/AST/Expr.hs
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
{-# LANGUAGE OverloadedStrings #-}

module Lib.AST.Expr where
module Lib.AST.Expr
( pExpression,
pFnCallArgs,
pFuncCallArgsFormatList,
pElemIndex,
pExprTenary,
pFuncCall,
pSelection,
)
where

import Control.Applicative (Applicative (liftA2), optional)
import Control.Monad (guard)
Expand All @@ -13,7 +22,42 @@ import Data.Text (Text)
import qualified Data.Text as T
import Debug.Trace (trace)
import Lib.AST.Model
( ExprBinary (ExprBinary),
ExprFnCall (..),
ExprIndex (ExprIndex, elemBase, elemIndex),
ExprSelection (ExprSelection, selectionBase, selectionField),
ExprTernary (..),
ExprUnary (..),
FnCallArgs (..),
Literal (..),
Operator (Minus),
SExpr
( SExprB,
SExprD,
SExprF,
SExprI,
SExprL,
SExprN,
SExprParentheses,
SExprS,
SExprT,
SExprU,
SExprVar
),
colon,
leftCurlyBrace,
leftParenthesis,
leftSquareBracket,
rightCurlyBrace,
rightParenthesis,
rightSquareBracket,
)
import Lib.AST.Oper
( allOperators,
pOpRank,
pOpRankLast,
pOperator,
)
import Lib.Parser
( Parser,
pBool,
Expand All @@ -25,23 +69,14 @@ import Lib.Parser
pString,
)
import Text.Parsec

ops :: [[Operator]]
ops =
reverse
[ opRank2,
opRank3,
opRank4,
opRank5,
opRank6,
opRank7,
opRank8,
opRank9,
opRank10,
opRank11,
opRank12,
opRank13
]
( getInput,
many,
many1,
optionMaybe,
setInput,
try,
(<|>),
)

pExpression :: Parser SExpr
pExpression =
Expand All @@ -58,7 +93,7 @@ pExpression =
rest
)
pBasicExpr
(pOpRankLast (concat ops) : fmap pOpRank ops)
(pOpRankLast (concat allOperators) : fmap pOpRank allOperators)

pBasicExpr :: Parser SExpr
pBasicExpr =
Expand Down
Loading

0 comments on commit 3ed3a23

Please sign in to comment.