summaryrefslogtreecommitdiff
path: root/toplevel/toploop.ml
diff options
context:
space:
mode:
Diffstat (limited to 'toplevel/toploop.ml')
-rw-r--r--toplevel/toploop.ml409
1 files changed, 0 insertions, 409 deletions
diff --git a/toplevel/toploop.ml b/toplevel/toploop.ml
deleted file mode 100644
index c50dbcbd97..0000000000
--- a/toplevel/toploop.ml
+++ /dev/null
@@ -1,409 +0,0 @@
-(***********************************************************************)
-(* *)
-(* Objective Caml *)
-(* *)
-(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
-(* *)
-(* Copyright 1996 Institut National de Recherche en Informatique et *)
-(* en Automatique. All rights reserved. This file is distributed *)
-(* under the terms of the Q Public License version 1.0. *)
-(* *)
-(***********************************************************************)
-
-(* $Id$ *)
-
-(* The interactive toplevel loop *)
-
-open Path
-open Lexing
-open Format
-open Config
-open Misc
-open Parsetree
-open Types
-open Typedtree
-open Outcometree
-
-type directive_fun =
- | Directive_none of (unit -> unit)
- | Directive_string of (string -> unit)
- | Directive_int of (int -> unit)
- | Directive_ident of (Longident.t -> unit)
- | Directive_bool of (bool -> unit)
-
-(* The table of toplevel value bindings and its accessors *)
-
-let toplevel_value_bindings =
- (Hashtbl.create 37 : (string, Obj.t) Hashtbl.t)
-
-let getvalue name =
- try
- Hashtbl.find toplevel_value_bindings name
- with Not_found ->
- fatal_error (name ^ " unbound at toplevel")
-
-let setvalue name v =
- Hashtbl.replace toplevel_value_bindings name v
-
-(* Return the value referred to by a path *)
-
-let rec eval_path = function
- | Pident id ->
- if Ident.persistent id || Ident.global id then
- Symtable.get_global_value id
- else begin
- let name = Ident.name id in
- try
- Hashtbl.find toplevel_value_bindings name
- with Not_found ->
- raise (Symtable.Error(Symtable.Undefined_global name))
- end
- | Pdot(p, s, pos) ->
- Obj.field (eval_path p) pos
- | Papply(p1, p2) ->
- fatal_error "Toploop.eval_path"
-
-(* To print values *)
-
-module EvalPath = struct
- type value = Obj.t
- exception Error
- let eval_path p = try eval_path p with Symtable.Error _ -> raise Error
- let same_value v1 v2 = (v1 == v2)
-end
-
-module Printer = Genprintval.Make(Obj)(EvalPath)
-
-let max_printer_depth = ref 100
-let max_printer_steps = ref 300
-
-let print_out_value = Oprint.out_value
-let print_out_type = Oprint.out_type
-let print_out_class_type = Oprint.out_class_type
-let print_out_module_type = Oprint.out_module_type
-let print_out_sig_item = Oprint.out_sig_item
-let print_out_signature = Oprint.out_signature
-let print_out_phrase = Oprint.out_phrase
-
-let print_untyped_exception ppf obj =
- !print_out_value ppf (Printer.outval_of_untyped_exception obj)
-let outval_of_value env obj ty =
- Printer.outval_of_value !max_printer_steps !max_printer_depth
- (fun _ _ _ -> None) env obj ty
-let print_value env obj ppf ty =
- !print_out_value ppf (outval_of_value env obj ty)
-
-let install_printer = Printer.install_printer
-let remove_printer = Printer.remove_printer
-
-(* Hooks for parsing functions *)
-
-let parse_toplevel_phrase = ref Parse.toplevel_phrase
-let parse_use_file = ref Parse.use_file
-let print_location = Location.print
-let print_warning = Location.print_warning
-let input_name = Location.input_name
-
-(* Hooks for initialization *)
-
-let toplevel_startup_hook = ref (fun () -> ())
-
-(* Load in-core and execute a lambda term *)
-
-let may_trace = ref false (* Global lock on tracing *)
-type evaluation_outcome = Result of Obj.t | Exception of exn
-
-let load_lambda ppf lam =
- if !Clflags.dump_rawlambda then fprintf ppf "%a@." Printlambda.lambda lam;
- let slam = Simplif.simplify_lambda lam in
- if !Clflags.dump_lambda then fprintf ppf "%a@." Printlambda.lambda slam;
- let (init_code, fun_code) = Bytegen.compile_phrase slam in
- if !Clflags.dump_instr then
- fprintf ppf "%a%a@."
- Printinstr.instrlist init_code
- Printinstr.instrlist fun_code;
- let (code, code_size, reloc) = Emitcode.to_memory init_code fun_code in
- let can_free = (fun_code = []) in
- let initial_symtable = Symtable.current_state() in
- Symtable.patch_object code reloc;
- Symtable.check_global_initialized reloc;
- Symtable.update_global_table();
- try
- may_trace := true;
- let retval = (Meta.reify_bytecode code code_size) () in
- may_trace := false;
- if can_free then Meta.static_free code;
- Result retval
- with x ->
- may_trace := false;
- if can_free then Meta.static_free code;
- Symtable.restore_state initial_symtable;
- Exception x
-
-(* Print the outcome of an evaluation *)
-
-let pr_item env = function
- | Tsig_value(id, decl) :: rem ->
- let tree = Printtyp.tree_of_value_description id decl in
- let valopt =
- match decl.val_kind with
- | Val_prim _ -> None
- | _ ->
- let v =
- outval_of_value env (getvalue (Translmod.toplevel_name id))
- decl.val_type
- in
- Some v
- in
- Some (tree, valopt, rem)
- | Tsig_type(id, decl) :: rem ->
- let tree = Printtyp.tree_of_type_declaration id decl in
- Some (tree, None, rem)
- | Tsig_exception(id, decl) :: rem ->
- let tree = Printtyp.tree_of_exception_declaration id decl in
- Some (tree, None, rem)
- | Tsig_module(id, mty) :: rem ->
- let tree = Printtyp.tree_of_module id mty in
- Some (tree, None, rem)
- | Tsig_modtype(id, decl) :: rem ->
- let tree = Printtyp.tree_of_modtype_declaration id decl in
- Some (tree, None, rem)
- | Tsig_class(id, decl) :: cltydecl :: tydecl1 :: tydecl2 :: rem ->
- let tree = Printtyp.tree_of_class_declaration id decl in
- Some (tree, None, rem)
- | Tsig_cltype(id, decl) :: tydecl1 :: tydecl2 :: rem ->
- let tree = Printtyp.tree_of_cltype_declaration id decl in
- Some (tree, None, rem)
- | _ -> None
-
-let rec item_list env = function
- | [] -> []
- | items ->
- match pr_item env items with
- | None -> []
- | Some (tree, valopt, items) -> (tree, valopt) :: item_list env items
-
-(* The current typing environment for the toplevel *)
-
-let toplevel_env = ref Env.empty
-
-(* Print an exception produced by an evaluation *)
-
-let print_out_exception ppf exn outv =
- !print_out_phrase ppf (Ophr_exception (exn, outv))
-
-let print_exception_outcome ppf exn =
- if exn = Out_of_memory then Gc.full_major ();
- let outv = outval_of_value !toplevel_env (Obj.repr exn) Predef.type_exn in
- print_out_exception ppf exn outv
-
-(* The table of toplevel directives.
- Filled by functions from module topdirs. *)
-
-let directive_table = (Hashtbl.create 13 : (string, directive_fun) Hashtbl.t)
-
-(* Execute a toplevel phrase *)
-
-let execute_phrase print_outcome ppf phr =
- match phr with
- | Ptop_def sstr ->
- let oldenv = !toplevel_env in
- Typecore.reset_delayed_checks ();
- let (str, sg, newenv) = Typemod.type_structure oldenv sstr in
- Typecore.force_delayed_checks ();
- let lam = Translmod.transl_toplevel_definition str in
- Warnings.check_fatal ();
- begin try
- toplevel_env := newenv;
- let res = load_lambda ppf lam in
- let out_phr =
- match res with
- | Result v ->
- if print_outcome then
- match str with
- | [Tstr_eval exp] ->
- let outv = outval_of_value newenv v exp.exp_type in
- let ty = Printtyp.tree_of_type_scheme exp.exp_type in
- Ophr_eval (outv, ty)
- | [] -> Ophr_signature []
- | _ -> Ophr_signature (item_list newenv
- (Typemod.simplify_signature sg))
- else Ophr_signature []
- | Exception exn ->
- toplevel_env := oldenv;
- if exn = Out_of_memory then Gc.full_major();
- let outv =
- outval_of_value !toplevel_env (Obj.repr exn) Predef.type_exn
- in
- Ophr_exception (exn, outv)
- in
- !print_out_phrase ppf out_phr;
- begin match out_phr with
- | Ophr_eval (_, _) | Ophr_signature _ -> true
- | Ophr_exception _ -> false
- end
- with x ->
- toplevel_env := oldenv; raise x
- end
- | Ptop_dir(dir_name, dir_arg) ->
- try
- match (Hashtbl.find directive_table dir_name, dir_arg) with
- | (Directive_none f, Pdir_none) -> f (); true
- | (Directive_string f, Pdir_string s) -> f s; true
- | (Directive_int f, Pdir_int n) -> f n; true
- | (Directive_ident f, Pdir_ident lid) -> f lid; true
- | (Directive_bool f, Pdir_bool b) -> f b; true
- | (_, _) ->
- fprintf ppf "Wrong type of argument for directive `%s'.@." dir_name;
- false
- with Not_found ->
- fprintf ppf "Unknown directive `%s'.@." dir_name;
- false
-
-(* Temporary assignment to a reference *)
-
-let protect r newval body =
- let oldval = !r in
- try
- r := newval;
- let res = body() in
- r := oldval;
- res
- with x ->
- r := oldval;
- raise x
-
-(* Read and execute commands from a file *)
-
-let use_print_results = ref true
-
-let use_file ppf name =
- try
- let filename = find_in_path !Config.load_path name in
- let ic = open_in_bin filename in
- let lb = Lexing.from_channel ic in
- Location.init lb filename;
- (* Skip initial #! line if any *)
- Lexer.skip_sharp_bang lb;
- let success =
- protect Location.input_name filename (fun () ->
- try
- List.iter
- (fun ph ->
- if !Clflags.dump_parsetree then Printast.top_phrase ppf ph;
- if not (execute_phrase !use_print_results ppf ph) then raise Exit)
- (!parse_use_file lb);
- true
- with
- | Exit -> false
- | Sys.Break -> fprintf ppf "Interrupted.@."; false
- | x -> Errors.report_error ppf x; false) in
- close_in ic;
- success
- with Not_found -> fprintf ppf "Cannot find file %s.@." name; false
-
-let use_silently ppf name =
- protect use_print_results false (fun () -> use_file ppf name)
-
-(* Reading function for interactive use *)
-
-let first_line = ref true
-let got_eof = ref false;;
-
-let refill_lexbuf buffer len =
- if !got_eof then (got_eof := false; 0) else begin
- let prompt =
- if !first_line then "# "
- else if Lexer.in_comment () then "* "
- else " "
- in
- output_string stdout prompt; flush stdout;
- first_line := false;
- let i = ref 0 in
- try
- while true do
- if !i >= len then raise Exit;
- let c = input_char stdin in
- buffer.[!i] <- c;
- incr i;
- if c = '\n' then raise Exit;
- done;
- !i
- with
- | End_of_file ->
- Location.echo_eof ();
- if !i > 0 then (got_eof := true; !i) else 0
- | Exit -> !i
- end
-
-(* Toplevel initialization. Performed here instead of at the
- beginning of loop() so that user code linked in with ocamlmktop
- can call directives from Topdirs. *)
-
-let _ =
- Sys.interactive := true;
- let crc_intfs = Symtable.init_toplevel() in
- Compile.init_path();
- List.iter
- (fun (name, crc) ->
- Consistbl.set Env.crc_units name crc Sys.executable_name)
- crc_intfs
-
-let load_ocamlinit ppf =
- let home_init =
- try Filename.concat (Sys.getenv "HOME") ".ocamlinit"
- with Not_found -> ".ocamlinit" in
- if Sys.file_exists ".ocamlinit" then ignore(use_silently ppf ".ocamlinit")
- else if Sys.file_exists home_init then ignore(use_silently ppf home_init)
-
-let set_paths () =
- (* Add whatever -I options have been specified on the command line,
- but keep the directories that user code linked in with ocamlmktop
- may have added to load_path. *)
- load_path := !load_path @ [Filename.concat Config.standard_library "camlp4"];
- load_path := "" :: (List.rev !Clflags.include_dirs @ !load_path);
- Dll.add_path !load_path
-
-let initialize_toplevel_env () =
- toplevel_env := Compile.initial_env()
-
-(* The interactive loop *)
-
-exception PPerror
-
-let loop ppf =
- fprintf ppf " Objective Caml version %s@.@." Config.version;
- initialize_toplevel_env ();
- let lb = Lexing.from_function refill_lexbuf in
- Location.input_name := "";
- Location.input_lexbuf := Some lb;
- Sys.catch_break true;
- load_ocamlinit ppf;
- while true do
- let snap = Btype.snapshot () in
- try
- Lexing.flush_input lb;
- Location.reset();
- first_line := true;
- let phr = try !parse_toplevel_phrase lb with Exit -> raise PPerror in
- if !Clflags.dump_parsetree then Printast.top_phrase ppf phr;
- ignore(execute_phrase true ppf phr)
- with
- | End_of_file -> exit 0
- | Sys.Break -> fprintf ppf "Interrupted.@."; Btype.backtrack snap
- | PPerror -> ()
- | x -> Errors.report_error ppf x; Btype.backtrack snap
- done
-
-(* Execute a script *)
-
-let run_script ppf name args =
- let len = Array.length args in
- if Array.length Sys.argv < len then invalid_arg "Toploop.run_script";
- Array.blit args 0 Sys.argv 0 len;
- Obj.truncate (Obj.repr Sys.argv) len;
- Arg.current := 0;
- Compile.init_path();
- toplevel_env := Compile.initial_env();
- Sys.interactive := false;
- use_silently ppf name