-
Notifications
You must be signed in to change notification settings - Fork 0
/
milho.ml
69 lines (62 loc) · 1.65 KB
/
milho.ml
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
let rec print_all_tokens scanner =
let token = Scanner.scan scanner in
token |> Token.to_string |> print_endline;
match token with
| Token.Eof -> ()
| _ -> print_all_tokens scanner
let make_ident size =
String.make size ' '
let rec string_of_expression ident exp =
make_ident ident ^
match exp with
| Reader.List xs ->
let interal_serialized_expression =
xs
|> List.map (string_of_expression (ident + 2))
|> String.concat "\n"
in
"(\n" ^ interal_serialized_expression ^ (make_ident ident) ^ ")\n"
| Reader.Number (n, d) ->
Printf.sprintf "%d/%d" n d
| Reader.String s ->
"\"" ^ s ^ "\""
| Reader.False ->
"False"
| Reader.True ->
"True"
| Reader.Nil ->
"Nil"
| Reader.Symbol s ->
"'" ^ s
| Reader.Quote e ->
"'" ^ string_of_expression ident e
| Reader.Eof ->
"\n"
let read_file channel =
let size = in_channel_length channel in
let buf = Bytes.create size in
really_input channel buf 0 size;
Bytes.unsafe_to_string buf
let run_file env name =
let rec loop_in_expressions scanner env =
let exp = Reader.read scanner in
try
exp
|> Runtime.stop_on_eof
|> Runtime.value_of_expression
|> Runtime.eval env
|> ignore;
loop_in_expressions scanner env
with
| Runtime.Stop_execution -> ()
in
let source = name |> open_in |> read_file in
let scanner = Scanner.init source in
loop_in_expressions scanner env
let () =
if (Array.length Sys.argv) < 2 then
print_endline "Need a file, example ./milho example.milho"
else
let env = Environment.init () in
run_file env "core.milho";
run_file env Sys.argv.(1)