diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2017 iostreamer-X
+
+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.
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/fsh-csv.cabal b/fsh-csv.cabal
new file mode 100644
--- /dev/null
+++ b/fsh-csv.cabal
@@ -0,0 +1,24 @@
+-- Initial fsh-csv.cabal generated by cabal init.  For further 
+-- documentation, see http://haskell.org/cabal/users-guide/
+
+name:                fsh-csv
+version:             0.1.0.0
+synopsis:            csv parser for fsh
+description:         This is a csv parser for fsh. To use this parser, use the -p flag and pass 'csv' as argument
+license:             MIT
+license-file:        LICENSE
+author:              iostreamer-X
+maintainer:          iostreamer007@gmail.com
+-- copyright:           
+category:            Distribution
+build-type:          Simple
+-- extra-source-files:  
+cabal-version:       >=1.10
+
+library
+  exposed-modules:     FSH_CSV
+  other-modules:       Transform
+  -- other-extensions:    
+  build-depends:       base >=4.8 && <4.9, hint
+  hs-source-dirs:      src
+  default-language:    Haskell2010
diff --git a/src/FSH_CSV.hs b/src/FSH_CSV.hs
new file mode 100644
--- /dev/null
+++ b/src/FSH_CSV.hs
@@ -0,0 +1,88 @@
+module FSH_CSV where
+
+import Transform
+import Text.ParserCombinators.ReadP
+import Language.Haskell.Interpreter as I
+import Data.List
+
+--- PARSING
+
+isChar = (/=',')
+
+charParser :: ReadP [Char]
+charParser = many1 (satisfy isChar)
+
+-- This parses characters till a comma is encountered
+getParsed :: ReadS [Char]
+getParsed = readP_to_S charParser
+
+-- Leading comma needs to be removed or else our parser will output []
+removeLeadingComma (',':xs) = removeLeadingComma xs
+removeLeadingComma str = str
+
+-- Only the last element is of interest, rest are incomplete
+getPair :: [Char] -> ([Char], [Char])
+getPair line = 
+  parsedPair $ getParsed.removeLeadingComma $ line
+  where
+    parsedPair list@(x:xs) = last list
+    parsedPair [] = ("","")
+
+{-
+ - When we run getPair on a string, we get a pair of strings.
+ - The first half is parsed, the second half failed our parser.
+ - The second half failed because it had comma, so if we run getPair on
+ - the unparsed string, it will ultimately be parsed.
+ -
+ - And that is the solution presented here, we run getPair,
+ - pick the parsed part and put it in a list, and run getPair on unparsed part.
+ - We do this till unparsed is [] ie empty and then we return the list of parsed words.
+ -}
+
+getWords' :: [[Char]] -> ([Char], [Char]) -> [[Char]]
+getWords' list (parsed,[]) = list++[parsed]
+getWords' list (parsed,unparsed) = return (getPair $ unparsed) >>= getWords' (if length parsed > 0 then (list++[parsed]) else [])
+
+getWords :: [Char] -> [[Char]]
+getWords line = getWords' [] ([],line)
+
+--- END PARSING
+
+--- TRANSFORMING
+
+mapLines :: [[Char]] -> [[[Char]]]
+mapLines = map getWords
+
+mapQuotes :: [[String]] -> [[Char]]
+mapQuotes = map ((\str->","++str).toStringList.encloseWithQuotes)
+
+mapBraces :: [String] -> [Char]
+mapBraces list = "[" ++ (tail (unwords list)) ++ "]"
+
+parse :: [[Char]] -> [Char]
+parse = mapBraces.mapQuotes.mapLines
+
+--- END TRANSFORMING
+
+--- EXECUTING
+
+printList (x:xs) = putStrLn x >> printList xs
+printList [] = return ()
+
+
+run :: [Char] -> String -> IO ()
+run functionStr processedArgs =
+  do
+    splits <- return (lines processedArgs)
+    header <- return (head splits)
+    unparsed <- return (tail splits)
+    result <- runInterpreter $ setImports ["Prelude"] >> interpret (functionStr ++ " " ++ parse unparsed) (as :: [[String]])
+    case result of
+      (Right res) -> 
+        do
+          outputMatrix <- return $ (getWords header) : res
+          output <- return $ map (intercalate ",") outputMatrix
+          printList output
+      (Left err)   -> error $ show err
+
+--- END EXECUTING
diff --git a/src/Transform.hs b/src/Transform.hs
new file mode 100644
--- /dev/null
+++ b/src/Transform.hs
@@ -0,0 +1,18 @@
+module Transform where
+
+-- The output of the bash command is converted to a list of strings
+-- and this list needs to represented as a String to be interpreted.
+-- To do this, each string in the list is enclosed with quotes
+-- and then joined together to get string representation of list.
+--
+-- The way this is achieved is each string in list is mapped to {,"str"},
+-- so ["1","2"] becomes [ ",\"1\"" , ",\"2\"" ]
+-- Now all that is left is join the list, hence unwords, but we get a leading {,}
+-- hence `tail` 
+
+encloseWithQuotes :: [String] -> [String]
+encloseWithQuotes = map (\s->",\""++s++"\"")
+
+toStringList :: [String] -> String
+toStringList str = "[" ++ (tail.unwords $ str) ++ "]"
+
