Created
June 23, 2024 22:16
-
-
Save BRonen/6f976e6955e40f83d93079f1e58adfcc to your computer and use it in GitHub Desktop.
5 minutes math expression interpreter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module MathInterpreter (mathInterpreter) where | |
import Data.Char | |
data Token = Number Integer | |
| Plus | |
| Dash | |
| Star | |
| Slash | |
deriving Show | |
data Ast = Value Integer | |
| Add Ast Ast | |
| Minus Ast Ast | |
| Mult Ast Ast | |
| Div Ast Ast | |
deriving Show | |
takeWhileIsDigit :: [Char] -> [Char] | |
takeWhileIsDigit = takeWhile Data.Char.isDigit | |
tokenize :: String -> [Token] | |
tokenize [] = [] | |
tokenize (' ':xs) = tokenize xs | |
tokenize ('+':xs) = Plus : (tokenize xs) | |
tokenize ('-':xs) = Dash : (tokenize xs) | |
tokenize ('*':xs) = Star : (tokenize xs) | |
tokenize ('/':xs) = Slash : (tokenize xs) | |
tokenize s = Number (read s') : tokenize r | |
where s' = takeWhileIsDigit s | |
r = drop (length s') s | |
parse :: [Token] -> (Ast, [Token]) | |
parse [] = (Value 0, []) | |
parse ((Number n):xs) = (Value n, xs) | |
parse (op:xs) = (op' f s, xs'') | |
where (f, xs') = parse xs | |
(s, xs'') = parse xs' | |
op' = case op of | |
Plus -> Add | |
Dash -> Minus | |
Star -> Mult | |
Slash -> Div | |
evaluate :: Ast -> Integer | |
evaluate (Value v) = v | |
evaluate (Add left right) = (evaluate left) + (evaluate right) | |
evaluate (Minus left right) = (evaluate left) - (evaluate right) | |
evaluate (Mult left right) = (evaluate left) * (evaluate right) | |
evaluate (Div left right) = (evaluate left) `div` (evaluate right) | |
tokens :: [Token] | |
tokens = tokenize "+ 2 3" | |
ast :: Ast | |
ast = fst . parse $ tokens | |
mathInterpreter :: IO Integer | |
mathInterpreter = print . evaluate $ ast -- 5 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment