ocaml-community / utop

Universal toplevel for OCaml
Other
846 stars 113 forks source link

Wrong handling of core sexplib syntax when pasting #46

Open yami-no-ryuu opened 10 years ago

yami-no-ryuu commented 10 years ago

When I am pasting a fragment with a default type flag utop gets confused about new lines and syntax extension fails with ."several default expressions are given". Default toplevel is unaffected.

Code in question:

open Core.Std;;

type http_server_config = { port: int with default(80); web_root: string; addr: string with default("localhost") } with sexp ;;

utop version 1.8 (using OCaml version 4.01.0) on Debian GNU/Linux testing (jessie/sid)

Both 1.7 and 1.8 are affected.

Example:

─( 03:00:00 )─< command 0 >─────────────────────────────{ counter: 0 }─ utop # type http_server_config = { port: int with default(80); web_root: string; Error: Failure: "several default expressions are given" ─( 23:17:08 )─< command 1 >─────────────────────────────{ counter: 0 }─ utop # addr: string with default("localhost") Error: Parse error: [str_item] or ";;" expected (in [top_phrase]) ─( 23:21:22 )─< command 2 >─────────────────────────────{ counter: 0 }─ utop # } with sexp ;; Error: Parse error: illegal begin of top_phrase ─( 23:21:22 )─< command 3 >─────────────────────────────{ counter: 0 }─ utop #

Meanwhile #use loads ok:

─( 23:21:22 )─< command 3 >────────────────────────────{ counter: 0 }─ utop # #use "a.ml";; type http_server_config = { port : int; web_root : string; addr : string; } val http_server_config_of_sexp : Sexp.t -> http_server_config = val sexp_of_http_server_config : http_server_config -> Sexp.t = ─( 23:21:27 )─< command 4 >────────────────────────────{ counter: 0 }─

Default toplevel is fine:

...
/home/ig/.opam/4.01.0/lib/core_bench/core_bench.cma: loaded
# open Core.Std;;

type http_server_config = {
port: int with default(80);
web_root: string;
addr: string with default("localhost")
} with sexp ;;
# type http_server_config = { port : int; web_root : string; addr : string; }
val __http_server_config_of_sexp__ : Sexplib.Sexp.t -> http_server_config =
<fun>
val http_server_config_of_sexp : Sexplib.Sexp.t -> http_server_config = <fun>
val sexp_of_http_server_config : http_server_config -> Sexplib.Sexp.t = <fun>
# 
ghost commented 10 years ago

OK, I got the problem, it is due to an implementation detail in pa_sexp_conv: it remembers the default value of a field using a hash table mapping locations to default values. So if the same expression is parsed twice it fails. The reason why it fails during copy/pasting is due to the way utop processes returns.

For example here is another strange behavior with utop:

# type t = { x : int with default(1) };;
type t = { x : int; }
# type t = { x : int with default(1) };;
Error: Failure: "several default expressions are given"
# type  t = { x : int with default(1) };;
type t = { x : int; }

It happens to work in the standard toplevel because it keeps advancing between new phrases while utop doesn't. I have to think of a way to workaround this oddities.

yami-no-ryuu commented 10 years ago

Yep, have looked into sources and realised it got to have to do with that accumulator map. Btw confirmed on 1.9 too :)

yami-no-ryuu commented 10 years ago

But the issue is pretty minor so worth to be docked for ttb as known issue I think