cimple 0.0.8 → 0.0.9
raw patch · 13 files changed
+126/−186 lines, 13 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Language.Cimple: DeclSpecVar :: lexeme -> NodeF lexeme a
- Language.Cimple: Declarator :: a -> Maybe a -> NodeF lexeme a
- Language.Cimple: FunctionParam :: a -> a -> NodeF lexeme a
+ Language.Cimple: VarDeclStmt :: a -> Maybe a -> NodeF lexeme a
- Language.Cimple: DeclSpecArray :: a -> Maybe a -> NodeF lexeme a
+ Language.Cimple: DeclSpecArray :: Maybe a -> NodeF lexeme a
- Language.Cimple: MemberDecl :: a -> a -> Maybe lexeme -> NodeF lexeme a
+ Language.Cimple: MemberDecl :: a -> Maybe lexeme -> NodeF lexeme a
- Language.Cimple: VarDecl :: a -> a -> NodeF lexeme a
+ Language.Cimple: VarDecl :: a -> lexeme -> [a] -> NodeF lexeme a
- Language.Cimple.Diagnostics: type Diagnostics' a = DiagnosticsT' [Text] a
+ Language.Cimple.Diagnostics: type Diagnostics' a = Diagnostics a
- Language.Cimple.Diagnostics: warn' :: (HasLocation at, HasDiagnostics diags) => FilePath -> at -> Text -> DiagnosticsT' diags ()
+ Language.Cimple.Diagnostics: warn' :: (HasLocation at, HasDiagnostics diags) => FilePath -> at -> Text -> DiagnosticsT diags ()
Files
- cimple.cabal +1/−1
- src/Language/Cimple/Annot.hs +5/−8
- src/Language/Cimple/Ast.hs +11/−13
- src/Language/Cimple/Diagnostics.hs +8/−14
- src/Language/Cimple/Flatten.hs +1/−0
- src/Language/Cimple/IO.hs +2/−1
- src/Language/Cimple/Lexer.x +1/−0
- src/Language/Cimple/Parser.y +33/−35
- src/Language/Cimple/Pretty.hs +25/−28
- src/Language/Cimple/SemCheck/Includes.hs +1/−0
- src/Language/Cimple/TraverseAst.hs +12/−17
- src/Language/Cimple/TreeParser.y +1/−3
- test/Language/Cimple/ParserSpec.hs +25/−66
cimple.cabal view
@@ -1,5 +1,5 @@ name: cimple-version: 0.0.8+version: 0.0.9 synopsis: Simple C-like programming language homepage: https://toktok.github.io/ license: GPL-3
src/Language/Cimple/Annot.hs view
@@ -1,11 +1,8 @@-{-# LANGUAGE DeriveFunctor #-}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE DeriveTraversable #-}-{-# LANGUAGE DerivingVia #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE StandaloneDeriving #-}-{-# LANGUAGE StrictData #-}-{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DerivingVia #-}+{-# LANGUAGE StrictData #-}+{-# LANGUAGE TypeOperators #-} module Language.Cimple.Annot ( AnnotF (..) , AnnotNode
src/Language/Cimple/Ast.hs view
@@ -1,10 +1,10 @@-{-# LANGUAGE DeriveFunctor #-}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE DeriveTraversable #-}-{-# LANGUAGE DerivingVia #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE StandaloneDeriving #-}-{-# LANGUAGE StrictData #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DeriveTraversable #-}+{-# LANGUAGE DerivingVia #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE Strict #-}+{-# LANGUAGE StrictData #-} module Language.Cimple.Ast ( AssignOp (..) , BinaryOp (..)@@ -64,10 +64,9 @@ | Label lexeme a -- Variable declarations | VLA a lexeme a- | VarDecl a a- | Declarator a (Maybe a)- | DeclSpecVar lexeme- | DeclSpecArray a (Maybe a)+ | VarDeclStmt a (Maybe a)+ | VarDecl a lexeme [a]+ | DeclSpecArray (Maybe a) -- Expressions | InitialiserList [a] | UnaryExpr UnaryOp a@@ -94,7 +93,7 @@ | TypedefFunction a | Struct lexeme [a] | Union lexeme [a]- | MemberDecl a a (Maybe lexeme)+ | MemberDecl a (Maybe lexeme) | TyConst a | TyPointer a | TyStruct lexeme@@ -105,7 +104,6 @@ | FunctionDecl Scope a | FunctionDefn Scope a a | FunctionPrototype a lexeme [a]- | FunctionParam a a | Ellipsis -- Constants | ConstDecl a lexeme
src/Language/Cimple/Diagnostics.hs view
@@ -1,18 +1,18 @@ {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE Strict #-} {-# LANGUAGE StrictData #-} module Language.Cimple.Diagnostics ( Diagnostics- , Diagnostics'+ , Diagnostics' -- deprecated , HasDiagnostics (..) , warn- , warn'+ , warn' -- deprecated , sloc ) where -import Control.Monad.State.Lazy (State)-import qualified Control.Monad.State.Lazy as State-import qualified Control.Monad.State.Strict as SState+import Control.Monad.State.Strict (State)+import qualified Control.Monad.State.Strict as State import Data.Fix (foldFix) import Data.Text (Text) import qualified Data.Text as Text@@ -22,19 +22,13 @@ type DiagnosticsT diags a = State diags a type Diagnostics a = DiagnosticsT [Text] a+type Diagnostics' a = Diagnostics a -warn+warn, warn' :: (HasLocation at, HasDiagnostics diags) => FilePath -> at -> Text -> DiagnosticsT diags () warn file l w = State.modify (addDiagnostic $ sloc file l <> ": " <> w)--type DiagnosticsT' diags a = SState.State diags a-type Diagnostics' a = DiagnosticsT' [Text] a--warn'- :: (HasLocation at, HasDiagnostics diags)- => FilePath -> at -> Text -> DiagnosticsT' diags ()-warn' file l w = SState.modify (addDiagnostic $ sloc file l <> ": " <> w)+warn' = warn class HasDiagnostics a where
src/Language/Cimple/Flatten.hs view
@@ -2,6 +2,7 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE Strict #-} {-# LANGUAGE StrictData #-} {-# LANGUAGE TypeOperators #-} module Language.Cimple.Flatten (lexemes) where
src/Language/Cimple/IO.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE Strict #-} {-# LANGUAGE StrictData #-} module Language.Cimple.IO ( parseFile@@ -7,7 +8,7 @@ ) where import Control.Monad ((>=>))-import Control.Monad.State.Lazy (State, evalState, get, put)+import Control.Monad.State.Strict (State, evalState, get, put) import qualified Data.ByteString as BS import Data.Map.Strict (Map) import qualified Data.Map.Strict as Map
src/Language/Cimple/Lexer.x view
@@ -3,6 +3,7 @@ {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DeriveTraversable #-} {-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE StrictData #-} module Language.Cimple.Lexer ( Alex , AlexPosn (..)
src/Language/Cimple/Parser.y view
@@ -247,12 +247,15 @@ | '#ifndef' ID_CONST decls PreprocElse(decls) '#endif' { Fix $ PreprocIfndef $2 (reverse $3) $4 } PreprocIf(decls)-: '#if' PreprocConstExpr '\n' decls PreprocElse(decls) '#endif' { Fix $ PreprocIf $2 (reverse $4) $5 }+: '#if' PreprocConstExpr '\n' decls PreprocElif(decls) '#endif' { Fix $ PreprocIf $2 (reverse $4) $5 } +PreprocElif(decls)+: PreprocElse(decls) { $1 }+| '#elif' PreprocConstExpr '\n' decls PreprocElif(decls) { Fix $ PreprocElif $2 (reverse $4) $5 }+ PreprocElse(decls) : { Fix $ PreprocElse [] } | '#else' decls { Fix $ PreprocElse (reverse $2) }-| '#elif' PreprocConstExpr '\n' decls PreprocElse(decls) { Fix $ PreprocElif $2 (reverse $4) $5 } PreprocInclude :: { StringNode } PreprocInclude@@ -287,7 +290,7 @@ MacroParam :: { StringNode } MacroParam-: IdVar { Fix $ MacroParam $1 }+: ID_VAR { Fix $ MacroParam $1 } MacroBody :: { StringNode } MacroBody@@ -345,7 +348,7 @@ ForInit :: { StringNode } ForInit : AssignExpr ';' { $1 }-| VarDecl { $1 }+| VarDeclStmt { $1 } ForNext :: { StringNode } ForNext@@ -378,34 +381,33 @@ DeclStmt :: { StringNode } DeclStmt-: VarDecl { $1 }-| VLA '(' QualType ',' IdVar ',' Expr ')' ';' { Fix $ VLA $3 $5 $7 }+: VarDeclStmt { $1 }+| VLA '(' QualType ',' ID_VAR ',' Expr ')' ';' { Fix $ VLA $3 $5 $7 } +VarDeclStmt :: { StringNode }+VarDeclStmt+: VarDecl '=' InitialiserExpr ';' { Fix $ VarDeclStmt $1 (Just $3) }+| VarDecl ';' { Fix $ VarDeclStmt $1 Nothing }+ VarDecl :: { StringNode } VarDecl-: QualType Declarator ';' { Fix $ VarDecl $1 $2 }+: QualType ID_VAR DeclSpecArrays { Fix $ VarDecl $1 $2 $3 } -Declarator :: { StringNode }-Declarator-: DeclSpec '=' InitialiserExpr { Fix $ Declarator $1 (Just $3) }-| DeclSpec { Fix $ Declarator $1 Nothing }+DeclSpecArrays :: { [StringNode] }+DeclSpecArrays+: { [] }+| DeclSpecArrays DeclSpecArray { $2 : $1 } +DeclSpecArray :: { StringNode }+DeclSpecArray+: '[' ']' { Fix $ DeclSpecArray Nothing }+| '[' Expr ']' { Fix $ DeclSpecArray (Just $2) }+ InitialiserExpr :: { StringNode } InitialiserExpr : InitialiserList { Fix $ InitialiserList $1 } | Expr { $1 } -DeclSpec :: { StringNode }-DeclSpec-: IdVar { Fix $ DeclSpecVar $1 }-| DeclSpec '[' ']' { Fix $ DeclSpecArray $1 Nothing }-| DeclSpec '[' Expr ']' { Fix $ DeclSpecArray $1 (Just $3) }--IdVar :: { Lexeme String }-IdVar-: ID_VAR { $1 }-| default { $1 }- InitialiserList :: { [StringNode] } InitialiserList : '{' Initialisers '}' { reverse $2 }@@ -479,10 +481,10 @@ LhsExpr :: { StringNode } LhsExpr-: IdVar { Fix $ VarExpr $1 }+: ID_VAR { Fix $ VarExpr $1 } | '*' LhsExpr %prec DEREF { Fix $ UnaryExpr UopDeref $2 }-| LhsExpr '.' IdVar { Fix $ MemberAccess $1 $3 }-| LhsExpr '->' IdVar { Fix $ PointerAccess $1 $3 }+| LhsExpr '.' ID_VAR { Fix $ MemberAccess $1 $3 }+| LhsExpr '->' ID_VAR { Fix $ PointerAccess $1 $3 } | LhsExpr '[' Expr ']' { Fix $ ArrayAccess $1 $3 } Expr :: { StringNode }@@ -587,8 +589,8 @@ MemberDecl :: { StringNode } MemberDecl-: QualType DeclSpec ';' { Fix $ MemberDecl $1 $2 Nothing }-| QualType DeclSpec ':' LIT_INTEGER ';' { Fix $ MemberDecl $1 $2 (Just $4) }+: VarDecl ';' { Fix $ MemberDecl $1 Nothing }+| VarDecl ':' LIT_INTEGER ';' { Fix $ MemberDecl $1 (Just $3) } | PreprocIfdef(MemberDeclList) { $1 } | Comment { $1 } @@ -628,8 +630,8 @@ FunctionDeclarator :: { Scope -> StringNode } FunctionDeclarator-: FunctionPrototype(IdVar) ';' { \s -> Fix $ FunctionDecl s $1 }-| FunctionPrototype(IdVar) CompoundStmt { \s -> Fix $ FunctionDefn s $1 $2 }+: FunctionPrototype(ID_VAR) ';' { \s -> Fix $ FunctionDecl s $1 }+| FunctionPrototype(ID_VAR) CompoundStmt { \s -> Fix $ FunctionDefn s $1 $2 } FunctionPrototype(id) : QualType id FunctionParamList { Fix $ FunctionPrototype $1 $2 $3 }@@ -644,12 +646,8 @@ FunctionParams :: { [StringNode] } FunctionParams-: FunctionParam { [$1] }-| FunctionParams ',' FunctionParam { $3 : $1 }--FunctionParam :: { StringNode }-FunctionParam-: QualType DeclSpec { Fix $ FunctionParam $1 $2 }+: VarDecl { [$1] }+| FunctionParams ',' VarDecl { $3 : $1 } ConstDecl :: { StringNode } ConstDecl
src/Language/Cimple/Pretty.hs view
@@ -308,12 +308,9 @@ CommentExpr c e -> semi $ fst c <+> fst e Ellipsis -> semi $ text "..." - Declarator dspec Nothing -> dspec- Declarator dspec (Just initr) -> bare $ fst dspec <+> char '=' <+> fst initr-- DeclSpecVar var -> bare $ ppLexeme var- DeclSpecArray dspec Nothing -> bare $ fst dspec <> text "[]"- DeclSpecArray dspec (Just dim) -> bare $ fst dspec <> char '[' <> fst dim <> char ']'+ VarDecl ty name arrs -> bare $ fst ty <+> ppLexeme name <> ppSep empty arrs+ DeclSpecArray Nothing -> bare $ text "[]"+ DeclSpecArray (Just dim) -> bare $ char '[' <> fst dim <> char ']' TyPointer ty -> bare $ fst ty <> char '*' TyConst ty -> bare $ fst ty <+> text "const"@@ -366,7 +363,7 @@ ppSemiSep decls <> fst elseBranch <$> text "#endif"- PreprocElse [] -> bare $ empty+ PreprocElse [] -> bare empty PreprocElse decls -> bare $ linebreak <> text "#else" <$>@@ -377,7 +374,6 @@ fst elseBranch <$> text "#endif" - FunctionParam ty dspec -> bare $ fst ty <+> fst dspec FunctionPrototype ty name params -> bare $ ppFunctionPrototype ty name params FunctionDecl scope proto -> semi $@@ -385,10 +381,10 @@ FunctionDefn scope proto body -> bare $ ppScope scope <> fst proto <+> fst body - MemberDecl ty dspec Nothing -> semi $- fst ty <+> fst dspec- MemberDecl ty dspec (Just size) -> semi $- fst ty <+> fst dspec <+> char ':' <+> ppLexeme size+ MemberDecl decl Nothing -> semi $+ fst decl+ MemberDecl decl (Just size) -> semi $+ fst decl <+> char ':' <+> ppLexeme size Struct name members -> semi $ nest 2 (@@ -432,22 +428,23 @@ ) <$> text "} " <> ppLexeme ty -- Statements- VarDecl ty declr -> semi $ fst ty <+> fst declr- Return Nothing -> semi $ text "return"- Return (Just e) -> semi $ text "return" <+> fst e- Continue -> semi $ text "continue"- Break -> semi $ text "break"- IfStmt cond t e -> bare $ ppIfStmt cond t e- ForStmt i c n body -> bare $ ppForStmt i c n body- Default s -> cp s $ text "default:" <+> fst s- Label l s -> bare $ ppLexeme l <> char ':' <$> fst s- Goto l -> semi $ text "goto " <> ppLexeme l- Case e s -> cp s $ text "case " <> fst e <> char ':' <+> fst s- WhileStmt c body -> bare $ ppWhileStmt c body- DoWhileStmt body c -> semi $ ppDoWhileStmt body c- SwitchStmt c body -> bare $ ppSwitchStmt c body- CompoundStmt body -> bare $ ppCompoundStmt body- VLA ty n sz -> semi $ ppVLA ty n sz+ VarDeclStmt decl Nothing -> semi $ fst decl+ VarDeclStmt decl (Just initr) -> semi $ fst decl <+> char '=' <+> fst initr+ Return Nothing -> semi $ text "return"+ Return (Just e) -> semi $ text "return" <+> fst e+ Continue -> semi $ text "continue"+ Break -> semi $ text "break"+ IfStmt cond t e -> bare $ ppIfStmt cond t e+ ForStmt i c n body -> bare $ ppForStmt i c n body+ Default s -> cp s $ text "default:" <+> fst s+ Label l s -> bare $ ppLexeme l <> char ':' <$> fst s+ Goto l -> semi $ text "goto " <> ppLexeme l+ Case e s -> cp s $ text "case " <> fst e <> char ':' <+> fst s+ WhileStmt c body -> bare $ ppWhileStmt c body+ DoWhileStmt body c -> semi $ ppDoWhileStmt body c+ SwitchStmt c body -> bare $ ppSwitchStmt c body+ CompoundStmt body -> bare $ ppCompoundStmt body+ VLA ty n sz -> semi $ ppVLA ty n sz ppTranslationUnit :: [Node (Lexeme Text)] -> Doc
src/Language/Cimple/SemCheck/Includes.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE Strict #-} {-# LANGUAGE StrictData #-} module Language.Cimple.SemCheck.Includes ( collectIncludes
src/Language/Cimple/TraverseAst.hs view
@@ -1,10 +1,9 @@ {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE InstanceSigs #-}-{-# LANGUAGE LambdaCase #-} {-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE Strict #-} {-# LANGUAGE StrictData #-} {-# LANGUAGE TypeFamilies #-} module Language.Cimple.TraverseAst@@ -150,11 +149,11 @@ CompoundStmt stmts -> Fix <$> (CompoundStmt <$> recurse stmts) Break ->- Fix <$> (pure Break)+ pure $ Fix Break Goto label -> Fix <$> (Goto <$> recurse label) Continue ->- Fix <$> (pure Continue)+ pure $ Fix Continue Return value -> Fix <$> (Return <$> recurse value) SwitchStmt value cases ->@@ -175,14 +174,12 @@ Fix <$> (Label <$> recurse label <*> recurse stmt) VLA ty name size -> Fix <$> (VLA <$> recurse ty <*> recurse name <*> recurse size)- VarDecl ty decl ->- Fix <$> (VarDecl <$> recurse ty <*> recurse decl)- Declarator spec value ->- Fix <$> (Declarator <$> recurse spec <*> recurse value)- DeclSpecVar name ->- Fix <$> (DeclSpecVar <$> recurse name)- DeclSpecArray spec size ->- Fix <$> (DeclSpecArray <$> recurse spec <*> recurse size)+ VarDeclStmt decl ini ->+ Fix <$> (VarDeclStmt <$> recurse decl <*> recurse ini)+ VarDecl ty name arrs ->+ Fix <$> (VarDecl <$> recurse ty <*> recurse name <*> recurse arrs)+ DeclSpecArray size ->+ Fix <$> (DeclSpecArray <$> recurse size) InitialiserList values -> Fix <$> (InitialiserList <$> recurse values) UnaryExpr op expr ->@@ -231,8 +228,8 @@ Fix <$> (Struct <$> recurse name <*> recurse members) Union name members -> Fix <$> (Union <$> recurse name <*> recurse members)- MemberDecl ty decl width ->- Fix <$> (MemberDecl <$> recurse ty <*> recurse decl <*> recurse width)+ MemberDecl decl bits ->+ Fix <$> (MemberDecl <$> recurse decl <*> recurse bits) TyConst ty -> Fix <$> (TyConst <$> recurse ty) TyPointer ty ->@@ -251,10 +248,8 @@ Fix <$> (FunctionDefn scope <$> recurse proto <*> recurse body) FunctionPrototype ty name params -> Fix <$> (FunctionPrototype <$> recurse ty <*> recurse name <*> recurse params)- FunctionParam ty decl ->- Fix <$> (FunctionParam <$> recurse ty <*> recurse decl) Ellipsis ->- Fix <$> (pure Ellipsis)+ pure $ Fix Ellipsis ConstDecl ty name -> Fix <$> (ConstDecl <$> recurse ty <*> recurse name) ConstDefn scope ty name value ->
src/Language/Cimple/TreeParser.y view
@@ -72,9 +72,8 @@ label { Fix (Label{}) } -- Variable declarations vLA { Fix (VLA{}) }+ varDeclStmt { Fix (VarDecl{}) } varDecl { Fix (VarDecl{}) }- declarator { Fix (Declarator{}) }- declSpecVar { Fix (DeclSpecVar{}) } declSpecArray { Fix (DeclSpecArray{}) } -- Expressions initialiserList { Fix (InitialiserList{}) }@@ -113,7 +112,6 @@ functionDecl { Fix (FunctionDecl{}) } functionDefn { Fix (FunctionDefn{}) } functionPrototype { Fix (FunctionPrototype{}) }- functionParam { Fix (FunctionParam{}) } ellipsis { Fix (Ellipsis) } -- Constants constDecl { Fix (ConstDecl{}) }
test/Language/Cimple/ParserSpec.hs view
@@ -2,96 +2,55 @@ module Language.Cimple.ParserSpec where import Data.Fix (Fix (..))-import Test.Hspec (Spec, describe, it, shouldBe)+import Test.Hspec (Spec, describe, it, shouldBe,+ shouldSatisfy) -import Language.Cimple (AlexPosn (..), CommentStyle (..),- Lexeme (..), LexemeClass (..),- LiteralType (..), NodeF (..), Scope (..))+import Language.Cimple (AlexPosn (..), Lexeme (..),+ LexemeClass (..), NodeF (..), Scope (..)) import Language.Cimple.IO (parseText) +isRight1 :: Either a [b] -> Bool+isRight1 (Right [_]) = True+isRight1 _ = False++ spec :: Spec spec = do describe "C parsing" $ do it "should parse a simple function" $ do let ast = parseText "int a(void) { return 3; }"- ast `shouldBe` Right- [ Fix (FunctionDefn- Global- (Fix (FunctionPrototype- (Fix (TyStd (L (AlexPn 0 1 1) IdStdType "int")))- (L (AlexPn 4 1 5) IdVar "a")- [Fix (TyStd (L (AlexPn 6 1 7) KwVoid "void"))]- ))- (Fix (CompoundStmt [ Fix (Return- (Just- (Fix (LiteralExpr- Int- (L (AlexPn 21 1 22) LitInteger "3")- ))- ))- ])))- ]+ ast `shouldSatisfy` isRight1 it "should parse a type declaration" $ do let ast = parseText "typedef struct Foo { int x; } Foo;"- ast `shouldBe` Right- [ Fix (Typedef- (Fix (Struct- (L (AlexPn 15 1 16) IdSueType "Foo")- [ Fix (MemberDecl- (Fix (TyStd (L (AlexPn 21 1 22) IdStdType "int")))- (Fix (DeclSpecVar (L (AlexPn 25 1 26) IdVar "x")))- Nothing)- ]- ))- (L (AlexPn 30 1 31) IdSueType "Foo"))- ]+ ast `shouldSatisfy` isRight1 it "should parse a struct with bit fields" $ do let ast = parseText "typedef struct Foo { int x : 123; } Foo;"- ast `shouldBe` Right- [ Fix (Typedef- (Fix (Struct- (L (AlexPn 15 1 16) IdSueType "Foo")- [ Fix (MemberDecl- (Fix (TyStd (L (AlexPn 21 1 22) IdStdType "int")))- (Fix (DeclSpecVar (L (AlexPn 25 1 26) IdVar "x")))- (Just (L (AlexPn 29 1 30) LitInteger "123")))- ]- ))- (L (AlexPn 36 1 37) IdSueType "Foo"))- ]+ ast `shouldSatisfy` isRight1 it "should parse a comment" $ do let ast = parseText "/* hello */"- ast `shouldBe` Right- [ Fix (Comment Regular- (L (AlexPn 0 1 1) CmtStart "/*")- [L (AlexPn 3 1 4) CmtWord "hello"]- (L (AlexPn 9 1 10) CmtEnd "*/"))- ]+ ast `shouldSatisfy` isRight1 it "supports single declarators" $ do let ast = parseText "int main() { int a; }" ast `shouldBe` Right- [ Fix (FunctionDefn- Global- (Fix (FunctionPrototype- (Fix (TyStd (L (AlexPn 0 1 1) IdStdType "int")))- (L (AlexPn 4 1 5) IdVar "main")- []- ))- (Fix (CompoundStmt [ Fix (VarDecl- (Fix (TyStd (L (AlexPn 13 1 14) IdStdType "int")))- (Fix (Declarator- (Fix (DeclSpecVar (L (AlexPn 17 1 18) IdVar "a")))- Nothing- )))- ])))+ [ Fix (FunctionDefn Global+ (Fix (FunctionPrototype+ (Fix (TyStd (L (AlexPn 0 1 1) IdStdType "int")))+ (L (AlexPn 4 1 5) IdVar "main")+ []))+ (Fix (CompoundStmt+ [ Fix (VarDeclStmt+ (Fix (VarDecl+ (Fix (TyStd (L (AlexPn 13 1 14) IdStdType "int")))+ (L (AlexPn 17 1 18) IdVar "a")+ [])) Nothing)]))) ] it "does not support multiple declarators per declaration" $ do let ast = parseText "int main() { int a, b; }" ast `shouldBe` Left- "1:19: Parse error near PctComma: \",\"; expected one of [\"';'\"]"+ "1:19: Parse error near PctComma: \",\"; expected one of [\"'='\",\"';'\"]"