1(*===----------------------------------------------------------------------===
2 * Top-Level parsing and JIT Driver
3 *===----------------------------------------------------------------------===*)
4
5open Llvm
6open Llvm_executionengine
7
8(* top ::= definition | external | expression | ';' *)
9let rec main_loop the_fpm the_execution_engine stream =
10  match Stream.peek stream with
11  | None -> ()
12
13  (* ignore top-level semicolons. *)
14  | Some (Token.Kwd ';') ->
15      Stream.junk stream;
16      main_loop the_fpm the_execution_engine stream
17
18  | Some token ->
19      begin
20        try match token with
21        | Token.Def ->
22            let e = Parser.parse_definition stream in
23            print_endline "parsed a function definition.";
24            dump_value (Codegen.codegen_func the_fpm e);
25        | Token.Extern ->
26            let e = Parser.parse_extern stream in
27            print_endline "parsed an extern.";
28            dump_value (Codegen.codegen_proto e);
29        | _ ->
30            (* Evaluate a top-level expression into an anonymous function. *)
31            let e = Parser.parse_toplevel stream in
32            print_endline "parsed a top-level expr";
33            let the_function = Codegen.codegen_func the_fpm e in
34            dump_value the_function;
35
36            (* JIT the function, returning a function pointer. *)
37            let result = ExecutionEngine.run_function the_function [||]
38              the_execution_engine in
39
40            print_string "Evaluated to ";
41            print_float (GenericValue.as_float Codegen.double_type result);
42            print_newline ();
43        with Stream.Error s | Codegen.Error s ->
44          (* Skip token for error recovery. *)
45          Stream.junk stream;
46          print_endline s;
47      end;
48      print_string "ready> "; flush stdout;
49      main_loop the_fpm the_execution_engine stream
50