| Anonymous | Login | Signup for a new account | 2013-06-20 05:39 CEST | ![]() |
| Main | My View | View Issues | Change Log | Roadmap |
| View Issue Details [ Jump to Notes ] | [ Issue History ] [ Print ] | ||||||||||
| ID | Project | Category | View Status | Date Submitted | Last Update | ||||||
| 0003121 | OCaml | OCaml general | public | 2004-08-29 21:42 | 2004-10-06 11:32 | ||||||
| Reporter | administrator | ||||||||||
| Assigned To | |||||||||||
| Priority | normal | Severity | feature | Reproducibility | always | ||||||
| Status | acknowledged | Resolution | open | ||||||||
| Platform | OS | OS Version | |||||||||
| Product Version | |||||||||||
| Target Version | Fixed in Version | ||||||||||
| Summary | 0003121: toplevel to provide #use like command with #load semantics | ||||||||||
| Description | Full_Name: Vladimir Silyaev Version: 3.08 OS: FreeBSD/ Win32 Submission from: ip68-5-38-56.oc.oc.cox.net (68.5.38.56) O'Caml toplevel blesses with two essential commands: #load which loads compiled module in two the toplevel environment, as expected symbols are defined in module own namespace. #use which textually loads source module into the current envrionment, and, as expected, all symbols defined in the module are defined in the top namespace (_not_ as separate module). What would be nice it's to have command (e.g. #require) which loads source module and compiles it into it's own namespace. So #require "test.ml". would be indentical to #load "test.cmo". Implementation is rather trivial, content of test.ml should included into the brackets 'module Test = struct' ... 'end' . There is a transcript of session with toplevel modified to support #require command. -=-=-=-=-=-=-=- >cat >hello.ml let world () = print_endline "Hello.world" ^D >ocamlc hello.ml >ocaml > ./ocaml Objective Caml version 3.09+dev1 (2004-08-21) Objective Caml version 3.09+dev1 (2004-08-21) # #use "hello.ml";; val world : unit -> unit = <fun> # Hello.world ();; Reference to undefined global `Hello' # #load "hello.cmo";; # Hello.world();; Hello.world - : unit = () # #require "hello.ml";; module Hello : sig val world : unit -> unit end # Hello.world ();; Hello.world - : unit = () # -=-=-=-=-=-=-=- Note #require is more suitable for interactive development, #load only to reload module if interface remains the same, #require doesn't limited by such constraints. Below is a patch against CVS version: Index: toplevel/topdirs.ml =================================================================== RCS file: /caml/ocaml/toplevel/topdirs.ml,v retrieving revision 1.63 diff -u -r1.63 topdirs.ml --- toplevel/topdirs.ml 2004/07/13 12:25:18 1.63 +++ toplevel/topdirs.ml 2004/08/29 19:18:42 @@ -133,6 +133,11 @@ let _ = Hashtbl.add directive_table "use" (Directive_string (dir_use std_out)) +let dir_require ppf name = ignore(Toploop.require_file ppf name) + +let _ = Hashtbl.add directive_table "require" (Directive_string (dir_require std_out)) + + (* Install, remove a printer *) type 'a printer_type_new = Format.formatter -> 'a -> unit Index: toplevel/toploop.ml =================================================================== RCS file: /caml/ocaml/toplevel/toploop.ml,v retrieving revision 1.87 diff -u -r1.87 toploop.ml --- toplevel/toploop.ml 2004/06/12 08:55:47 1.87 +++ toplevel/toploop.ml 2004/08/29 19:18:45 @@ -280,17 +280,13 @@ raise x (* Read and execute commands from a file *) - let use_print_results = ref true -let use_file ppf name = +let use_source make_lexer 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 lb = make_lexer ic filename name in let success = protect Location.input_name filename (fun () -> try @@ -307,6 +303,50 @@ close_in ic; success with Not_found -> fprintf ppf "Cannot find file %s.@." name; false + +let use_file_lexer ic filename name = + let lb = Lexing.from_channel ic in + Location.init lb filename; + (* skip initial #! line if any *) + Lexer.skip_sharp_bang lb; + lb + +let use_file = use_source use_file_lexer + +let require_file_lexer ic filename name = + let prolog = "module " + ^ (String.capitalize (Filename.chop_extension name)) + ^ " = struct\n" + and epilog = "\n end" in + let lexing_str str next = + let pos = ref 0 in + let lexing buf n = + if !pos >= (String.length str) then next buf n + else begin + let n = min n ((String.length str) - !pos) in + String.blit str !pos buf 0 n; + pos := !pos + n; + n + end in + lexing + and lexing_file ic next = + let lexing buf n = + match input ic buf 0 n with + 0 -> next buf n + | n -> + n + in lexing + and eof _ _ = 0 in + let lexing = + lexing_str prolog (lexing_file ic (lexing_str epilog eof)) in + + let lb = Lexing.from_function lexing in + Location.init lb filename; + lb.Lexing.lex_curr_p <- {lb.Lexing.lex_curr_p with Lexing.pos_lnum = 0}; + lb + + +let require_file = use_source require_file_lexer let use_silently ppf name = protect use_print_results false (fun () -> use_file ppf name) Index: toplevel/toploop.mli =================================================================== RCS file: /caml/ocaml/toplevel/toploop.mli,v retrieving revision 1.25 diff -u -r1.25 toploop.mli --- toplevel/toploop.mli 2004/05/15 09:59:37 1.25 +++ toplevel/toploop.mli 2004/08/29 19:18:46 @@ -56,6 +56,7 @@ First bool says whether the values and types of the results should be printed. Uncaught exceptions are always printed. *) val use_file : formatter -> string -> bool +val require_file : formatter -> string -> bool val use_silently : formatter -> string -> bool (* Read and execute commands from a file. [use_file] prints the types and values of the results. | ||||||||||
| Tags | No tags attached. | ||||||||||
| Attached Files | |||||||||||
Issue History |
|||
| Date Modified | Username | Field | Change |
| 2005-11-18 10:13 | administrator | New Issue | |
| Copyright © 2000 - 2011 MantisBT Group |