Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

toplevel to provide #use like command with #load semantics #3121

Closed
vicuna opened this issue Aug 29, 2004 · 1 comment
Closed

toplevel to provide #use like command with #load semantics #3121

vicuna opened this issue Aug 29, 2004 · 1 comment
Assignees

Comments

@vicuna
Copy link

vicuna commented Aug 29, 2004

Original bug ID: 3121
Reporter: administrator
Assigned to: @gasche
Status: closed (set by @xavierleroy on 2015-12-11T18:21:16Z)
Resolution: fixed
Priority: normal
Severity: feature
Fixed in version: 4.01.0+dev
Category: ~DO NOT USE (was: OCaml general)
Has duplicate: #5825

Bug 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 =

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.

@vicuna
Copy link
Author

vicuna commented Jul 29, 2013

Comment author: @gasche

This is implemented in trunk (future 4.01) by the #mod_use directive.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants