Able to compile some files, but still crashing because of labels

This commit is contained in:
Ekdohibs 2018-09-23 12:13:03 +02:00
parent a6852d25f2
commit f72d23fe36
2 changed files with 257 additions and 102 deletions

1
.merlin Normal file
View File

@ -0,0 +1 @@
PKG compiler-libs.common

352
interp.ml
View File

@ -12,7 +12,7 @@ type value =
| String of bytes
| Float of float
| Tuple of value list
| Constructor of string * value option
| Constructor of string * int * value option
| Prim of (value -> value)
| ModVal of mdl
| InChannel of in_channel
@ -37,8 +37,8 @@ let rec pp_print_value ff = function
| String s -> Format.fprintf ff "%S" (Bytes.to_string s)
| Float f -> Format.fprintf ff "%f" f
| Tuple l -> Format.fprintf ff "(%a)" (Format.pp_print_list ~pp_sep:(fun ff () -> Format.fprintf ff ", ") pp_print_value) l
| Constructor (c, None) -> Format.fprintf ff "%s" c
| Constructor (c, Some v) -> Format.fprintf ff "%s %a" c pp_print_value v
| Constructor (c, d, None) -> Format.fprintf ff "%s#%d" c d
| Constructor (c, d, Some v) -> Format.fprintf ff "%s#%d %a" c d pp_print_value v
| ModVal _ -> Format.fprintf ff "<module>"
| InChannel _ -> Format.fprintf ff "<in_channel>"
| OutChannel _ -> Format.fprintf ff "<out_channel>"
@ -46,21 +46,28 @@ let rec pp_print_value ff = function
| Array a -> Format.fprintf ff "[|%a|]" (Format.pp_print_list ~pp_sep:(fun ff () -> Format.fprintf ff "; ") pp_print_value) (Array.to_list a)
let read_caml_int s =
let c = ref 0 in
let sign = if s.[0] = '-' then -1 else 1 in
let init = if s.[0] = '-' then 1 else 0 in
let c = ref 0L in
let sign, init = if String.length s > 0 && s.[0] = '-' then (-1L, 1) else (1L, 0) in
let base, init =
if String.length s >= init + 2 && s.[init] = '0' then
((match s.[init + 1] with 'x' | 'X' -> 16L | 'b' | 'B' -> 2L | 'o' | 'O' -> 8L | _ -> assert false), init + 2)
else
(10L, init)
in
for i = init to String.length s - 1 do
match s.[i] with
| '0'..'9' as x -> c := 10 * !c + int_of_char x - int_of_char '0'
| '0'..'9' as x -> c := Int64.(add (mul base !c) (of_int (int_of_char x - int_of_char '0')))
| 'a'..'f' as x -> c := Int64.(add (mul base !c) (of_int (int_of_char x - int_of_char 'a' + 10)))
| 'A'..'F' as x -> c := Int64.(add (mul base !c) (of_int (int_of_char x - int_of_char 'A' + 10)))
| '_' -> ()
| _ -> Format.eprintf "FIXME literal: %s@." s
| _ -> Format.eprintf "FIXME literal: %s@." s; assert false
done;
sign * !c
Int64.mul sign !c
let value_of_constant = function
| Pconst_integer (s, None) -> Int (read_caml_int s)
| Pconst_integer (s, Some 'L') -> Int64 (Int64.of_int (read_caml_int s))
| Pconst_integer (s, Some _) -> Int (read_caml_int s)
| Pconst_integer (s, (None | Some 'l')) -> Int (Int64.to_int (read_caml_int s))
| Pconst_integer (s, Some ('L' | 'n')) -> Int64 (read_caml_int s)
| Pconst_integer (s, Some c) -> Format.eprintf "Unsupported suffix %c@." c; assert false
| Pconst_char c -> Int (int_of_char c)
| Pconst_float _ -> Float (1.)
| Pconst_string (s, _) -> String (Bytes.of_string s)
@ -78,8 +85,9 @@ let rec value_equal v1 v2 =
| Int64 n1, Int64 n2 -> n1 = n2
| Float f1, Float f2 -> f1 = f2
| String s1, String s2 -> s1 = s2
| Constructor (c1, None), Constructor (c2, None) -> c1 = c2
| Constructor (c1, Some v1), Constructor (c2, Some v2) -> c1 = c2 && value_equal v1 v2
| Constructor (c1, d1, None), Constructor (c2, d2, None) -> d1 = d2 && c1 = c2
| Constructor (c1, d1, Some v1), Constructor (c2, d2, Some v2) -> d1 = d2 && c1 = c2 && value_equal v1 v2
| Constructor _, Constructor _ -> false
| Tuple l1, Tuple l2 -> assert (List.length l1 = List.length l2); List.for_all2 value_equal l1 l2
| Record r1, Record r2 ->
SMap.for_all (fun _ b -> b) (SMap.merge (fun _ u v -> match u, v with None, None -> None | None, Some _ | Some _, None -> Some false | Some u, Some v -> Some (value_equal !u !v)) r1 r2)
@ -98,8 +106,10 @@ let rec value_compare v1 v2 =
| Int64 n1, Int64 n2 -> compare n1 n2
| Float f1, Float f2 -> compare f1 f2
| String s1, String s2 -> compare s1 s2
| Constructor (c1, vv1), Constructor (c2, vv2) ->
let c = compare c1 c2 in
| Constructor (_, _, None), Constructor (_, _, Some _) -> -1
| Constructor (_, _, Some _), Constructor (_, _, None) -> 1
| Constructor (c1, d1, vv1), Constructor (c2, d2, vv2) ->
let c = compare (d1, c1) (d2, c2) in
if c <> 0 then c else begin
match vv1, vv2 with
| None, None -> 0
@ -121,8 +131,8 @@ let value_ge v1 v2 = value_compare v1 v2 >= 0
exception Match_fail
let is_true = function
| Constructor ("true", None) -> true
| Constructor ("false", None) -> false
| Constructor ("true", _, None) -> true
| Constructor ("false", _, None) -> false
| _ -> assert false
let rec lident_name = function
@ -130,7 +140,7 @@ let rec lident_name = function
| Longident.Ldot (_, s) -> s
| Longident.Lapply (l1, l2) -> lident_name l2
let unit = Constructor ("()", None)
let unit = Constructor ("()", 0, None)
let set_env env = function
| Fun (_, _, _, _, ev) | Function (_, ev) -> ev := env
@ -220,7 +230,7 @@ let rec seeded_hash_param meaningful total seed = function
| Float f -> Hashtbl.seeded_hash seed f
| Tuple l -> 0
| String s -> Hashtbl.seeded_hash seed (Bytes.to_string s)
| Constructor (c, v) -> Hashtbl.seeded_hash seed c
| Constructor (c, _, v) -> Hashtbl.seeded_hash seed c
| Array a -> 0
| Record r -> 0
| Fun _ | Function _ | SeqOr | SeqAnd | InChannel _ | OutChannel _ | Prim _ | Lz _ | ModVal _-> assert false
@ -241,10 +251,10 @@ let wrap_float f = Float f
let unwrap_float v = match v with Float f -> f | _ -> assert false
let unwrap_bool = is_true
let wrap_bool b = if b then Constructor ("true", None) else Constructor ("false", None)
let wrap_bool b = if b then Constructor ("true", 1, None) else Constructor ("false", 0, None)
let wrap_unit () = unit
let unwrap_unit = function Constructor ("()", None) -> () | _ -> assert false
let unwrap_unit = function Constructor ("()", _, None) -> () | _ -> assert false
let wrap_bytes s = String s
let unwrap_bytes = function String s -> s | _ -> assert false
@ -268,35 +278,35 @@ let unwrap_in_channel = function InChannel ic -> ic | _ -> assert false
let wrap_out_channel oc = OutChannel oc
let unwrap_out_channel = function OutChannel oc -> oc | _ -> assert false
let cc x = Constructor (x, None)
let cc x d = Constructor (x, d, None)
let wrap_open_flag = function
| Open_rdonly -> cc "Open_rdonly"
| Open_wronly -> cc "Open_wronly"
| Open_append -> cc "Open_append"
| Open_creat -> cc "Open_creat"
| Open_trunc -> cc "Open_trunc"
| Open_excl -> cc "Open_excl"
| Open_binary -> cc "Open_binary"
| Open_text -> cc "Open_text"
| Open_nonblock -> cc "Open_nonblock"
| Open_rdonly -> cc "Open_rdonly" 0
| Open_wronly -> cc "Open_wronly" 1
| Open_append -> cc "Open_append" 2
| Open_creat -> cc "Open_creat" 3
| Open_trunc -> cc "Open_trunc" 4
| Open_excl -> cc "Open_excl" 5
| Open_binary -> cc "Open_binary" 6
| Open_text -> cc "Open_text" 7
| Open_nonblock -> cc "Open_nonblock" 8
let unwrap_open_flag = function
| Constructor ("Open_rdonly", None) -> Open_rdonly
| Constructor ("Open_wronly", None) -> Open_wronly
| Constructor ("Open_append", None) -> Open_append
| Constructor ("Open_creat", None) -> Open_creat
| Constructor ("Open_trunc", None) -> Open_trunc
| Constructor ("Open_excl", None) -> Open_excl
| Constructor ("Open_binary", None) -> Open_binary
| Constructor ("Open_text", None) -> Open_text
| Constructor ("Open_nonblock", None) -> Open_nonblock
| Constructor ("Open_rdonly", _, None) -> Open_rdonly
| Constructor ("Open_wronly", _, None) -> Open_wronly
| Constructor ("Open_append", _, None) -> Open_append
| Constructor ("Open_creat", _, None) -> Open_creat
| Constructor ("Open_trunc", _, None) -> Open_trunc
| Constructor ("Open_excl", _, None) -> Open_excl
| Constructor ("Open_binary", _, None) -> Open_binary
| Constructor ("Open_text", _, None) -> Open_text
| Constructor ("Open_nonblock", _, None) -> Open_nonblock
| _ -> assert false
let rec wrap_list wrapf = function
| [] -> cc "[]"
| x :: l -> Constructor ("::", Some (Tuple [wrapf x; wrap_list wrapf l]))
| [] -> cc "[]" 0
| x :: l -> Constructor ("::", 0, Some (Tuple [wrapf x; wrap_list wrapf l]))
let rec unwrap_list unwrapf = function
| Constructor ("[]", None) -> []
| Constructor ("::", Some (Tuple [x; l])) -> unwrapf x :: unwrap_list unwrapf l
| Constructor ("[]", _, None) -> []
| Constructor ("::", _, Some (Tuple [x; l])) -> unwrapf x :: unwrap_list unwrapf l
| _ -> assert false
external open_descriptor_out : int -> out_channel = "caml_ml_open_descriptor_out"
@ -308,7 +318,11 @@ external unsafe_output : out_channel -> bytes -> int -> int -> unit = "caml_ml_o
external unsafe_output_string : out_channel -> string -> int -> int -> unit = "caml_ml_output"
external set_in_channel_name: in_channel -> string -> unit = "caml_ml_set_channel_name"
external unsafe_input : in_channel -> bytes -> int -> int -> int = "caml_ml_input"
external format_int : string -> int -> string = "caml_format_int"
external format_float : string -> float -> string = "caml_format_float"
external random_seed : unit -> int array = "caml_sys_random_seed"
external digest_unsafe_string : string -> int -> int -> string = "caml_md5_string"
external marshal_to_channel : out_channel -> 'a -> unit list -> unit = "caml_output_value"
let unwrap_position = function
| Record r -> Lexing.{
@ -372,12 +386,12 @@ type parser_input =
| Error_detected
let unwrap_parser_input = function
| Constructor ("Start", None) -> Start
| Constructor ("Token_read", None) -> Token_read
| Constructor ("Stacks_grown_1", None) -> Stacks_grown_1
| Constructor ("Stacks_grown_2", None) -> Stacks_grown_2
| Constructor ("Semantic_action_computed", None) -> Semantic_action_computed
| Constructor ("Error_detected", None) -> Error_detected
| Constructor ("Start", _, None) -> Start
| Constructor ("Token_read", _, None) -> Token_read
| Constructor ("Stacks_grown_1", _, None) -> Stacks_grown_1
| Constructor ("Stacks_grown_2", _, None) -> Stacks_grown_2
| Constructor ("Semantic_action_computed", _, None) -> Semantic_action_computed
| Constructor ("Error_detected", _, None) -> Error_detected
| _ -> assert false
type parser_output =
@ -389,12 +403,12 @@ type parser_output =
| Call_error_function
let wrap_parser_output = function
| Read_token -> cc "Read_token"
| Raise_parse_error -> cc "Raise_parse_error"
| Grow_stacks_1 -> cc "Grow_stacks_1"
| Grow_stacks_2 -> cc "Grow_stacks_2"
| Compute_semantic_action -> cc "Compute_semantic_action"
| Call_error_function -> cc "Call_error_function"
| Read_token -> cc "Read_token" 0
| Raise_parse_error -> cc "Raise_parse_error" 1
| Grow_stacks_1 -> cc "Grow_stacks_1" 2
| Grow_stacks_2 -> cc "Grow_stacks_2" 3
| Compute_semantic_action -> cc "Compute_semantic_action" 4
| Call_error_function -> cc "Call_error_function" 5
let apply_ref = ref (fun _ _ -> assert false)
@ -476,12 +490,11 @@ let parse_engine_wrapper tables env input token =
let obj =
if input = Semantic_action_computed then Obj.repr token else
match token with
| Constructor (c, None) ->
if c = "()" then Obj.repr 0 else
Obj.repr (env_get_constr !cur_env (Longident.Lident c))
| Constructor (c, Some arg) ->
| Constructor (c, d, None) ->
Obj.repr d
| Constructor (c, d, Some arg) ->
let w = Obj.repr (Some arg) in
Obj.set_tag w (env_get_constr !cur_env (Longident.Lident c));
Obj.set_tag w d;
w
| _ -> assert false
in
@ -564,6 +577,30 @@ let parse_engine_prim = prim4 parse_engine_wrapper id id unwrap_parser_input id
let lex_engine_prim = prim3 lex_engine_wrapper id unwrap_int id wrap_int
let new_lex_engine_prim = prim3 new_lex_engine_wrapper id unwrap_int id wrap_int
let initial_env = ref (empty_env : env)
let exn_id = ref 0
let declare_builtin_constructor name d =
initial_env := env_set_constr name d !initial_env
let declare_exn name =
let d = !exn_id in
incr exn_id;
declare_builtin_constructor name d
let not_found_exn_id = declare_exn "Not_found"
let not_found_exn = Constructor ("Not_found", 0, None)
let _ = declare_exn "Exit"
let _ = declare_exn "Invalid_argument"
let _ = declare_exn "Failure"
let _ = declare_exn "Match_failure"
let _ = declare_exn "Assert_failure"
let _ = declare_builtin_constructor "false" 0
let _ = declare_builtin_constructor "true" 1
let _ = declare_builtin_constructor "None" 0
let _ = declare_builtin_constructor "Some" 0
let _ = declare_builtin_constructor "[]" 0
let _ = declare_builtin_constructor "::" 0
let _ = declare_builtin_constructor "()" 0
let prims = [
("%apply", Prim (fun vf -> Prim (fun v -> !apply_ref vf [(Nolabel, v)])));
@ -623,6 +660,11 @@ let prims = [
("%incr", Prim (function | Record r -> let z = SMap.find "contents" r in z := wrap_int (unwrap_int !z + 1); unit | _ -> assert false));
("%decr", Prim (function | Record r -> let z = SMap.find "contents" r in z := wrap_int (unwrap_int !z - 1); unit | _ -> assert false));
("%ignore", Prim (fun _ -> unit));
("caml_format_int", prim2 format_int unwrap_string unwrap_int wrap_string);
("caml_format_float", prim2 format_float unwrap_string unwrap_float wrap_string);
("caml_int_of_string", prim1 int_of_string unwrap_string wrap_int);
("caml_output_value", prim3 marshal_to_channel unwrap_out_channel id (unwrap_list unwrap_unit) wrap_unit);
("caml_input_value", prim1 input_value unwrap_in_channel id);
("caml_sys_exit", prim1 exit unwrap_int wrap_unit);
("caml_parse_engine", parse_engine_prim);
("caml_lex_engine", lex_engine_prim);
@ -630,16 +672,19 @@ let prims = [
(* Sys *)
("caml_sys_get_argv", Prim (fun _ -> Tuple [wrap_string ""; Array (Array.map wrap_string Sys.argv)]));
("caml_sys_get_config", Prim (fun _ -> Tuple [wrap_string ""; Int 0; Constructor ("true", None)]));
("%big_endian", Prim (fun _ -> Constructor ("false", None)));
("caml_sys_get_config", Prim (fun _ -> Tuple [wrap_string ""; Int 0; wrap_bool true]));
("%big_endian", Prim (fun _ -> wrap_bool false));
("%word_size", Prim (fun _ -> Int 64));
("%int_size", Prim (fun _ -> Int 64));
("%max_wosize", Prim (fun _ -> Int 1000000));
("%ostype_unix", Prim (fun _ -> Constructor ("false", None)));
("%ostype_win32", Prim (fun _ -> Constructor ("false", None)));
("%ostype_cygwin", Prim (fun _ -> Constructor ("false", None)));
("%backend_type", Prim (fun _ -> Constructor ("Other", Some (wrap_string "Interpreter"))));
("caml_sys_getenv", Prim (fun _ -> raise (InternalException (Constructor ("Not_found", None)))));
("%ostype_unix", Prim (fun _ -> wrap_bool false));
("%ostype_win32", Prim (fun _ -> wrap_bool false));
("%ostype_cygwin", Prim (fun _ -> wrap_bool false));
("%backend_type", Prim (fun _ -> Constructor ("Other", 0, Some (wrap_string "Interpreter"))));
("caml_sys_getenv", Prim (fun _ -> raise (InternalException not_found_exn)));
("caml_sys_file_exists", prim1 Sys.file_exists unwrap_string wrap_bool);
("caml_sys_getcwd", prim1 Sys.getcwd unwrap_unit wrap_string);
("caml_sys_rename", prim2 Sys.rename unwrap_string unwrap_string wrap_unit);
(* Bytes *)
("caml_create_bytes", prim1 Bytes.create unwrap_int wrap_bytes);
@ -675,6 +720,23 @@ let prims = [
("%int64_asr", prim2 Int64.shift_right unwrap_int64 unwrap_int wrap_int64);
("%int64_of_int", prim1 Int64.of_int unwrap_int wrap_int64);
("%int64_to_int", prim1 Int64.to_int unwrap_int64 wrap_int);
("caml_int64_of_string", prim1 Int64.of_string unwrap_string wrap_int64);
(* Nativeint *)
("%nativeint_neg", prim1 Int64.neg unwrap_int64 wrap_int64);
("%nativeint_add", prim2 Int64.add unwrap_int64 unwrap_int64 wrap_int64);
("%nativeint_sub", prim2 Int64.sub unwrap_int64 unwrap_int64 wrap_int64);
("%nativeint_mul", prim2 Int64.mul unwrap_int64 unwrap_int64 wrap_int64);
("%nativeint_div", prim2 Int64.div unwrap_int64 unwrap_int64 wrap_int64);
("%nativeint_mod", prim2 Int64.rem unwrap_int64 unwrap_int64 wrap_int64);
("%nativeint_and", prim2 Int64.logand unwrap_int64 unwrap_int64 wrap_int64);
("%nativeint_or", prim2 Int64.logor unwrap_int64 unwrap_int64 wrap_int64);
("%nativeint_xor", prim2 Int64.logxor unwrap_int64 unwrap_int64 wrap_int64);
("%nativeint_lsl", prim2 Int64.shift_left unwrap_int64 unwrap_int wrap_int64);
("%nativeint_lsr", prim2 Int64.shift_right_logical unwrap_int64 unwrap_int wrap_int64);
("%nativeint_asr", prim2 Int64.shift_right unwrap_int64 unwrap_int wrap_int64);
("%nativeint_of_int", prim1 Int64.of_int unwrap_int wrap_int64);
("%nativeint_to_int", prim1 Int64.to_int unwrap_int64 wrap_int);
(* Array *)
("caml_make_vect", prim2 Array.make unwrap_int id wrap_array_id);
@ -690,16 +752,23 @@ let prims = [
("caml_hash", prim4 seeded_hash_param unwrap_int unwrap_int unwrap_int id wrap_int); (* TODO: records defined in different order... *)
(* Weak *)
("caml_weak_create", prim1 (fun n -> Array.make n (Constructor ("None", None))) unwrap_int wrap_array_id);
("caml_weak_create", prim1 (fun n -> Array.make n (Constructor ("None", 0, None))) unwrap_int wrap_array_id);
("caml_weak_get", prim2 (fun a n -> a.(n)) unwrap_array_id unwrap_int id);
("caml_weak_get_copy", prim2 (fun a n -> a.(n)) unwrap_array_id unwrap_int id);
("caml_weak_set", prim3 (fun a n v -> a.(n) <- v) unwrap_array_id unwrap_int id wrap_unit);
("caml_weak_check", prim2 (fun a n -> a.(n) <> Constructor ("None", None)) unwrap_array_id unwrap_int wrap_bool);
("caml_weak_check", prim2 (fun a n -> a.(n) <> Constructor ("None", 0, None)) unwrap_array_id unwrap_int wrap_bool);
("caml_weak_blit", prim5 Array.blit unwrap_array_id unwrap_int unwrap_array_id unwrap_int unwrap_int wrap_unit);
(* Random *)
("caml_sys_random_seed", prim1 random_seed unwrap_unit (wrap_array wrap_int));
(* Digest *)
("caml_md5_string", prim3 digest_unsafe_string unwrap_string unwrap_int unwrap_int wrap_string);
("caml_md5_chan", prim2 Digest.channel unwrap_in_channel unwrap_int wrap_string);
(* Ugly *)
("%obj_size", prim1 (function Array a -> Array.length a + 2 | _ -> 4) id wrap_int);
("caml_sys_file_exists", Prim (fun _ -> wrap_bool false));
("caml_obj_block", prim2 (fun tag n -> Constructor ("", tag, Some (Tuple []))) unwrap_int unwrap_int id);
]
let prims = List.fold_left (fun env (name, v) -> SMap.add name v env) SMap.empty prims
@ -716,6 +785,8 @@ let fun_label_shape = function
| SeqOr | SeqAnd -> [(Nolabel, None); (Nolabel, None)]
| _ -> []
let fmt_ebb_of_string_fct = ref (Int 0)
let trace = true
let tracearg_from = 1668000000
let tracecur = ref 0
@ -729,15 +800,15 @@ let rec apply vf args =
match label, lab, default with
| Optional s, Labelled s', None ->
assert (s = s');
eval_expr (pattern_bind !fenv p (Constructor ("Some", Some arg))) e
eval_expr (pattern_bind !fenv p (Constructor ("Some", 0, Some arg))) e
| Optional s, Labelled s', Some _ | Optional s, Optional s', None | Labelled s, Labelled s', None ->
assert (s = s');
eval_expr (pattern_bind !fenv p arg) e
| Optional s, Optional s', Some def ->
assert (s = s');
let arg = match arg with
| Constructor ("None", None) -> eval_expr !fenv def
| Constructor ("Some", Some arg) -> arg
| Constructor ("None", 0, None) -> eval_expr !fenv def
| Constructor ("Some", 0, Some arg) -> arg
| _ -> assert false
in eval_expr (pattern_bind !fenv p arg) e
| _ -> assert false
@ -746,7 +817,7 @@ let rec apply vf args =
in
let apply_optional_noarg vf =
match vf with
| Fun (Optional _, None, p, e, fenv) -> eval_expr (pattern_bind !fenv p (Constructor ("None", None))) e
| Fun (Optional _, None, p, e, fenv) -> eval_expr (pattern_bind !fenv p (Constructor ("None", 0, None))) e
| Fun (Optional _, Some def, p, e, fenv) -> eval_expr (pattern_bind !fenv p (eval_expr !fenv def)) e
| _ -> assert false
in
@ -775,8 +846,8 @@ let rec apply vf args =
eval_expr (pattern_bind !fenv p arg) e
| Function (cl, fenv) -> eval_match !fenv cl (Ok arg)
| Prim prim -> prim arg
| SeqOr -> if is_true arg then Prim (fun _ -> Constructor ("true", None)) else Prim (fun x -> x)
| SeqAnd -> if is_true arg then Prim (fun x -> x) else Prim (fun _ -> Constructor ("false", None))
| SeqOr -> if is_true arg then Prim (fun _ -> wrap_bool true) else Prim (fun x -> x)
| SeqAnd -> if is_true arg then Prim (fun x -> x) else Prim (fun _ -> wrap_bool false)
| v -> Format.eprintf "%a@." pp_print_value v; assert false
in
let vf = List.fold_left apply_one vf unlabelled in
@ -814,9 +885,9 @@ and eval_expr env expr =
let fc = eval_expr env f in
(match fc, l with
| SeqOr, [(_, arg1); (_, arg2)] ->
let a1 = eval_expr env arg1 in if is_true a1 then Constructor ("true", None) else eval_expr env arg2
let a1 = eval_expr env arg1 in if is_true a1 then wrap_bool true else eval_expr env arg2
| SeqAnd, [(_, arg1); (_, arg2)] ->
let a1 = eval_expr env arg1 in if is_true a1 then eval_expr env arg2 else Constructor ("false", None)
let a1 = eval_expr env arg1 in if is_true a1 then eval_expr env arg2 else wrap_bool false
| _ ->
let args = List.map (fun (lab, e) -> (lab, eval_expr env e)) l in
if trace then begin match f.pexp_desc with Pexp_ident {txt=lident} ->
@ -857,11 +928,12 @@ and eval_expr env expr =
)
| Pexp_construct ({ txt = c }, e) ->
let cn = lident_name c in
let d = env_get_constr env c in
let ee = match e with None -> None | Some e -> Some (eval_expr env e) in
Constructor (cn, ee)
Constructor (cn, d, ee)
| Pexp_variant (cn, e) ->
let ee = match e with None -> None | Some e -> Some (eval_expr env e) in
Constructor (cn, ee)
Constructor (cn, Hashtbl.hash cn, ee)
| Pexp_record (r, e) ->
let base = match e with None -> SMap.empty | Some e -> match eval_expr env e with Record r -> r | _ -> assert false in
Record (
@ -905,7 +977,7 @@ and eval_expr env expr =
| Pexp_extension _ -> assert false
and eval_expr_exn env expr =
try Ok (eval_expr env expr) with InternalException v -> (Format.eprintf "eval_expr_exn produced error %a@." pp_print_value v; Error v)
try Ok (eval_expr env expr) with InternalException v -> Error v
and bind_value evalenv bindenv vb =
let v = eval_expr evalenv vb.pvb_expr in
@ -937,9 +1009,11 @@ and pattern_bind env pat v =
| Ppat_construct ({ txt = c }, p) ->
begin
let cn = lident_name c in
let dn = env_get_constr env c in
match v with
| Constructor (ccn, e) ->
| Constructor (ccn, ddn, e) ->
if cn <> ccn then raise Match_fail;
if dn <> ddn then raise Match_fail;
(match (p, e) with
| None, None -> env
| Some p, Some e -> pattern_bind env p e
@ -947,13 +1021,22 @@ and pattern_bind env pat v =
| String s ->
assert (lident_name c = "Format");
let p = match p with None -> assert false | Some p -> p in
let fmt_ebb_of_string_fct = env_get_value env (Longident.Ldot (Longident.Lident "CamlinternalFormat", "fmt_ebb_of_string")) in
let fmt = apply fmt_ebb_of_string_fct [(Nolabel, String s)] in
let fmt = match fmt with | Constructor ("Fmt_EBB", Some fmt) -> fmt | _ -> assert false in
let fmt = apply !fmt_ebb_of_string_fct [(Nolabel, String s)] in
let fmt = match fmt with | Constructor ("Fmt_EBB", _, Some fmt) -> fmt | _ -> assert false in
pattern_bind env p (Tuple [fmt; v])
| _ -> Format.eprintf "cn = %s@.v = %a@." cn pp_print_value v; assert false
end
| Ppat_variant _ -> assert false
| Ppat_variant (name, p) ->
begin
match v with
| Constructor (cn, _, e) ->
if cn <> name then raise Match_fail;
(match (p, e) with
| None, None -> env
| Some p, Some e -> pattern_bind env p e
| _ -> assert false)
| _ -> assert false
end
| Ppat_record (rp, _) ->
begin
match v with
@ -985,7 +1068,7 @@ and pattern_bind_checkexn env pat v =
and eval_match env cl arg =
match cl with
| [] -> (match arg with Ok _ -> raise Match_fail | Error v -> Format.eprintf "eval_match failed to catch error %a@." pp_print_value v; raise (InternalException v))
| [] -> (match arg with Ok _ -> raise Match_fail | Error v -> raise (InternalException v))
| c :: cl ->
match pattern_bind_checkexn env c.pc_lhs arg with
| exception Match_fail -> eval_match env cl arg
@ -1054,7 +1137,12 @@ and eval_structitem init_ignored env it =
| _ -> env
) env tl
| Pstr_typext _ -> env
| Pstr_exception _ -> env
| Pstr_exception { pext_name = { txt = name } ; pext_kind = k } ->
begin
match k with
| Pext_decl _ -> let d = !exn_id in incr exn_id; env_set_constr name d env
| Pext_rebind { txt = path } -> env_set_constr name (env_get_constr env path) env
end
| Pstr_module { pmb_name = { txt = name } ; pmb_expr = me } ->
begin
match init_ignored with
@ -1071,8 +1159,7 @@ and eval_structitem init_ignored env it =
| Pstr_open { popen_lid = { txt = lident } } ->
(match env_get_module env lident with
| Module (venv, menv, cenv) -> env_extend false env (venv, menv, cenv)
| Functor _ -> assert false
| exception Not_found -> env (* Module might be a .mli only *))
| Functor _ -> assert false)
| Pstr_class _ -> assert false
| Pstr_class_type _ -> assert false
| Pstr_include { pincl_mod = me } ->
@ -1088,6 +1175,58 @@ and eval_structure init_ignored env str =
| [] -> env
| it :: str -> eval_structure init_ignored (eval_structitem init_ignored env it) str
and eval_sigitem_noimpl env = function
| Psig_attribute _ -> env
| Psig_class _ -> assert false
| Psig_class_type _ -> assert false
| Psig_exception { pext_name = { txt = name } ; pext_kind = k } ->
begin
match k with
| Pext_decl _ -> let d = !exn_id in incr exn_id; env_set_constr name d env
| Pext_rebind { txt = path } -> env_set_constr name (env_get_constr env path) env
end
| Psig_extension _ -> assert false
| Psig_include { pincl_mod = mt } ->
let m = eval_module_type env mt in
(match m with
| Module (venv, menv, cenv) -> env_extend true env (venv, menv, cenv)
| Functor _ -> assert false)
| Psig_open { popen_lid = { txt = lident } } ->
(match env_get_module env lident with
| Module (venv, menv, cenv) -> env_extend false env (venv, menv, cenv)
| Functor _ -> assert false)
| Psig_value z -> assert false (* load mlis without implementation only *)
| Psig_module _ -> assert false (* TODO *)
| Psig_modtype _ -> assert false
| Psig_type (_, tl) ->
List.fold_left (fun env t ->
match t.ptype_kind with
| Ptype_variant l ->
let (_, _, env) = List.fold_left (fun (u, v, env) cd ->
match cd.pcd_args with
| Pcstr_tuple [] -> (u + 1, v, env_set_constr cd.pcd_name.txt u env)
| _ -> (u, v + 1, env_set_constr cd.pcd_name.txt v env)
) (0, 0, env) l in
env
| _ -> env
) env tl
| Psig_typext _ -> assert false
| Psig_recmodule _ -> assert false
and eval_module_type env mt =
match mt.pmty_desc with
| Pmty_ident { txt = lident } -> env_get_module env lident
| Pmty_signature sg -> make_module (eval_signature_noimpl env sg)
| Pmty_functor ({ txt = argname }, input_type, result) -> (* hope it doesn't happen *) assert false
| Pmty_with _ -> assert false
| Pmty_typeof _ -> assert false
| Pmty_alias _ -> assert false
| Pmty_extension _ -> assert false
and eval_signature_noimpl env = function
| [] -> env
| it :: sg -> eval_signature_noimpl (eval_sigitem_noimpl env it.psig_desc) sg
let () = apply_ref := apply
let parse filename =
@ -1110,22 +1249,27 @@ let stdlib_modules = [
("String", "string.ml", z);
("Buffer", "buffer.ml", z);
("CamlinternalFormatBasics", "camlinternalFormatBasics.ml", z);
("CamlinternalFormat", "camlinternalFormat.ml", z);
("CamlinternalFormat", "camlinternalFormat.ml", (fun env ->
fmt_ebb_of_string_fct := env_get_value env (Longident.Lident "fmt_ebb_of_string"); env));
("Printf", "printf.ml", z);
("Format", "format.ml", z);
("Obj", "obj.ml", z);
("CamlinternalLazy", "camlinternalLazy.ml", z);
("Lazy", "lazy.ml", z);
("Array", "array.ml", z);
("Hashtbl", "hashtbl.ml", z);
("Int64", "int64.ml", z);
("Int32", "int32.ml", z);
("Nativeint", "nativeint.ml", z);
("Digest", "digest.ml", z);
("Random", "random.ml", z);
("Hashtbl", "hashtbl.ml", z);
("Lexing", "lexing.ml", z);
("Parsing", "parsing.ml", z);
("Weak", "weak.ml", z);
("Stack", "stack.ml", z);
("Arg", "arg.ml", z);
("Filename", "filename.ml", z);
("CamlinternalOO", "camlinternalOO.ml", z);
]
let stdlib_path = "/home/nathanael/.opam/4.07.0/lib/ocaml"
@ -1134,13 +1278,14 @@ let stdlib_modules = List.map (fun (n, p, modifier) -> (n, stdlib_path ^ "/" ^ p
let load_modules env modules =
List.fold_left (fun env (modname, modpath, modifier) ->
Format.eprintf "Loading %s@." modname;
env_set_module modname (make_module (modifier (eval_structure None env (parse modpath)))) env
let module_contents = modifier (eval_structure None env (parse modpath)) in
env_set_module modname (make_module module_contents) env
) env modules
let init_env =
let stdlib_main = parse (stdlib_path ^ "/stdlib.ml") in
let ign = ref SSet.empty in
let env = eval_structure (Some ign) empty_env stdlib_main in
let env = eval_structure (Some ign) !initial_env stdlib_main in
let env = load_modules env stdlib_modules in
env_set_module "Stdlib" (make_module env) env
@ -1163,8 +1308,10 @@ let compiler_modules = [
("Targetint", "utils/targetint.ml", z);
(* Parsing *)
("Asttypes", "parsing/asttypes.mli", z);
("Location", "parsing/location.ml", z);
("Longident", "parsing/longident.ml", z);
("Parsetree", "parsing/parsetree.mli", z);
("Docstrings", "parsing/docstrings.ml", z);
("Syntaxerr", "parsing/syntaxerr.ml", z);
("Ast_helper", "parsing/ast_helper.ml", z);
@ -1182,6 +1329,8 @@ let compiler_modules = [
(* Typing *)
("Ident", "typing/ident.ml", z);
("Outcometree", "typing/outcometree.mli", z);
("Annot", "typing/annot.mli", z);
("Path", "typing/path.ml", z);
("Primitive", "typing/primitive.ml", z);
("Types", "typing/types.ml", z);
@ -1211,13 +1360,18 @@ let compiler_modules = [
("Parmatch", "typing/parmatch.ml", z);
("Stypes", "typing/stypes.ml", z);
("Typedecl", "typing/typedecl.ml", z);
(* Comp *)
("Lambda", "bytecomp/lambda.ml", z);
(* Typing *)
("Typeopt", "typing/typeopt.ml", z);
("Typecore", "typing/typecore.ml", z);
("Typeclass", "typing/typeclass.ml", z);
("Typemod", "typing/typemod.ml", z);
(* Comp *)
("Lambda", "bytecomp/lambda.ml", z);
("Cmo_format", "bytecomp/cmo_format.mli", z);
("Printlambda", "bytecomp/printlambda.ml", z);
("Semantics_of_primitives", "bytecomp/semantics_of_primitives.ml", z);
("Switch", "bytecomp/switch.ml", z);
@ -1239,7 +1393,7 @@ let compiler_modules = [
("Main_args", "driver/main_args.ml", z);
("Compenv", "driver/compenv.ml", z);
("Compmisc", "driver/compmisc.ml", z);
(* ("Compdynlink", "driver/compdynlink.ml"); *)
("Compdynlink", "driver/compdynlink.mlno", z);
("Compplugin", "driver/compplugin.ml", z);
("Makedepend", "driver/makedepend.ml", z);