From a02771594011a544832f4990e8c18347b3b8b24b Mon Sep 17 00:00:00 2001 From: John <37978984+johnridesabike@users.noreply.github.com> Date: Sat, 23 Nov 2024 17:35:54 -0500 Subject: [PATCH] Use first-class sequences, iterators, & generators This also cleans up some of the decoding functions. --- acutis.ml | 313 ++++--- acutis.mli | 35 +- acutis_cli.ml | 32 +- acutis_js.ml | 80 +- lib/instruct.ml | 523 ++++++------ test/data-test.t/run.t | 16 +- test/error_test.ml | 32 +- test/parse-test.t/run.t | 956 ++++++++++------------ test/printjs/esm-cjs.t/run.t | 60 +- test/printjs/printjs.t/run.t | 615 +++++++------- test/printjs/printjs_example.compiled.mjs | 54 +- 11 files changed, 1301 insertions(+), 1415 deletions(-) diff --git a/acutis.ml b/acutis.ml index f63ca562..b64b7e28 100644 --- a/acutis.ml +++ b/acutis.ml @@ -86,34 +86,27 @@ module type PROMISE = sig end module type DECODABLE = sig - type 'a linear - - val length : 'a linear -> int - val iteri : (int -> 'a -> unit) -> 'a linear -> unit - + type t type 'a assoc + val get_int : t -> int option + val get_string : t -> string option + val get_float : t -> float option + val get_bool : t -> bool option + val get_some : t -> t option + val get_seq : t -> t Seq.t option + val get_assoc : t -> t assoc option val assoc_find : string -> 'a assoc -> 'a val assoc_mem : string -> 'a assoc -> bool - val assoc_iter : (string -> 'a -> unit) -> 'a assoc -> unit - - type t - + val assoc_to_seq : 'a assoc -> (string * 'a) Seq.t val null : t val some : t -> t val of_float : float -> t val of_string : string -> t val of_bool : bool -> t val of_int : int -> t - val of_array : t array -> t - val of_assoc : (string * t) Seq.t -> t - val decode_int : t -> int option - val decode_string : t -> string option - val decode_float : t -> float option - val decode_bool : t -> bool option - val decode_some : t -> t option - val decode_linear : t -> t linear option - val decode_assoc : t -> t assoc option + val of_seq : t Seq.t -> t + val of_seq_assoc : (string * t) Seq.t -> t val to_string : t -> string end @@ -145,36 +138,51 @@ end = struct let float = Fun.id let string = Fun.id let bool = Fun.id + let pair = Fun.id + let unpair = Fun.id type 'a obs = 'a let observe = Fun.id - let string_iter s f = String.iter f s + + let uncons seq ~nil ~cons = + match seq () with Seq.Nil -> nil () | Seq.Cons (x, s) -> cons x s + + let generator : type a. ((a -> unit) -> unit) -> a Seq.t = + fun f -> + let module M = struct + type _ Effect.t += Yield : a -> unit Effect.t + end in + let yield v = Effect.perform (M.Yield v) in + let retc () = Seq.Nil in + let effc : + type b. b Effect.t -> ((b, _) Effect.Deep.continuation -> _) option = + function + | M.Yield v -> Some (fun k -> Seq.Cons (v, Effect.Deep.continue k)) + | _ -> None + in + fun () -> Effect.Deep.match_with f yield { retc; exnc = raise; effc } + + let iter s f = Seq.iter f s + let string_to_seq = String.to_seq let match_char = ( |> ) let array = Fun.id let array_make = Array.make let ( .%() ) = Array.get let ( .%()<- ) = Array.set - module Tbl = Hashtbl.Make (String) - - type 'a hashtbl = 'a Tbl.t + module Tbl = Hashtbl.MakeSeeded (String) let hashtbl = Tbl.of_seq let hashtbl_create () = Tbl.create 16 let ( .%{} ) = Tbl.find let ( .%{}<- ) = Tbl.add let hashtbl_mem = Tbl.mem - let hashtbl_iter x f = Tbl.iter f x - - type buffer = Buffer.t - + let hashtbl_to_seq = Tbl.to_seq let buffer_create () = Buffer.create 1024 let buffer_add_string = Buffer.add_string - let buffer_add_buffer = Buffer.add_buffer let buffer_add_char = Buffer.add_char let buffer_contents = Buffer.contents - let buffer_clear = Buffer.clear let buffer_length = Buffer.length type 'a promise = 'a P.t @@ -187,28 +195,10 @@ end = struct module External = struct include D - let of_hashtbl x = Tbl.to_seq x |> D.of_assoc - - type _ classify = - | Int : int classify - | String : string classify - | Float : float classify - | Bool : bool classify - | Not_null : t classify - | Linear : t linear classify - | Assoc : t assoc classify - - let classify_opt : type a. a classify -> t -> a option = function - | Int -> decode_int - | String -> decode_string - | Float -> decode_float - | Bool -> decode_bool - | Linear -> decode_linear - | Assoc -> decode_assoc - | Not_null -> decode_some - - let classify c t ~ok ~error = - match classify_opt c t with Some x -> ok x | None -> error () + type 'a decoder = t -> 'a option + + let decode f t ~ok ~error = + match f t with Some x -> ok x | None -> error () end module Data = struct @@ -217,7 +207,7 @@ end = struct | Float of float | String of string | Array of t array - | Hashtbl of t hashtbl + | Hashtbl of t Tbl.t | Unknown of External.t let int x = Int x @@ -252,11 +242,12 @@ end = struct | Int x -> External.of_int x | Float x -> External.of_float x | String x -> External.of_string x - | Array x -> Array.map to_external_untyped x |> External.of_array + | Array x -> + Array.to_seq x |> Seq.map to_external_untyped |> External.of_seq | Hashtbl x -> Tbl.to_seq x |> Seq.map (fun (k, v) -> (k, to_external_untyped v)) - |> External.of_assoc + |> External.of_seq_assoc let rec equal a b = match (a, b) with @@ -332,23 +323,28 @@ module PrintJs = struct F.pp_print_custom_break ~fits:("", 0, "") ~breaks:(",", -2, "") (** See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String#escape_sequences *) + let pp_char_aux ~newline ppf = function + | '\n' -> F.fprintf ppf "\\n%a" newline () + | '\b' -> F.pp_print_string ppf "\\b" + | '\t' -> F.pp_print_string ppf "\\t" + | '\012' -> F.pp_print_string ppf "\\f" + | '\r' -> F.pp_print_string ppf "\\r" + | '\\' -> F.pp_print_string ppf "\\\\" + | '"' -> F.pp_print_string ppf "\\\"" + | c -> F.pp_print_char ppf c + let pp_string ppf s = let newline = if String.length s < 60 then F.pp_print_nothing else fun ppf () -> F.pp_print_string ppf "\\\n" in - let pp_char ppf = function - | '\n' -> F.fprintf ppf "\\n%a" newline () - | '\b' -> F.pp_print_string ppf "\\b" - | '\t' -> F.pp_print_string ppf "\\t" - | '\012' -> F.pp_print_string ppf "\\f" - | '\r' -> F.pp_print_string ppf "\\r" - | '\\' -> F.pp_print_string ppf "\\\\" - | '"' -> F.pp_print_string ppf "\\\"" - | c -> F.pp_print_char ppf c - in let pp_sep = F.pp_print_nothing in - F.fprintf ppf "\"%a\"" (F.pp_print_iter ~pp_sep String.iter pp_char) s + F.fprintf ppf "\"%a\"" + (F.pp_print_iter ~pp_sep String.iter (pp_char_aux ~newline)) + s + + let pp_char ppf c = + F.fprintf ppf "\"%a\"" (pp_char_aux ~newline:F.pp_print_nothing) c (** Common functions used amongst the different modules. *) module JavascriptShared = struct @@ -364,9 +360,13 @@ module PrintJs = struct f name) ppf state - let ( @@ ) f e ppf state = - F.fprintf ppf "@[%a(@,@[%a@]@;<0 -2>)@]" f state e state + let apply_n f args ppf state = + F.fprintf ppf "@[%a(@,%a@;<0 -2>)@]" f state + (F.pp_print_list ~pp_sep:A.Pp.comma (fun ppf x -> + F.fprintf ppf "@[%a@]" x state)) + args + let ( @@ ) f e = apply_n f [ e ] let string x ppf _ = pp_string ppf x let set a b = @@ -466,27 +466,52 @@ module PrintJs = struct let state = State.add_block state in F.fprintf ppf "{@ %a@;<1 -2>}@]" (stmts ()) state + let array_of_seq seq ppf state = + F.fprintf ppf "[@,%a%t]" + (F.pp_print_seq ~pp_sep:A.Pp.comma (fun ppf x -> + F.fprintf ppf "@[%a@]" x state)) + seq trailing_comma + let unit _ _ = () let not x ppf state = F.fprintf ppf "@[!(%a)@]" x state let int x ppf _ = F.pp_print_int ppf x let float x ppf _ = F.pp_print_float ppf x - let char x ppf _ = F.pp_print_int ppf (Char.code x) + let char x ppf _ = pp_char ppf x let bool x ppf _ = F.pp_print_bool ppf x let ( = ) a b ppf state = F.fprintf ppf "%a ===@ %a" a state b state + let pair (a, b) = array_of_seq (Seq.cons a (Seq.cons b Seq.empty)) + let unpair x = (x.%(int 0), x.%(int 1)) let to_string x = global "String" @@ x let string_of_int = to_string - let float_of_int = Fun.id let string_of_float = to_string let string_of_bool = to_string - let for_ expr stmts ppf state = + let obj l ppf state = + F.fprintf ppf "@[{@,%a@;<0 -2>}@]" + (F.pp_print_list ~pp_sep:A.Pp.comma (fun ppf (k, v) -> + F.fprintf ppf "@[%s:@ %a@]" k v state)) + l + + (** Sequences use the JS iterator protocol. **) + let uncons seq ~nil ~cons = + let$ next = ("next", apply_n seq.!("next") []) in + if_else next.!("done") ~then_:nil ~else_:(fun () -> + cons next.!("value") seq) + + let yield x = + stmt (fun ppf -> F.fprintf ppf "yield (@,@[%a@]@;<0 -2>)" x) + + let generator f ppf state = + let state = State.add_block state in + F.fprintf ppf "(function* () {@ %a@;<1 -2>})()" (f yield) state + + let iter seq f ppf state = let state' = State.add_block state in - let i = State.var "i" state' in - F.fprintf ppf "@[for (let %a = 0; %a < %a; %a++) {@ %a@;<0 -2>}@]" i - state' i state' expr state i state' (stmts i) state' + let item = State.var "item" state' in + F.fprintf ppf "@[for (let %a of %a) {@ %a@;<0 -2>}@]" item state' + seq state (f item) state' - let string_iter s f = - for_ s.!("length") (fun i -> ( let$ ) ("c", s.!("charCodeAt") @@ i) f) + let string_to_seq x = apply_n x.%((global "Symbol").!("iterator")) [] let switch exp cases default ppf state = F.fprintf ppf "@[@[switch (%a)@] {@ " exp state; @@ -512,34 +537,8 @@ module PrintJs = struct ] (f '\x00') - let array_of_iter iter s ppf state = - F.fprintf ppf "[@,%a%t]" - (F.pp_print_iter ~pp_sep:A.Pp.comma iter (fun ppf x -> - F.fprintf ppf "@[%a@]" x state)) - s trailing_comma - - let array = array_of_iter Array.iter - - let apply_n f args ppf state = - F.fprintf ppf "@[%a(@,%a@;<0 -2>)@]" f state - (F.pp_print_list ~pp_sep:A.Pp.comma (fun ppf x -> - F.fprintf ppf "@[%a@]" x state)) - args - - let obj l ppf state = - F.fprintf ppf "@[{@,%a@;<0 -2>}@]" - (F.pp_print_list ~pp_sep:A.Pp.comma (fun ppf (k, v) -> - F.fprintf ppf "@[%s:@ %a@]" k v state)) - l - - let array_make i x = - apply_n - (global "Array").!("from") - [ obj [ ("length", i) ]; lambda (fun _ -> return x) ] - - type 'a hashtbl - - let pair = array_of_iter (fun f (a, b) -> f a; f b) + let array a = array_of_seq (Array.to_seq a) + let array_make i x = array_of_seq (Seq.init i (Fun.const x)) let new_ name args ppf state = F.fprintf ppf "@[new %s(@,@[%a@]@;<0 -2>)@]" name @@ -547,22 +546,12 @@ module PrintJs = struct F.fprintf ppf "@[%a@]" x state)) args - let hashtbl s = new_ "Map" [ array_of_iter Seq.iter (Seq.map pair s) ] + let hashtbl s = new_ "Map" [ array_of_seq (Seq.map pair s) ] let hashtbl_create () = new_ "Map" [ unit ] let ( .%{} ) x k = x.!("get") @@ k let ( .%{}<- ) x k v = stmt (apply_n x.!("set") [ k; v ]) let hashtbl_mem x k = x.!("has") @@ k - - let for_of expr stmts ppf state = - let state' = State.add_block state in - let x = State.var "x" state' in - F.fprintf ppf "@[for (let %a of %a) {@ %a@;<0 -2>}@]" x state' expr - state (stmts x) state' - - let hashtbl_iter x f = - for_of x (fun entry -> f entry.%(int 0) entry.%(int 1)) - - type buffer + let hashtbl_to_seq x = apply_n x.!("entries") [] let ( += ) a b = stmt (fun ppf state -> @@ -570,13 +559,8 @@ module PrintJs = struct let buffer_create () = obj [ ("contents", string "") ] let buffer_add_string b s = b.!("contents") += s - let buffer_add_buffer b1 b2 = buffer_add_string b1 b2.!("contents") - - let buffer_add_char b c = - buffer_add_string b ((global "String").!("fromCharCode") @@ c) - + let buffer_add_char = buffer_add_string let buffer_contents b = b.!("contents") - let buffer_clear b = set b.!("contents") (string "") let buffer_length b = b.!("contents").!("length") type 'a promise @@ -592,19 +576,6 @@ module PrintJs = struct let typeof expr ppf state = F.fprintf ppf "typeof %a" expr state module External = struct - type 'a linear - - let length a = a.!("length") - let iteri f a = for_ (length a) (fun i -> f i a.%(i)) - - type 'a assoc - - let assoc_find k x = x.%(k) - let assoc_mem k x = apply_n (global "Object").!("hasOwn") [ x; k ] - - let assoc_iter f x = - for_of ((global "Object").!("keys") @@ x) (fun key -> f key x.%(key)) - type t let null = global "null" @@ -613,30 +584,56 @@ module PrintJs = struct let of_float = Fun.id let of_string = Fun.id let of_bool = Fun.id - let of_array = Fun.id - let of_hashtbl x = (global "Object").!("fromEntries") @@ x - - type _ classify = - | Int : int classify - | String : string classify - | Float : float classify - | Bool : bool classify - | Not_null : t classify - | Linear : t linear classify - | Assoc : t assoc classify - - let classify (type a) (c : a classify) x ~ok ~error = - let cond = - match c with - | Int -> (global "Number").!("isInteger") @@ x - | String -> typeof x = string "string" - | Float -> typeof x = string "number" - | Bool -> typeof x = string "boolean" - | Not_null -> and_ (not (x = null)) (not (x = global "undefined")) - | Linear -> (global "Array").!("isArray") @@ x - | Assoc -> and_ (typeof x = string "object") (not (x = null)) - in - if_else cond ~then_:(fun () -> ok x) ~else_:error + let of_seq x = (global "Array").!("from") @@ x + let of_seq_assoc x = (global "Object").!("fromEntries") @@ x + + type 'a assoc + + let assoc_find k x = x.%(k) + let assoc_mem k x = apply_n (global "Object").!("hasOwn") [ x; k ] + let array_values a = apply_n a.!("values") [] + let assoc_to_seq x = array_values ((global "Object").!("entries") @@ x) + + type 'a decoder = { + test : t exp -> bool exp; + convert : 'b. t exp -> ('a exp -> 'b stmt) -> 'b stmt; + } + + let get_int = + { + test = (fun x -> (global "Number").!("isInteger") @@ x); + convert = ( |> ); + } + + let get_string = + { test = (fun x -> typeof x = string "string"); convert = ( |> ) } + + let get_float = + { test = (fun x -> typeof x = string "number"); convert = ( |> ) } + + let get_bool = + { test = (fun x -> typeof x = string "boolean"); convert = ( |> ) } + + let get_some = + { + test = (fun x -> and_ (not (x = null)) (not (x = global "undefined"))); + convert = ( |> ); + } + + let get_seq = + { + test = (fun x -> (global "Array").!("isArray") @@ x); + convert = (fun x f -> ( let$ ) ("seq", array_values x) f); + } + + let get_assoc = + { + test = (fun x -> and_ (typeof x = string "object") (not (x = null))); + convert = ( |> ); + } + + let decode { test; convert } x ~ok ~error = + if_else (test x) ~then_:(fun () -> convert x ok) ~else_:error let to_string = to_string end @@ -720,7 +717,6 @@ module PrintJs = struct let lambda f = fwde (F.lambda (fun x -> bwds (f { from = x; identity = true }))) - let float_of_int x = { x with from = F.float_of_int x.from } let ( ! ) x = { from = F.(!x); identity = true } module Data = struct @@ -750,7 +746,6 @@ module PrintJs = struct let of_float x = { x with from = F.External.of_float x.from } let of_string x = { x with from = F.External.of_string x.from } let of_bool x = { x with from = F.External.of_bool x.from } - let of_array x = { x with from = F.External.of_array x.from } end end diff --git a/acutis.mli b/acutis.mli index 5835e7bf..8987260d 100644 --- a/acutis.mli +++ b/acutis.mli @@ -171,22 +171,23 @@ end module type DECODABLE = sig (** Decode and encode input data. *) - (** {1 Container types.} *) - - type 'a linear - (** A linear container such as a list or array. *) - - val length : 'a linear -> int - val iteri : (int -> 'a -> unit) -> 'a linear -> unit + type t type 'a assoc (** A key-value container such as an association list or a string map. *) + (** {1 Decoding} *) + + val get_int : t -> int option + val get_string : t -> string option + val get_float : t -> float option + val get_bool : t -> bool option + val get_some : t -> t option + val get_seq : t -> t Seq.t option + val get_assoc : t -> t assoc option val assoc_find : string -> 'a assoc -> 'a val assoc_mem : string -> 'a assoc -> bool - val assoc_iter : (string -> 'a -> unit) -> 'a assoc -> unit - - type t + val assoc_to_seq : 'a assoc -> (string * 'a) Seq.t (** {1 Encoding} *) @@ -196,18 +197,8 @@ module type DECODABLE = sig val of_string : string -> t val of_bool : bool -> t val of_int : int -> t - val of_array : t array -> t - val of_assoc : (string * t) Seq.t -> t - - (** {1 Decoding} *) - - val decode_int : t -> int option - val decode_string : t -> string option - val decode_float : t -> float option - val decode_bool : t -> bool option - val decode_some : t -> t option - val decode_linear : t -> t linear option - val decode_assoc : t -> t assoc option + val of_seq : t Seq.t -> t + val of_seq_assoc : (string * t) Seq.t -> t (** {1 Debugging} *) diff --git a/acutis_cli.ml b/acutis_cli.ml index c7e96d2d..9d04b356 100644 --- a/acutis_cli.ml +++ b/acutis_cli.ml @@ -9,34 +9,32 @@ (**************************************************************************) module Json = struct - type 'a linear = 'a list + type t = Yojson.Basic.t + type 'a assoc = (string * 'a) list - let length = List.length - let iteri = List.iteri + let get_int = function `Int x -> Some x | _ -> None + let get_string = function `String x -> Some x | _ -> None - type 'a assoc = (string * 'a) list + let get_float = function + | `Float x -> Some x + | `Int x -> Some (Float.of_int x) + | _ -> None + let get_bool = function `Bool x -> Some x | _ -> None + let get_some = function `Null -> None | x -> Some x + let get_seq = function `List x -> Some (List.to_seq x) | _ -> None + let get_assoc = function `Assoc x -> Some x | _ -> None let assoc_find = List.assoc let assoc_mem = List.mem_assoc - let assoc_iter f l = List.iter (fun (k, v) -> f k v) l - - type t = Yojson.Basic.t - + let assoc_to_seq = List.to_seq let null = `Null let some = Fun.id let of_float x = `Float x let of_string x = `String x let of_bool x = `Bool x let of_int x = `Int x - let of_array x = `List (Array.to_list x) - let of_assoc x = `Assoc (List.of_seq x) - let decode_int = function `Int x -> Some x | _ -> None - let decode_string = function `String x -> Some x | _ -> None - let decode_float = function `Float x -> Some x | _ -> None - let decode_bool = function `Bool x -> Some x | _ -> None - let decode_linear = function `List x -> Some x | _ -> None - let decode_assoc = function `Assoc x -> Some x | _ -> None - let decode_some = function `Null -> None | x -> Some x + let of_seq x = `List (List.of_seq x) + let of_seq_assoc x = `Assoc (List.of_seq x) let to_string t = Yojson.Basic.pretty_to_string t end diff --git a/acutis_js.ml b/acutis_js.ml index 701defdb..b139881e 100644 --- a/acutis_js.ml +++ b/acutis_js.ml @@ -11,10 +11,7 @@ open Js_of_ocaml module DecodeJs = struct - type 'a linear = 'a Js.js_array Js.t - - let length a = a##.length - let iteri f a = a##forEach (Js.wrap_callback (fun v i _ -> f i v)) + type t = Js.Unsafe.any type 'a assoc = Js.Unsafe.any (** When we convert JavaScript objects into Acutis records, we cannot convert @@ -24,63 +21,74 @@ module DecodeJs = struct accessing the precise values that we need, we avoid triggering unexpected behavior. *) - let assoc_find : string -> 'a assoc -> 'a = - fun k m -> Js.Unsafe.get m (Js.string k) - - let assoc_mem : string -> 'a assoc -> bool = - fun k m -> Js.Unsafe.global##._Object##hasOwn m (Js.string k) |> Js.to_bool - - let assoc_iter : (string -> 'a -> unit) -> 'a assoc -> unit = - fun f m -> - (Js.object_keys m)##forEach - (Js.wrap_callback (fun k _ _ -> f (Js.to_string k) (Js.Unsafe.get m k))) - - type t = Js.Unsafe.any - let coerce = Js.Unsafe.coerce - let null = Js.Unsafe.inject Js.null - let some = Fun.id - let of_float x = Js.number_of_float x |> coerce - let of_string x = Js.string x |> coerce - let of_bool x = Js.bool x |> coerce - let of_int x = Float.of_int x |> Js.number_of_float |> coerce - let of_array x = Js.array x |> coerce - let of_assoc x = Array.of_seq x |> Js.Unsafe.obj - let decode_int j = + let get_int j = match Js.to_string (Js.typeof j) with | "number" -> let n = coerce j |> Js.float_of_number in if Float.is_integer n then Some (Float.to_int n) else None | _ -> None - let decode_string j = + let get_string j = match Js.to_string (Js.typeof j) with | "string" -> Some (coerce j |> Js.to_string) | _ -> None - let decode_float j = + let get_float j = match Js.to_string (Js.typeof j) with | "number" -> Some (coerce j |> Js.float_of_number) | _ -> None - let decode_bool j = + let get_bool j = match Js.to_string (Js.typeof j) with | "boolean" -> Some (coerce j |> Js.to_bool) | _ -> None - let decode_linear j = - if Js.Unsafe.global##._Array##isArray j then Some (coerce j) else None + let get_some j = + match Js.to_string (Js.typeof j) with + | "undefined" -> None + | _ -> Js.Opt.to_option (Js.Opt.return j) - let decode_assoc j = + let get_seq j = + if Js.Unsafe.global##._Array##isArray j then + let a = coerce j in + let rec aux i () = + Js.Optdef.case (Js.array_get a i) + (fun () -> Seq.Nil) + (fun x -> Seq.Cons (x, aux (succ i))) + in + Some (aux 0) + else None + + let get_assoc j = match Js.to_string (Js.typeof j) with | "object" -> Js.Opt.to_option (Js.Opt.return j) | _ -> None - let decode_some j = - match Js.to_string (Js.typeof j) with - | "undefined" -> None - | _ -> Js.Opt.to_option (Js.Opt.return j) + let assoc_find : string -> 'a assoc -> 'a = + fun k m -> Js.Unsafe.get m (Js.string k) + + let assoc_mem : string -> 'a assoc -> bool = + fun k m -> Js.Unsafe.global##._Object##hasOwn m (Js.string k) |> Js.to_bool + + let assoc_to_seq m = + let keys = Js.object_keys m in + let rec aux i () = + Js.Optdef.case (Js.array_get keys i) + (fun () -> Seq.Nil) + (fun k -> Seq.Cons ((Js.to_string k, Js.Unsafe.get m k), aux (succ i))) + in + aux 0 + + let null = Js.Unsafe.inject Js.null + let some = Fun.id + let of_float x = Js.number_of_float x |> coerce + let of_string x = Js.string x |> coerce + let of_bool x = Js.bool x |> coerce + let of_int x = Float.of_int x |> Js.number_of_float |> coerce + let of_seq x = Array.of_seq x |> Js.array |> coerce + let of_seq_assoc x = Array.of_seq x |> Js.Unsafe.obj let to_string j = Js.Unsafe.fun_call Js.Unsafe.global##._String [| j |] |> Js.to_string diff --git a/lib/instruct.ml b/lib/instruct.ml index 51b39d5b..0f4ad0f2 100644 --- a/lib/instruct.ml +++ b/lib/instruct.ml @@ -47,10 +47,10 @@ module type SEM = sig val stmt : 'a exp -> 'a stmt type 'a ref - (** A mutable reference variable. *) + (** A mutable reference variable. This is not compatible with expressions. *) val ( let| ) : unit stmt -> (unit -> 'a stmt) -> 'a stmt - (** Sequence statements.*) + (** Evaluate a unit statement.*) val ( let$ ) : string * 'a exp -> ('a exp -> 'b stmt) -> 'b stmt (** Define a new immutable binding. The string is used for pretty-printing. *) @@ -86,14 +86,26 @@ module type SEM = sig val string : string -> string exp val bool : bool -> bool exp val ( = ) : 'a exp -> 'a exp -> bool exp + val pair : 'a exp * 'b exp -> ('a * 'b) exp + val unpair : ('a * 'b) exp -> 'a exp * 'b exp val string_of_int : int exp -> string exp - val float_of_int : int exp -> float exp val string_of_float : float exp -> string exp val string_of_bool : bool exp -> string exp + (** {1 Sequences.} *) + + val uncons : + 'a Seq.t exp -> + nil:(unit -> 'b stmt) -> + cons:('a exp -> 'a Seq.t exp -> 'b stmt) -> + 'b stmt + + val generator : (('a exp -> unit stmt) -> unit stmt) -> 'a Seq.t exp + val iter : 'a Seq.t exp -> ('a exp -> unit stmt) -> unit stmt + (** {1 Strings and characters.} *) - val string_iter : string exp -> (char exp -> unit stmt) -> unit stmt + val string_to_seq : string exp -> char Seq.t exp val match_char : char exp -> (char -> 'a stmt) -> 'a stmt (** The given function applies to the following characters and it ignores all @@ -102,36 +114,28 @@ module type SEM = sig (** {1 Arrays.} *) val array : 'a exp array -> 'a array exp - val array_make : int exp -> 'a exp -> 'a array exp + val array_make : int -> 'a exp -> 'a array exp val ( .%() ) : 'a array exp -> int exp -> 'a exp val ( .%()<- ) : 'a array exp -> int exp -> 'a exp -> unit stmt (** {1 Hash tables.} *) - type 'a hashtbl - (** A mutable map of string keys to ['a] values. *) + type 'a hashtbl := 'a Hashtbl.MakeSeeded(String).t val hashtbl : (string exp * 'a exp) Seq.t -> 'a hashtbl exp val hashtbl_create : unit -> 'a hashtbl exp val ( .%{} ) : 'a hashtbl exp -> string exp -> 'a exp val ( .%{}<- ) : 'a hashtbl exp -> string exp -> 'a exp -> unit stmt val hashtbl_mem : 'a hashtbl exp -> string exp -> bool exp + val hashtbl_to_seq : 'a hashtbl exp -> (string * 'a) Seq.t exp - val hashtbl_iter : - 'a hashtbl exp -> (string exp -> 'a exp -> unit stmt) -> unit stmt + (** {1 Mutable string buffers.} *) - (** {1 Buffers.} *) - - type buffer - (** A mutable string buffer. *) - - val buffer_create : unit -> buffer exp - val buffer_add_string : buffer exp -> string exp -> unit stmt - val buffer_add_buffer : buffer exp -> buffer exp -> unit stmt - val buffer_add_char : buffer exp -> char exp -> unit stmt - val buffer_contents : buffer exp -> string exp - val buffer_length : buffer exp -> int exp - val buffer_clear : buffer exp -> unit stmt + val buffer_create : unit -> Buffer.t exp + val buffer_add_string : Buffer.t exp -> string exp -> unit stmt + val buffer_add_char : Buffer.t exp -> char exp -> unit stmt + val buffer_contents : Buffer.t exp -> string exp + val buffer_length : Buffer.t exp -> int exp (** {1 Promises.} *) @@ -148,46 +152,38 @@ module type SEM = sig (** {1 Data} *) module External : sig - (** Foreign data before it's parsed into {!Data.t}. *) + (** Data from the outside world that we need to decode. *) - type 'a linear - (** A linear container such as a list or array. *) + type t - val length : 'a linear exp -> int exp - val iteri : (int exp -> 'a exp -> unit stmt) -> 'a linear exp -> unit stmt + val null : t exp + val some : t exp -> t exp + val of_int : int exp -> t exp + val of_float : float exp -> t exp + val of_string : string exp -> t exp + val of_bool : bool exp -> t exp + val of_seq : t Seq.t exp -> t exp + val of_seq_assoc : (string * t) Seq.t exp -> t exp type 'a assoc (** A key-value container such as an association list or a string map. *) val assoc_find : string exp -> 'a assoc exp -> 'a exp val assoc_mem : string exp -> 'a assoc exp -> bool exp + val assoc_to_seq : 'a assoc exp -> (string * 'a) Seq.t exp - val assoc_iter : - (string exp -> 'a exp -> unit stmt) -> 'a assoc exp -> unit stmt + type 'a decoder - type t - (** Data from the outside world that we need to decode. *) + val get_int : int decoder + val get_string : string decoder + val get_float : float decoder + val get_bool : bool decoder + val get_some : t decoder + val get_seq : t Seq.t decoder + val get_assoc : t assoc decoder - val null : t exp - val some : t exp -> t exp - val of_int : int exp -> t exp - val of_float : float exp -> t exp - val of_string : string exp -> t exp - val of_bool : bool exp -> t exp - val of_array : t array exp -> t exp - val of_hashtbl : t hashtbl exp -> t exp - - type _ classify = - | Int : int classify - | String : string classify - | Float : float classify - | Bool : bool classify - | Not_null : t classify - | Linear : t linear classify - | Assoc : t assoc classify - - val classify : - 'a classify -> + val decode : + 'a decoder -> t exp -> ok:('a exp -> 'b stmt) -> error:(unit -> 'b stmt) -> @@ -200,7 +196,6 @@ module type SEM = sig (** Runtime data. *) type t - (** Either a string, an integer, a float, an array, or a hash table. *) val int : int exp -> t exp val float : float exp -> t exp @@ -267,10 +262,12 @@ end = struct fun seq -> match seq () with Seq.Nil -> unit | Seq.Cons (s1, seq) -> aux s1 seq + type 'a hashtbl = 'a Hashtbl.MakeSeeded(String).t + type state = { components : (Data.t hashtbl -> string promise) hashtbl exp; - buf : buffer exp; - escape : (buffer -> string -> unit) exp; + buf : Buffer.t exp; + escape : (Buffer.t -> string -> unit) exp; props : Data.t hashtbl exp; (** We need to use a hash table as the root scope because components take a hash table as input. *) @@ -501,7 +498,10 @@ end = struct | Compile.Map_dict (blocks, data, { tree; exits }) -> let@ blocks = construct_blocks state blocks in let$ match_arg = ("match_arg", construct_data blocks state data) in - hashtbl_iter (Data.to_hashtbl match_arg) (fun k v -> + iter + (hashtbl_to_seq (Data.to_hashtbl match_arg)) + (fun p -> + let k, v = unpair p in let@ new_props = make_match_props exits in let& exit = ("exit", unset_exit) in let| () = @@ -552,9 +552,9 @@ end = struct ty_str : string exp; stack : 'stack exp; stack_add : (string -> 'stack -> 'stack) exp; - buffer_add_sep : (buffer -> string -> string -> unit) exp; + buffer_add_sep : (Buffer.t -> string -> string -> unit) exp; decode_error : (External.t -> 'stack -> string -> unit) exp; - key_error : (buffer -> 'stack -> string -> unit) exp; + key_error : (Buffer.t -> 'stack -> string -> unit) exp; } let show_type = @@ -580,7 +580,7 @@ end = struct match ty.contents with | T.Unknown _ -> set (Data.unknown input) | T.Enum_int ({ cases; _ }, Bool) -> - External.classify Bool input + External.decode External.get_bool input ~ok:(fun b -> if_else b ~then_:(fun () -> @@ -591,11 +591,11 @@ end = struct else push_error debug input)) ~error:(fun () -> push_error debug input) | T.String | T.Enum_string { row = `Open; _ } -> - External.classify String input + External.decode External.get_string input ~ok:(fun s -> set (Data.string s)) ~error:(fun () -> push_error debug input) | T.Enum_string { row = `Closed; cases } -> - External.classify String input + External.decode External.get_string input ~ok:(fun s -> let rec aux seq = match seq () with @@ -609,11 +609,11 @@ end = struct aux (SetString.to_seq cases)) ~error:(fun () -> push_error debug input) | T.Int | T.Enum_int ({ row = `Open; _ }, _) -> - External.classify Int input + External.decode External.get_int input ~ok:(fun i -> set (Data.int i)) ~error:(fun () -> push_error debug input) | T.Enum_int ({ row = `Closed; cases }, _) -> - External.classify Int input + External.decode External.get_int input ~ok:(fun s -> let rec aux seq = match seq () with @@ -627,14 +627,11 @@ end = struct aux (SetInt.to_seq cases)) ~error:(fun () -> push_error debug input) | T.Float -> - External.classify Float input + External.decode External.get_float input ~ok:(fun f -> set (Data.float f)) - ~error:(fun () -> - External.classify Int input - ~ok:(fun i -> set (Data.float (float_of_int i))) - ~error:(fun () -> push_error debug input)) + ~error:(fun () -> push_error debug input) | T.Nullable ty -> - External.classify Not_null input + External.decode External.get_some input ~ok:(fun input -> let$ decoded = ("decoded", array [| nil_value |]) in let$ stack = ("stack", stack_add debug (string "")) in @@ -646,80 +643,76 @@ end = struct set (Data.array decoded)) ~error:(fun () -> set nil_value) | T.List ty -> - External.classify Linear input - ~ok:(fun l -> + External.decode External.get_seq input + ~ok:(fun seq -> + let& i = ("index", int 0) in let$ decoded = ("decoded", array [| nil_value; nil_value |]) in let& decode_dst = ("decode_dst", decoded) in let| () = - External.iteri - (fun i input -> + iter seq (fun input -> let$ decode_dst_new = ("decode_dst_new", array [| nil_value; nil_value |]) in - let$ stack = ("stack", stack_add debug (string_of_int i)) in + let$ stack = ("stack", stack_add debug (string_of_int !i)) in let| () = decode ~set:(fun data -> decode_dst_new.%(int 0) <- data) ~debug:{ debug with stack } input ty in let| () = !decode_dst.%(int 1) <- Data.array decode_dst_new in + let| () = incr i in decode_dst := decode_dst_new) - l in set (list_tl decoded)) ~error:(fun () -> push_error debug input) | T.Tuple tys -> - let length = int (List.length tys) in - External.classify Linear input - ~ok:(fun l -> - if_else - (External.length l = length) - ~then_:(fun () -> - let$ decoded = ("decoded", array_make length nil_value) in - External.iteri - (fun i input -> - let$ stack = ("stack", stack_add debug (string_of_int i)) in - let debug = { debug with stack } in - let rec aux i' = function - | [] -> push_error debug input - | ty :: tl -> - if_else - (i = int i') - ~then_:(fun () -> - decode - ~set:(fun data -> decoded.%(i) <- data) - ~debug input ty) - ~else_:(fun () -> aux (succ i') tl) - in - let| () = aux 0 tys in - set (Data.array decoded)) - l) - ~else_:(fun () -> push_error debug input)) + External.decode External.get_seq input + ~ok:(fun seq -> + let length = List.length tys in + let$ decoded = ("decoded", array_make length nil_value) in + let rec aux i seq = function + | [] -> unit + | ty :: tl -> + uncons seq + ~nil:(fun () -> push_error debug input) + ~cons:(fun input seq -> + let$ stack = + ("stack", stack_add debug (string_of_int (int i))) + in + let debug = { debug with stack } in + let| () = + decode + ~set:(fun data -> decoded.%(int i) <- data) + ~debug input ty + in + aux (succ i) seq tl) + in + let| () = aux 0 seq tys in + set (Data.array decoded)) ~error:(fun () -> push_error debug input) | T.Record tys -> - External.classify Assoc input - ~ok:(fun input' -> + External.decode External.get_assoc input + ~ok:(fun input -> let$ decoded = ("decoded", hashtbl_create ()) in - let| () = decode_record_aux ~debug decoded input' tys.contents in + let| () = decode_record_aux ~debug decoded input tys.contents in set (Data.hashtbl decoded)) ~error:(fun () -> push_error debug input) | T.Dict (ty, _) -> - External.classify Assoc input - ~ok:(fun a -> + External.decode External.get_assoc input + ~ok:(fun input -> let$ decoded = ("decoded", hashtbl_create ()) in - External.assoc_iter - (fun k input -> + iter (External.assoc_to_seq input) (fun p -> + let k, input = unpair p in let$ stack = ("stack", stack_add debug k) in let| () = decode ~set:(fun data -> decoded.%{k} <- data) ~debug:{ debug with stack } input ty in - set (Data.hashtbl decoded)) - a) + set (Data.hashtbl decoded))) ~error:(fun () -> push_error debug input) | T.Union_int (key, { cases; row }, Bool) -> - decode_union Bool + decode_union External.get_bool ~if_equal:(fun extern ty ~then_ ~else_ -> match ty with | 0 -> @@ -731,14 +724,14 @@ end = struct ~else_:(fun () -> f false_value)) (MapInt.to_seq cases) (string key) row ~set ~debug input | T.Union_int (key, { cases; row }, Not_bool) -> - decode_union Int + decode_union External.get_int ~if_equal:(fun extern ty ~then_ ~else_ -> let ty = int ty in if_else (extern = ty) ~then_:(fun () -> then_ (Data.int ty)) ~else_) ~if_open:(fun x f -> f (Data.int x)) (MapInt.to_seq cases) (string key) row ~set ~debug input | T.Union_string (key, { cases; row }) -> - decode_union String + decode_union External.get_string ~if_equal:(fun extern ty ~then_ ~else_ -> let ty = string ty in if_else (extern = ty) @@ -749,7 +742,7 @@ end = struct and decode_union : type ty extern. - extern External.classify -> + extern External.decoder -> if_equal: (extern exp -> ty -> @@ -759,13 +752,13 @@ end = struct if_open:(extern exp -> (Data.t exp -> unit stmt) -> unit stmt) -> (ty * T.record) Seq.t -> _ = - fun classify ~if_equal ~if_open seq key row ~set ~debug input -> - External.classify Assoc input + fun decoder ~if_equal ~if_open seq key row ~set ~debug input -> + External.decode External.get_assoc input ~ok:(fun input' -> if_else (External.assoc_mem key input') ~then_:(fun () -> - External.classify classify + External.decode decoder (External.assoc_find key input') ~ok:(fun x -> let$ decoded = ("decoded", hashtbl_create ()) in @@ -832,53 +825,43 @@ end = struct let$ props = ("props", get_nullable props) in encode ~set:(fun x -> set (External.some x)) props ty) | T.List ty -> - let& index = ("index", int 0) in - let& cell = ("cell", props) in - let| () = - while_ is_not_nil cell (fun () -> - let| () = incr index in - cell := list_tl (Data.to_array !cell)) - in - let$ encoded = ("encoded", array_make !index External.null) in - let| () = cell := props in - let| () = index := int 0 in - let| () = - while_ is_not_nil cell (fun () -> - let$ props = ("props", Data.to_array !cell |> list_hd) in - let| () = - encode ~set:(fun x -> encoded.%(!index) <- x) props ty - in - let| () = incr index in - cell := list_tl (Data.to_array !cell)) + let$ seq = + ( "seq", + generator (fun yield -> + let& cell = ("cell", props) in + while_ is_not_nil cell (fun () -> + let$ cell' = ("cell", Data.to_array !cell) in + let$ props = ("props", list_hd cell') in + let| () = cell := list_tl cell' in + encode ~set:yield props ty)) ) in - set (External.of_array encoded) + set (External.of_seq seq) | T.Tuple tys -> let$ props = ("props", Data.to_array props) in - let$ encoded = - ("encoded", array_make (int (List.length tys)) External.null) - in - let| () = - List.to_seq tys - |> Seq.mapi (fun i ty -> - let i = int i in - let$ props = ("props", props.%(i)) in - encode ~set:(fun x -> encoded.%(i) <- x) props ty) - |> stmt_join + let$ seq = + ( "seq", + generator (fun yield -> + List.to_seq tys + |> Seq.mapi (fun i ty -> encode ~set:yield props.%(int i) ty) + |> stmt_join) ) in - set (External.of_array encoded) + set (External.of_seq seq) | T.Record tys -> - let$ encoded = ("encoded", hashtbl_create ()) in - let| () = - encode_record_aux encoded (Data.to_hashtbl props) tys.contents + let$ seq = + ("seq", encode_record_aux (Data.to_hashtbl props) tys.contents) in - set (External.of_hashtbl encoded) + set (External.of_seq_assoc seq) | T.Dict (ty, _) -> - let$ encoded = ("encoded", hashtbl_create ()) in - let| () = - hashtbl_iter (Data.to_hashtbl props) (fun k props -> - encode ~set:(fun x -> encoded.%{k} <- x) props ty) + let$ seq = + ( "seq", + generator (fun yield -> + iter + (hashtbl_to_seq (Data.to_hashtbl props)) + (fun p -> + let k, props = unpair p in + encode ~set:(fun v -> yield (pair (k, v))) props ty)) ) in - set (External.of_hashtbl encoded) + set (External.of_seq_assoc seq) | T.Union_int (key, { cases; row }, Bool) -> encode_union ~of_data:Data.to_int ~to_extern:external_of_int_bool (MapInt.to_seq cases |> Seq.map (fun (k, v) -> (int k, v))) @@ -901,35 +884,42 @@ end = struct fun ~of_data ~to_extern cases row key ~set props -> let$ props = ("props", Data.to_hashtbl props) in let$ tag = ("tag", props.%{key} |> of_data) in - let$ encoded = ("encoded", hashtbl_create ()) in - let| () = - match cases () with - | Seq.Nil -> unit - | Seq.Cons (hd, seq) -> - let rec aux (tag', tys) seq = - if_else (tag = tag') - ~then_:(fun () -> - let| () = encoded.%{key} <- to_extern tag in - encode_record_aux encoded props tys.contents) - ~else_:(fun () -> - match seq () with - | Seq.Nil -> ( + match cases () with + | Seq.Nil -> unit + | Seq.Cons (hd, seq) -> + let rec aux (tag', tys) seq = + if_else (tag = tag') + ~then_:(fun () -> + let$ seq = + ( "seq", + encode_record_aux ~tag:(key, to_extern tag) props tys.contents + ) + in + set (External.of_seq_assoc seq)) + ~else_:(fun () -> + match seq () with + | Seq.Nil -> + let tag = match row with - | `Closed -> unit - | `Open -> encoded.%{key} <- to_extern tag) - | Seq.Cons (hd, seq) -> aux hd seq) - in - aux hd seq - in - set (External.of_hashtbl encoded) + | `Closed -> None + | `Open -> Some (key, to_extern tag) + in + let$ seq = + ("seq", encode_record_aux ?tag props MapString.empty) + in + set (External.of_seq_assoc seq) + | Seq.Cons (hd, seq) -> aux hd seq) + in + aux hd seq - and encode_record_aux encoded props tys = - MapString.to_seq tys - |> Seq.map (fun (k, ty) -> - let k = string k in - let$ props = ("props", props.%{k}) in - encode ~set:(fun x -> encoded.%{k} <- x) props ty) - |> stmt_join + and encode_record_aux ?tag props tys = + generator (fun yield -> + let| () = match tag with Some t -> yield (pair t) | None -> unit in + MapString.to_seq tys + |> Seq.map (fun (k, ty) -> + let k = string k in + encode ~set:(fun v -> yield (pair (k, v))) props.%{k} ty) + |> stmt_join) let lambdak k f = lambda (fun a -> return (k (f a))) let lambda2 f = lambdak lambda f @@ -940,7 +930,7 @@ end = struct let$ escape = ( "buffer_add_escape", lambda2 (fun buf str -> - string_iter str (fun c -> + iter (string_to_seq str) (fun c -> match_char c (function | '&' -> buffer_add_string buf (string "&") | '"' -> buffer_add_string buf (string """) @@ -978,9 +968,8 @@ end = struct import v (fun import -> components.%{string k} <- lambda (fun props -> - let$ encoded = ("encoded", hashtbl_create ()) in - let| () = encode_record_aux encoded props tys in - return (import @@ External.of_hashtbl encoded))))) + let$ seq = ("seq", encode_record_aux props tys) in + return (import @@ External.of_seq_assoc seq))))) (MapString.to_seq compiled.components |> Seq.map (fun (k, v) -> components.%{string k} <- @@ -1053,7 +1042,7 @@ end = struct } in let| () = - External.classify Assoc input + External.decode External.get_assoc input ~ok:(fun input -> decode_record_aux ~debug props input compiled.types) ~error:(fun () -> push_error debug input) @@ -1101,13 +1090,10 @@ module MakeTrans and type 'a obs = 'a F.obs and type 'a exp = 'a T.exp and type 'a ref = 'a F.ref - and type 'a hashtbl = 'a F.hashtbl - and type buffer = F.buffer and type 'a promise = 'a F.promise - and type 'a External.linear = 'a F.External.linear and type 'a External.assoc = 'a F.External.assoc and type External.t = F.External.t - and type 'a External.classify = 'a F.External.classify + and type 'a External.decoder = 'a F.External.decoder and type Data.t = F.Data.t and type import = F.import = struct open T @@ -1148,19 +1134,33 @@ module MakeTrans let string x = fwde (F.string x) let bool x = fwde (F.bool x) let ( = ) a b = fwde F.(bwde a = bwde b) + let pair (a, b) = fwde (F.pair (bwde a, bwde b)) + + let unpair x = + let a, b = F.unpair (bwde x) in + (fwde a, fwde b) + let string_of_int x = fwde (F.string_of_int (bwde x)) - let float_of_int x = fwde (F.float_of_int (bwde x)) let string_of_float x = fwde (F.string_of_float (bwde x)) let string_of_bool x = fwde (F.string_of_bool (bwde x)) - let string_iter s f = - fwds (F.string_iter (bwde s) (fun c -> bwds (f (fwde c)))) + let uncons s ~nil ~cons = + fwds + (F.uncons (bwde s) + ~nil:(fun () -> bwds (nil ())) + ~cons:(fun x s -> bwds (cons (fwde x) (fwde s)))) + + let generator f = + fwde (F.generator (fun yield -> bwds (f (fun x -> fwds (yield (bwde x)))))) + + let iter s f = fwds (F.iter (bwde s) (fun x -> bwds (f (fwde x)))) + let string_to_seq s = fwde (F.string_to_seq (bwde s)) let match_char c f = fwds (F.match_char (bwde c) (fun shape -> bwds (f shape))) let array x = fwde (F.array (Array.map bwde x)) - let array_make i x = fwde (F.array_make (bwde i) (bwde x)) + let array_make i x = fwde (F.array_make i (bwde x)) let ( .%() ) a i = fwde F.((bwde a).%(bwde i)) let ( .%()<- ) a i x = fwds F.((bwde a).%(bwde i) <- bwde x) let hashtbl x = fwde (F.hashtbl (Seq.map (fun (a, b) -> (bwde a, bwde b)) x)) @@ -1168,16 +1168,11 @@ module MakeTrans let ( .%{} ) h k = fwde F.((bwde h).%{bwde k}) let ( .%{}<- ) h k x = fwds F.((bwde h).%{bwde k} <- bwde x) let hashtbl_mem h k = fwde (F.hashtbl_mem (bwde h) (bwde k)) - - let hashtbl_iter h f = - fwds (F.hashtbl_iter (bwde h) (fun k v -> bwds (f (fwde k) (fwde v)))) - + let hashtbl_to_seq h = fwde (F.hashtbl_to_seq (bwde h)) let buffer_create () = fwde (F.buffer_create ()) let buffer_add_string b s = fwds (F.buffer_add_string (bwde b) (bwde s)) - let buffer_add_buffer b s = fwds (F.buffer_add_buffer (bwde b) (bwde s)) let buffer_add_char b c = fwds (F.buffer_add_char (bwde b) (bwde c)) let buffer_contents b = fwde (F.buffer_contents (bwde b)) - let buffer_clear b = fwds (F.buffer_clear (bwde b)) let buffer_length b = fwde (F.buffer_length (bwde b)) let promise x = fwde (F.promise (bwde x)) let await p = fwde (F.await (bwde p)) @@ -1187,30 +1182,21 @@ module MakeTrans module External = struct include F.External - let length t = fwde (F.External.length (bwde t)) - - let iteri f t = - fwds (F.External.iteri (fun k v -> bwds (f (fwde k) (fwde v))) (bwde t)) - - let assoc_find s t = fwde (F.External.assoc_find (bwde s) (bwde t)) - let assoc_mem s t = fwde (F.External.assoc_mem (bwde s) (bwde t)) - - let assoc_iter f t = - fwds - (F.External.assoc_iter (fun k v -> bwds (f (fwde k) (fwde v))) (bwde t)) - let null = fwde F.External.null let some x = fwde (F.External.some (bwde x)) let of_int x = fwde (F.External.of_int (bwde x)) let of_float x = fwde (F.External.of_float (bwde x)) let of_string x = fwde (F.External.of_string (bwde x)) let of_bool x = fwde (F.External.of_bool (bwde x)) - let of_array x = fwde (F.External.of_array (bwde x)) - let of_hashtbl x = fwde (F.External.of_hashtbl (bwde x)) + let of_seq x = fwde (F.External.of_seq (bwde x)) + let of_seq_assoc x = fwde (F.External.of_seq_assoc (bwde x)) + let assoc_find s t = fwde (F.External.assoc_find (bwde s) (bwde t)) + let assoc_mem s t = fwde (F.External.assoc_mem (bwde s) (bwde t)) + let assoc_to_seq t = fwde (F.External.assoc_to_seq (bwde t)) - let classify c x ~ok ~error = + let decode d x ~ok ~error = fwds - (F.External.classify c (bwde x) + (F.External.decode d (bwde x) ~ok:(fun x -> bwds (ok (fwde x))) ~error:(fun () -> bwds (error ()))) @@ -1243,7 +1229,7 @@ end let pp (type a) pp_import ppf c = let module F = Format in let module M = Make (struct - module Tbl = Hashtbl.Make (String) + module Tbl = Hashtbl.MakeSeeded (String) let var = let tbl = Tbl.create 128 in @@ -1300,14 +1286,26 @@ let pp (type a) pp_import ppf c = let string = F.dprintf "%S" let bool = F.dprintf "%B" let ( = ) = F.dprintf "(@[%t@ =@ %t@])" + let pair (a, b) = F.dprintf "(@[%t,@ %t@])" a b + let unpair x = (F.dprintf "(@[fst@ %t@])" x, F.dprintf "(@[snd@ %t@])" x) let string_of_int = F.dprintf "(@[string_of_int@ %t@])" - let float_of_int = F.dprintf "(@[float_of_int@ %t@])" let string_of_float = F.dprintf "(@[string_of_float@ %t@])" let string_of_bool = F.dprintf "(@[string_of_bool@ %t@])" - let string_iter s f = - let arg = var "char" in - F.dprintf "(@[string_iter@ %t@ %t@])" s (f arg) + let uncons seq ~nil ~cons = + let hd = var "hd" in + let seq' = var "seq" in + F.dprintf "(@[uncons@ %t@ (@[nil@ %t@])@ (@[cons@ %t@ %t@ %t@])@])" seq + (nil ()) hd seq' (cons hd seq') + + let generator f = + F.dprintf "(@[generator@ %t@])" (f (F.dprintf "(@[yield@ %t@])")) + + let iter s f = + let arg = var "arg" in + F.dprintf "(@[iter@ %t@ %t@])" s (f arg) + + let string_to_seq = F.dprintf "(@[string_to_seq@ %t@])" let match_char c f = F.dprintf "(@[match_char@ %t@ (@[%a@ (@[_@ (@[%t@])@])@])@])" c @@ -1319,14 +1317,12 @@ let pp (type a) pp_import ppf c = let array a = F.dprintf "[@[%a@]]" (F.pp_print_array ~pp_sep:Pp.comma ( |> )) a - let array_make = F.dprintf "(@[array_make@ %t@ %t@])" + let array_make = F.dprintf "(@[array_make@ %i@ %t@])" let bindop_get = F.dprintf "(@[%t@,.%%%c@[@,%t@,@]%c@])" let bindop_set = F.dprintf "(@[%t@,.%%%c@[@,%t@,@]%c@ <-@ %t@])" let ( .%() ) a i = bindop_get a '(' i ')' let ( .%()<- ) a i v = bindop_set a '(' i ')' v - type 'a hashtbl - let hashtbl = F.dprintf "(@[hashtbl@ [@[%a@]]@])" (F.pp_print_seq ~pp_sep:Pp.comma (fun ppf (a, b) -> @@ -1336,21 +1332,11 @@ let pp (type a) pp_import ppf c = let ( .%{} ) t k = bindop_get t '{' k '}' let ( .%{}<- ) t k v = bindop_set t '{' k '}' v let hashtbl_mem = F.dprintf "(@[hashtbl_mem@ %t@ %t@])" - - let hashtbl_iter t f = - let arg_k = var "key" in - let arg_v = var "value" in - F.dprintf "(@[hashtbl_iter@ %t@ %t@ %t@ %t@])" t arg_k arg_v - (f arg_k arg_v) - - type buffer - + let hashtbl_to_seq = F.dprintf "(@[hashtbl_to_seq@ %t@])" let buffer_create () = F.dprintf "(buffer_create)" let buffer_add_string = F.dprintf "(@[buffer_add_string@ %t@ %t@])" - let buffer_add_buffer = F.dprintf "(@[buffer_add_buffer@ %t@ %t@])" let buffer_add_char = F.dprintf "(@[buffer_add_char@ %t@ %t@])" let buffer_contents = F.dprintf "(@[buffer_contents@ %t@])" - let buffer_clear = F.dprintf "(@[buffer_clear@ %t@])" let buffer_length = F.dprintf "(@[buffer_length@ %t@])" type 'a promise @@ -1361,62 +1347,39 @@ let pp (type a) pp_import ppf c = let async_lambda = lambda_aux "async_" module External = struct - type 'a linear - - let length = F.dprintf "(@[External.length@ %t@])" + type t - let iteri f a = - let arg_k = var "key" in - let arg_v = var "value" in - F.dprintf "(@[External.iteri@ %t@ %t@ %t@ %t@])" a arg_k arg_v - (f arg_k arg_v) + let null = F.dprintf "null" + let some = F.dprintf "(@[External.some@ %t@])" + let of_int = F.dprintf "(@[External.of_int@ %t@])" + let of_string = F.dprintf "(@[External.of_string@ %t@])" + let of_float = F.dprintf "(@[External.of_float@ %t@])" + let of_bool = F.dprintf "(@[External.of_bool@ %t@])" + let of_seq = F.dprintf "(@[External.of_seq@ %t@])" + let of_seq_assoc = F.dprintf "(@[External.of_seq_assoc@ %t@])" type 'a assoc let assoc_find = F.dprintf "(@[External.assoc_find@ %t@ %t@])" let assoc_mem = F.dprintf "(@[External.assoc_mem@ %t@ %t@])" + let assoc_to_seq = F.dprintf "(@[External.assoc_to_seq@ %t@])" - let assoc_iter f a = - let arg_k = var "key" in - let arg_v = var "value" in - F.dprintf "(@[External.assoc_iter@ %t@ %t@ %t@ %t@])" a arg_k arg_v - (f arg_k arg_v) + type 'a decoder = string - type t + let get_int = "(int)" + let get_string = "(string)" + let get_float = "(float)" + let get_bool = "(bool)" + let get_some = "(some)" + let get_seq = "(seq)" + let get_assoc = "(assoc)" - let null = F.dprintf "null" - let some = F.dprintf "(@[External.some@ %t@])" - let of_int = F.dprintf "(@[External.of_int@ %t@])" - let of_string = F.dprintf "(@[External.of_string@ %t@])" - let of_float = F.dprintf "(@[External.of_float@ %t@])" - let of_bool = F.dprintf "(@[External.of_bool@ %t@])" - let of_array = F.dprintf "(@[External.of_array@ %t@])" - let of_hashtbl = F.dprintf "(@[External.of_hashtbl@ %t@])" - - type _ classify = - | Int : int classify - | String : string classify - | Float : float classify - | Bool : bool classify - | Not_null : t classify - | Linear : t linear classify - | Assoc : t assoc classify - - let classify_to_string : type a. a classify -> string = function - | Int -> "(int)" - | String -> "(string)" - | Float -> "(float)" - | Bool -> "(bool)" - | Not_null -> "(not_null)" - | Linear -> "(linear)" - | Assoc -> "(assoc)" - - let classify c t ~ok ~error = - let classified = var "classified" in + let decode c t ~ok ~error = + let decoded = var "decoded" in F.dprintf - "(@[External.classify@ %s@ %t@ (@[@[ok@ %t@]@ %t@])@ \ + "(@[External.decode@ %s@ %t@ (@[@[ok@ %t@]@ %t@])@ \ (@[error@ %t@])@])" - (classify_to_string c) t classified (ok classified) (error ()) + c t decoded (ok decoded) (error ()) let to_string = F.dprintf "(@[External.to_string@ %t@])" end diff --git a/test/data-test.t/run.t b/test/data-test.t/run.t index 36afa75a..622216d9 100644 --- a/test/data-test.t/run.t +++ b/test/data-test.t/run.t @@ -48,25 +48,22 @@ the value given keeps its internal representation intact. $ node run.js encode.acutis Encoding: { - "none": null, - "f": false, - "t": true, "arr": [ "x", "y" ], + "arrEmpty": [], "dict": { "a": 0, "b": "b" }, + "f": false, + "none": null, "some": "some", - "arrEmpty": [] + "t": true } Encoding unknowns: { - "none": 0, - "f": 0, - "t": 1, "arr": [ "x", [ @@ -74,12 +71,15 @@ the value given keeps its internal representation intact. 0 ] ], + "arrEmpty": 0, "dict": { "a": 0, "b": "b" }, + "f": 0, + "none": 0, "some": [ "some" ], - "arrEmpty": 0 + "t": 1 } diff --git a/test/error_test.ml b/test/error_test.ml index b0f42514..3be75664 100644 --- a/test/error_test.ml +++ b/test/error_test.ml @@ -3,34 +3,32 @@ test is easier to maintain and faster to execute. *) module Json = struct - type 'a linear = 'a list + type t = Yojson.Basic.t + type 'a assoc = (string * 'a) list - let length = List.length - let iteri = List.iteri + let get_int = function `Int x -> Some x | _ -> None + let get_string = function `String x -> Some x | _ -> None - type 'a assoc = (string * 'a) list + let get_float = function + | `Float x -> Some x + | `Int x -> Some (Float.of_int x) + | _ -> None + let get_bool = function `Bool x -> Some x | _ -> None + let get_some = function `Null -> None | x -> Some x + let get_seq = function `List x -> Some (List.to_seq x) | _ -> None + let get_assoc = function `Assoc x -> Some x | _ -> None let assoc_find = List.assoc let assoc_mem = List.mem_assoc - let assoc_iter f l = List.iter (fun (k, v) -> f k v) l - - type t = Yojson.Basic.t - + let assoc_to_seq = List.to_seq let null = `Null let some = Fun.id let of_float x = `Float x let of_string x = `String x let of_bool x = `Bool x let of_int x = `Int x - let of_array x = `List (Array.to_list x) - let of_assoc x = `Assoc (List.of_seq x) - let decode_int = function `Int x -> Some x | _ -> None - let decode_string = function `String x -> Some x | _ -> None - let decode_float = function `Float x -> Some x | _ -> None - let decode_bool = function `Bool x -> Some x | _ -> None - let decode_linear = function `List x -> Some x | _ -> None - let decode_assoc = function `Assoc x -> Some x | _ -> None - let decode_some = function `Null -> None | x -> Some x + let of_seq x = `List (List.of_seq x) + let of_seq_assoc x = `Assoc (List.of_seq x) let to_string t = Yojson.Basic.pretty_to_string t end diff --git a/test/parse-test.t/run.t b/test/parse-test.t/run.t index 2780f02e..596b6fac 100644 --- a/test/parse-test.t/run.t +++ b/test/parse-test.t/run.t @@ -876,8 +876,8 @@ Print the runtime instructions (lambda arg/0 ((return (lambda arg/1 - ((string_iter arg/1 - (match_char char/0 + ((iter (string_to_seq arg/1) + (match_char arg/2 (('&' ((buffer_add_string arg/0 "&"))) ('"' ((buffer_add_string arg/0 """))) ('\'' ((buffer_add_string arg/0 "'"))) @@ -886,68 +886,68 @@ Print the runtime instructions ('/' ((buffer_add_string arg/0 "/"))) ('`' ((buffer_add_string arg/0 "`"))) ('=' ((buffer_add_string arg/0 "="))) - (_ ((buffer_add_char arg/0 char/0)))))))))))) + (_ ((buffer_add_char arg/0 arg/2)))))))))))) (let$ buffer_add_sep/0 = - (lambda arg/2 + (lambda arg/3 ((return - (lambda arg/3 + (lambda arg/4 ((return - (lambda arg/4 - ((if (not ((buffer_length arg/2) = 0)) - (then (buffer_add_string arg/2 arg/3))) - (buffer_add_string arg/2 arg/4)))))))))) - (let$ stack_empty/0 = (lambda arg/5 ((unit)))) + (lambda arg/5 + ((if (not ((buffer_length arg/3) = 0)) + (then (buffer_add_string arg/3 arg/4))) + (buffer_add_string arg/3 arg/5)))))))))) + (let$ stack_empty/0 = (lambda arg/6 ((unit)))) (let$ stack_add/0 = - (lambda arg/6 + (lambda arg/7 ((return - (lambda arg/7 + (lambda arg/8 ((return - (lambda arg/8 ((stmt (arg/7 @@ arg/8)) (return (arg/8 @@ arg/6))))))))))) + (lambda arg/9 ((stmt (arg/8 @@ arg/9)) (return (arg/9 @@ arg/7))))))))))) (let$ components/0 = (hashtbl_create)) (components/0.%{"Component"} <- - (async_lambda arg/9 + (async_lambda arg/10 ((let$ buf/0 = (buffer_create)) (stmt - ((buffer_add_escape/0 @@ buf/0) @@ (Data.to_string (arg/9.%{"a_prop"})))) + ((buffer_add_escape/0 @@ buf/0) @@ (Data.to_string (arg/10.%{"a_prop"})))) (buffer_add_string buf/0 "\n") (stmt - ((buffer_add_escape/0 @@ buf/0) @@ (Data.to_string (arg/9.%{"c_prop"})))) + ((buffer_add_escape/0 @@ buf/0) @@ (Data.to_string (arg/10.%{"c_prop"})))) (buffer_add_string buf/0 "\n") (stmt - ((buffer_add_escape/0 @@ buf/0) @@ (Data.to_string (arg/9.%{"d_prop"})))) + ((buffer_add_escape/0 @@ buf/0) @@ (Data.to_string (arg/10.%{"d_prop"})))) (buffer_add_string buf/0 "\n") (stmt - ((buffer_add_escape/0 @@ buf/0) @@ (Data.to_string (arg/9.%{"f_prop"})))) + ((buffer_add_escape/0 @@ buf/0) @@ (Data.to_string (arg/10.%{"f_prop"})))) (buffer_add_string buf/0 "\n") (stmt - ((buffer_add_escape/0 @@ buf/0) @@ (Data.to_string (arg/9.%{"g_prop"})))) + ((buffer_add_escape/0 @@ buf/0) @@ (Data.to_string (arg/10.%{"g_prop"})))) (buffer_add_string buf/0 "\n") (stmt - ((buffer_add_escape/0 @@ buf/0) @@ (Data.to_string (arg/9.%{"h_prop"})))) + ((buffer_add_escape/0 @@ buf/0) @@ (Data.to_string (arg/10.%{"h_prop"})))) (buffer_add_string buf/0 "\n") (stmt - ((buffer_add_escape/0 @@ buf/0) @@ (Data.to_string (arg/9.%{"i_prop"})))) + ((buffer_add_escape/0 @@ buf/0) @@ (Data.to_string (arg/10.%{"i_prop"})))) (buffer_add_string buf/0 "\n") (return (promise (buffer_contents buf/0)))))) (components/0.%{"Component2"} <- - (async_lambda arg/10 + (async_lambda arg/11 ((let$ buf/1 = (buffer_create)) (stmt ((buffer_add_escape/0 @@ buf/1) - @@ (Data.to_string (arg/10.%{"children"})))) + @@ (Data.to_string (arg/11.%{"children"})))) (buffer_add_string buf/1 "\n") (return (promise (buffer_contents buf/1)))))) (export - (async_lambda arg/11 + (async_lambda arg/12 ((let$ errors/0 = (buffer_create)) (let$ error_aux/0 = - (lambda arg/12 + (lambda arg/13 ((return - (lambda arg/13 + (lambda arg/14 ((return - (lambda arg/14 + (lambda arg/15 ((return - (lambda arg/15 + (lambda arg/16 ((if (not ((buffer_length errors/0) = 0)) (then (buffer_add_string errors/0 "\n\n"))) (buffer_add_string errors/0 "File \"") @@ -955,54 +955,54 @@ Print the runtime instructions (buffer_add_string errors/0 "\"\nRender error.\nThe data supplied does not match this template's interface.\n") (buffer_add_string errors/0 "Path:\n") - (stmt (arg/14 @@ ((buffer_add_sep/0 @@ errors/0) @@ " -> "))) + (stmt (arg/15 @@ ((buffer_add_sep/0 @@ errors/0) @@ " -> "))) (buffer_add_string errors/0 "\nExpected type:\n") - (buffer_add_string errors/0 arg/15) - (buffer_add_string errors/0 arg/12) - (buffer_add_string errors/0 arg/13))))))))))))) + (buffer_add_string errors/0 arg/16) + (buffer_add_string errors/0 arg/13) + (buffer_add_string errors/0 arg/14))))))))))))) (let$ decode_error/0 = - (lambda arg/16 + (lambda arg/17 ((return - ((error_aux/0 @@ "\nReceived value:\n") @@ (External.to_string arg/16)))))) + ((error_aux/0 @@ "\nReceived value:\n") @@ (External.to_string arg/17)))))) (let$ key_error/0 = - (lambda arg/17 + (lambda arg/18 ((return ((error_aux/0 @@ "\nInput is missing keys:\n") - @@ (buffer_contents arg/17)))))) + @@ (buffer_contents arg/18)))))) (let$ props/0 = (hashtbl_create)) (let$ type/0 = "{\n a: {b: {c: false | true}},\n a_prop: string,\n b_prop: string,\n c_prop: string,\n d: string,\n dict: ,\n e: string,\n e_prop: string,\n ech_a: string,\n ech_b: false | true,\n ech_d: ?string,\n ech_e: ?string,\n ech_f: float,\n ech_i: int,\n enums: (@\"a\" | ..., @1 | ..., false | true, false | true),\n f_prop: string,\n list: [?string],\n map_d: ,\n map_l: [int],\n match_a: int,\n match_b: string,\n numbers:\n {\n exp1: float,\n exp2: float,\n exp3: float,\n frac: float,\n int: int,\n negfrac: float,\n negint: int\n },\n record: {\"!#%@\": string, a: string},\n tagged: {@tag: false} | {@tag: true, a: string},\n trim_a: string,\n trim_b: string,\n trim_c: string,\n trim_d: string,\n trim_e: string,\n trim_f: string,\n trim_g: string,\n tuple: (int, float, string)\n}") - (External.classify (assoc) arg/11 - (ok classified/0 + (External.decode (assoc) arg/12 + (ok decoded/0 (let$ missing_keys/0 = (buffer_create)) - (if_else (External.assoc_mem "a" classified/0) + (if_else (External.assoc_mem "a" decoded/0) (then - (let$ input/0 = (External.assoc_find "a" classified/0)) + (let$ input/0 = (External.assoc_find "a" decoded/0)) (let$ stack/0 = ((stack_add/0 @@ "a") @@ stack_empty/0)) (let$ type/1 = "{b: {c: false | true}}") - (External.classify (assoc) input/0 - (ok classified/1 - (let$ decoded/0 = (hashtbl_create)) + (External.decode (assoc) input/0 + (ok decoded/1 + (let$ decoded/2 = (hashtbl_create)) (let$ missing_keys/1 = (buffer_create)) - (if_else (External.assoc_mem "b" classified/1) + (if_else (External.assoc_mem "b" decoded/1) (then - (let$ input/1 = (External.assoc_find "b" classified/1)) + (let$ input/1 = (External.assoc_find "b" decoded/1)) (let$ stack/1 = ((stack_add/0 @@ "b") @@ stack/0)) (let$ type/2 = "{c: false | true}") - (External.classify (assoc) input/1 - (ok classified/2 - (let$ decoded/1 = (hashtbl_create)) + (External.decode (assoc) input/1 + (ok decoded/3 + (let$ decoded/4 = (hashtbl_create)) (let$ missing_keys/2 = (buffer_create)) - (if_else (External.assoc_mem "c" classified/2) + (if_else (External.assoc_mem "c" decoded/3) (then - (let$ input/2 = (External.assoc_find "c" classified/2)) + (let$ input/2 = (External.assoc_find "c" decoded/3)) (let$ stack/2 = ((stack_add/0 @@ "c") @@ stack/1)) (let$ type/3 = "false | true") - (External.classify (bool) input/2 - (ok classified/3 - (if_else classified/3 - (then (decoded/1.%{"c"} <- (Data.int 1))) - (else (decoded/1.%{"c"} <- (Data.int 0))))) + (External.decode (bool) input/2 + (ok decoded/5 + (if_else decoded/5 + (then (decoded/4.%{"c"} <- (Data.int 1))) + (else (decoded/4.%{"c"} <- (Data.int 0))))) (error (stmt (((decode_error/0 @@ input/2) @@ stack/2) @@ type/3))))) (else @@ -1010,7 +1010,7 @@ Print the runtime instructions (if (not ((buffer_length missing_keys/2) = 0)) (then (stmt (((key_error/0 @@ missing_keys/2) @@ stack/1) @@ type/2)))) - (decoded/0.%{"b"} <- (Data.hashtbl decoded/1))) + (decoded/2.%{"b"} <- (Data.hashtbl decoded/4))) (error (stmt (((decode_error/0 @@ input/1) @@ stack/1) @@ type/2))))) (else @@ -1018,698 +1018,636 @@ Print the runtime instructions (if (not ((buffer_length missing_keys/1) = 0)) (then (stmt (((key_error/0 @@ missing_keys/1) @@ stack/0) @@ type/1)))) - (props/0.%{"a"} <- (Data.hashtbl decoded/0))) + (props/0.%{"a"} <- (Data.hashtbl decoded/2))) (error (stmt (((decode_error/0 @@ input/0) @@ stack/0) @@ type/1))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/0) @@ ", ") @@ "a")))) - (if_else (External.assoc_mem "a_prop" classified/0) + (if_else (External.assoc_mem "a_prop" decoded/0) (then - (let$ input/3 = (External.assoc_find "a_prop" classified/0)) + (let$ input/3 = (External.assoc_find "a_prop" decoded/0)) (let$ stack/3 = ((stack_add/0 @@ "a_prop") @@ stack_empty/0)) (let$ type/4 = "string") - (External.classify (string) input/3 - (ok classified/4 (props/0.%{"a_prop"} <- (Data.string classified/4))) + (External.decode (string) input/3 + (ok decoded/6 (props/0.%{"a_prop"} <- (Data.string decoded/6))) (error (stmt (((decode_error/0 @@ input/3) @@ stack/3) @@ type/4))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/0) @@ ", ") @@ "a_prop")))) - (if_else (External.assoc_mem "b_prop" classified/0) + (if_else (External.assoc_mem "b_prop" decoded/0) (then - (let$ input/4 = (External.assoc_find "b_prop" classified/0)) + (let$ input/4 = (External.assoc_find "b_prop" decoded/0)) (let$ stack/4 = ((stack_add/0 @@ "b_prop") @@ stack_empty/0)) (let$ type/5 = "string") - (External.classify (string) input/4 - (ok classified/5 (props/0.%{"b_prop"} <- (Data.string classified/5))) + (External.decode (string) input/4 + (ok decoded/7 (props/0.%{"b_prop"} <- (Data.string decoded/7))) (error (stmt (((decode_error/0 @@ input/4) @@ stack/4) @@ type/5))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/0) @@ ", ") @@ "b_prop")))) - (if_else (External.assoc_mem "c_prop" classified/0) + (if_else (External.assoc_mem "c_prop" decoded/0) (then - (let$ input/5 = (External.assoc_find "c_prop" classified/0)) + (let$ input/5 = (External.assoc_find "c_prop" decoded/0)) (let$ stack/5 = ((stack_add/0 @@ "c_prop") @@ stack_empty/0)) (let$ type/6 = "string") - (External.classify (string) input/5 - (ok classified/6 (props/0.%{"c_prop"} <- (Data.string classified/6))) + (External.decode (string) input/5 + (ok decoded/8 (props/0.%{"c_prop"} <- (Data.string decoded/8))) (error (stmt (((decode_error/0 @@ input/5) @@ stack/5) @@ type/6))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/0) @@ ", ") @@ "c_prop")))) - (if_else (External.assoc_mem "d" classified/0) + (if_else (External.assoc_mem "d" decoded/0) (then - (let$ input/6 = (External.assoc_find "d" classified/0)) + (let$ input/6 = (External.assoc_find "d" decoded/0)) (let$ stack/6 = ((stack_add/0 @@ "d") @@ stack_empty/0)) (let$ type/7 = "string") - (External.classify (string) input/6 - (ok classified/7 (props/0.%{"d"} <- (Data.string classified/7))) + (External.decode (string) input/6 + (ok decoded/9 (props/0.%{"d"} <- (Data.string decoded/9))) (error (stmt (((decode_error/0 @@ input/6) @@ stack/6) @@ type/7))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/0) @@ ", ") @@ "d")))) - (if_else (External.assoc_mem "dict" classified/0) + (if_else (External.assoc_mem "dict" decoded/0) (then - (let$ input/7 = (External.assoc_find "dict" classified/0)) + (let$ input/7 = (External.assoc_find "dict" decoded/0)) (let$ stack/7 = ((stack_add/0 @@ "dict") @@ stack_empty/0)) (let$ type/8 = "") - (External.classify (assoc) input/7 - (ok classified/8 - (let$ decoded/2 = (hashtbl_create)) - (External.assoc_iter classified/8 key/0 value/0 - (let$ stack/8 = ((stack_add/0 @@ key/0) @@ stack/7)) + (External.decode (assoc) input/7 + (ok decoded/10 + (let$ decoded/11 = (hashtbl_create)) + (iter (External.assoc_to_seq decoded/10) + (let$ stack/8 = ((stack_add/0 @@ (fst arg/19)) @@ stack/7)) (let$ type/9 = "int") - (External.classify (int) value/0 - (ok classified/9 (decoded/2.%{key/0} <- (Data.int classified/9))) - (error (stmt (((decode_error/0 @@ value/0) @@ stack/8) @@ type/9)))) - (props/0.%{"dict"} <- (Data.hashtbl decoded/2)))) + (External.decode (int) (snd arg/19) + (ok decoded/12 + (decoded/11.%{(fst arg/19)} <- (Data.int decoded/12))) + (error + (stmt (((decode_error/0 @@ (snd arg/19)) @@ stack/8) @@ type/9)))) + (props/0.%{"dict"} <- (Data.hashtbl decoded/11)))) (error (stmt (((decode_error/0 @@ input/7) @@ stack/7) @@ type/8))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/0) @@ ", ") @@ "dict")))) - (if_else (External.assoc_mem "e" classified/0) + (if_else (External.assoc_mem "e" decoded/0) (then - (let$ input/8 = (External.assoc_find "e" classified/0)) + (let$ input/8 = (External.assoc_find "e" decoded/0)) (let$ stack/9 = ((stack_add/0 @@ "e") @@ stack_empty/0)) (let$ type/10 = "string") - (External.classify (string) input/8 - (ok classified/10 (props/0.%{"e"} <- (Data.string classified/10))) + (External.decode (string) input/8 + (ok decoded/13 (props/0.%{"e"} <- (Data.string decoded/13))) (error (stmt (((decode_error/0 @@ input/8) @@ stack/9) @@ type/10))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/0) @@ ", ") @@ "e")))) - (if_else (External.assoc_mem "e_prop" classified/0) + (if_else (External.assoc_mem "e_prop" decoded/0) (then - (let$ input/9 = (External.assoc_find "e_prop" classified/0)) + (let$ input/9 = (External.assoc_find "e_prop" decoded/0)) (let$ stack/10 = ((stack_add/0 @@ "e_prop") @@ stack_empty/0)) (let$ type/11 = "string") - (External.classify (string) input/9 - (ok classified/11 - (props/0.%{"e_prop"} <- (Data.string classified/11))) + (External.decode (string) input/9 + (ok decoded/14 (props/0.%{"e_prop"} <- (Data.string decoded/14))) (error (stmt (((decode_error/0 @@ input/9) @@ stack/10) @@ type/11))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/0) @@ ", ") @@ "e_prop")))) - (if_else (External.assoc_mem "ech_a" classified/0) + (if_else (External.assoc_mem "ech_a" decoded/0) (then - (let$ input/10 = (External.assoc_find "ech_a" classified/0)) + (let$ input/10 = (External.assoc_find "ech_a" decoded/0)) (let$ stack/11 = ((stack_add/0 @@ "ech_a") @@ stack_empty/0)) (let$ type/12 = "string") - (External.classify (string) input/10 - (ok classified/12 (props/0.%{"ech_a"} <- (Data.string classified/12))) + (External.decode (string) input/10 + (ok decoded/15 (props/0.%{"ech_a"} <- (Data.string decoded/15))) (error (stmt (((decode_error/0 @@ input/10) @@ stack/11) @@ type/12))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/0) @@ ", ") @@ "ech_a")))) - (if_else (External.assoc_mem "ech_b" classified/0) + (if_else (External.assoc_mem "ech_b" decoded/0) (then - (let$ input/11 = (External.assoc_find "ech_b" classified/0)) + (let$ input/11 = (External.assoc_find "ech_b" decoded/0)) (let$ stack/12 = ((stack_add/0 @@ "ech_b") @@ stack_empty/0)) (let$ type/13 = "false | true") - (External.classify (bool) input/11 - (ok classified/13 - (if_else classified/13 + (External.decode (bool) input/11 + (ok decoded/16 + (if_else decoded/16 (then (props/0.%{"ech_b"} <- (Data.int 1))) (else (props/0.%{"ech_b"} <- (Data.int 0))))) (error (stmt (((decode_error/0 @@ input/11) @@ stack/12) @@ type/13))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/0) @@ ", ") @@ "ech_b")))) - (if_else (External.assoc_mem "ech_d" classified/0) + (if_else (External.assoc_mem "ech_d" decoded/0) (then - (let$ input/12 = (External.assoc_find "ech_d" classified/0)) + (let$ input/12 = (External.assoc_find "ech_d" decoded/0)) (let$ stack/13 = ((stack_add/0 @@ "ech_d") @@ stack_empty/0)) (let$ type/14 = "?string") - (External.classify (not_null) input/12 - (ok classified/14 - (let$ decoded/3 = [(Data.int 0)]) + (External.decode (some) input/12 + (ok decoded/17 + (let$ decoded/18 = [(Data.int 0)]) (let$ stack/14 = ((stack_add/0 @@ "") @@ stack/13)) (let$ type/15 = "string") - (External.classify (string) classified/14 - (ok classified/15 (decoded/3.%(0) <- (Data.string classified/15))) + (External.decode (string) decoded/17 + (ok decoded/19 (decoded/18.%(0) <- (Data.string decoded/19))) (error - (stmt (((decode_error/0 @@ classified/14) @@ stack/14) @@ type/15)))) - (props/0.%{"ech_d"} <- (Data.array decoded/3))) + (stmt (((decode_error/0 @@ decoded/17) @@ stack/14) @@ type/15)))) + (props/0.%{"ech_d"} <- (Data.array decoded/18))) (error (props/0.%{"ech_d"} <- (Data.int 0))))) (else (props/0.%{"ech_d"} <- (Data.int 0)))) - (if_else (External.assoc_mem "ech_e" classified/0) + (if_else (External.assoc_mem "ech_e" decoded/0) (then - (let$ input/13 = (External.assoc_find "ech_e" classified/0)) + (let$ input/13 = (External.assoc_find "ech_e" decoded/0)) (let$ stack/15 = ((stack_add/0 @@ "ech_e") @@ stack_empty/0)) (let$ type/16 = "?string") - (External.classify (not_null) input/13 - (ok classified/16 - (let$ decoded/4 = [(Data.int 0)]) + (External.decode (some) input/13 + (ok decoded/20 + (let$ decoded/21 = [(Data.int 0)]) (let$ stack/16 = ((stack_add/0 @@ "") @@ stack/15)) (let$ type/17 = "string") - (External.classify (string) classified/16 - (ok classified/17 (decoded/4.%(0) <- (Data.string classified/17))) + (External.decode (string) decoded/20 + (ok decoded/22 (decoded/21.%(0) <- (Data.string decoded/22))) (error - (stmt (((decode_error/0 @@ classified/16) @@ stack/16) @@ type/17)))) - (props/0.%{"ech_e"} <- (Data.array decoded/4))) + (stmt (((decode_error/0 @@ decoded/20) @@ stack/16) @@ type/17)))) + (props/0.%{"ech_e"} <- (Data.array decoded/21))) (error (props/0.%{"ech_e"} <- (Data.int 0))))) (else (props/0.%{"ech_e"} <- (Data.int 0)))) - (if_else (External.assoc_mem "ech_f" classified/0) + (if_else (External.assoc_mem "ech_f" decoded/0) (then - (let$ input/14 = (External.assoc_find "ech_f" classified/0)) + (let$ input/14 = (External.assoc_find "ech_f" decoded/0)) (let$ stack/17 = ((stack_add/0 @@ "ech_f") @@ stack_empty/0)) (let$ type/18 = "float") - (External.classify (float) input/14 - (ok classified/18 (props/0.%{"ech_f"} <- (Data.float classified/18))) - (error - (External.classify (int) input/14 - (ok classified/19 - (props/0.%{"ech_f"} <- (Data.float (float_of_int classified/19)))) - (error - (stmt (((decode_error/0 @@ input/14) @@ stack/17) @@ type/18))))))) + (External.decode (float) input/14 + (ok decoded/23 (props/0.%{"ech_f"} <- (Data.float decoded/23))) + (error (stmt (((decode_error/0 @@ input/14) @@ stack/17) @@ type/18))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/0) @@ ", ") @@ "ech_f")))) - (if_else (External.assoc_mem "ech_i" classified/0) + (if_else (External.assoc_mem "ech_i" decoded/0) (then - (let$ input/15 = (External.assoc_find "ech_i" classified/0)) + (let$ input/15 = (External.assoc_find "ech_i" decoded/0)) (let$ stack/18 = ((stack_add/0 @@ "ech_i") @@ stack_empty/0)) (let$ type/19 = "int") - (External.classify (int) input/15 - (ok classified/20 (props/0.%{"ech_i"} <- (Data.int classified/20))) + (External.decode (int) input/15 + (ok decoded/24 (props/0.%{"ech_i"} <- (Data.int decoded/24))) (error (stmt (((decode_error/0 @@ input/15) @@ stack/18) @@ type/19))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/0) @@ ", ") @@ "ech_i")))) - (if_else (External.assoc_mem "enums" classified/0) + (if_else (External.assoc_mem "enums" decoded/0) (then - (let$ input/16 = (External.assoc_find "enums" classified/0)) + (let$ input/16 = (External.assoc_find "enums" decoded/0)) (let$ stack/19 = ((stack_add/0 @@ "enums") @@ stack_empty/0)) (let$ type/20 = "(@\"a\" | ..., @1 | ..., false | true, false | true)") - (External.classify (linear) input/16 - (ok classified/21 - (if_else ((External.length classified/21) = 4) - (then - (let$ decoded/5 = (array_make 4 (Data.int 0))) - (External.iteri classified/21 key/1 value/1 - (let$ stack/20 = - ((stack_add/0 @@ (string_of_int key/1)) @@ stack/19)) - (if_else (key/1 = 0) - (then - (let$ type/24 = "@\"a\" | ...") - (External.classify (string) value/1 - (ok classified/25 - (decoded/5.%(key/1) <- (Data.string classified/25))) - (error - (stmt (((decode_error/0 @@ value/1) @@ stack/20) @@ type/24))))) - (else - (if_else (key/1 = 1) - (then - (let$ type/23 = "@1 | ...") - (External.classify (int) value/1 - (ok classified/24 - (decoded/5.%(key/1) <- (Data.int classified/24))) - (error - (stmt - (((decode_error/0 @@ value/1) @@ stack/20) @@ type/23))))) - (else - (if_else (key/1 = 2) - (then - (let$ type/22 = "false | true") - (External.classify (bool) value/1 - (ok classified/23 - (if_else classified/23 - (then (decoded/5.%(key/1) <- (Data.int 1))) - (else (decoded/5.%(key/1) <- (Data.int 0))))) - (error - (stmt - (((decode_error/0 @@ value/1) @@ stack/20) @@ type/22))))) - (else - (if_else (key/1 = 3) - (then - (let$ type/21 = "false | true") - (External.classify (bool) value/1 - (ok classified/22 - (if_else classified/22 - (then (decoded/5.%(key/1) <- (Data.int 1))) - (else (decoded/5.%(key/1) <- (Data.int 0))))) - (error - (stmt - (((decode_error/0 @@ value/1) @@ stack/20) @@ type/21))))) - (else - (stmt - (((decode_error/0 @@ value/1) @@ stack/20) @@ type/20)))))))))) - (props/0.%{"enums"} <- (Data.array decoded/5)))) - (else - (stmt (((decode_error/0 @@ input/16) @@ stack/19) @@ type/20))))) + (External.decode (seq) input/16 + (ok decoded/25 + (let$ decoded/26 = (array_make 4 (Data.int 0))) + (uncons decoded/25 + (nil (stmt (((decode_error/0 @@ input/16) @@ stack/19) @@ type/20))) + (cons hd/0 seq/0 + (let$ stack/20 = ((stack_add/0 @@ (string_of_int 0)) @@ stack/19)) + (let$ type/21 = "@\"a\" | ...") + (External.decode (string) hd/0 + (ok decoded/27 (decoded/26.%(0) <- (Data.string decoded/27))) + (error (stmt (((decode_error/0 @@ hd/0) @@ stack/20) @@ type/21)))) + (uncons seq/0 + (nil + (stmt (((decode_error/0 @@ input/16) @@ stack/19) @@ type/20))) + (cons hd/1 seq/1 + (let$ stack/21 = + ((stack_add/0 @@ (string_of_int 1)) @@ stack/19)) + (let$ type/22 = "@1 | ...") + (External.decode (int) hd/1 + (ok decoded/28 (decoded/26.%(1) <- (Data.int decoded/28))) + (error + (stmt (((decode_error/0 @@ hd/1) @@ stack/21) @@ type/22)))) + (uncons seq/1 + (nil + (stmt (((decode_error/0 @@ input/16) @@ stack/19) @@ type/20))) + (cons hd/2 seq/2 + (let$ stack/22 = + ((stack_add/0 @@ (string_of_int 2)) @@ stack/19)) + (let$ type/23 = "false | true") + (External.decode (bool) hd/2 + (ok decoded/29 + (if_else decoded/29 + (then (decoded/26.%(2) <- (Data.int 1))) + (else (decoded/26.%(2) <- (Data.int 0))))) + (error + (stmt (((decode_error/0 @@ hd/2) @@ stack/22) @@ type/23)))) + (uncons seq/2 + (nil + (stmt + (((decode_error/0 @@ input/16) @@ stack/19) @@ type/20))) + (cons hd/3 seq/3 + (let$ stack/23 = + ((stack_add/0 @@ (string_of_int 3)) @@ stack/19)) + (let$ type/24 = "false | true") + (External.decode (bool) hd/3 + (ok decoded/30 + (if_else decoded/30 + (then (decoded/26.%(3) <- (Data.int 1))) + (else (decoded/26.%(3) <- (Data.int 0))))) + (error + (stmt (((decode_error/0 @@ hd/3) @@ stack/23) @@ type/24)))) + (unit))))))))) + (props/0.%{"enums"} <- (Data.array decoded/26))) (error (stmt (((decode_error/0 @@ input/16) @@ stack/19) @@ type/20))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/0) @@ ", ") @@ "enums")))) - (if_else (External.assoc_mem "f_prop" classified/0) + (if_else (External.assoc_mem "f_prop" decoded/0) (then - (let$ input/17 = (External.assoc_find "f_prop" classified/0)) - (let$ stack/21 = ((stack_add/0 @@ "f_prop") @@ stack_empty/0)) + (let$ input/17 = (External.assoc_find "f_prop" decoded/0)) + (let$ stack/24 = ((stack_add/0 @@ "f_prop") @@ stack_empty/0)) (let$ type/25 = "string") - (External.classify (string) input/17 - (ok classified/26 - (props/0.%{"f_prop"} <- (Data.string classified/26))) - (error (stmt (((decode_error/0 @@ input/17) @@ stack/21) @@ type/25))))) + (External.decode (string) input/17 + (ok decoded/31 (props/0.%{"f_prop"} <- (Data.string decoded/31))) + (error (stmt (((decode_error/0 @@ input/17) @@ stack/24) @@ type/25))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/0) @@ ", ") @@ "f_prop")))) - (if_else (External.assoc_mem "list" classified/0) + (if_else (External.assoc_mem "list" decoded/0) (then - (let$ input/18 = (External.assoc_find "list" classified/0)) - (let$ stack/22 = ((stack_add/0 @@ "list") @@ stack_empty/0)) + (let$ input/18 = (External.assoc_find "list" decoded/0)) + (let$ stack/25 = ((stack_add/0 @@ "list") @@ stack_empty/0)) (let$ type/26 = "[?string]") - (External.classify (linear) input/18 - (ok classified/27 - (let$ decoded/6 = [(Data.int 0), (Data.int 0)]) - (let& decode_dst/0 = decoded/6) - (External.iteri classified/27 key/2 value/2 + (External.decode (seq) input/18 + (ok decoded/32 + (let& index/0 = 0) + (let$ decoded/33 = [(Data.int 0), (Data.int 0)]) + (let& decode_dst/0 = decoded/33) + (iter decoded/32 (let$ decode_dst_new/0 = [(Data.int 0), (Data.int 0)]) - (let$ stack/23 = - ((stack_add/0 @@ (string_of_int key/2)) @@ stack/22)) + (let$ stack/26 = + ((stack_add/0 @@ (string_of_int !index/0)) @@ stack/25)) (let$ type/27 = "?string") - (External.classify (not_null) value/2 - (ok classified/28 - (let$ decoded/7 = [(Data.int 0)]) - (let$ stack/24 = ((stack_add/0 @@ "") @@ stack/23)) + (External.decode (some) arg/20 + (ok decoded/34 + (let$ decoded/35 = [(Data.int 0)]) + (let$ stack/27 = ((stack_add/0 @@ "") @@ stack/26)) (let$ type/28 = "string") - (External.classify (string) classified/28 - (ok classified/29 - (decoded/7.%(0) <- (Data.string classified/29))) + (External.decode (string) decoded/34 + (ok decoded/36 (decoded/35.%(0) <- (Data.string decoded/36))) (error - (stmt - (((decode_error/0 @@ classified/28) @@ stack/24) @@ type/28)))) - (decode_dst_new/0.%(0) <- (Data.array decoded/7))) + (stmt (((decode_error/0 @@ decoded/34) @@ stack/27) @@ type/28)))) + (decode_dst_new/0.%(0) <- (Data.array decoded/35))) (error (decode_dst_new/0.%(0) <- (Data.int 0)))) (!decode_dst/0.%(1) <- (Data.array decode_dst_new/0)) - (decode_dst/0 := decode_dst_new/0)) - (props/0.%{"list"} <- (decoded/6.%(1)))) - (error (stmt (((decode_error/0 @@ input/18) @@ stack/22) @@ type/26))))) + (incr index/0) (decode_dst/0 := decode_dst_new/0)) + (props/0.%{"list"} <- (decoded/33.%(1)))) + (error (stmt (((decode_error/0 @@ input/18) @@ stack/25) @@ type/26))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/0) @@ ", ") @@ "list")))) - (if_else (External.assoc_mem "map_d" classified/0) + (if_else (External.assoc_mem "map_d" decoded/0) (then - (let$ input/19 = (External.assoc_find "map_d" classified/0)) - (let$ stack/25 = ((stack_add/0 @@ "map_d") @@ stack_empty/0)) + (let$ input/19 = (External.assoc_find "map_d" decoded/0)) + (let$ stack/28 = ((stack_add/0 @@ "map_d") @@ stack_empty/0)) (let$ type/29 = "") - (External.classify (assoc) input/19 - (ok classified/30 - (let$ decoded/8 = (hashtbl_create)) - (External.assoc_iter classified/30 key/3 value/3 - (let$ stack/26 = ((stack_add/0 @@ key/3) @@ stack/25)) + (External.decode (assoc) input/19 + (ok decoded/37 + (let$ decoded/38 = (hashtbl_create)) + (iter (External.assoc_to_seq decoded/37) + (let$ stack/29 = ((stack_add/0 @@ (fst arg/21)) @@ stack/28)) (let$ type/30 = "int") - (External.classify (int) value/3 - (ok classified/31 (decoded/8.%{key/3} <- (Data.int classified/31))) + (External.decode (int) (snd arg/21) + (ok decoded/39 + (decoded/38.%{(fst arg/21)} <- (Data.int decoded/39))) (error - (stmt (((decode_error/0 @@ value/3) @@ stack/26) @@ type/30)))) - (props/0.%{"map_d"} <- (Data.hashtbl decoded/8)))) - (error (stmt (((decode_error/0 @@ input/19) @@ stack/25) @@ type/29))))) + (stmt (((decode_error/0 @@ (snd arg/21)) @@ stack/29) @@ type/30)))) + (props/0.%{"map_d"} <- (Data.hashtbl decoded/38)))) + (error (stmt (((decode_error/0 @@ input/19) @@ stack/28) @@ type/29))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/0) @@ ", ") @@ "map_d")))) - (if_else (External.assoc_mem "map_l" classified/0) + (if_else (External.assoc_mem "map_l" decoded/0) (then - (let$ input/20 = (External.assoc_find "map_l" classified/0)) - (let$ stack/27 = ((stack_add/0 @@ "map_l") @@ stack_empty/0)) + (let$ input/20 = (External.assoc_find "map_l" decoded/0)) + (let$ stack/30 = ((stack_add/0 @@ "map_l") @@ stack_empty/0)) (let$ type/31 = "[int]") - (External.classify (linear) input/20 - (ok classified/32 - (let$ decoded/9 = [(Data.int 0), (Data.int 0)]) - (let& decode_dst/1 = decoded/9) - (External.iteri classified/32 key/4 value/4 + (External.decode (seq) input/20 + (ok decoded/40 + (let& index/1 = 0) + (let$ decoded/41 = [(Data.int 0), (Data.int 0)]) + (let& decode_dst/1 = decoded/41) + (iter decoded/40 (let$ decode_dst_new/1 = [(Data.int 0), (Data.int 0)]) - (let$ stack/28 = - ((stack_add/0 @@ (string_of_int key/4)) @@ stack/27)) + (let$ stack/31 = + ((stack_add/0 @@ (string_of_int !index/1)) @@ stack/30)) (let$ type/32 = "int") - (External.classify (int) value/4 - (ok classified/33 - (decode_dst_new/1.%(0) <- (Data.int classified/33))) + (External.decode (int) arg/22 + (ok decoded/42 (decode_dst_new/1.%(0) <- (Data.int decoded/42))) (error - (stmt (((decode_error/0 @@ value/4) @@ stack/28) @@ type/32)))) + (stmt (((decode_error/0 @@ arg/22) @@ stack/31) @@ type/32)))) (!decode_dst/1.%(1) <- (Data.array decode_dst_new/1)) - (decode_dst/1 := decode_dst_new/1)) - (props/0.%{"map_l"} <- (decoded/9.%(1)))) - (error (stmt (((decode_error/0 @@ input/20) @@ stack/27) @@ type/31))))) + (incr index/1) (decode_dst/1 := decode_dst_new/1)) + (props/0.%{"map_l"} <- (decoded/41.%(1)))) + (error (stmt (((decode_error/0 @@ input/20) @@ stack/30) @@ type/31))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/0) @@ ", ") @@ "map_l")))) - (if_else (External.assoc_mem "match_a" classified/0) + (if_else (External.assoc_mem "match_a" decoded/0) (then - (let$ input/21 = (External.assoc_find "match_a" classified/0)) - (let$ stack/29 = ((stack_add/0 @@ "match_a") @@ stack_empty/0)) + (let$ input/21 = (External.assoc_find "match_a" decoded/0)) + (let$ stack/32 = ((stack_add/0 @@ "match_a") @@ stack_empty/0)) (let$ type/33 = "int") - (External.classify (int) input/21 - (ok classified/34 (props/0.%{"match_a"} <- (Data.int classified/34))) - (error (stmt (((decode_error/0 @@ input/21) @@ stack/29) @@ type/33))))) + (External.decode (int) input/21 + (ok decoded/43 (props/0.%{"match_a"} <- (Data.int decoded/43))) + (error (stmt (((decode_error/0 @@ input/21) @@ stack/32) @@ type/33))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/0) @@ ", ") @@ "match_a")))) - (if_else (External.assoc_mem "match_b" classified/0) + (if_else (External.assoc_mem "match_b" decoded/0) (then - (let$ input/22 = (External.assoc_find "match_b" classified/0)) - (let$ stack/30 = ((stack_add/0 @@ "match_b") @@ stack_empty/0)) + (let$ input/22 = (External.assoc_find "match_b" decoded/0)) + (let$ stack/33 = ((stack_add/0 @@ "match_b") @@ stack_empty/0)) (let$ type/34 = "string") - (External.classify (string) input/22 - (ok classified/35 - (props/0.%{"match_b"} <- (Data.string classified/35))) - (error (stmt (((decode_error/0 @@ input/22) @@ stack/30) @@ type/34))))) + (External.decode (string) input/22 + (ok decoded/44 (props/0.%{"match_b"} <- (Data.string decoded/44))) + (error (stmt (((decode_error/0 @@ input/22) @@ stack/33) @@ type/34))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/0) @@ ", ") @@ "match_b")))) - (if_else (External.assoc_mem "numbers" classified/0) + (if_else (External.assoc_mem "numbers" decoded/0) (then - (let$ input/23 = (External.assoc_find "numbers" classified/0)) - (let$ stack/31 = ((stack_add/0 @@ "numbers") @@ stack_empty/0)) + (let$ input/23 = (External.assoc_find "numbers" decoded/0)) + (let$ stack/34 = ((stack_add/0 @@ "numbers") @@ stack_empty/0)) (let$ type/35 = "{\n exp1: float,\n exp2: float,\n exp3: float,\n frac: float,\n int: int,\n negfrac: float,\n negint: int\n}") - (External.classify (assoc) input/23 - (ok classified/36 - (let$ decoded/10 = (hashtbl_create)) + (External.decode (assoc) input/23 + (ok decoded/45 + (let$ decoded/46 = (hashtbl_create)) (let$ missing_keys/3 = (buffer_create)) - (if_else (External.assoc_mem "exp1" classified/36) + (if_else (External.assoc_mem "exp1" decoded/45) (then - (let$ input/24 = (External.assoc_find "exp1" classified/36)) - (let$ stack/32 = ((stack_add/0 @@ "exp1") @@ stack/31)) + (let$ input/24 = (External.assoc_find "exp1" decoded/45)) + (let$ stack/35 = ((stack_add/0 @@ "exp1") @@ stack/34)) (let$ type/36 = "float") - (External.classify (float) input/24 - (ok classified/37 - (decoded/10.%{"exp1"} <- (Data.float classified/37))) + (External.decode (float) input/24 + (ok decoded/47 (decoded/46.%{"exp1"} <- (Data.float decoded/47))) (error - (External.classify (int) input/24 - (ok classified/38 - (decoded/10.%{"exp1"} <- - (Data.float (float_of_int classified/38)))) - (error - (stmt (((decode_error/0 @@ input/24) @@ stack/32) @@ type/36))))))) + (stmt (((decode_error/0 @@ input/24) @@ stack/35) @@ type/36))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/3) @@ ", ") @@ "exp1")))) - (if_else (External.assoc_mem "exp2" classified/36) + (if_else (External.assoc_mem "exp2" decoded/45) (then - (let$ input/25 = (External.assoc_find "exp2" classified/36)) - (let$ stack/33 = ((stack_add/0 @@ "exp2") @@ stack/31)) + (let$ input/25 = (External.assoc_find "exp2" decoded/45)) + (let$ stack/36 = ((stack_add/0 @@ "exp2") @@ stack/34)) (let$ type/37 = "float") - (External.classify (float) input/25 - (ok classified/39 - (decoded/10.%{"exp2"} <- (Data.float classified/39))) + (External.decode (float) input/25 + (ok decoded/48 (decoded/46.%{"exp2"} <- (Data.float decoded/48))) (error - (External.classify (int) input/25 - (ok classified/40 - (decoded/10.%{"exp2"} <- - (Data.float (float_of_int classified/40)))) - (error - (stmt (((decode_error/0 @@ input/25) @@ stack/33) @@ type/37))))))) + (stmt (((decode_error/0 @@ input/25) @@ stack/36) @@ type/37))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/3) @@ ", ") @@ "exp2")))) - (if_else (External.assoc_mem "exp3" classified/36) + (if_else (External.assoc_mem "exp3" decoded/45) (then - (let$ input/26 = (External.assoc_find "exp3" classified/36)) - (let$ stack/34 = ((stack_add/0 @@ "exp3") @@ stack/31)) + (let$ input/26 = (External.assoc_find "exp3" decoded/45)) + (let$ stack/37 = ((stack_add/0 @@ "exp3") @@ stack/34)) (let$ type/38 = "float") - (External.classify (float) input/26 - (ok classified/41 - (decoded/10.%{"exp3"} <- (Data.float classified/41))) + (External.decode (float) input/26 + (ok decoded/49 (decoded/46.%{"exp3"} <- (Data.float decoded/49))) (error - (External.classify (int) input/26 - (ok classified/42 - (decoded/10.%{"exp3"} <- - (Data.float (float_of_int classified/42)))) - (error - (stmt (((decode_error/0 @@ input/26) @@ stack/34) @@ type/38))))))) + (stmt (((decode_error/0 @@ input/26) @@ stack/37) @@ type/38))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/3) @@ ", ") @@ "exp3")))) - (if_else (External.assoc_mem "frac" classified/36) + (if_else (External.assoc_mem "frac" decoded/45) (then - (let$ input/27 = (External.assoc_find "frac" classified/36)) - (let$ stack/35 = ((stack_add/0 @@ "frac") @@ stack/31)) + (let$ input/27 = (External.assoc_find "frac" decoded/45)) + (let$ stack/38 = ((stack_add/0 @@ "frac") @@ stack/34)) (let$ type/39 = "float") - (External.classify (float) input/27 - (ok classified/43 - (decoded/10.%{"frac"} <- (Data.float classified/43))) + (External.decode (float) input/27 + (ok decoded/50 (decoded/46.%{"frac"} <- (Data.float decoded/50))) (error - (External.classify (int) input/27 - (ok classified/44 - (decoded/10.%{"frac"} <- - (Data.float (float_of_int classified/44)))) - (error - (stmt (((decode_error/0 @@ input/27) @@ stack/35) @@ type/39))))))) + (stmt (((decode_error/0 @@ input/27) @@ stack/38) @@ type/39))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/3) @@ ", ") @@ "frac")))) - (if_else (External.assoc_mem "int" classified/36) + (if_else (External.assoc_mem "int" decoded/45) (then - (let$ input/28 = (External.assoc_find "int" classified/36)) - (let$ stack/36 = ((stack_add/0 @@ "int") @@ stack/31)) + (let$ input/28 = (External.assoc_find "int" decoded/45)) + (let$ stack/39 = ((stack_add/0 @@ "int") @@ stack/34)) (let$ type/40 = "int") - (External.classify (int) input/28 - (ok classified/45 - (decoded/10.%{"int"} <- (Data.int classified/45))) + (External.decode (int) input/28 + (ok decoded/51 (decoded/46.%{"int"} <- (Data.int decoded/51))) (error - (stmt (((decode_error/0 @@ input/28) @@ stack/36) @@ type/40))))) + (stmt (((decode_error/0 @@ input/28) @@ stack/39) @@ type/40))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/3) @@ ", ") @@ "int")))) - (if_else (External.assoc_mem "negfrac" classified/36) + (if_else (External.assoc_mem "negfrac" decoded/45) (then - (let$ input/29 = (External.assoc_find "negfrac" classified/36)) - (let$ stack/37 = ((stack_add/0 @@ "negfrac") @@ stack/31)) + (let$ input/29 = (External.assoc_find "negfrac" decoded/45)) + (let$ stack/40 = ((stack_add/0 @@ "negfrac") @@ stack/34)) (let$ type/41 = "float") - (External.classify (float) input/29 - (ok classified/46 - (decoded/10.%{"negfrac"} <- (Data.float classified/46))) + (External.decode (float) input/29 + (ok decoded/52 + (decoded/46.%{"negfrac"} <- (Data.float decoded/52))) (error - (External.classify (int) input/29 - (ok classified/47 - (decoded/10.%{"negfrac"} <- - (Data.float (float_of_int classified/47)))) - (error - (stmt (((decode_error/0 @@ input/29) @@ stack/37) @@ type/41))))))) + (stmt (((decode_error/0 @@ input/29) @@ stack/40) @@ type/41))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/3) @@ ", ") @@ "negfrac")))) - (if_else (External.assoc_mem "negint" classified/36) + (if_else (External.assoc_mem "negint" decoded/45) (then - (let$ input/30 = (External.assoc_find "negint" classified/36)) - (let$ stack/38 = ((stack_add/0 @@ "negint") @@ stack/31)) + (let$ input/30 = (External.assoc_find "negint" decoded/45)) + (let$ stack/41 = ((stack_add/0 @@ "negint") @@ stack/34)) (let$ type/42 = "int") - (External.classify (int) input/30 - (ok classified/48 - (decoded/10.%{"negint"} <- (Data.int classified/48))) + (External.decode (int) input/30 + (ok decoded/53 (decoded/46.%{"negint"} <- (Data.int decoded/53))) (error - (stmt (((decode_error/0 @@ input/30) @@ stack/38) @@ type/42))))) + (stmt (((decode_error/0 @@ input/30) @@ stack/41) @@ type/42))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/3) @@ ", ") @@ "negint")))) (if (not ((buffer_length missing_keys/3) = 0)) (then - (stmt (((key_error/0 @@ missing_keys/3) @@ stack/31) @@ type/35)))) - (props/0.%{"numbers"} <- (Data.hashtbl decoded/10))) - (error (stmt (((decode_error/0 @@ input/23) @@ stack/31) @@ type/35))))) + (stmt (((key_error/0 @@ missing_keys/3) @@ stack/34) @@ type/35)))) + (props/0.%{"numbers"} <- (Data.hashtbl decoded/46))) + (error (stmt (((decode_error/0 @@ input/23) @@ stack/34) @@ type/35))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/0) @@ ", ") @@ "numbers")))) - (if_else (External.assoc_mem "record" classified/0) + (if_else (External.assoc_mem "record" decoded/0) (then - (let$ input/31 = (External.assoc_find "record" classified/0)) - (let$ stack/39 = ((stack_add/0 @@ "record") @@ stack_empty/0)) + (let$ input/31 = (External.assoc_find "record" decoded/0)) + (let$ stack/42 = ((stack_add/0 @@ "record") @@ stack_empty/0)) (let$ type/43 = "{\"!#%@\": string, a: string}") - (External.classify (assoc) input/31 - (ok classified/49 - (let$ decoded/11 = (hashtbl_create)) + (External.decode (assoc) input/31 + (ok decoded/54 + (let$ decoded/55 = (hashtbl_create)) (let$ missing_keys/4 = (buffer_create)) - (if_else (External.assoc_mem "!#%@" classified/49) + (if_else (External.assoc_mem "!#%@" decoded/54) (then - (let$ input/32 = (External.assoc_find "!#%@" classified/49)) - (let$ stack/40 = ((stack_add/0 @@ "!#%@") @@ stack/39)) + (let$ input/32 = (External.assoc_find "!#%@" decoded/54)) + (let$ stack/43 = ((stack_add/0 @@ "!#%@") @@ stack/42)) (let$ type/44 = "string") - (External.classify (string) input/32 - (ok classified/50 - (decoded/11.%{"!#%@"} <- (Data.string classified/50))) + (External.decode (string) input/32 + (ok decoded/56 (decoded/55.%{"!#%@"} <- (Data.string decoded/56))) (error - (stmt (((decode_error/0 @@ input/32) @@ stack/40) @@ type/44))))) + (stmt (((decode_error/0 @@ input/32) @@ stack/43) @@ type/44))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/4) @@ ", ") @@ "!#%@")))) - (if_else (External.assoc_mem "a" classified/49) + (if_else (External.assoc_mem "a" decoded/54) (then - (let$ input/33 = (External.assoc_find "a" classified/49)) - (let$ stack/41 = ((stack_add/0 @@ "a") @@ stack/39)) + (let$ input/33 = (External.assoc_find "a" decoded/54)) + (let$ stack/44 = ((stack_add/0 @@ "a") @@ stack/42)) (let$ type/45 = "string") - (External.classify (string) input/33 - (ok classified/51 - (decoded/11.%{"a"} <- (Data.string classified/51))) + (External.decode (string) input/33 + (ok decoded/57 (decoded/55.%{"a"} <- (Data.string decoded/57))) (error - (stmt (((decode_error/0 @@ input/33) @@ stack/41) @@ type/45))))) + (stmt (((decode_error/0 @@ input/33) @@ stack/44) @@ type/45))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/4) @@ ", ") @@ "a")))) (if (not ((buffer_length missing_keys/4) = 0)) (then - (stmt (((key_error/0 @@ missing_keys/4) @@ stack/39) @@ type/43)))) - (props/0.%{"record"} <- (Data.hashtbl decoded/11))) - (error (stmt (((decode_error/0 @@ input/31) @@ stack/39) @@ type/43))))) + (stmt (((key_error/0 @@ missing_keys/4) @@ stack/42) @@ type/43)))) + (props/0.%{"record"} <- (Data.hashtbl decoded/55))) + (error (stmt (((decode_error/0 @@ input/31) @@ stack/42) @@ type/43))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/0) @@ ", ") @@ "record")))) - (if_else (External.assoc_mem "tagged" classified/0) + (if_else (External.assoc_mem "tagged" decoded/0) (then - (let$ input/34 = (External.assoc_find "tagged" classified/0)) - (let$ stack/42 = ((stack_add/0 @@ "tagged") @@ stack_empty/0)) + (let$ input/34 = (External.assoc_find "tagged" decoded/0)) + (let$ stack/45 = ((stack_add/0 @@ "tagged") @@ stack_empty/0)) (let$ type/46 = "{@tag: false} | {@tag: true, a: string}") - (External.classify (assoc) input/34 - (ok classified/52 - (if_else (External.assoc_mem "tag" classified/52) + (External.decode (assoc) input/34 + (ok decoded/58 + (if_else (External.assoc_mem "tag" decoded/58) (then - (External.classify (bool) - (External.assoc_find "tag" classified/52) - (ok classified/53 - (let$ decoded/12 = (hashtbl_create)) - (if_else (not classified/53) + (External.decode (bool) (External.assoc_find "tag" decoded/58) + (ok decoded/59 + (let$ decoded/60 = (hashtbl_create)) + (if_else (not decoded/59) (then - (decoded/12.%{"tag"} <- (Data.int 0)) + (decoded/60.%{"tag"} <- (Data.int 0)) (let$ missing_keys/6 = (buffer_create)) (unit) (if (not ((buffer_length missing_keys/6) = 0)) (then (stmt - (((key_error/0 @@ missing_keys/6) @@ stack/42) @@ type/46))))) + (((key_error/0 @@ missing_keys/6) @@ stack/45) @@ type/46))))) (else - (if_else classified/53 + (if_else decoded/59 (then - (decoded/12.%{"tag"} <- (Data.int 1)) + (decoded/60.%{"tag"} <- (Data.int 1)) (let$ missing_keys/5 = (buffer_create)) - (if_else (External.assoc_mem "a" classified/52) + (if_else (External.assoc_mem "a" decoded/58) (then - (let$ input/35 = (External.assoc_find "a" classified/52)) - (let$ stack/43 = ((stack_add/0 @@ "a") @@ stack/42)) + (let$ input/35 = (External.assoc_find "a" decoded/58)) + (let$ stack/46 = ((stack_add/0 @@ "a") @@ stack/45)) (let$ type/47 = "string") - (External.classify (string) input/35 - (ok classified/54 - (decoded/12.%{"a"} <- (Data.string classified/54))) + (External.decode (string) input/35 + (ok decoded/61 + (decoded/60.%{"a"} <- (Data.string decoded/61))) (error (stmt - (((decode_error/0 @@ input/35) @@ stack/43) @@ type/47))))) + (((decode_error/0 @@ input/35) @@ stack/46) @@ type/47))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/5) @@ ", ") @@ "a")))) (if (not ((buffer_length missing_keys/5) = 0)) (then (stmt - (((key_error/0 @@ missing_keys/5) @@ stack/42) @@ type/46))))) + (((key_error/0 @@ missing_keys/5) @@ stack/45) @@ type/46))))) (else (stmt - (((decode_error/0 @@ input/34) @@ stack/42) @@ type/46)))))) - (props/0.%{"tagged"} <- (Data.hashtbl decoded/12))) + (((decode_error/0 @@ input/34) @@ stack/45) @@ type/46)))))) + (props/0.%{"tagged"} <- (Data.hashtbl decoded/60))) (error - (stmt (((decode_error/0 @@ input/34) @@ stack/42) @@ type/46))))) + (stmt (((decode_error/0 @@ input/34) @@ stack/45) @@ type/46))))) (else - (stmt (((decode_error/0 @@ input/34) @@ stack/42) @@ type/46))))) - (error (stmt (((decode_error/0 @@ input/34) @@ stack/42) @@ type/46))))) + (stmt (((decode_error/0 @@ input/34) @@ stack/45) @@ type/46))))) + (error (stmt (((decode_error/0 @@ input/34) @@ stack/45) @@ type/46))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/0) @@ ", ") @@ "tagged")))) - (if_else (External.assoc_mem "trim_a" classified/0) + (if_else (External.assoc_mem "trim_a" decoded/0) (then - (let$ input/36 = (External.assoc_find "trim_a" classified/0)) - (let$ stack/44 = ((stack_add/0 @@ "trim_a") @@ stack_empty/0)) + (let$ input/36 = (External.assoc_find "trim_a" decoded/0)) + (let$ stack/47 = ((stack_add/0 @@ "trim_a") @@ stack_empty/0)) (let$ type/48 = "string") - (External.classify (string) input/36 - (ok classified/55 - (props/0.%{"trim_a"} <- (Data.string classified/55))) - (error (stmt (((decode_error/0 @@ input/36) @@ stack/44) @@ type/48))))) + (External.decode (string) input/36 + (ok decoded/62 (props/0.%{"trim_a"} <- (Data.string decoded/62))) + (error (stmt (((decode_error/0 @@ input/36) @@ stack/47) @@ type/48))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/0) @@ ", ") @@ "trim_a")))) - (if_else (External.assoc_mem "trim_b" classified/0) + (if_else (External.assoc_mem "trim_b" decoded/0) (then - (let$ input/37 = (External.assoc_find "trim_b" classified/0)) - (let$ stack/45 = ((stack_add/0 @@ "trim_b") @@ stack_empty/0)) + (let$ input/37 = (External.assoc_find "trim_b" decoded/0)) + (let$ stack/48 = ((stack_add/0 @@ "trim_b") @@ stack_empty/0)) (let$ type/49 = "string") - (External.classify (string) input/37 - (ok classified/56 - (props/0.%{"trim_b"} <- (Data.string classified/56))) - (error (stmt (((decode_error/0 @@ input/37) @@ stack/45) @@ type/49))))) + (External.decode (string) input/37 + (ok decoded/63 (props/0.%{"trim_b"} <- (Data.string decoded/63))) + (error (stmt (((decode_error/0 @@ input/37) @@ stack/48) @@ type/49))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/0) @@ ", ") @@ "trim_b")))) - (if_else (External.assoc_mem "trim_c" classified/0) + (if_else (External.assoc_mem "trim_c" decoded/0) (then - (let$ input/38 = (External.assoc_find "trim_c" classified/0)) - (let$ stack/46 = ((stack_add/0 @@ "trim_c") @@ stack_empty/0)) + (let$ input/38 = (External.assoc_find "trim_c" decoded/0)) + (let$ stack/49 = ((stack_add/0 @@ "trim_c") @@ stack_empty/0)) (let$ type/50 = "string") - (External.classify (string) input/38 - (ok classified/57 - (props/0.%{"trim_c"} <- (Data.string classified/57))) - (error (stmt (((decode_error/0 @@ input/38) @@ stack/46) @@ type/50))))) + (External.decode (string) input/38 + (ok decoded/64 (props/0.%{"trim_c"} <- (Data.string decoded/64))) + (error (stmt (((decode_error/0 @@ input/38) @@ stack/49) @@ type/50))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/0) @@ ", ") @@ "trim_c")))) - (if_else (External.assoc_mem "trim_d" classified/0) + (if_else (External.assoc_mem "trim_d" decoded/0) (then - (let$ input/39 = (External.assoc_find "trim_d" classified/0)) - (let$ stack/47 = ((stack_add/0 @@ "trim_d") @@ stack_empty/0)) + (let$ input/39 = (External.assoc_find "trim_d" decoded/0)) + (let$ stack/50 = ((stack_add/0 @@ "trim_d") @@ stack_empty/0)) (let$ type/51 = "string") - (External.classify (string) input/39 - (ok classified/58 - (props/0.%{"trim_d"} <- (Data.string classified/58))) - (error (stmt (((decode_error/0 @@ input/39) @@ stack/47) @@ type/51))))) + (External.decode (string) input/39 + (ok decoded/65 (props/0.%{"trim_d"} <- (Data.string decoded/65))) + (error (stmt (((decode_error/0 @@ input/39) @@ stack/50) @@ type/51))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/0) @@ ", ") @@ "trim_d")))) - (if_else (External.assoc_mem "trim_e" classified/0) + (if_else (External.assoc_mem "trim_e" decoded/0) (then - (let$ input/40 = (External.assoc_find "trim_e" classified/0)) - (let$ stack/48 = ((stack_add/0 @@ "trim_e") @@ stack_empty/0)) + (let$ input/40 = (External.assoc_find "trim_e" decoded/0)) + (let$ stack/51 = ((stack_add/0 @@ "trim_e") @@ stack_empty/0)) (let$ type/52 = "string") - (External.classify (string) input/40 - (ok classified/59 - (props/0.%{"trim_e"} <- (Data.string classified/59))) - (error (stmt (((decode_error/0 @@ input/40) @@ stack/48) @@ type/52))))) + (External.decode (string) input/40 + (ok decoded/66 (props/0.%{"trim_e"} <- (Data.string decoded/66))) + (error (stmt (((decode_error/0 @@ input/40) @@ stack/51) @@ type/52))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/0) @@ ", ") @@ "trim_e")))) - (if_else (External.assoc_mem "trim_f" classified/0) + (if_else (External.assoc_mem "trim_f" decoded/0) (then - (let$ input/41 = (External.assoc_find "trim_f" classified/0)) - (let$ stack/49 = ((stack_add/0 @@ "trim_f") @@ stack_empty/0)) + (let$ input/41 = (External.assoc_find "trim_f" decoded/0)) + (let$ stack/52 = ((stack_add/0 @@ "trim_f") @@ stack_empty/0)) (let$ type/53 = "string") - (External.classify (string) input/41 - (ok classified/60 - (props/0.%{"trim_f"} <- (Data.string classified/60))) - (error (stmt (((decode_error/0 @@ input/41) @@ stack/49) @@ type/53))))) + (External.decode (string) input/41 + (ok decoded/67 (props/0.%{"trim_f"} <- (Data.string decoded/67))) + (error (stmt (((decode_error/0 @@ input/41) @@ stack/52) @@ type/53))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/0) @@ ", ") @@ "trim_f")))) - (if_else (External.assoc_mem "trim_g" classified/0) + (if_else (External.assoc_mem "trim_g" decoded/0) (then - (let$ input/42 = (External.assoc_find "trim_g" classified/0)) - (let$ stack/50 = ((stack_add/0 @@ "trim_g") @@ stack_empty/0)) + (let$ input/42 = (External.assoc_find "trim_g" decoded/0)) + (let$ stack/53 = ((stack_add/0 @@ "trim_g") @@ stack_empty/0)) (let$ type/54 = "string") - (External.classify (string) input/42 - (ok classified/61 - (props/0.%{"trim_g"} <- (Data.string classified/61))) - (error (stmt (((decode_error/0 @@ input/42) @@ stack/50) @@ type/54))))) + (External.decode (string) input/42 + (ok decoded/68 (props/0.%{"trim_g"} <- (Data.string decoded/68))) + (error (stmt (((decode_error/0 @@ input/42) @@ stack/53) @@ type/54))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/0) @@ ", ") @@ "trim_g")))) - (if_else (External.assoc_mem "tuple" classified/0) + (if_else (External.assoc_mem "tuple" decoded/0) (then - (let$ input/43 = (External.assoc_find "tuple" classified/0)) - (let$ stack/51 = ((stack_add/0 @@ "tuple") @@ stack_empty/0)) + (let$ input/43 = (External.assoc_find "tuple" decoded/0)) + (let$ stack/54 = ((stack_add/0 @@ "tuple") @@ stack_empty/0)) (let$ type/55 = "(int, float, string)") - (External.classify (linear) input/43 - (ok classified/62 - (if_else ((External.length classified/62) = 3) - (then - (let$ decoded/13 = (array_make 3 (Data.int 0))) - (External.iteri classified/62 key/5 value/5 - (let$ stack/52 = - ((stack_add/0 @@ (string_of_int key/5)) @@ stack/51)) - (if_else (key/5 = 0) - (then - (let$ type/58 = "int") - (External.classify (int) value/5 - (ok classified/66 - (decoded/13.%(key/5) <- (Data.int classified/66))) - (error - (stmt (((decode_error/0 @@ value/5) @@ stack/52) @@ type/58))))) - (else - (if_else (key/5 = 1) - (then - (let$ type/57 = "float") - (External.classify (float) value/5 - (ok classified/64 - (decoded/13.%(key/5) <- (Data.float classified/64))) - (error - (External.classify (int) value/5 - (ok classified/65 - (decoded/13.%(key/5) <- - (Data.float (float_of_int classified/65)))) - (error - (stmt - (((decode_error/0 @@ value/5) @@ stack/52) @@ type/57))))))) - (else - (if_else (key/5 = 2) - (then - (let$ type/56 = "string") - (External.classify (string) value/5 - (ok classified/63 - (decoded/13.%(key/5) <- (Data.string classified/63))) - (error - (stmt - (((decode_error/0 @@ value/5) @@ stack/52) @@ type/56))))) - (else - (stmt - (((decode_error/0 @@ value/5) @@ stack/52) @@ type/55)))))))) - (props/0.%{"tuple"} <- (Data.array decoded/13)))) - (else - (stmt (((decode_error/0 @@ input/43) @@ stack/51) @@ type/55))))) - (error (stmt (((decode_error/0 @@ input/43) @@ stack/51) @@ type/55))))) + (External.decode (seq) input/43 + (ok decoded/69 + (let$ decoded/70 = (array_make 3 (Data.int 0))) + (uncons decoded/69 + (nil (stmt (((decode_error/0 @@ input/43) @@ stack/54) @@ type/55))) + (cons hd/4 seq/4 + (let$ stack/55 = ((stack_add/0 @@ (string_of_int 0)) @@ stack/54)) + (let$ type/56 = "int") + (External.decode (int) hd/4 + (ok decoded/71 (decoded/70.%(0) <- (Data.int decoded/71))) + (error (stmt (((decode_error/0 @@ hd/4) @@ stack/55) @@ type/56)))) + (uncons seq/4 + (nil + (stmt (((decode_error/0 @@ input/43) @@ stack/54) @@ type/55))) + (cons hd/5 seq/5 + (let$ stack/56 = + ((stack_add/0 @@ (string_of_int 1)) @@ stack/54)) + (let$ type/57 = "float") + (External.decode (float) hd/5 + (ok decoded/72 (decoded/70.%(1) <- (Data.float decoded/72))) + (error + (stmt (((decode_error/0 @@ hd/5) @@ stack/56) @@ type/57)))) + (uncons seq/5 + (nil + (stmt (((decode_error/0 @@ input/43) @@ stack/54) @@ type/55))) + (cons hd/6 seq/6 + (let$ stack/57 = + ((stack_add/0 @@ (string_of_int 2)) @@ stack/54)) + (let$ type/58 = "string") + (External.decode (string) hd/6 + (ok decoded/73 (decoded/70.%(2) <- (Data.string decoded/73))) + (error + (stmt (((decode_error/0 @@ hd/6) @@ stack/57) @@ type/58)))) + (unit))))))) + (props/0.%{"tuple"} <- (Data.array decoded/70))) + (error (stmt (((decode_error/0 @@ input/43) @@ stack/54) @@ type/55))))) (else (stmt (((buffer_add_sep/0 @@ missing_keys/0) @@ ", ") @@ "tuple")))) (if (not ((buffer_length missing_keys/0) = 0)) (then (stmt (((key_error/0 @@ missing_keys/0) @@ stack_empty/0) @@ type/0))))) - (error (stmt (((decode_error/0 @@ arg/11) @@ stack_empty/0) @@ type/0)))) + (error (stmt (((decode_error/0 @@ arg/12) @@ stack_empty/0) @@ type/0)))) (if_else ((buffer_length errors/0) = 0) (then (let$ buf/2 = (buffer_create)) @@ -1851,7 +1789,7 @@ Print the runtime instructions (buffer_add_string buf/2 " ") (buffer_add_string buf/2 "\n") (buffer_add_string buf/2 "\n\nMap list\n") - (let& index/0 = 0) + (let& index/2 = 0) (let& cell/0 = (props/0.%{"map_l"})) (while (not (Data.equal !cell/0 (Data.int 0))) ((let$ match_props/2 = (hashtbl_create)) @@ -1865,7 +1803,7 @@ Print the runtime instructions (then (unit) (exit/4 := 0)) (else (if_else (Data.equal head/0 (Data.int 3)) - (then (match_props/2.%{"i"} <- (Data.int !index/0)) (exit/4 := 1)) + (then (match_props/2.%{"i"} <- (Data.int !index/2)) (exit/4 := 1)) (else (unit) (exit/4 := 2))))))) (if_else (!exit/4 = 0) (then (unit)) @@ -1878,20 +1816,22 @@ Print the runtime instructions @@ (string_of_int (Data.to_int (match_props/2.%{"i"}))))) (buffer_add_string buf/2 " ")) (else (buffer_add_string buf/2 " "))))) - (incr index/0) + (incr index/2) (cell/0 := (list/0.%(1))))) (buffer_add_string buf/2 "\n\nMap dict\n") (let$ match_arg/12 = (props/0.%{"map_d"})) - (hashtbl_iter (Data.to_hashtbl match_arg/12) key/6 value/6 + (iter (hashtbl_to_seq (Data.to_hashtbl match_arg/12)) (let$ match_props/3 = (hashtbl_create)) (let& exit/5 = -1) - (if_else (Data.equal value/6 (Data.int 1)) + (if_else (Data.equal (snd arg/23) (Data.int 1)) (then (unit) (exit/5 := 0)) (else - (if_else (Data.equal value/6 (Data.int 2)) + (if_else (Data.equal (snd arg/23) (Data.int 2)) (then (unit) (exit/5 := 0)) (else - (if_else (Data.equal value/6 (Data.int 3)) - (then (match_props/3.%{"k"} <- (Data.string key/6)) (exit/5 := 1)) + (if_else (Data.equal (snd arg/23) (Data.int 3)) + (then + (match_props/3.%{"k"} <- (Data.string (fst arg/23))) + (exit/5 := 1)) (else (unit) (exit/5 := 2))))))) (if_else (!exit/5 = 0) (then (unit)) diff --git a/test/printjs/esm-cjs.t/run.t b/test/printjs/esm-cjs.t/run.t index 3ee41458..217900da 100644 --- a/test/printjs/esm-cjs.t/run.t +++ b/test/printjs/esm-cjs.t/run.t @@ -7,18 +7,17 @@ (arg$0) => { return ( (arg$1) => { - for (let i$0 = 0; i$0 < arg$1.length; i$0++) { - let c$0 = arg$1.charCodeAt(i$0); - switch (c$0) { - case 38: arg$0.contents += "&"; break; - case 34: arg$0.contents += """; break; - case 39: arg$0.contents += "'"; break; - case 62: arg$0.contents += ">"; break; - case 60: arg$0.contents += "<"; break; - case 47: arg$0.contents += "/"; break; - case 96: arg$0.contents += "`"; break; - case 61: arg$0.contents += "="; break; - default: arg$0.contents += String.fromCharCode(c$0); + for (let item$0 of arg$1[Symbol.iterator]()) { + switch (item$0) { + case "&": arg$0.contents += "&"; break; + case "\"": arg$0.contents += """; break; + case "'": arg$0.contents += "'"; break; + case ">": arg$0.contents += ">"; break; + case "<": arg$0.contents += "<"; break; + case "/": arg$0.contents += "/"; break; + case "`": arg$0.contents += "`"; break; + case "=": arg$0.contents += "="; break; + default: arg$0.contents += item$0; } } } @@ -51,10 +50,9 @@ components$0.set( "ExternalFunction", (arg$0) => { - let encoded$0 = new Map(); - let props$0 = arg$0.get("children"); - encoded$0.set("children", props$0); - return (import$0(Object.fromEntries(encoded$0))); + let seq$0 = + (function* () { yield (["children", arg$0.get("children")]); })(); + return (import$0(Object.fromEntries(seq$0))); } ); export default async (arg$0) => { @@ -133,18 +131,17 @@ (arg$0) => { return ( (arg$1) => { - for (let i$0 = 0; i$0 < arg$1.length; i$0++) { - let c$0 = arg$1.charCodeAt(i$0); - switch (c$0) { - case 38: arg$0.contents += "&"; break; - case 34: arg$0.contents += """; break; - case 39: arg$0.contents += "'"; break; - case 62: arg$0.contents += ">"; break; - case 60: arg$0.contents += "<"; break; - case 47: arg$0.contents += "/"; break; - case 96: arg$0.contents += "`"; break; - case 61: arg$0.contents += "="; break; - default: arg$0.contents += String.fromCharCode(c$0); + for (let item$0 of arg$1[Symbol.iterator]()) { + switch (item$0) { + case "&": arg$0.contents += "&"; break; + case "\"": arg$0.contents += """; break; + case "'": arg$0.contents += "'"; break; + case ">": arg$0.contents += ">"; break; + case "<": arg$0.contents += "<"; break; + case "/": arg$0.contents += "/"; break; + case "`": arg$0.contents += "`"; break; + case "=": arg$0.contents += "="; break; + default: arg$0.contents += item$0; } } } @@ -177,10 +174,9 @@ components$0.set( "ExternalFunction", (arg$0) => { - let encoded$0 = new Map(); - let props$0 = arg$0.get("children"); - encoded$0.set("children", props$0); - return (import$0["externalFunction"](Object.fromEntries(encoded$0))); + let seq$0 = + (function* () { yield (["children", arg$0.get("children")]); })(); + return (import$0["externalFunction"](Object.fromEntries(seq$0))); } ); module.exports = diff --git a/test/printjs/printjs.t/run.t b/test/printjs/printjs.t/run.t index e060731d..d7cdecd6 100644 --- a/test/printjs/printjs.t/run.t +++ b/test/printjs/printjs.t/run.t @@ -14,18 +14,17 @@ (arg$0) => { return ( (arg$1) => { - for (let i$0 = 0; i$0 < arg$1.length; i$0++) { - let c$0 = arg$1.charCodeAt(i$0); - switch (c$0) { - case 38: arg$0.contents += "&"; break; - case 34: arg$0.contents += """; break; - case 39: arg$0.contents += "'"; break; - case 62: arg$0.contents += ">"; break; - case 60: arg$0.contents += "<"; break; - case 47: arg$0.contents += "/"; break; - case 96: arg$0.contents += "`"; break; - case 61: arg$0.contents += "="; break; - default: arg$0.contents += String.fromCharCode(c$0); + for (let item$0 of arg$1[Symbol.iterator]()) { + switch (item$0) { + case "&": arg$0.contents += "&"; break; + case "\"": arg$0.contents += """; break; + case "'": arg$0.contents += "'"; break; + case ">": arg$0.contents += ">"; break; + case "<": arg$0.contents += "<"; break; + case "/": arg$0.contents += "/"; break; + case "`": arg$0.contents += "`"; break; + case "=": arg$0.contents += "="; break; + default: arg$0.contents += item$0; } } } @@ -58,209 +57,209 @@ components$0.set( "Another_function", (arg$0) => { - let encoded$0 = new Map(); - return (import$0(Object.fromEntries(encoded$0))); + let seq$0 = (function* () { })(); + return (import$0(Object.fromEntries(seq$0))); } ); import {"stringify" as import$1} from "./jscomponents.mjs"; components$0.set( "Stringify", (arg$0) => { - let encoded$0 = new Map(); - let props$0 = arg$0.get("int_list"); - let index$0 = 0; - let cell$0 = props$0; - while (!(cell$0 === 0)) { index$0++; cell$0 = cell$0[1]; } - let encoded$1 = - Array.from({length: index$0}, (arg$1) => { return (null); }); - cell$0 = props$0; - index$0 = 0; - while (!(cell$0 === 0)) { - let props$1 = cell$0[0]; - encoded$1[index$0] = props$1; - index$0++; - cell$0 = cell$0[1]; - } - encoded$0.set("int_list", encoded$1); - let props$1 = arg$0.get("nested_list"); - let index$1 = 0; - let cell$1 = props$1; - while (!(cell$1 === 0)) { index$1++; cell$1 = cell$1[1]; } - let encoded$2 = - Array.from({length: index$1}, (arg$1) => { return (null); }); - cell$1 = props$1; - index$1 = 0; - while (!(cell$1 === 0)) { - let props$2 = cell$1[0]; - let index$2 = 0; - let cell$2 = props$2; - while (!(cell$2 === 0)) { index$2++; cell$2 = cell$2[1]; } - let encoded$3 = - Array.from({length: index$2}, (arg$1) => { return (null); }); - cell$2 = props$2; - index$2 = 0; - while (!(cell$2 === 0)) { - let props$3 = cell$2[0]; - let index$3 = 0; - let cell$3 = props$3; - while (!(cell$3 === 0)) { index$3++; cell$3 = cell$3[1]; } - let encoded$4 = - Array.from({length: index$3}, (arg$1) => { return (null); }); - cell$3 = props$3; - index$3 = 0; - while (!(cell$3 === 0)) { - let props$4 = cell$3[0]; - encoded$4[index$3] = props$4; - index$3++; - cell$3 = cell$3[1]; + let seq$0 = + (function* () { + let seq$1 = + (function* () { + let cell$0 = arg$0.get("int_list"); + while (!(cell$0 === 0)) { + let props$0 = cell$0[0]; + cell$0 = cell$0[1]; + yield (props$0); + } + })(); + yield (["int_list", Array.from(seq$1)]); + let seq$2 = + (function* () { + let cell$0 = arg$0.get("nested_list"); + while (!(cell$0 === 0)) { + let props$0 = cell$0[0]; + cell$0 = cell$0[1]; + let seq$3 = + (function* () { + let cell$1 = props$0; + while (!(cell$1 === 0)) { + let props$1 = cell$1[0]; + cell$1 = cell$1[1]; + let seq$4 = + (function* () { + let cell$2 = props$1; + while (!(cell$2 === 0)) { + let props$2 = cell$2[0]; + cell$2 = cell$2[1]; + yield (props$2); + } + })(); + yield (Array.from(seq$4)); + } + })(); + yield (Array.from(seq$3)); + } + })(); + yield (["nested_list", Array.from(seq$2)]); + let seq$3 = + (function* () { + let cell$0 = arg$0.get("nested_nullable_list"); + while (!(cell$0 === 0)) { + let props$0 = cell$0[0]; + cell$0 = cell$0[1]; + if (props$0 === 0) { + yield (null); + } else { + let props$1 = props$0[0]; + if (props$1 === 0) { + yield (null); + } else { + let props$2 = props$1[0]; + yield (!(props$2 === 0)); + } + } + } + })(); + yield (["nested_nullable_list", Array.from(seq$3)]); + let seq$4 = + (function* () { + for (let item$0 of arg$0.get("null_string_dict").entries()) { + if (item$0[1] === 0) { + yield ([item$0[0], null]); + } else { + let props$0 = item$0[1][0]; + yield ([item$0[0], props$0]); + } + } + })(); + yield (["null_string_dict", Object.fromEntries(seq$4)]); + let seq$5 = + (function* () { + yield (["int_enum", arg$0.get("record").get("int_enum")]); + yield (["string_enum", arg$0.get("record").get("string_enum")]); + })(); + yield (["record", Object.fromEntries(seq$5)]); + let props$0 = arg$0.get("tagged_record_bool"); + let tag$0 = props$0.get("tag"); + if (tag$0 === 0) { + let seq$6 = + (function* () { + yield (["tag", !(tag$0 === 0)]); + yield (["a", props$0.get("a")]); + })(); + yield (["tagged_record_bool", Object.fromEntries(seq$6)]); + } else { + if (tag$0 === 1) { + let seq$6 = + (function* () { + yield (["tag", !(tag$0 === 0)]); + yield (["b", props$0.get("b")]); + })(); + yield (["tagged_record_bool", Object.fromEntries(seq$6)]); + } else { + let seq$6 = (function* () { })(); + yield (["tagged_record_bool", Object.fromEntries(seq$6)]); + } } - encoded$3[index$2] = encoded$4; - index$2++; - cell$2 = cell$2[1]; - } - encoded$2[index$1] = encoded$3; - index$1++; - cell$1 = cell$1[1]; - } - encoded$0.set("nested_list", encoded$2); - let props$2 = arg$0.get("nested_nullable_list"); - let index$2 = 0; - let cell$2 = props$2; - while (!(cell$2 === 0)) { index$2++; cell$2 = cell$2[1]; } - let encoded$3 = - Array.from({length: index$2}, (arg$1) => { return (null); }); - cell$2 = props$2; - index$2 = 0; - while (!(cell$2 === 0)) { - let props$3 = cell$2[0]; - if (props$3 === 0) { - encoded$3[index$2] = null; - } else { - let props$4 = props$3[0]; - if (props$4 === 0) { - encoded$3[index$2] = null; + let props$1 = arg$0.get("tagged_record_int"); + let tag$1 = props$1.get("tag"); + if (tag$1 === 0) { + let seq$6 = (function* () { yield (["tag", tag$1]); })(); + yield (["tagged_record_int", Object.fromEntries(seq$6)]); } else { - let props$5 = props$4[0]; - encoded$3[index$2] = !(props$5 === 0); + if (tag$1 === 1) { + let seq$6 = + (function* () { + yield (["tag", tag$1]); + let props$2 = props$1.get("tuple"); + let seq$7 = + (function* () { + yield (props$2[0]); + yield (props$2[1]); + yield (!(props$2[2] === 0)); + })(); + yield (["tuple", Array.from(seq$7)]); + })(); + yield (["tagged_record_int", Object.fromEntries(seq$6)]); + } else { + let seq$6 = (function* () { })(); + yield (["tagged_record_int", Object.fromEntries(seq$6)]); + } } - } - index$2++; - cell$2 = cell$2[1]; - } - encoded$0.set("nested_nullable_list", encoded$3); - let props$3 = arg$0.get("null_string_dict"); - let encoded$4 = new Map(); - for (let x$0 of props$3) { - if (x$0[1] === 0) { - encoded$4.set(x$0[0], null); - } else { - let props$4 = x$0[1][0]; - encoded$4.set(x$0[0], props$4); - } - } - encoded$0.set("null_string_dict", Object.fromEntries(encoded$4)); - let props$4 = arg$0.get("record"); - let encoded$5 = new Map(); - let props$5 = props$4.get("int_enum"); - encoded$5.set("int_enum", props$5); - let props$6 = props$4.get("string_enum"); - encoded$5.set("string_enum", props$6); - encoded$0.set("record", Object.fromEntries(encoded$5)); - let props$7 = arg$0.get("tagged_record_bool"); - let tag$0 = props$7.get("tag"); - let encoded$6 = new Map(); - if (tag$0 === 0) { - encoded$6.set("tag", !(tag$0 === 0)); - let props$8 = props$7.get("a"); - encoded$6.set("a", props$8); - } else { - if (tag$0 === 1) { - encoded$6.set("tag", !(tag$0 === 0)); - let props$8 = props$7.get("b"); - encoded$6.set("b", props$8); - } - } - encoded$0.set("tagged_record_bool", Object.fromEntries(encoded$6)); - let props$8 = arg$0.get("tagged_record_int"); - let tag$1 = props$8.get("tag"); - let encoded$7 = new Map(); - if (tag$1 === 0) { - encoded$7.set("tag", tag$1); - } else { - if (tag$1 === 1) { - encoded$7.set("tag", tag$1); - let props$9 = props$8.get("tuple"); - let encoded$8 = - Array.from({length: 3}, (arg$1) => { return (null); }); - let props$10 = props$9[0]; - encoded$8[0] = props$10; - let props$11 = props$9[1]; - encoded$8[1] = props$11; - let props$12 = props$9[2]; - encoded$8[2] = !(props$12 === 0); - encoded$7.set("tuple", encoded$8); - } - } - encoded$0.set("tagged_record_int", Object.fromEntries(encoded$7)); - let props$9 = arg$0.get("tagged_record_open"); - let tag$2 = props$9.get("tag"); - let encoded$8 = new Map(); - if (tag$2 === 100) { - encoded$8.set("tag", tag$2); - let props$10 = props$9.get("a"); - encoded$8.set("a", props$10); - } else { - if (tag$2 === 200) { - encoded$8.set("tag", tag$2); - let props$10 = props$9.get("b"); - encoded$8.set("b", props$10); - } else { - if (tag$2 === 300) { - encoded$8.set("tag", tag$2); - let props$10 = props$9.get("c"); - encoded$8.set("c", props$10); + let props$2 = arg$0.get("tagged_record_open"); + let tag$2 = props$2.get("tag"); + if (tag$2 === 100) { + let seq$6 = + (function* () { + yield (["tag", tag$2]); + yield (["a", props$2.get("a")]); + })(); + yield (["tagged_record_open", Object.fromEntries(seq$6)]); + } else { + if (tag$2 === 200) { + let seq$6 = + (function* () { + yield (["tag", tag$2]); + yield (["b", props$2.get("b")]); + })(); + yield (["tagged_record_open", Object.fromEntries(seq$6)]); + } else { + if (tag$2 === 300) { + let seq$6 = + (function* () { + yield (["tag", tag$2]); + yield (["c", props$2.get("c")]); + })(); + yield (["tagged_record_open", Object.fromEntries(seq$6)]); + } else { + let seq$6 = (function* () { yield (["tag", tag$2]); })(); + yield (["tagged_record_open", Object.fromEntries(seq$6)]); + } + } + } + let props$3 = arg$0.get("tagged_record_string"); + let tag$3 = props$3.get("tag"); + if (tag$3 === "a") { + let seq$6 = + (function* () { + yield (["tag", tag$3]); + let seq$7 = + (function* () { + let cell$0 = props$3.get("record_list"); + while (!(cell$0 === 0)) { + let props$4 = cell$0[0]; + cell$0 = cell$0[1]; + let seq$8 = + (function* () { + yield (["job", props$4.get("job")]); + yield (["name", props$4.get("name")]); + })(); + yield (Object.fromEntries(seq$8)); + } + })(); + yield (["record_list", Array.from(seq$7)]); + })(); + yield (["tagged_record_string", Object.fromEntries(seq$6)]); } else { - encoded$8.set("tag", tag$2); + if (tag$3 === "b") { + let seq$6 = + (function* () { + yield (["tag", tag$3]); + yield (["open_enum", props$3.get("open_enum")]); + })(); + yield (["tagged_record_string", Object.fromEntries(seq$6)]); + } else { + let seq$6 = (function* () { })(); + yield (["tagged_record_string", Object.fromEntries(seq$6)]); + } } - } - } - encoded$0.set("tagged_record_open", Object.fromEntries(encoded$8)); - let props$10 = arg$0.get("tagged_record_string"); - let tag$3 = props$10.get("tag"); - let encoded$9 = new Map(); - if (tag$3 === "a") { - encoded$9.set("tag", tag$3); - let props$11 = props$10.get("record_list"); - let index$3 = 0; - let cell$3 = props$11; - while (!(cell$3 === 0)) { index$3++; cell$3 = cell$3[1]; } - let encoded$10 = - Array.from({length: index$3}, (arg$1) => { return (null); }); - cell$3 = props$11; - index$3 = 0; - while (!(cell$3 === 0)) { - let props$12 = cell$3[0]; - let encoded$11 = new Map(); - let props$13 = props$12.get("job"); - encoded$11.set("job", props$13); - let props$14 = props$12.get("name"); - encoded$11.set("name", props$14); - encoded$10[index$3] = Object.fromEntries(encoded$11); - index$3++; - cell$3 = cell$3[1]; - } - encoded$9.set("record_list", encoded$10); - } else { - if (tag$3 === "b") { - encoded$9.set("tag", tag$3); - let props$11 = props$10.get("open_enum"); - encoded$9.set("open_enum", props$11); - } - } - encoded$0.set("tagged_record_string", Object.fromEntries(encoded$9)); - let props$11 = arg$0.get("unknown"); - encoded$0.set("unknown", props$11); - return (import$1(Object.fromEntries(encoded$0))); + yield (["unknown", arg$0.get("unknown")]); + })(); + return (import$1(Object.fromEntries(seq$0))); } ); components$0.set( @@ -370,11 +369,7 @@ if (typeof input$0 === "number") { props$0.set("big_float", input$0); } else { - if (Number.isInteger(input$0)) { - props$0.set("big_float", input$0); - } else { - decode_error$0(input$0)(stack$0)(type$1); - } + decode_error$0(input$0)(stack$0)(type$1); } } else { buffer_add_sep$0(missing_keys$0)(", ")("big_float"); @@ -440,18 +435,21 @@ let stack$0 = stack_add$0("int_list")(stack_empty$0); let type$1 = "[int]"; if (Array.isArray(input$0)) { + let seq$0 = input$0.values(); + let index$0 = 0; let decoded$0 = [0, 0]; let decode_dst$0 = decoded$0; - for (let i$0 = 0; i$0 < input$0.length; i$0++) { + for (let item$0 of seq$0) { let decode_dst_new$0 = [0, 0]; - let stack$1 = stack_add$0(String(i$0))(stack$0); + let stack$1 = stack_add$0(String(index$0))(stack$0); let type$2 = "int"; - if (Number.isInteger(input$0[i$0])) { - decode_dst_new$0[0] = input$0[i$0]; + if (Number.isInteger(item$0)) { + decode_dst_new$0[0] = item$0; } else { - decode_error$0(input$0[i$0])(stack$1)(type$2); + decode_error$0(item$0)(stack$1)(type$2); } decode_dst$0[1] = decode_dst_new$0; + index$0++; decode_dst$0 = decode_dst_new$0; } props$0.set("int_list", decoded$0[1]); @@ -466,46 +464,55 @@ let stack$0 = stack_add$0("nested_list")(stack_empty$0); let type$1 = "[[[int]]]"; if (Array.isArray(input$0)) { + let seq$0 = input$0.values(); + let index$0 = 0; let decoded$0 = [0, 0]; let decode_dst$0 = decoded$0; - for (let i$0 = 0; i$0 < input$0.length; i$0++) { + for (let item$0 of seq$0) { let decode_dst_new$0 = [0, 0]; - let stack$1 = stack_add$0(String(i$0))(stack$0); + let stack$1 = stack_add$0(String(index$0))(stack$0); let type$2 = "[[int]]"; - if (Array.isArray(input$0[i$0])) { + if (Array.isArray(item$0)) { + let seq$1 = item$0.values(); + let index$1 = 0; let decoded$1 = [0, 0]; let decode_dst$1 = decoded$1; - for (let i$1 = 0; i$1 < input$0[i$0].length; i$1++) { + for (let item$1 of seq$1) { let decode_dst_new$1 = [0, 0]; - let stack$2 = stack_add$0(String(i$1))(stack$1); + let stack$2 = stack_add$0(String(index$1))(stack$1); let type$3 = "[int]"; - if (Array.isArray(input$0[i$0][i$1])) { + if (Array.isArray(item$1)) { + let seq$2 = item$1.values(); + let index$2 = 0; let decoded$2 = [0, 0]; let decode_dst$2 = decoded$2; - for (let i$2 = 0; i$2 < input$0[i$0][i$1].length; i$2++) { + for (let item$2 of seq$2) { let decode_dst_new$2 = [0, 0]; - let stack$3 = stack_add$0(String(i$2))(stack$2); + let stack$3 = stack_add$0(String(index$2))(stack$2); let type$4 = "int"; - if (Number.isInteger(input$0[i$0][i$1][i$2])) { - decode_dst_new$2[0] = input$0[i$0][i$1][i$2]; + if (Number.isInteger(item$2)) { + decode_dst_new$2[0] = item$2; } else { - decode_error$0(input$0[i$0][i$1][i$2])(stack$3)(type$4); + decode_error$0(item$2)(stack$3)(type$4); } decode_dst$2[1] = decode_dst_new$2; + index$2++; decode_dst$2 = decode_dst_new$2; } decode_dst_new$1[0] = decoded$2[1]; } else { - decode_error$0(input$0[i$0][i$1])(stack$2)(type$3); + decode_error$0(item$1)(stack$2)(type$3); } decode_dst$1[1] = decode_dst_new$1; + index$1++; decode_dst$1 = decode_dst_new$1; } decode_dst_new$0[0] = decoded$1[1]; } else { - decode_error$0(input$0[i$0])(stack$1)(type$2); + decode_error$0(item$0)(stack$1)(type$2); } decode_dst$0[1] = decode_dst_new$0; + index$0++; decode_dst$0 = decode_dst_new$0; } props$0.set("nested_list", decoded$0[1]); @@ -520,28 +527,26 @@ let stack$0 = stack_add$0("nested_nullable_list")(stack_empty$0); let type$1 = "[??false | true]"; if (Array.isArray(input$0)) { + let seq$0 = input$0.values(); + let index$0 = 0; let decoded$0 = [0, 0]; let decode_dst$0 = decoded$0; - for (let i$0 = 0; i$0 < input$0.length; i$0++) { + for (let item$0 of seq$0) { let decode_dst_new$0 = [0, 0]; - let stack$1 = stack_add$0(String(i$0))(stack$0); + let stack$1 = stack_add$0(String(index$0))(stack$0); let type$2 = "??false | true"; - if (!(input$0[i$0] === null) && !(input$0[i$0] === undefined)) { + if (!(item$0 === null) && !(item$0 === undefined)) { let decoded$1 = [0]; let stack$2 = stack_add$0("")(stack$1); let type$3 = "?false | true"; - if (!(input$0[i$0] === null) && !(input$0[i$0] === undefined)) { + if (!(item$0 === null) && !(item$0 === undefined)) { let decoded$2 = [0]; let stack$3 = stack_add$0("")(stack$2); let type$4 = "false | true"; - if (typeof input$0[i$0] === "boolean") { - if (input$0[i$0]) { - decoded$2[0] = 1; - } else { - decoded$2[0] = 0; - } + if (typeof item$0 === "boolean") { + if (item$0) { decoded$2[0] = 1; } else { decoded$2[0] = 0; } } else { - decode_error$0(input$0[i$0])(stack$3)(type$4); + decode_error$0(item$0)(stack$3)(type$4); } decoded$1[0] = decoded$2; } else { @@ -552,6 +557,7 @@ decode_dst_new$0[0] = 0; } decode_dst$0[1] = decode_dst_new$0; + index$0++; decode_dst$0 = decode_dst_new$0; } props$0.set("nested_nullable_list", decoded$0[1]); @@ -592,11 +598,7 @@ if (typeof input$0 === "number") { decoded$0[0] = input$0; } else { - if (Number.isInteger(input$0)) { - decoded$0[0] = input$0; - } else { - decode_error$0(input$0)(stack$1)(type$2); - } + decode_error$0(input$0)(stack$1)(type$2); } props$0.set("null_float", decoded$0); } else { @@ -651,21 +653,21 @@ let type$1 = ""; if (typeof input$0 === "object" && !(input$0 === null)) { let decoded$0 = new Map(); - for (let x$0 of Object.keys(input$0)) { - let stack$1 = stack_add$0(x$0)(stack$0); + for (let item$0 of Object.entries(input$0).values()) { + let stack$1 = stack_add$0(item$0[0])(stack$0); let type$2 = "?string"; - if (!(input$0[x$0] === null) && !(input$0[x$0] === undefined)) { + if (!(item$0[1] === null) && !(item$0[1] === undefined)) { let decoded$1 = [0]; let stack$2 = stack_add$0("")(stack$1); let type$3 = "string"; - if (typeof input$0[x$0] === "string") { - decoded$1[0] = input$0[x$0]; + if (typeof item$0[1] === "string") { + decoded$1[0] = item$0[1]; } else { - decode_error$0(input$0[x$0])(stack$2)(type$3); + decode_error$0(item$0[1])(stack$2)(type$3); } - decoded$0.set(x$0, decoded$1); + decoded$0.set(item$0[0], decoded$1); } else { - decoded$0.set(x$0, 0); + decoded$0.set(item$0[0], 0); } props$0.set("null_string_dict", decoded$0); } @@ -818,52 +820,49 @@ let stack$1 = stack_add$0("tuple")(stack$0); let type$2 = "(float, string, false | true)"; if (Array.isArray(input$1)) { - if (input$1.length === 3) { - let decoded$1 = - Array.from({length: 3}, (arg$1) => { return (0); }); - for (let i$0 = 0; i$0 < input$1.length; i$0++) { - let stack$2 = stack_add$0(String(i$0))(stack$1); - if (i$0 === 0) { - let type$3 = "float"; - if (typeof input$1[i$0] === "number") { - decoded$1[i$0] = input$1[i$0]; - } else { - if (Number.isInteger(input$1[i$0])) { - decoded$1[i$0] = input$1[i$0]; - } else { - decode_error$0(input$1[i$0])(stack$2)(type$3); - } - } + let seq$0 = input$1.values(); + let decoded$1 = [0, 0, 0]; + let next$0 = seq$0.next(); + if (next$0.done) { + decode_error$0(input$1)(stack$1)(type$2); + } else { + let stack$2 = stack_add$0(String(0))(stack$1); + let type$3 = "float"; + if (typeof next$0.value === "number") { + decoded$1[0] = next$0.value; + } else { + decode_error$0(next$0.value)(stack$2)(type$3); + } + let next$1 = seq$0.next(); + if (next$1.done) { + decode_error$0(input$1)(stack$1)(type$2); + } else { + let stack$3 = stack_add$0(String(1))(stack$1); + let type$4 = "string"; + if (typeof next$1.value === "string") { + decoded$1[1] = next$1.value; + } else { + decode_error$0(next$1.value)(stack$3)(type$4); + } + let next$2 = seq$0.next(); + if (next$2.done) { + decode_error$0(input$1)(stack$1)(type$2); } else { - if (i$0 === 1) { - let type$3 = "string"; - if (typeof input$1[i$0] === "string") { - decoded$1[i$0] = input$1[i$0]; + let stack$4 = stack_add$0(String(2))(stack$1); + let type$5 = "false | true"; + if (typeof next$2.value === "boolean") { + if (next$2.value) { + decoded$1[2] = 1; } else { - decode_error$0(input$1[i$0])(stack$2)(type$3); + decoded$1[2] = 0; } } else { - if (i$0 === 2) { - let type$3 = "false | true"; - if (typeof input$1[i$0] === "boolean") { - if (input$1[i$0]) { - decoded$1[i$0] = 1; - } else { - decoded$1[i$0] = 0; - } - } else { - decode_error$0(input$1[i$0])(stack$2)(type$3); - } - } else { - decode_error$0(input$1[i$0])(stack$2)(type$2); - } + decode_error$0(next$2.value)(stack$4)(type$5); } } - decoded$0.set("tuple", decoded$1); } - } else { - decode_error$0(input$1)(stack$1)(type$2); } + decoded$0.set("tuple", decoded$1); } else { decode_error$0(input$1)(stack$1)(type$2); } @@ -947,11 +946,7 @@ if (typeof input$1 === "number") { decoded$0.set("c", input$1); } else { - if (Number.isInteger(input$1)) { - decoded$0.set("c", input$1); - } else { - decode_error$0(input$1)(stack$1)(type$2); - } + decode_error$0(input$1)(stack$1)(type$2); } } else { buffer_add_sep$0(missing_keys$1)(", ")("c"); @@ -995,20 +990,19 @@ let stack$1 = stack_add$0("record_list")(stack$0); let type$2 = "[{job: string, name: string}]"; if (Array.isArray(input$1)) { + let seq$0 = input$1.values(); + let index$0 = 0; let decoded$1 = [0, 0]; let decode_dst$0 = decoded$1; - for (let i$0 = 0; i$0 < input$1.length; i$0++) { + for (let item$0 of seq$0) { let decode_dst_new$0 = [0, 0]; - let stack$2 = stack_add$0(String(i$0))(stack$1); + let stack$2 = stack_add$0(String(index$0))(stack$1); let type$3 = "{job: string, name: string}"; - if ( - typeof input$1[i$0] === "object" && - !(input$1[i$0] === null) - ) { + if (typeof item$0 === "object" && !(item$0 === null)) { let decoded$2 = new Map(); let missing_keys$2 = {contents: ""}; - if (Object.hasOwn(input$1[i$0], "job")) { - let input$2 = input$1[i$0]["job"]; + if (Object.hasOwn(item$0, "job")) { + let input$2 = item$0["job"]; let stack$3 = stack_add$0("job")(stack$2); let type$4 = "string"; if (typeof input$2 === "string") { @@ -1019,8 +1013,8 @@ } else { buffer_add_sep$0(missing_keys$2)(", ")("job"); } - if (Object.hasOwn(input$1[i$0], "name")) { - let input$2 = input$1[i$0]["name"]; + if (Object.hasOwn(item$0, "name")) { + let input$2 = item$0["name"]; let stack$3 = stack_add$0("name")(stack$2); let type$4 = "string"; if (typeof input$2 === "string") { @@ -1036,9 +1030,10 @@ } decode_dst_new$0[0] = decoded$2; } else { - decode_error$0(input$1[i$0])(stack$2)(type$3); + decode_error$0(item$0)(stack$2)(type$3); } decode_dst$0[1] = decode_dst_new$0; + index$0++; decode_dst$0 = decode_dst_new$0; } decoded$0.set("record_list", decoded$1[1]); @@ -1250,15 +1245,15 @@ } buf$0.contents += "\n\nMapping\n-------\n\n"; let match_arg$9 = props$0.get("null_string_dict"); - for (let x$0 of match_arg$9) { + for (let item$0 of match_arg$9.entries()) { let match_props$3 = new Map(); let exit$5 = -1; - if (x$0[1] === 0) { - match_props$3.set("key", x$0[0]); + if (item$0[1] === 0) { + match_props$3.set("key", item$0[0]); exit$5 = 0; } else { - let match_arg$10 = x$0[1][0]; - match_props$3.set("key", x$0[0]); + let match_arg$10 = item$0[1][0]; + match_props$3.set("key", item$0[0]); match_props$3.set("str", match_arg$10); exit$5 = 1; } diff --git a/test/printjs/printjs_example.compiled.mjs b/test/printjs/printjs_example.compiled.mjs index 25d86fd8..8a796a28 100644 --- a/test/printjs/printjs_example.compiled.mjs +++ b/test/printjs/printjs_example.compiled.mjs @@ -3,18 +3,17 @@ let buffer_add_escape$0 = (arg$0) => { return ( (arg$1) => { - for (let i$0 = 0; i$0 < arg$1.length; i$0++) { - let c$0 = arg$1.charCodeAt(i$0); - switch (c$0) { - case 38: arg$0.contents += "&"; break; - case 34: arg$0.contents += """; break; - case 39: arg$0.contents += "'"; break; - case 62: arg$0.contents += ">"; break; - case 60: arg$0.contents += "<"; break; - case 47: arg$0.contents += "/"; break; - case 96: arg$0.contents += "`"; break; - case 61: arg$0.contents += "="; break; - default: arg$0.contents += String.fromCharCode(c$0); + for (let item$0 of arg$1[Symbol.iterator]()) { + switch (item$0) { + case "&": arg$0.contents += "&"; break; + case "\"": arg$0.contents += """; break; + case "'": arg$0.contents += "'"; break; + case ">": arg$0.contents += ">"; break; + case "<": arg$0.contents += "<"; break; + case "/": arg$0.contents += "/"; break; + case "`": arg$0.contents += "`"; break; + case "=": arg$0.contents += "="; break; + default: arg$0.contents += item$0; } } } @@ -115,11 +114,13 @@ The data supplied does not match this template's interface.\n\ }\n\ ]"; if (Array.isArray(input$0)) { + let seq$0 = input$0.values(); + let index$0 = 0; let decoded$0 = [0, 0]; let decode_dst$0 = decoded$0; - for (let i$0 = 0; i$0 < input$0.length; i$0++) { + for (let item$0 of seq$0) { let decode_dst_new$0 = [0, 0]; - let stack$1 = stack_add$0(String(i$0))(stack$0); + let stack$1 = stack_add$0(String(index$0))(stack$0); let type$2 = "{\n\ author: {name: ?string},\n\ @@ -128,11 +129,11 @@ The data supplied does not match this template's interface.\n\ image: ?{alt: string, src: string},\n\ title: string\n\ }"; - if (typeof input$0[i$0] === "object" && !(input$0[i$0] === null)) { + if (typeof item$0 === "object" && !(item$0 === null)) { let decoded$1 = new Map(); let missing_keys$1 = {contents: ""}; - if (Object.hasOwn(input$0[i$0], "author")) { - let input$1 = input$0[i$0]["author"]; + if (Object.hasOwn(item$0, "author")) { + let input$1 = item$0["author"]; let stack$2 = stack_add$0("author")(stack$1); let type$3 = "{name: ?string}"; if (typeof input$1 === "object" && !(input$1 === null)) { @@ -168,8 +169,8 @@ The data supplied does not match this template's interface.\n\ } else { buffer_add_sep$0(missing_keys$1)(", ")("author"); } - if (Object.hasOwn(input$0[i$0], "content")) { - let input$1 = input$0[i$0]["content"]; + if (Object.hasOwn(item$0, "content")) { + let input$1 = item$0["content"]; let stack$2 = stack_add$0("content")(stack$1); let type$3 = "string"; if (typeof input$1 === "string") { @@ -180,8 +181,8 @@ The data supplied does not match this template's interface.\n\ } else { buffer_add_sep$0(missing_keys$1)(", ")("content"); } - if (Object.hasOwn(input$0[i$0], "date")) { - let input$1 = input$0[i$0]["date"]; + if (Object.hasOwn(item$0, "date")) { + let input$1 = item$0["date"]; let stack$2 = stack_add$0("date")(stack$1); let type$3 = "string"; if (typeof input$1 === "string") { @@ -192,8 +193,8 @@ The data supplied does not match this template's interface.\n\ } else { buffer_add_sep$0(missing_keys$1)(", ")("date"); } - if (Object.hasOwn(input$0[i$0], "image")) { - let input$1 = input$0[i$0]["image"]; + if (Object.hasOwn(item$0, "image")) { + let input$1 = item$0["image"]; let stack$2 = stack_add$0("image")(stack$1); let type$3 = "?{alt: string, src: string}"; if (!(input$1 === null) && !(input$1 === undefined)) { @@ -241,8 +242,8 @@ The data supplied does not match this template's interface.\n\ } else { decoded$1.set("image", 0); } - if (Object.hasOwn(input$0[i$0], "title")) { - let input$1 = input$0[i$0]["title"]; + if (Object.hasOwn(item$0, "title")) { + let input$1 = item$0["title"]; let stack$2 = stack_add$0("title")(stack$1); let type$3 = "string"; if (typeof input$1 === "string") { @@ -258,9 +259,10 @@ The data supplied does not match this template's interface.\n\ } decode_dst_new$0[0] = decoded$1; } else { - decode_error$0(input$0[i$0])(stack$1)(type$2); + decode_error$0(item$0)(stack$1)(type$2); } decode_dst$0[1] = decode_dst_new$0; + index$0++; decode_dst$0 = decode_dst_new$0; } props$0.set("blogPosts", decoded$0[1]);