Travis: add remaining implementations.
[jackhill/mal.git] / fsharp / step2_eval.fs
CommitLineData
8f1ee487
PS
1module REPL
2 open System
a71aefe1 3 open Node
52bc43ad 4 open Types
8f1ee487 5
52bc43ad
PS
6 let rec eval_ast env = function
7 | Symbol(sym) -> Env.get env sym
a71aefe1
PS
8 | List(_, lst) -> lst |> List.map (eval env) |> makeList
9 | Vector(_, seg) -> seg |> Seq.map (eval env) |> Array.ofSeq |> Node.ofArray
10 | Map(_, map) -> map |> Map.map (fun k v -> eval env v) |> makeMap
52bc43ad
PS
11 | node -> node
12
13 and eval env = function
a71aefe1 14 | List(_, _) as node ->
52bc43ad
PS
15 let resolved = node |> eval_ast env
16 match resolved with
a71aefe1 17 | List(_, BuiltInFunc(_, _, f)::rest) -> f rest
f0e1608b 18 | _ -> raise <| Error.errExpectedX "func"
52bc43ad
PS
19 | node -> node |> eval_ast env
20
21 let READ input =
8f1ee487
PS
22 try
23 Reader.read_str input
24 with
6d809e32 25 | Error.ReaderError(msg) ->
8f1ee487
PS
26 printfn "%s" msg
27 []
28
52bc43ad 29 let EVAL env ast =
8f1ee487 30 try
52bc43ad 31 Some(eval env ast)
8f1ee487 32 with
6d809e32
PS
33 | Error.EvalError(msg)
34 | Error.ReaderError(msg) ->
8f1ee487
PS
35 printfn "%s" msg
36 None
37
52bc43ad 38 let PRINT v =
8f1ee487 39 v
6a4627fb 40 |> Seq.singleton
8f1ee487
PS
41 |> Printer.pr_str
42 |> printfn "%s"
43
52bc43ad
PS
44 let REP env input =
45 READ input
8f1ee487 46 |> Seq.ofList
52bc43ad
PS
47 |> Seq.choose (fun form -> EVAL env form)
48 |> Seq.iter (fun value -> PRINT value)
8f1ee487 49
52c92124
PS
50 let getReadlineMode args =
51 if args |> Array.exists (fun e -> e = "--raw") then
8f1ee487
PS
52 Readline.Mode.Raw
53 else
54 Readline.Mode.Terminal
55
56 [<EntryPoint>]
57 let rec main args =
58 let mode = getReadlineMode args
37bb752e 59 let env = Env.makeRootEnv ()
8f1ee487
PS
60 match Readline.read "user> " mode with
61 | null -> 0
62 | input ->
52bc43ad 63 REP env input
8f1ee487 64 main args