Skip to content

Commit

Permalink
feature: support to parse a whole sol file (#4)
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 authored Aug 14, 2024
1 parent a6f2d9a commit 343a781
Show file tree
Hide file tree
Showing 19 changed files with 478 additions and 201 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/haskell.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: build-test-check

on:
push:
branches: "*"
branches: ["master"]
pull_request:
branches: ["master"]

Expand Down
3 changes: 2 additions & 1 deletion devtool/hook.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,11 @@ $command
ensure_hook_file_exists "$pre_push_hook" "$pre_push_sample"
ensure_hook_file_exists "$pre_commit_hook" "$pre_commit_sample"

add_command_to_hook "$pre_push_hook" "cabal test"
add_command_to_hook "$pre_push_hook" "cabal build --enable-tests --enable-benchmarks all && cabal test"

pre_commit_commands=$(cat <<'EOF'
ormolu --mode inplace $(find . -name '*.hs')
find src tests -name '*.hs' | xargs wc -l
git add .
echo "format the code and then run cmamnd 'git add .'"
EOF
Expand Down
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 343a781

Please sign in to comment.