From be520a67c1127a6d254596442fda4b343849886d Mon Sep 17 00:00:00 2001 From: Suguivy Date: Sun, 28 Feb 2021 00:20:42 +0100 Subject: [PATCH] Cleaned the code a bit --- src/Evaluator.hs | 8 +++++--- src/Expression.hs | 1 + src/Parser.hs | 9 ++++----- src/Primitives.hs | 17 +++++++++++------ 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/Evaluator.hs b/src/Evaluator.hs index 3a83a07..a9150a3 100644 --- a/src/Evaluator.hs +++ b/src/Evaluator.hs @@ -3,17 +3,19 @@ module Evaluator where import Expression import Primitives +-- Evals (reduces) an expression eval :: Expression -> Either String Expression eval n@(Number _) = Right n eval s@(Symbol _) = Right s -eval (SExpr es) = mapM eval es >>= apply . SExpr +eval (SExpr es) = apply . SExpr =<< mapM eval es +-- Applies, in a SExpr, a function to its arguments apply :: Expression -> Either String Expression apply (SExpr (f:args)) = case f of Symbol "+" -> Right $ pAdd args Symbol "-" -> Right $ pSub args Symbol "*" -> Right $ pMul args Symbol "/" -> Right $ pDiv args - Symbol _ -> Left "no primitive functions not supported (only +, -, * and /)" - _ -> Left "object not applicable" + Symbol x -> Left $ show x ++ ": no primitive functions not supported" + _ -> Left "object not applicable" apply _ = Left "object not applicable" diff --git a/src/Expression.hs b/src/Expression.hs index e5e009a..b43da72 100644 --- a/src/Expression.hs +++ b/src/Expression.hs @@ -3,6 +3,7 @@ module Expression where -- The basic unit of the language are Expressions, so we make an -- Expression data with the primitive expression values as the -- constructors + data Expression = Number Double | Symbol String | SExpr [Expression] diff --git a/src/Parser.hs b/src/Parser.hs index 2ba71f0..32186fd 100644 --- a/src/Parser.hs +++ b/src/Parser.hs @@ -1,7 +1,6 @@ module Parser where import Text.ParserCombinators.Parsec -import Data.Char import Expression @@ -11,11 +10,11 @@ parseExpression s = do e <- parse anyExpressionParser "" s return e --- Parser any possible expression +-- Parser for any possible expression anyExpressionParser :: GenParser Char st Expression anyExpressionParser = numberParser <|> symbolParser <|> sexprParser --- Parses an S-expr +-- Parser for an S-expr sexprParser :: GenParser Char st Expression sexprParser = do _ <- spaces @@ -25,7 +24,7 @@ sexprParser = do _ <- char ')' >> spaces return $ SExpr es --- Parses a symbol +-- Parser for a symbol symbolParser :: GenParser Char st Expression symbolParser = Symbol <$> do c <- symbolChar @@ -33,7 +32,7 @@ symbolParser = Symbol <$> do return $ c:cs where symbolChar = letter <|> oneOf "!#$%&*+-/:<=>?@\\^_`~" --- Parses a number +-- Parser for a number numberParser :: GenParser Char st Expression numberParser = do num <- read <$> many1 digit diff --git a/src/Primitives.hs b/src/Primitives.hs index b85d213..f247f69 100644 --- a/src/Primitives.hs +++ b/src/Primitives.hs @@ -1,10 +1,15 @@ -module Primitives where +module Primitives (pAdd, pSub, pMul, pDiv) where + +-- This module exports the primitve expressions for our language import Expression -pAdd, pSub, pMul, pDiv :: [Expression] -> Expression +pArith :: (Double -> Double -> Double) -> [Expression] -> Expression +pArith f es = Number . foldr1 f $ map unnum es + where unnum = \(Number x) -> x -pAdd = foldr1 $ \(Number a) (Number b) -> Number (a+b) -pSub = foldr1 $ \(Number a) (Number b) -> Number (a-b) -pMul = foldr1 $ \(Number a) (Number b) -> Number (a*b) -pDiv = foldr1 $ \(Number a) (Number b) -> Number (a/b) +pAdd, pSub, pMul, pDiv :: [Expression] -> Expression +pAdd = pArith (+) +pSub = pArith (-) +pMul = pArith (*) +pDiv = pArith (/)