This repository was archived by the owner on Feb 10, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathCalc.elm
More file actions
90 lines (67 loc) · 1.78 KB
/
Calc.elm
File metadata and controls
90 lines (67 loc) · 1.78 KB
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
module Calc exposing (calc)
{-| An example parser that computes arithmetic expressions.
To run this example, simply enter the examples and:
1. run `elm repl`
2. type in `import Calc exposing (calc)`
3. try out some expressions like `calc "22*2+(3+18)"`
@docs calc
-}
import Combine exposing (..)
import Combine.Num exposing (int)
addop : Parser s (Int -> Int -> Int)
addop =
choice
[ string "+" |> onsuccess (+)
, string "-" |> onsuccess (-)
]
mulop : Parser s (Int -> Int -> Int)
mulop =
choice
[ string "*" |> onsuccess (*)
, string "/" |> onsuccess (//)
]
expr : Parser s Int
expr =
let
go () =
chainl addop term
in
lazy go
term : Parser s Int
term =
let
go () =
chainl mulop factor
in
lazy go
factor : Parser s Int
factor =
whitespace
|> keep (or (parens expr) int)
|> ignore whitespace
{-| Compute the result of an expression.
import Calc exposing (calc)
calc "22*2+(3+18)"
-- Ok 65
calc "33 ** 12"
-- Err ("parse error: [ \"expected end of input\" ] , { data: 33 ** 12, input: ** 12, position: 3 }")
-}
calc : String -> Result String Int
calc s =
case parse (expr |> ignore end) s of
Ok ( _, _, n ) ->
Ok n
Err ( _, stream, ms ) ->
Err
("parse error: "
++ "[ \""
++ (ms |> List.intersperse "\", \"" |> String.concat)
++ "\" ] , "
++ "{ data: "
++ stream.data
++ ", input: "
++ stream.input
++ ", position: "
++ String.fromInt stream.position
++ " }"
)