1
1
mirror of https://github.com/kanaka/mal.git synced 2024-11-10 12:47:45 +03:00
mal/fsharp/step6_file.fs
2015-05-02 01:50:09 -05:00

83 lines
2.0 KiB
Forth

module REPL
open System
let read input =
try
Reader.read_str input
with
| Error.ReaderError(msg) ->
printfn "%s" msg
[]
let eval env ast =
try
Some(Eval.eval env ast)
with
| Error.EvalError(msg)
| Error.ReaderError(msg) ->
printfn "%s" msg
None
let print v =
v
|> Seq.singleton
|> Printer.pr_str
|> printfn "%s"
let re env input =
read input
|> Seq.ofList
|> Seq.choose (fun form -> eval env form)
let rep env input =
input
|> re env
|> Seq.iter (fun value -> print value)
let getReadlineMode args =
if args |> Array.exists (fun e -> e = "--raw") then
Readline.Mode.Raw
else
Readline.Mode.Terminal
let eval_func env = function
| [ast] -> Eval.eval env ast
| _ -> raise <| Error.wrongArity ()
let argv_func = function
| file::rest -> rest |> List.map Types.String |> Types.List
| [] -> Types.List([])
let configureEnv args =
let env = Env.makeRootEnv ()
Env.set env "eval" <| Env.makeBuiltInFunc (fun nodes -> eval_func env nodes)
Env.set env "*ARGV*" <| argv_func args
re env """
(def! not (fn* (a) (if a false true)))
(def! load-file (fn* (f) (eval (read-string (slurp f)))))
""" |> Seq.iter ignore
env
[<EntryPoint>]
let main args =
let mode = getReadlineMode args
let args = Seq.ofArray args |> Seq.filter (fun e -> e <> "--raw") |> List.ofSeq
let env = configureEnv args
match args with
| file::_ ->
System.IO.File.ReadAllText file
|> rep env
0
| _ ->
let rec loop () =
match Readline.read "user> " mode with
| null -> 0
| input ->
rep env input
loop ()
loop ()