interpreter
authorTomáš Musil <tomik.musil@gmail.com>
Sun, 23 Nov 2014 21:04:21 +0000 (22:04 +0100)
committerTomáš Musil <tomik.musil@gmail.com>
Sun, 23 Nov 2014 21:04:21 +0000 (22:04 +0100)
Arithmetic.lc [new file with mode: 0644]
LICENSE [new file with mode: 0644]
Setup.hs [new file with mode: 0644]
fp.cabal [new file with mode: 0644]
src/Lambda.hs [moved from Lambda.hs with 100% similarity]
src/Main.hs [new file with mode: 0644]

diff --git a/Arithmetic.lc b/Arithmetic.lc
new file mode 100644 (file)
index 0000000..115a869
--- /dev/null
@@ -0,0 +1,4 @@
+Nula=\f.\x.x
+Succ=\n.\f.\x.(f ((n f) x))
+\f.\x.(f x)
+(\n.\f.\x.(f ((n f) x)) \f.\x.(f x))
diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..d3b5f50
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2014, Tomáš Musil
+
+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 Tomáš Musil 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/Setup.hs b/Setup.hs
new file mode 100644 (file)
index 0000000..9a994af
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/fp.cabal b/fp.cabal
new file mode 100644 (file)
index 0000000..0b212a6
--- /dev/null
+++ b/fp.cabal
@@ -0,0 +1,27 @@
+-- Initial fp.cabal generated by cabal init.  For further documentation, 
+-- see http://haskell.org/cabal/users-guide/
+
+name:                fp
+version:             0.1.0.0
+-- synopsis:            
+-- description:         
+license:             BSD3
+license-file:        LICENSE
+author:              Tomáš Musil
+maintainer:          tomik.musil@gmail.com
+-- copyright:           
+category:            Language
+build-type:          Simple
+-- extra-source-files:  
+cabal-version:       >=1.10
+
+executable fp
+  main-is:             Main.hs
+  other-modules:       Lambda
+  -- other-extensions:    
+  build-depends:       base >=4.7 && <4.8
+                     , text >=1.2 && <1.3
+                     , attoparsec >=0.12 && <0.13
+                     , containers
+  hs-source-dirs:      src
+  default-language:    Haskell2010
similarity index 100%
rename from Lambda.hs
rename to src/Lambda.hs
diff --git a/src/Main.hs b/src/Main.hs
new file mode 100644 (file)
index 0000000..4de3762
--- /dev/null
@@ -0,0 +1,46 @@
+{-# OPTIONS_GHC -fno-warn-unused-do-bind #-}
+
+module Main where
+
+import Data.Text as T (Text)
+import qualified Data.Text.IO as T
+import Data.Attoparsec.Text
+import qualified Data.Map as M
+import Control.Applicative
+import System.Environment
+
+import Lambda
+
+data Definition = Definition String Term
+
+dictionary :: [Definition] -> M.Map String Term
+dictionary = M.fromList . map (\ (Definition s t) -> (s, t))
+
+parseDefinition :: Parser Definition
+parseDefinition = do
+  name <- many1 letter
+  char '='
+  t <- parseTerm
+  return $! Definition name t
+
+parseFile :: Text -> ([Definition], [Term])
+parseFile txt = case cnt of
+    (Right t) -> t
+    (Left e) -> error e
+  where cnt = parseOnly (parserF <* endOfInput) txt
+        parserF = do
+          defs <- many (parseDefinition <* char '\n')
+          terms <- many (parseTerm <* char '\n')
+          return $! (defs, terms)
+
+printEval :: Term -> IO ()
+printEval t = do
+  putStrLn $ show t ++ ":"
+  putStrLn $ "  " ++ show (reduce t)
+  putStrLn ""
+
+main :: IO ()
+main = do
+  [filename] <- getArgs
+  (defs, terms) <- parseFile <$> T.readFile filename
+  mapM_ printEval terms