c-dsl (empty) → 0.1.0.0
raw patch · 8 files changed
+369/−0 lines, 8 filesdep +basedep +language-csetup-changed
Dependencies added: base, language-c
Files
- LICENSE +21/−0
- Setup.hs +2/−0
- c-dsl.cabal +27/−0
- src/Language/C/DSL.hs +17/−0
- src/Language/C/DSL/Decl.hs +96/−0
- src/Language/C/DSL/Exp.hs +132/−0
- src/Language/C/DSL/Stat.hs +60/−0
- src/Language/C/DSL/StringLike.hs +14/−0
+ LICENSE view
@@ -0,0 +1,21 @@+The MIT License (MIT)++Copyright (c) <year> <copyright holders>++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in+all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN+THE SOFTWARE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ c-dsl.cabal view
@@ -0,0 +1,27 @@+name: c-dsl+version: 0.1.0.0+synopsis: A higher level DSL on top of language-c+description: This DSL is meant to make it easier to write language-c's DSL by providing simple+ functions/operators for writing C AST's in Haskell+license: MIT+license-file: LICENSE+author: Danny Gratzer+maintainer: danny.gratzer@gmail.com+category: Language+build-type: Simple+cabal-version: >=1.10+source-repository head+ type: hg+ location: http://bitbucket.org/jozefg/c-dsl+library+ exposed-modules: Language.C.DSL,+ Language.C.DSL.Decl,+ Language.C.DSL.Stat,+ Language.C.DSL.Exp,+ Language.C.DSL.StringLike+ + build-depends: base >=4.6 && <4.7,+ language-c+ hs-source-dirs: src/+ default-language: Haskell2010+
+ src/Language/C/DSL.hs view
@@ -0,0 +1,17 @@+-- | This module simply exists to export the entirety of the DSL and as+-- a convenience, "Language.C".++++module Language.C.DSL (+ module Language.C.DSL.StringLike,+ module Language.C.DSL.Exp,+ module Language.C.DSL.Stat,+ module Language.C.DSL.Decl,+ module Language.C) where++import Language.C+import Language.C.DSL.StringLike+import Language.C.DSL.Exp+import Language.C.DSL.Stat+import Language.C.DSL.Decl
+ src/Language/C/DSL/Decl.hs view
@@ -0,0 +1,96 @@+{-# LANGUAGE FlexibleInstances #-}+module Language.C.DSL.Decl where+import Language.C+import Data.String+import Language.C.DSL.StringLike++-- | A low level way to declare something.+decl :: CDeclSpec -> CDeclr -> Maybe CExpr -> CDecl+decl ty name exp = CDecl [ty] [(Just name, flip CInitExpr undefNode `fmap` exp, Nothing)] undefNode++-- | Simple types that can be used in declarations.+voidTy, charTy, shortTy, intTy, longTy, floatTy :: CDeclSpec+voidTy = CTypeSpec $ CVoidType undefNode+charTy = CTypeSpec $ CCharType undefNode+shortTy = CTypeSpec $ CShortType undefNode+intTy = CTypeSpec $ CIntType undefNode+longTy = CTypeSpec $ CLongType undefNode+floatTy = CTypeSpec $ CFloatType undefNode+doubleTy = CTypeSpec $ CDoubleType undefNode++-- | Modifies a declarator to be a pointer. For example+-- @ptr "x"@ would be @*x@ in C.+ptr :: CDeclr -> CDeclr+ptr (CDeclr nm mods cstr attrs node) = CDeclr nm (CPtrDeclr [] undefNode : mods) cstr attrs node++-- | Clever functions that can be applied to declarators, for example @int "x" .= 1@ is equivalent+-- to @int x = 1@. To leave a variable uninitialized @int "x" Nothing@ does the job.+char, short, int, long, float, double :: CDeclr -> Maybe CExpr -> CDecl+char = decl charTy+short = decl shortTy+int = decl intTy+long = decl longTy+float = decl floatTy+double = decl doubleTy++-- | Equivalent to the above but with pointer wrappers.+charPtr, shortPtr, intPtr, longPtr, floatPtr, doublePtr :: CDeclr -> Maybe CExpr -> CDecl+charPtr = char . ptr+shortPtr = short . ptr+intPtr = int . ptr+longPtr = long . ptr+floatPtr = float . ptr+doublePtr = double . ptr++-- | Supplies an initializer for an expression.+(.=) :: (Maybe CExpr -> CDecl) -> CExpr -> CDecl+f .= e = f (Just e)+infixl 7 .=++-- | Leave a declaration uninitialized. For example @uninit $ char "x"@.+uninit :: (Maybe CExpr -> CDecl) -> CDecl+uninit = ($ Nothing)++csu :: CStructTag -> String -> [(String, CTypeSpec)] -> CDecl+csu tag ident fields = CDecl+ [CStorageSpec $ CTypedef undefNode, CTypeSpec $ CSUType structTy undefNode]+ [(Just $ fromString ident, Nothing, Nothing)]+ undefNode+ where structTy = CStruct tag (Just $ fromString ident) (Just $ map structify fields) [] undefNode+ structify (name, ty) = CDecl [CTypeSpec ty] [(Just (fromString name), Nothing, Nothing)] undefNode++struct, union :: String -> [(String, CTypeSpec)] -> CDecl+-- ^ Create a structure or union, for example @struct "foo" [("bar", intTy)]@ is+-- @typedef struct foo {int bar;} foo;@+struct = csu CStructTag+union = csu CUnionTag++-- Defines a C function. For example+-- > test =+-- > fun [intTy] "test"[int "a", int "b"] $ hblock [+-- > creturn ("a" + "b")+-- > ]+-- Would be the equivalent of+-- > int test(int a, int b)+-- > {+-- > return a + b;+-- > }+fun :: [CDeclSpec] -> String -> [Maybe CExpr -> CDecl] -> CStat -> CFunDef+fun specs name args body = CFunDef specs decl [] body undefNode+ where decl = CDeclr (Just $ fromString name)+ [CFunDeclr (Right (fmap ($Nothing) args, False)) [] undefNode]+ Nothing [] undefNode++class External a where+ export :: a -> CExtDecl+instance External CFunDef where+ export = CFDefExt+instance External CDecl where+ export = CDeclExt+instance External CStrLit where+ export = flip CAsmExt undefNode++-- | Exports a series of declarations to a translation unit.+transUnit :: [CExtDecl] -> CTranslUnit+transUnit = flip CTranslUnit undefNode+
+ src/Language/C/DSL/Exp.hs view
@@ -0,0 +1,132 @@+{-# LANGUAGE FlexibleInstances #-}+-- | This module contians the DSL for writing @CExpr@s.+-- It doesn't export the orphan instance for @IsString CExpr@ which+-- can be found in "Language.C.DSL.StringLike".+module Language.C.DSL.Exp where+import Language.C+import Data.String+import Language.C.DSL.StringLike++-- | Lift a Haskell string into a literal C string.+str :: String -> CExpr+str = CConst . flip CStrConst undefNode . cString++cOp :: CBinaryOp -> CExpr -> CExpr -> CExpr+cOp op a b = CBinary op a b undefNode++-- | Comparison operators, normal haskell operators with @:@ at the end.+(==:), (/=:), (<:), (>:), (<=:), (>=:) :: CExpr -> CExpr -> CExpr+(==:) = cOp CEqOp+(/=:) = cOp CNeqOp+(<:) = cOp CLeOp+(>:) = cOp CGrOp+(<=:) = cOp CLeqOp+(>=:) = cOp CGeqOp++-- | The ternary operator in C. @ternary a b c@ will turn into @a ? b : c@.+ternary :: CExpr -> CExpr -> CExpr -> CExpr+ternary i t e = CCond i (Just t) e undefNode++-- | An orphan @Num@ instance for @CExpr@. It provides inline implementations+-- of @abs@ and @signum@ that don't rely on @math.h@.+instance Num CExpr where+ fromInteger = CConst . flip CIntConst undefNode . cInteger+ (*) = cOp CMulOp+ (+) = cOp CAddOp+ (-) = cOp CSubOp+ abs a = ternary (a >=: 0) a (negate a)+ signum a = ternary (a >=: 0) (ternary (a ==: 0) a 1) (-1)+instance Fractional CExpr where+ (/) = cOp CDivOp+ fromRational = CConst . flip CFloatConst undefNode . cFloat . fromRational++-- | A function mapping identifier in C to be used as variables. Normally this can be+-- avoided since "Language.C.DSL.StringLike" provides an 'IsString' instance.+var :: Ident -> CExpr+var = flip CVar undefNode++-- | Function calls, @f#[a, b, c]@ will become @f(a, b, c)@. Note+-- that @f@ is also an expression.+(#) :: CExpr -> [CExpr] -> CExpr+f # args = CCall f args undefNode++-- | The assignment operator. @var <-- value@ will become @var = value;@ in C.+(<--) :: CExpr -> CExpr -> CExpr+var <-- val = CAssign CAssignOp var val undefNode+infixl 3 <--++-- | This is the more generalized version of '(<--)'. It allows+-- any 'CAssignOp' to be passed in to facilitate writing @a += b@ and+-- similar.+assign :: CAssignOp -> CExpr -> CExpr -> CExpr+assign mode var val = CAssign mode var val undefNode+++-- | A simplified unary operator type. It+-- can be converted to 'Language.C's version using+-- 'toCUnaryOp'.+data UnOp = PlusPlus+ | MinusMinus+ | Minus+ | Plus+ | Not+ | Addr -- ^ The address of operator @&@.+ | Ind -- ^ The dereferencing operator in C @*@.+ deriving(Eq, Show)++-- | Convert a 'UnOp' to the corresponding 'CUnaryOp'.+toCUnaryOp :: UnOp -> CUnaryOp+toCUnaryOp Minus = CMinOp+toCUnaryOp Plus = CPlusOp+toCUnaryOp Not = CNegOp+toCUnaryOp Addr = CAdrOp+toCUnaryOp Ind = CIndOp++-- | Apply a unary operator prefix, @op `pre` exp@ will transform into something like @op exp@+-- in C. This only matters for 'PlusPlus' and 'MinusMinus'.+pre :: UnOp -> CExpr -> CExpr+PlusPlus `pre` exp = CUnary CPreIncOp exp undefNode+MinusMinus `pre` exp = CUnary CPreDecOp exp undefNode+op `pre` exp = CUnary (toCUnaryOp op) exp undefNode++-- | The postfix equivalent of 'pre'.+post :: CExpr -> UnOp -> CExpr+exp `post` PlusPlus = CUnary CPostIncOp exp undefNode+exp `post` MinusMinus = CUnary CPostDecOp exp undefNode+exp `post` op = CUnary (toCUnaryOp op) exp undefNode++-- | A quick wrapper of @pre Ind exp@ since it's so common.+star :: CExpr -> CExpr+star = pre Ind++-- | The C comma operator, @comma [a, b, c]@ is equivalent to @a, b, c@ in C.+comma :: [CExpr] -> CExpr+comma = flip CComma undefNode++-- | Implements C style casts for expressions.+castTo :: CExpr -> CDecl -> CExpr+exp `castTo` ty = CCast ty exp undefNode++-- | @size of@ for types. +sizeOfDecl :: CDecl -> CExpr+sizeOfDecl = flip CSizeofType undefNode++-- | @size of@ for expressions. Carefully note that @sizeOf "someType"@ will+-- incorrectly treat @someType@ as a variable, not a type.+sizeOf :: CExpr -> CExpr+sizeOf = flip CSizeofExpr undefNode++-- | Access a field of a struct, this C's @.@ operator.+(&) :: CExpr -> String -> CExpr+struct & field = CMember struct (fromString field) False undefNode+infixl 8 &++-- | The automatic dereferencing @->@ in C.+(&*) :: CExpr -> String -> CExpr+struct &* field = CMember struct (fromString field) True undefNode+infixl 8 &*++-- | This is the indexing operator in C, @a ! i@ is @a[i]@.+(!) :: CExpr -> CExpr -> CExpr+arr ! ind = CIndex arr ind undefNode+infixl 8 !
+ src/Language/C/DSL/Stat.hs view
@@ -0,0 +1,60 @@+{-# LANGUAGE FlexibleInstances #-}+module Language.C.DSL.Stat where+import Language.C++-- | An if statement with no else clause+cif :: CExpr -> CStat -> CStat+cif exp stat = CIf exp stat Nothing undefNode++-- | An if statement with an else clause+cifElse :: CExpr -> CStat -> CStat -> CStat+cifElse exp th el = CIf exp th (Just el) undefNode++-- | A while loop, the 'CExpr' is the looping condition.+while :: CExpr -> CStat -> CStat+while exp stat = CWhile exp stat False undefNode++-- | A for loop, an example use+-- > for(int "x" .= 1, 1, PlusPlus `pre` "x")+-- > "printf"#[str "%d\n", "x"]+for :: (CDecl, CExpr, CExpr) -> CStat -> CStat+for (init, test, upd) block = CFor (Right init) (Just test) (Just upd) block undefNode++-- | A for loop with no declarations.+noDeclFor :: (CExpr, CExpr) -> CStat -> CStat+noDeclFor (test, upd) block = CFor (Left Nothing) (Just test) (Just upd) block undefNode++-- | A do while loop.+doWhile :: CExpr -> CStat -> CStat+doWhile exp stat = CWhile exp stat True undefNode++cbreak :: CStat+cbreak = CBreak undefNode++ccont :: CStat+ccont = CCont undefNode++creturn :: CExpr -> CStat+creturn = flip CReturn undefNode . Just++cvoidReturn :: CStat+cvoidReturn = CReturn Nothing undefNode++liftE :: CExpr -> CStat+liftE e = CExpr (Just e) undefNode++class BlockLike a where+ intoB :: a -> CBlockItem+instance BlockLike CStat where+ intoB = CBlockStmt+instance BlockLike CExpr where+ intoB = intoB . liftE+instance BlockLike CDecl where+ intoB = CBlockDecl++block :: [CBlockItem] -> CStat+block = flip (CCompound []) undefNode++hBlock :: BlockLike a => [a] -> CStat+hBlock = block . map intoB+
+ src/Language/C/DSL/StringLike.hs view
@@ -0,0 +1,14 @@+{-# LANGUAGE FlexibleInstances #-}+-- | The home of all the orphaned 'IsString' instances+-- used throughout the DSL.+module Language.C.DSL.StringLike where+import Data.String+import Language.C+instance IsString Ident where+ fromString = internalIdent+instance IsString CExpr where+ fromString s = CVar (fromString s) undefNode+instance IsString CDeclr where+ fromString str = CDeclr (Just $ fromString str) [] Nothing [] undefNode+instance IsString CDecl where+ fromString str = CDecl [CTypeSpec (CTypeDef (fromString str) undefNode)] [] undefNode