-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcalc.hs
41 lines (30 loc) · 1.03 KB
/
calc.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import Data.Char
data Lexem = O Char | N Double
deriving (Show)
getNumber x = _getNumber x 0.0
_getNumber [] n = (n, [])
_getNumber l@(h:t) n
| h == '.' = _getNumber2 1 t n
| isDigit h = _getNumber t. (+) (digit h) $ 10 * n
| otherwise = (n, l)
_getNumber2 d [] n = (n/d, [])
_getNumber2 d l@(h:t) n
| isDigit h = _getNumber2 (d*10) t. (+) (digit h) $ 10 * n
| otherwise =(n, l)
digit = fromIntegral.digitToInt
recognize acc [] = acc
recognize acc l@(h:t)
| elem h "+-/*()" = recognize (O h: acc) t
| isDigit h = recognize (N (fst next) : acc) $ snd next
| otherwise = recognize acc t
where next = getNumber l
calc (x:acc) [] = (x,[])
calc acc (O ')':t) = calc (fst next:acc) (snd next)
where next = calc [] t
calc (x:acc) (O '(':t) = (x,t)
calc acc (N x:t) = calc (x:acc) t
calc (x:y:acc) (O '+':t) = calc (x+y:acc) t
calc (x:y:acc) (O '-':t) = calc (x-y:acc) t
calc (x:y:acc) (O '/':t) = calc (x/y:acc) t
calc (x:y:acc) (O '*':t) = calc (x*y:acc) t
calculate = fst.calc [].recognize []