17abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao(*===----------------------------------------------------------------------===
27abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao * Top-Level parsing and JIT Driver
37abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao *===----------------------------------------------------------------------===*)
47abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao
57abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liaoopen Llvm
67abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liaoopen Llvm_executionengine
77abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao
87abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao(* top ::= definition | external | expression | ';' *)
97abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liaolet rec main_loop the_fpm the_execution_engine stream =
107abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  match Stream.peek stream with
117abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  | None -> ()
127abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao
137abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  (* ignore top-level semicolons. *)
147abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  | Some (Token.Kwd ';') ->
157abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      Stream.junk stream;
167abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      main_loop the_fpm the_execution_engine stream
177abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao
187abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  | Some token ->
197abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      begin
207abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao        try match token with
217abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao        | Token.Def ->
227abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao            let e = Parser.parse_definition stream in
237abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao            print_endline "parsed a function definition.";
247abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao            dump_value (Codegen.codegen_func the_fpm e);
257abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao        | Token.Extern ->
267abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao            let e = Parser.parse_extern stream in
277abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao            print_endline "parsed an extern.";
287abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao            dump_value (Codegen.codegen_proto e);
297abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao        | _ ->
307abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao            (* Evaluate a top-level expression into an anonymous function. *)
317abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao            let e = Parser.parse_toplevel stream in
327abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao            print_endline "parsed a top-level expr";
337abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao            let the_function = Codegen.codegen_func the_fpm e in
347abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao            dump_value the_function;
357abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao
367abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao            (* JIT the function, returning a function pointer. *)
377abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao            let result = ExecutionEngine.run_function the_function [||]
387abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao              the_execution_engine in
397abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao
407abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao            print_string "Evaluated to ";
417abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao            print_float (GenericValue.as_float Codegen.double_type result);
427abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao            print_newline ();
437abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao        with Stream.Error s | Codegen.Error s ->
447abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao          (* Skip token for error recovery. *)
457abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao          Stream.junk stream;
467abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao          print_endline s;
477abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      end;
487abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      print_string "ready> "; flush stdout;
497abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      main_loop the_fpm the_execution_engine stream
50