diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Masato Mouri (c) 2017
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Masato Mouri nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,3 @@
+# ast-monad
+A library for constructing AST by using do-notation
+
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/ast-monad.cabal b/ast-monad.cabal
new file mode 100644
--- /dev/null
+++ b/ast-monad.cabal
@@ -0,0 +1,33 @@
+name:                ast-monad
+version:             0.1.0.0
+synopsis:            A library for constructing AST by using do-notation
+-- description:
+homepage:            https://github.com/mkdag/ast-monad#readme
+license:             BSD3
+license-file:        LICENSE
+author:              Masato Mouri
+maintainer:          mkdagjp@gmail.com
+copyright:           2017 Masato Mouri
+category:            Language
+build-type:          Simple
+extra-source-files:  README.md
+cabal-version:       >=1.10
+
+library
+  hs-source-dirs:      src
+  exposed-modules:     Language.ASTMonad
+  build-depends:       base >= 4.7 && < 5
+  default-language:    Haskell2010
+
+test-suite ast-monad-test
+  type:                exitcode-stdio-1.0
+  hs-source-dirs:      test
+  main-is:             Spec.hs
+  build-depends:       base
+                     , ast-monad
+  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
+  default-language:    Haskell2010
+
+source-repository head
+  type:     git
+  location: https://github.com/mkdag/ast-monad
diff --git a/src/Language/ASTMonad.hs b/src/Language/ASTMonad.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/ASTMonad.hs
@@ -0,0 +1,72 @@
+{-# LANGUAGE GADTs #-}
+module Language.ASTMonad
+  ( Code(..)
+  , CodeSeq(..)
+  , ASTM(..)
+  , fromCodeSeq
+  , toCodeSeq
+  , getParam
+  , getEnv
+  , putEnv
+  , modifyEnv
+  , buildAST
+  , fromCode
+  , fromCode'
+  ) where
+
+import Data.Monoid
+
+data Code s = Code s (CodeSeq s)
+newtype CodeSeq s = CodeSeq { getCodeSeq :: [Code s] -> [Code s] }
+
+instance Monoid (CodeSeq s) where
+  mempty = CodeSeq $ \xs -> [] ++ xs
+  mappend (CodeSeq f) (CodeSeq g) = CodeSeq $ f . g
+
+fromCodeSeq :: CodeSeq s -> [Code s]
+fromCodeSeq (CodeSeq f) = f []
+
+toCodeSeq :: [Code s] -> CodeSeq s
+toCodeSeq xs = CodeSeq $ \ys -> xs ++ ys
+
+newtype ASTM p s e a = ASTM { runASTM :: p -> e -> (a, e, CodeSeq s) }
+
+instance Functor (ASTM p s e) where
+  fmap f (ASTM rA) = ASTM $ \p e -> case rA p e of
+                                      (a', e', cs') -> (f a', e', cs')
+
+instance Applicative (ASTM p s e) where
+  pure x = ASTM $ \p e -> (x, e, mempty)
+  (<*>) (ASTM rA) (ASTM rA') = ASTM $ \p e -> case rA p e of
+                                                (f', e', cs') -> case rA' p e' of
+                                                                   (a'', e'', cs'') -> (f' a'', e'', cs' <> cs'')
+
+instance Monad (ASTM p s e) where
+  (>>=) (ASTM rA) f = ASTM $ \p e -> case rA p e of
+                                       (a', e', cs') -> case f a' of
+                                                          ASTM rA' -> case rA' p e' of
+                                                                       (b'', e'', cs'') -> (b'', e'', cs' <> cs'')
+                                                                                       
+getParam :: (p -> a) -> ASTM p s e a
+getParam f = ASTM $ \p e -> (f p, e, mempty)
+
+getEnv :: ASTM p s e e
+getEnv = ASTM $ \p e -> (e, e, mempty)
+
+putEnv :: e -> ASTM p s e ()
+putEnv e = ASTM $ \p e -> ((), e, mempty)
+
+modifyEnv :: (e -> e) -> ASTM p s e ()
+modifyEnv f = ASTM $ \p e -> ((), f e, mempty)
+
+buildAST :: ASTM p s e () -> p -> e -> (e, CodeSeq s)
+buildAST (ASTM x) p e = case x p e of
+                       (_,e',z) -> (e', z)
+
+fromCode :: (p -> e -> (e, s)) -> ASTM p s e ()
+fromCode f = ASTM $ \p e -> let (e', s') = f p e in ((), e', toCodeSeq [Code s' mempty])
+
+fromCode' :: ASTM p s e () -> (p -> e -> (e, s)) -> ASTM p s e ()
+fromCode' b f = ASTM $ \p e -> let (e', s') = f p e
+                                   (e'', cs'') = buildAST b p e'
+                               in ((), e'', toCodeSeq [Code s' cs''])
diff --git a/test/Spec.hs b/test/Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec.hs
@@ -0,0 +1,2 @@
+main :: IO ()
+main = putStrLn "Test suite not yet implemented"
