diff --git a/src/ir_interpreter/interpret_ir.ml b/src/ir_interpreter/interpret_ir.ml index 8f0a4f9a9b7..f8c245b5769 100644 --- a/src/ir_interpreter/interpret_ir.ml +++ b/src/ir_interpreter/interpret_ir.ml @@ -80,8 +80,8 @@ let trace fmt = Printf.printf "%s%s\n%!" (String.make (2 * !trace_depth) ' ') s ) fmt -let string_of_val env = V.string_of_val env.flags.print_depth -let string_of_def flags = V.string_of_def flags.print_depth +let string_of_val env = V.string_of_val env.flags.print_depth T.Non +let string_of_def flags = V.string_of_def flags.print_depth T.Non let string_of_arg env = function | V.Tup _ as v -> string_of_val env v | v -> "(" ^ string_of_val env v ^ ")" @@ -643,7 +643,7 @@ and match_args at args v : val_env = | _ -> let vs = V.as_tup v in if (List.length vs <> List.length args) then - failwith (Printf.sprintf "%s %s" (Source.string_of_region at) (V.string_of_val 0 v)); + failwith (Printf.sprintf "%s %s" (Source.string_of_region at) (V.string_of_val 0 T.Non v)); List.fold_left V.Env.adjoin V.Env.empty (List.map2 match_arg args vs) (* Patterns *) diff --git a/src/mo_frontend/coverage.ml b/src/mo_frontend/coverage.ml index 110c6e61b1c..00eebf501e3 100644 --- a/src/mo_frontend/coverage.ml +++ b/src/mo_frontend/coverage.ml @@ -126,7 +126,7 @@ let rec expand_nottag tfs n ls : desc list = (* TODO: pretty print *) let rec string_of_desc t = function | Any -> "_" - | Val v -> V.string_of_val 100 v + | Val v -> V.string_of_val 100 t v | NotVal vs -> string_of_descs t (expand_notval (T.promote t) 0 vs) | Tup descs -> let ts = T.as_tup_sub (List.length descs) t in diff --git a/src/mo_interpreter/interpret.ml b/src/mo_interpreter/interpret.ml index 6c0674dfb4a..8537e4e74fe 100644 --- a/src/mo_interpreter/interpret.ml +++ b/src/mo_interpreter/interpret.ml @@ -92,8 +92,8 @@ let trace fmt = Printf.printf "%s%s\n%!" (String.make (2 * !trace_depth) ' ') s ) fmt -let string_of_val env = V.string_of_val env.flags.print_depth -let string_of_def flags = V.string_of_def flags.print_depth +let string_of_val env = V.string_of_val env.flags.print_depth T.Non +let string_of_def flags = V.string_of_def flags.print_depth T.Non let string_of_arg env = function | V.Tup _ as v -> string_of_val env v | v -> "(" ^ string_of_val env v ^ ")" diff --git a/src/mo_values/show.ml b/src/mo_values/show.ml index 7b04f4f5e40..037fea29ed7 100644 --- a/src/mo_values/show.ml +++ b/src/mo_values/show.ml @@ -83,7 +83,7 @@ let rec show_val t v = end | _ -> Format.eprintf "@[show_val: %a : %a@.@]" - (Value.pp_val 2) v + (Value.pp_val 2) (t, v) T.pp_typ t; assert false diff --git a/src/mo_values/value.ml b/src/mo_values/value.ml index c08735ba16c..c21d255e6a4 100644 --- a/src/mo_values/value.ml +++ b/src/mo_values/value.ml @@ -1,4 +1,5 @@ open Numerics +module T = Mo_types.Type (* Environments *) @@ -180,75 +181,113 @@ let comma ppf () = fprintf ppf ",@ " let semi ppf () = fprintf ppf ";@ " -let rec pp_val_nullary d ppf = function - | Null -> pr ppf "null" - | Bool b -> pr ppf (if b then "true" else "false") - | Int n when Int.(ge n zero) -> pr ppf (Int.to_pretty_string n) - | Int8 n when Int_8.(n = zero) -> pr ppf (Int_8.to_pretty_string n) - | Int16 n when Int_16.(n = zero) -> pr ppf (Int_16.to_pretty_string n) - | Int32 n when Int_32.(n = zero) -> pr ppf (Int_32.to_pretty_string n) - | Int64 n when Int_64.(n = zero) -> pr ppf (Int_64.to_pretty_string n) - | Nat8 n -> pr ppf (Nat8.to_pretty_string n) - | Nat16 n -> pr ppf (Nat16.to_pretty_string n) - | Nat32 n -> pr ppf (Nat32.to_pretty_string n) - | Nat64 n -> pr ppf (Nat64.to_pretty_string n) - | Float f -> pr ppf (Float.to_pretty_string f) - | Char c -> pr ppf (string_of_string '\'' [c] '\'') - | Text t -> pr ppf (string_of_string '\"' (Lib.Utf8.decode t) '\"') - | Blob b -> pr ppf ("\"" ^ Blob.escape b ^ "\"") - | Tup vs -> - fprintf ppf "@[<1>(%a%s)@]" - (pp_print_list ~pp_sep:comma (pp_val d)) vs - (if List.length vs = 1 then "," else "") - | Obj ve -> - if d = 0 then pr ppf "{...}" else - fprintf ppf "@[{@;<0 0>%a@;<0 -2>}@]" - (pp_print_list ~pp_sep:semi (pp_field d)) (Env.bindings ve) - | Array a -> - fprintf ppf "@[<1>[%a]@]" - (pp_print_list ~pp_sep:comma (pp_val d)) (Array.to_list a) - | Func (_, _) -> pr ppf "func" - | Comp _ -> pr ppf "async*" - | v -> - (* "(" ^ string_of_val d v ^ ")" *) - fprintf ppf "@[<1>(%a)@]" (pp_val d) v - -and pp_field d ppf (lab, v) = - fprintf ppf "@[<2>%s =@ %a@]" lab (pp_val d) v - -and pp_val d ppf = function - | Int i -> pr ppf (Int.to_pretty_string i) - | Int8 i -> pr ppf (Int_8.(pos_sign (gt i zero) ^ to_pretty_string i)) - | Int16 i -> pr ppf (Int_16.(pos_sign (gt i zero) ^ to_pretty_string i)) - | Int32 i -> pr ppf (Int_32.(pos_sign (gt i zero) ^ to_pretty_string i)) - | Int64 i -> pr ppf (Int_64.(pos_sign (gt i zero) ^ to_pretty_string i)) - | Opt v -> fprintf ppf "@[<1>?%a@]" (pp_val_nullary d) v - | Variant (l, Tup []) -> fprintf ppf "#%s" l - | Variant (l, Tup vs) -> fprintf ppf "@[#%s@;<0 1>%a@]" l (pp_val d) (Tup vs) - | Variant (l, v) -> fprintf ppf "@[#%s@;<0 1>(%a)@]" l (pp_val d) v - | Async {result; waiters = []} -> - fprintf ppf "@[<2>async@ %a@]" (pp_res d) result - | Async {result; waiters} -> - fprintf ppf "@[<2>async[%d]@ %a@]" - (List.length waiters) (pp_res d) result - | Mut r -> pp_val d ppf !r - | v -> pp_val_nullary d ppf v - -and pp_res d ppf result = +let rec pp_val_nullary d ppf (t, v : T.typ * value) = + match T.normalize t with + | T.Any -> pr ppf "" + | t -> + match v with + | Null -> pr ppf "null" + | Bool b -> pr ppf (if b then "true" else "false") + | Int n when Int.(ge n zero) -> pr ppf (Int.to_pretty_string n) + | Int8 n when Int_8.(n = zero) -> pr ppf (Int_8.to_pretty_string n) + | Int16 n when Int_16.(n = zero) -> pr ppf (Int_16.to_pretty_string n) + | Int32 n when Int_32.(n = zero) -> pr ppf (Int_32.to_pretty_string n) + | Int64 n when Int_64.(n = zero) -> pr ppf (Int_64.to_pretty_string n) + | Nat8 n -> pr ppf (Nat8.to_pretty_string n) + | Nat16 n -> pr ppf (Nat16.to_pretty_string n) + | Nat32 n -> pr ppf (Nat32.to_pretty_string n) + | Nat64 n -> pr ppf (Nat64.to_pretty_string n) + | Float f -> pr ppf (Float.to_pretty_string f) + | Char c -> pr ppf (string_of_string '\'' [c] '\'') + | Text t -> pr ppf (string_of_string '\"' (Lib.Utf8.decode t) '\"') + | Blob b -> + (match t with + T.Obj (T.Actor, _) -> + pr ppf (string_of_string '`' (Lib.Utf8.decode (Ic.Url.encode_principal b)) '`') + | _ -> pr ppf ("\"" ^ Blob.escape b ^ "\"")) + | Tup vs -> + let list = match t with + | T.Tup ts -> List.combine ts vs + | _ -> List.map (fun v -> (T.Non, v)) vs in + fprintf ppf "@[<1>(%a%s)@]" + (pp_print_list ~pp_sep:comma (pp_val d)) list + (if List.length vs = 1 then "," else "") + | Obj ve -> + if d = 0 then pr ppf "{...}" else + let sort, lookup = match t with + | T.Obj (s, fs) -> + T.string_of_obj_sort s, + fun lab -> T.lookup_val_field_opt lab fs + | _ -> + "", fun lab -> Some T.Non + in + fprintf ppf "@[%a{@;<0 0>%a@;<0 -2>}@]" + pr sort + (pp_print_list ~pp_sep:semi (pp_field d)) (List.filter_map (fun (lab, v) -> + match lookup lab with + | Some t -> Some (lab, t, v) + | None -> None) + (Env.bindings ve)) + | Array vs -> + let t' = match t with T.Array t' -> t' | _ -> T.Non in + fprintf ppf "@[<1>[%a%a]@]" + pr (match t' with T.Mut t -> "var " | _ -> "") + (pp_print_list ~pp_sep:comma (pp_val d)) (List.map (fun v -> (t', v)) (Array.to_list vs)) + + | Func (_, _) -> pr ppf "" + | Comp _ -> pr ppf "" + | v -> + fprintf ppf "@[<1>(%a)@]" (pp_val d) (t, v) + +and pp_field d ppf (lab, t, v) = + fprintf ppf "@[<2>%s =@ %a@]" lab (pp_val d) (t, v) + +and pp_val d ppf (t, v) = + match T.normalize t with + | T.Any -> pr ppf "" + | t -> + match v with + | Int i -> pr ppf (Int.to_pretty_string i) + | Int8 i -> pr ppf (Int_8.(pos_sign (gt i zero) ^ to_pretty_string i)) + | Int16 i -> pr ppf (Int_16.(pos_sign (gt i zero) ^ to_pretty_string i)) + | Int32 i -> pr ppf (Int_32.(pos_sign (gt i zero) ^ to_pretty_string i)) + | Int64 i -> pr ppf (Int_64.(pos_sign (gt i zero) ^ to_pretty_string i)) + | Opt v -> + let t' = match t with T.Opt t' -> t' | _ -> T.Non in + fprintf ppf "@[<1>?%a@]" (pp_val_nullary d) (t', v) + | Variant (l, Tup []) -> fprintf ppf "#%s" l + | Variant (l, v) -> + let t' = match t with T.Variant fs -> T.lookup_val_field l fs | _ -> T.Non in + (match v with + | Tup vs -> fprintf ppf "@[#%s@;<0 1>%a@]" l (pp_val d) (t', Tup vs) + | _ -> fprintf ppf "@[#%s@;<0 1>(%a)@]" l (pp_val d) (t', v)) + | Async {result; waiters = []} -> + let t' = match t with T.Async (_, _, t') -> t' | _ -> T.Non in + fprintf ppf "@[<2>async@ %a@]" (pp_res d) (t', result) + | Async {result; waiters} -> + let t' = match t with T.Async (_, _, t') -> t' | _ -> T.Non in + fprintf ppf "@[<2>async[%d]@ %a@]" + (List.length waiters) (pp_res d) (t', result) + | Mut r -> + let t' = match t with T.Mut t' -> t' | _ -> T.Non in + pp_val d ppf (t', !r) + | v -> pp_val_nullary d ppf (t, v) + +and pp_res d ppf (t, result) = match Lib.Promise.value_opt result with - | Some (Error v)-> fprintf ppf "@[Error@ %a@]" (pp_val_nullary d) v - | Some (Ok v) -> pp_val_nullary d ppf v + | Some (Error v) -> fprintf ppf "@[Error@ %a@]" (pp_val_nullary d) (t, v) + | Some (Ok v) -> pp_val_nullary d ppf (t, v) | None -> pr ppf "_" -and pp_def d ppf def = +and pp_def d ppf (t, def) = match Lib.Promise.value_opt def with - | Some v -> pp_val d ppf v + | Some v -> pp_val d ppf (t, v) | None -> pr ppf "_" -let string_of_val d v : string = +and string_of_val d t v : string = Lib.Format.with_str_formatter (fun ppf -> - pp_val d ppf) v + pp_val d ppf) (t, v) -let string_of_def d def : string = +let string_of_def d t def : string = Lib.Format.with_str_formatter (fun ppf -> - pp_def d ppf) def + pp_def d ppf) (t, def) diff --git a/src/mo_values/value.mli b/src/mo_values/value.mli index 9b8689cf275..8da635962b4 100644 --- a/src/mo_values/value.mli +++ b/src/mo_values/value.mli @@ -113,8 +113,10 @@ val compare : value -> value -> int (* Pretty Printing *) -val pp_val : int -> Format.formatter -> value -> unit -val pp_def : int -> Format.formatter -> def -> unit +(* NB: Pass Type.Non to print value at full dynamic, not static, type. *) +val pp_val : int -> Format.formatter -> (Type.typ * value) -> unit +val pp_def : int -> Format.formatter -> (Type.typ * def) -> unit -val string_of_val : int -> value -> string -val string_of_def : int -> def -> string +(* NB: Pass Type.Non to print value at full dynamic, not static, type. *) +val string_of_val : int -> Type.typ -> value -> string +val string_of_def : int -> Type.typ -> def -> string diff --git a/src/pipeline/pipeline.ml b/src/pipeline/pipeline.ml index ac73a960b4d..5c0649a4322 100644 --- a/src/pipeline/pipeline.ml +++ b/src/pipeline/pipeline.ml @@ -53,16 +53,16 @@ let print_dyn_ve scope = Format.printf "@[%s %s :@ %a =@ %a@]@." (if t == t' then "let" else "var") x Type.pp_typ t' - (Value.pp_def !Flags.print_depth) d + (Value.pp_def !Flags.print_depth) (t', d) ) let print_scope senv scope dve = print_ce scope.Scope.con_env; print_dyn_ve senv dve -let print_val _senv v t = +let print_val _senv t v = Format.printf "@[%a :@ %a@]@." - (Value.pp_val !Flags.print_depth) v + (Value.pp_val !Flags.print_depth) (t, v) Type.pp_typ t @@ -559,7 +559,7 @@ let is_exp dec = match dec.Source.it with Syntax.ExpD _ -> true | _ -> false let output_scope (senv, _) t v sscope dscope = print_scope senv sscope dscope.Interpret.val_env; - if v <> Value.unit then print_val senv v t + if v <> Value.unit then print_val senv t v let run_stdin lexer (senv, denv) : env option = match Diag.flush_messages (load_decl (parse_lexer lexer) senv) with @@ -593,9 +593,7 @@ let run_stdin_from_file files file : Value.value option = Diag.flush_messages (load_decl (parse_file Source.no_region file) senv) in let denv' = interpret_libs denv libs in let* (v, dscope) = interpret_prog denv' prog in - Format.printf "@[%a :@ %a@]@." - (Value.pp_val 10) v - Type.pp_typ t; + print_val senv t v; Some v let run_files_and_stdin files = diff --git a/src/profiler/counters.ml b/src/profiler/counters.ml index c396f493094..e707d3e1204 100644 --- a/src/profiler/counters.ml +++ b/src/profiler/counters.ml @@ -10,6 +10,7 @@ such as search, sorting, etc. open Source module Value = Mo_values.Value +module T = Mo_types.Type type t = { label : ((region * string), int) Hashtbl.t ; @@ -60,7 +61,7 @@ let dump (c:t) (ve: Value.value Value.Env.t) = Printf.printf "{\n" ; Value.Env.iter (fun fn fv -> Printf.printf " %s = %s;\n" - fn (Value.string_of_val 0 fv) + fn (Value.string_of_val 0 T.Non fv) ) ve ; Printf.printf "}\n" @@ -112,7 +113,7 @@ let dump (c:t) (ve: Value.value Value.Env.t) = (fun var (line, flds) -> match Value.Env.find_opt var ve with None -> (Printf.sprintf "%s, #err" line, (var :: flds)) - | Some v -> (Printf.sprintf "%s, %s" line (Value.string_of_val 0 v), var :: flds) + | Some v -> (Printf.sprintf "%s, %s" line (Value.string_of_val 0 T.Non v), var :: flds) ) !ProfilerFlags.profile_field_names ("", []) in Printf.fprintf file "# column: source region\n" ; diff --git a/test/repl/ok/pretty-val.stdout.ok b/test/repl/ok/pretty-val.stdout.ok index fa85c5bf81e..afdf5737811 100644 --- a/test/repl/ok/pretty-val.stdout.ok +++ b/test/repl/ok/pretty-val.stdout.ok @@ -1,9 +1,9 @@ Motoko compiler (source XXX) > let Prim : module {...} -> let a_small : [var Text] = ["hello", "hello", "hello", "hello", "hello"] +> let a_small : [var Text] = [var "hello", "hello", "hello", "hello", "hello"] > let a_large : [var Text] = - ["hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", + [var "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", @@ -15,7 +15,7 @@ Motoko compiler (source XXX) "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", "hello", - "hello", "hello", "hello", "hello"] + "hello", "hello", "hello", "hello", "hello"] > let a_small : [Nat] = [0, 1, 2, 3, 4] > let a_large : [Nat] = @@ -25,7 +25,7 @@ Motoko compiler (source XXX) 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99] -> let a : (T, T) -> [T] = func +> let a : (T, T) -> [T] = > let a1 : [{#A; #B}] = [#A, #B] > let a2 : [[{#A; #B}]] = [[#A, #B], [#A, #B]] > let a3 : [[[{#A; #B}]]] = [[[#A, #B], [#A, #B]], [[#A, #B], [#A, #B]]] @@ -39,7 +39,7 @@ Motoko compiler (source XXX) [[[#A, #B], [#A, #B]], [[#A, #B], [#A, #B]]]], [[[[#A, #B], [#A, #B]], [[#A, #B], [#A, #B]]], [[[#A, #B], [#A, #B]], [[#A, #B], [#A, #B]]]]] -> let r : (T, U) -> {A : T; B : U} = func +> let r : (T, U) -> {A : T; B : U} = > let r1 : {A : {#A}; B : {#B}} = {A = #A; B = #B} > let r2 : {A : {A : {#A}; B : {#B}}; B : {A : {#A}; B : {#B}}} = @@ -135,27 +135,27 @@ Motoko compiler (source XXX) } } } -> let m : (T, U) -> module {A : T; B : U} = func +> let m : (T, U) -> module {A : T; B : U} = > let m1 : module {...} > let m2 : module {...} > let m3 : module {...} > let m4 : module {...} > let m5 : module {...} -> let f : (T -> U) -> (U -> T) -> T -> U = func -> let f1 : ({#B} -> {#A}) -> {#A} -> {#B} = func +> let f : (T -> U) -> (U -> T) -> T -> U = +> let f1 : ({#B} -> {#A}) -> {#A} -> {#B} = > let f2 : (({#A} -> {#B}) -> {#B} -> {#A}) -> ({#B} -> {#A}) -> {#A} -> {#B} = - func + > let f3 : ((({#B} -> {#A}) -> {#A} -> {#B}) -> ({#A} -> {#B}) -> {#B} -> {#A}) -> (({#A} -> {#B}) -> {#B} -> {#A}) -> ({#B} -> {#A}) -> {#A} -> {#B} = - func + > let f4 : (((({#A} -> {#B}) -> {#B} -> {#A}) -> ({#B} -> {#A}) -> {#A} -> {#B}) -> (({#B} -> {#A}) -> {#A} -> {#B}) -> ({#A} -> {#B}) -> {#B} -> {#A}) -> ((({#B} -> {#A}) -> {#A} -> {#B}) -> ({#A} -> {#B}) -> {#B} -> {#A}) -> (({#A} -> {#B}) -> {#B} -> {#A}) -> ({#B} -> {#A}) -> {#A} -> {#B} = - func + > let f5 : ((((({#B} -> {#A}) -> {#A} -> {#B}) -> ({#A} -> {#B}) -> {#B} -> {#A}) -> (({#A} -> {#B}) -> {#B} -> {#A}) -> ({#B} -> {#A}) -> {#A} -> {#B}) -> @@ -165,8 +165,8 @@ Motoko compiler (source XXX) (({#B} -> {#A}) -> {#A} -> {#B}) -> ({#A} -> {#B}) -> {#B} -> {#A}) -> ((({#B} -> {#A}) -> {#A} -> {#B}) -> ({#A} -> {#B}) -> {#B} -> {#A}) -> (({#A} -> {#B}) -> {#B} -> {#A}) -> ({#B} -> {#A}) -> {#A} -> {#B} = - func -> let p : (T, U) -> (T, U) = func + +> let p : (T, U) -> (T, U) = > let p1 : ({#A}, {#B}) = (#A, #B) > let p2 : (({#A}, {#B}), ({#A}, {#B})) = ((#A, #B), (#A, #B)) > let p3 : @@ -186,7 +186,7 @@ Motoko compiler (source XXX) (((#A, #B), (#A, #B)), ((#A, #B), (#A, #B)))), ((((#A, #B), (#A, #B)), ((#A, #B), (#A, #B))), (((#A, #B), (#A, #B)), ((#A, #B), (#A, #B))))) -> let v : (T, U) -> {#A : T; #B : U} = func +> let v : (T, U) -> {#A : T; #B : U} = > let v1 : {#A : {#Foo}; #B : {#Bar}} = #A(#Foo) > let v2 : {#A : {#A : {#Foo}; #B : {#Bar}}; #B : {#A : {#Foo}; #B : {#Bar}}} = @@ -277,14 +277,14 @@ Motoko compiler (source XXX) } } = #A(#A(#A(#A(#A(#Foo))))) -> let o : T -> ?T = func +> let o : T -> ?T = > let o1 : ?Nat = ?666 > let o2 : ??Nat = ?(?666) > let o3 : ???Nat = ?(?(?666)) > let o4 : ????Nat = ?(?(?(?666))) > let o5 : ?????Nat = ?(?(?(?(?666)))) > type c = {type List = ?(T_1, List); A : T; B : U} -let c : (T, U) -> c = func +let c : (T, U) -> c = > let c1 : {type List = ?(T, List); A : {#A}; B : {#B}} = {A = #A; B = #B} @@ -467,4 +467,7 @@ let c : (T, U) -> c = func } } } +> let a : Any = +> let r : {a : Nat} = {a = 1} +> let r : Any = > diff --git a/test/repl/ok/type-lub-repl.stdout.ok b/test/repl/ok/type-lub-repl.stdout.ok index 0e138542451..f8ed8788522 100644 --- a/test/repl/ok/type-lub-repl.stdout.ok +++ b/test/repl/ok/type-lub-repl.stdout.ok @@ -1,29 +1,29 @@ Motoko compiler (source XXX) > [null, ?42, ?(-25)] : [?Int] > [null, null] : [Null] -> [{a = 42}, {b = 42}] : [{}] -> [{a = 42}, {a = 1; b = 42}, {a = -25}] : [{a : Int}] +> [{}, {}] : [{}] +> [{a = 42}, {a = 1}, {a = -25}] : [{a : Int}] > [(12, -1), (-42, 25)] : [(Int, Int)] > [-1, 25] : [Int] > [[-42], [25]] : [[Int]] -> [func, func] : [None -> Int] -> [func, func] : [[Nat] -> Int] +> [, ] : [None -> Int] +> [, ] : [[Nat] -> Int] > 3 : Int > -42 : Int -> [func, func] : [[Nat] -> Int] +> [, ] : [[Nat] -> Int] > 3 : Int > -42 : Int -> [func, func] : [[Nat] -> Int] +> [, ] : [[Nat] -> Int] > 3 : Int > -42 : Int -> [func, func] : [([A], B) -> A] -> [func, func] : [{#bar} -> ()] -> > > [[42], [25], [77]] : [Any] -> [42, 77, [1, 2, 3]] : [Any] -> [77, [1, 2, 3], 42] : [Any] -> [func, func] : [Nat -> Int] +> [, ] : [([A], B) -> A] +> [, ] : [{#bar} -> ()] +> > > [, , ] : [Any] +> [, , ] : [Any] +> [, , ] : [Any] +> [, ] : [Nat -> Int] > 25 : Int > 42 : Int -> func : (C, D) -> [C] +> : (C, D) -> [C] > [async (?4), async (?(-42))] : [async<$top-level> ?Int] > diff --git a/test/repl/pretty-val.sh b/test/repl/pretty-val.sh index bb7c37907f7..1f8d21be931 100755 --- a/test/repl/pretty-val.sh +++ b/test/repl/pretty-val.sh @@ -69,4 +69,11 @@ let c3 = c(c2, c2); let c4 = c(c3, c3); let c5 = c(c4, c4); +// subtyping hides values +let a : Any = 1; + +let r : {a : Nat} = { a = 1; hidden = true}; + +let r : Any = { a = 1; hidden = true}; + __END__ diff --git a/test/test-moc.js b/test/test-moc.js index 7629ebe9cd5..e359624a506 100644 --- a/test/test-moc.js +++ b/test/test-moc.js @@ -147,6 +147,13 @@ const astString = JSON.stringify( Motoko.parseMotoko(Motoko.readFile("ast.mo")) ); +// Run interpreter +assert.deepStrictEqual(Motoko.run([], "actor.mo"), { + stdout: "`ys6dh-5cjiq-5dc` : actor {main : shared query () -> async A__9}\n", + stderr: "", + result: { error: null }, +}); + // Check doc comments assert.match(astString, /"name":"\*","args":\["Program comment\\n multi-line"/); assert.match(astString, /"name":"\*","args":\["Type comment"/);