summaryrefslogtreecommitdiff
path: root/Biz/Language/Bs/Primitives.hs
diff options
context:
space:
mode:
Diffstat (limited to 'Biz/Language/Bs/Primitives.hs')
-rw-r--r--Biz/Language/Bs/Primitives.hs179
1 files changed, 92 insertions, 87 deletions
diff --git a/Biz/Language/Bs/Primitives.hs b/Biz/Language/Bs/Primitives.hs
index c074c59..4c70499 100644
--- a/Biz/Language/Bs/Primitives.hs
+++ b/Biz/Language/Bs/Primitives.hs
@@ -1,5 +1,6 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE NoImplicitPrelude #-}
+
-- | bs primitives
--
-- I would like to reduce the number of primitives in the language to some
@@ -18,134 +19,138 @@ import Protolude
import System.Directory
import System.IO
-type Prim = [(T.Text, Expr)]
-type Unary = Expr -> Eval Expr
+type Prim = [(T.Text, Expr)]
+
+type Unary = Expr -> Eval Expr
+
type Binary = Expr -> Expr -> Eval Expr
mkF :: ([Expr] -> Eval Expr) -> Expr
mkF = IFun . IFunc
primEnv :: Prim
-primEnv = [
- ("+" , mkF $ binopFold (numOp (+)) (Numb 0) )
- , ("*" , mkF $ binopFold (numOp (*)) (Numb 1) )
- , ("string-append", mkF $ binopFold (strOp (<>)) (Tape "") )
- , ("-" , mkF $ binop $ numOp (-))
- , ("<" , mkF $ binop $ numCmp (<))
- , ("<=" , mkF $ binop $ numCmp (<=))
- , (">" , mkF $ binop $ numCmp (>))
- , (">=" , mkF $ binop $ numCmp (>=))
- , ("==" , mkF $ binop $ numCmp (==))
- , ("even?" , mkF $ unop $ numBool even)
- , ("odd?" , mkF $ unop $ numBool odd)
- , ("neg?" , mkF $ unop $ numBool (< 0))
- , ("pos?" , mkF $ unop $ numBool (> 0))
- , ("eq?" , mkF $ binop eqCmd )
- , ("null?" , mkF $ unop (eqCmd Nil) )
- , ("bl-eq?" , mkF $ binop $ eqOp (==))
- , ("and" , mkF $ binopFold (eqOp (&&)) (Bool True))
- , ("or" , mkF $ binopFold (eqOp (||)) (Bool False))
- , ("not" , mkF $ unop $ notOp)
- , ("cons" , mkF $ Language.Bs.Primitives.cons)
- , ("cdr" , mkF $ Language.Bs.Primitives.cdr)
- , ("car" , mkF $ Language.Bs.Primitives.car)
- , ("quote" , mkF $ quote)
- , ("file?" , mkF $ unop fileExists)
- , ("slurp" , mkF $ unop slurp)
- , ("wslurp" , mkF $ unop wSlurp)
- , ("put" , mkF $ binop put_)
+primEnv =
+ [ ("+", mkF $ binopFold (numOp (+)) (Numb 0)),
+ ("*", mkF $ binopFold (numOp (*)) (Numb 1)),
+ ("string-append", mkF $ binopFold (strOp (<>)) (Tape "")),
+ ("-", mkF $ binop $ numOp (-)),
+ ("<", mkF $ binop $ numCmp (<)),
+ ("<=", mkF $ binop $ numCmp (<=)),
+ (">", mkF $ binop $ numCmp (>)),
+ (">=", mkF $ binop $ numCmp (>=)),
+ ("==", mkF $ binop $ numCmp (==)),
+ ("even?", mkF $ unop $ numBool even),
+ ("odd?", mkF $ unop $ numBool odd),
+ ("neg?", mkF $ unop $ numBool (< 0)),
+ ("pos?", mkF $ unop $ numBool (> 0)),
+ ("eq?", mkF $ binop eqCmd),
+ ("null?", mkF $ unop (eqCmd Nil)),
+ ("bl-eq?", mkF $ binop $ eqOp (==)),
+ ("and", mkF $ binopFold (eqOp (&&)) (Bool True)),
+ ("or", mkF $ binopFold (eqOp (||)) (Bool False)),
+ ("not", mkF $ unop $ notOp),
+ ("cons", mkF $ Language.Bs.Primitives.cons),
+ ("cdr", mkF $ Language.Bs.Primitives.cdr),
+ ("car", mkF $ Language.Bs.Primitives.car),
+ ("quote", mkF $ quote),
+ ("file?", mkF $ unop fileExists),
+ ("slurp", mkF $ unop slurp),
+ ("wslurp", mkF $ unop wSlurp),
+ ("put", mkF $ binop put_)
]
unop :: Unary -> [Expr] -> Eval Expr
-unop op [x] = op x
-unop _ args = throw $ NumArgs 1 args
+unop op [x] = op x
+unop _ args = throw $ NumArgs 1 args
binop :: Binary -> [Expr] -> Eval Expr
-binop op [x,y] = op x y
-binop _ args = throw $ NumArgs 2 args
+binop op [x, y] = op x y
+binop _ args = throw $ NumArgs 2 args
-fileExists :: Expr -> Eval Expr
+fileExists :: Expr -> Eval Expr
fileExists (Tape txt) = Bool <$> liftIO (doesFileExist $ T.unpack txt)
-fileExists val = throw $ TypeMismatch "read expects string, instead got: " val
+fileExists val = throw $ TypeMismatch "read expects string, instead got: " val
-slurp :: Expr -> Eval Expr
+slurp :: Expr -> Eval Expr
slurp (Tape txt) = liftIO $ wFileSlurp txt
-slurp val = throw $ TypeMismatch "read expects string, instead got: " val
+slurp val = throw $ TypeMismatch "read expects string, instead got: " val
wFileSlurp :: T.Text -> IO Expr
wFileSlurp fileName = withFile (T.unpack fileName) ReadMode go
- where go = readTextFile fileName
+ where
+ go = readTextFile fileName
openURL :: T.Text -> IO Expr
openURL x = do
- req <- simpleHTTP (getRequest $ T.unpack x)
+ req <- simpleHTTP (getRequest $ T.unpack x)
body <- getResponseBody req
return $ Tape $ T.pack body
wSlurp :: Expr -> Eval Expr
-wSlurp (Tape txt) = liftIO $ openURL txt
+wSlurp (Tape txt) = liftIO $ openURL txt
wSlurp val = throw $ TypeMismatch "wSlurp expects a string, instead got: " val
readTextFile :: T.Text -> Handle -> IO Expr
readTextFile fileName h = do
exists <- doesFileExist $ T.unpack fileName
if exists
- then (TIO.hGetContents h) >>= (return . Tape)
- else throw $ ReadFileError $ T.concat [" file does not exist: ", fileName]
+ then (TIO.hGetContents h) >>= (return . Tape)
+ else throw $ ReadFileError $ T.concat [" file does not exist: ", fileName]
put_ :: Expr -> Expr -> Eval Expr
-put_ (Tape file) (Tape msg) = liftIO $ wFilePut file msg
-put_ (Tape _) val = throw $ TypeMismatch "put expects string in the second argument (try using show), instead got: " val
-put_ val _ = throw $ TypeMismatch "put expects string, instead got: " val
+put_ (Tape file) (Tape msg) = liftIO $ wFilePut file msg
+put_ (Tape _) val = throw $ TypeMismatch "put expects string in the second argument (try using show), instead got: " val
+put_ val _ = throw $ TypeMismatch "put expects string, instead got: " val
wFilePut :: T.Text -> T.Text -> IO Expr
wFilePut fileName msg = withFile (T.unpack fileName) WriteMode go
- where go = putTextFile fileName msg
+ where
+ go = putTextFile fileName msg
putTextFile :: T.Text -> T.Text -> Handle -> IO Expr
putTextFile fileName msg h = do
canWrite <- hIsWritable h
if canWrite
- then (TIO.hPutStr h msg) >> (return $ Tape msg)
- else throw $ ReadFileError $ T.concat [" file does not exist: ", fileName]
+ then (TIO.hPutStr h msg) >> (return $ Tape msg)
+ else throw $ ReadFileError $ T.concat [" file does not exist: ", fileName]
binopFold :: Binary -> Expr -> [Expr] -> Eval Expr
binopFold op farg args = case args of
- []-> throw $ NumArgs 2 args
- [a,b] -> op a b
- _ -> foldM op farg args
+ [] -> throw $ NumArgs 2 args
+ [a, b] -> op a b
+ _ -> foldM op farg args
numBool :: (Integer -> Bool) -> Expr -> Eval Expr
numBool op (Numb x) = return $ Bool $ op x
-numBool _ x = throw $ TypeMismatch "numeric op " x
+numBool _ x = throw $ TypeMismatch "numeric op " x
numOp :: (Integer -> Integer -> Integer) -> Expr -> Expr -> Eval Expr
-numOp op (Numb x) (Numb y) = return $ Numb $ op x y
-numOp _ Nil (Numb y) = return $ Numb y
-numOp _ (Numb x) Nil = return $ Numb x
-numOp _ x (Numb _) = throw $ TypeMismatch "numeric op" x
-numOp _ (Numb _) y = throw $ TypeMismatch "numeric op" y
-numOp _ x _ = throw $ TypeMismatch "numeric op" x
+numOp op (Numb x) (Numb y) = return $ Numb $ op x y
+numOp _ Nil (Numb y) = return $ Numb y
+numOp _ (Numb x) Nil = return $ Numb x
+numOp _ x (Numb _) = throw $ TypeMismatch "numeric op" x
+numOp _ (Numb _) y = throw $ TypeMismatch "numeric op" y
+numOp _ x _ = throw $ TypeMismatch "numeric op" x
strOp :: (T.Text -> T.Text -> T.Text) -> Expr -> Expr -> Eval Expr
strOp op (Tape x) (Tape y) = return $ Tape $ op x y
-strOp _ Nil (Tape y) = return $ Tape y
-strOp _ (Tape x) Nil = return $ Tape x
-strOp _ x (Tape _) = throw $ TypeMismatch "string op" x
-strOp _ (Tape _) y = throw $ TypeMismatch "string op" y
-strOp _ x _ = throw $ TypeMismatch "string op" x
+strOp _ Nil (Tape y) = return $ Tape y
+strOp _ (Tape x) Nil = return $ Tape x
+strOp _ x (Tape _) = throw $ TypeMismatch "string op" x
+strOp _ (Tape _) y = throw $ TypeMismatch "string op" y
+strOp _ x _ = throw $ TypeMismatch "string op" x
eqOp :: (Bool -> Bool -> Bool) -> Expr -> Expr -> Eval Expr
eqOp op (Bool x) (Bool y) = return $ Bool $ op x y
-eqOp _ x (Bool _) = throw $ TypeMismatch "bool op" x
-eqOp _ (Bool _) y = throw $ TypeMismatch "bool op" y
-eqOp _ x _ = throw $ TypeMismatch "bool op" x
+eqOp _ x (Bool _) = throw $ TypeMismatch "bool op" x
+eqOp _ (Bool _) y = throw $ TypeMismatch "bool op" y
+eqOp _ x _ = throw $ TypeMismatch "bool op" x
numCmp :: (Integer -> Integer -> Bool) -> Expr -> Expr -> Eval Expr
-numCmp op (Numb x) (Numb y) = return . Bool $ op x y
-numCmp _ x (Numb _) = throw $ TypeMismatch "numeric op" x
-numCmp _ (Numb _) y = throw $ TypeMismatch "numeric op" y
-numCmp _ x _ = throw $ TypeMismatch "numeric op" x
+numCmp op (Numb x) (Numb y) = return . Bool $ op x y
+numCmp _ x (Numb _) = throw $ TypeMismatch "numeric op" x
+numCmp _ (Numb _) y = throw $ TypeMismatch "numeric op" y
+numCmp _ x _ = throw $ TypeMismatch "numeric op" x
notOp :: Expr -> Eval Expr
notOp (Bool True) = return $ Bool False
@@ -157,27 +162,27 @@ eqCmd (Atom x) (Atom y) = return . Bool $ x == y
eqCmd (Numb x) (Numb y) = return . Bool $ x == y
eqCmd (Tape x) (Tape y) = return . Bool $ x == y
eqCmd (Bool x) (Bool y) = return . Bool $ x == y
-eqCmd Nil Nil = return $ Bool True
-eqCmd _ _ = return $ Bool False
+eqCmd Nil Nil = return $ Bool True
+eqCmd _ _ = return $ Bool False
cons :: [Expr] -> Eval Expr
-cons [x,(List ys)] = return $ List $ x:ys
-cons [x,y] = return $ List [x,y]
-cons _ = throw $ ExpectedList "cons, in second argument"
+cons [x, (List ys)] = return $ List $ x : ys
+cons [x, y] = return $ List [x, y]
+cons _ = throw $ ExpectedList "cons, in second argument"
car :: [Expr] -> Eval Expr
-car [List [] ] = return Nil
-car [List (x:_)] = return x
-car [] = return Nil
-car _ = throw $ ExpectedList "car"
+car [List []] = return Nil
+car [List (x : _)] = return x
+car [] = return Nil
+car _ = throw $ ExpectedList "car"
cdr :: [Expr] -> Eval Expr
-cdr [List (_:xs)] = return $ List xs
-cdr [List []] = return Nil
-cdr [] = return Nil
-cdr _ = throw $ ExpectedList "cdr"
+cdr [List (_ : xs)] = return $ List xs
+cdr [List []] = return Nil
+cdr [] = return Nil
+cdr _ = throw $ ExpectedList "cdr"
quote :: [Expr] -> Eval Expr
-quote [List xs] = return $ List $ Atom "quote" : xs
-quote [expr] = return $ List $ Atom "quote" : [expr]
-quote args = throw $ NumArgs 1 args
+quote [List xs] = return $ List $ Atom "quote" : xs
+quote [expr] = return $ List $ Atom "quote" : [expr]
+quote args = throw $ NumArgs 1 args