
  Syntax error!
  syntax_tests/data/parsing/infiniteLoops/nonRecTypes.res:4:29-36

  2 ┆ include (
  3 ┆           {
  4 ┆             type t('value) = {
  5 ┆               mutable size: int,
  6 ┆               mutable root: option(node('value)),

  Type parameters require angle brackets:
  t<'value>


  Syntax error!
  syntax_tests/data/parsing/infiniteLoops/nonRecTypes.res:19:45-51

  17 ┆   ~size: int,
  18 ┆   ~root: option(node('value)),
  19 ┆   ~compare: Js.Internal.fn([ | `Arity_2('value, 'value)], int)
  20 ┆ ) =>
  21 ┆ t('value) =

  consecutive statements on a line must be separated by ';' or a newline


  Syntax error!
  syntax_tests/data/parsing/infiniteLoops/nonRecTypes.res:61:26-62:3

  59 │         };
  60 │ let has = (rbt, value) => _findNode(rbt, rootGet(rbt), value) !== None;
  61 │ let rec minNode = node =>
  62 │ let findMin = rbt =>
  63 │ let removeNode = (rbt, node) => {
  64 │   let nodeToRemove =

  I'm not sure what to parse here when looking at "let".


  Syntax error!
  syntax_tests/data/parsing/infiniteLoops/nonRecTypes.res:62:21-63:3

  60 │ let has = (rbt, value) => _findNode(rbt, rootGet(rbt), value) !== None;
  61 │ let rec minNode = node =>
  62 │ let findMin = rbt =>
  63 │ let removeNode = (rbt, node) => {
  64 │   let nodeToRemove =
  65 │     switch (leftGet(node), rightGet(node)) {

  I'm not sure what to parse here when looking at "let".


  Syntax error!
  syntax_tests/data/parsing/infiniteLoops/nonRecTypes.res:428:31-38

  426 │     updateSum(Some(node), ~delta);
  427 │   };
  428 │ type nonrec oldNewVisibleNodes('value) = {
  429 │   mutable old: array('value),
  430 │   mutable new_: array('value),

  Type parameters require angle brackets:
  oldNewVisibleNodes<'value>

include
  struct
    include
      struct
        type nonrec 'value t =
          {
          mutable size: int ;
          mutable root: 'value node option ;
          compare: [ [%rescript.typehole ]] Js.Internal.fn }
        ;;(({js|Arity_2('value, 'value)], int),
                      };
                    }: {

                    }
                  );
          type t('value);
          external t:
            (
              ~size: int,
              ~root: option(node('value)),
              ~compare: Js.Internal.fn([ | |js})
          [@res.template ])
        ;;Arity_2 (value, value)
        ;;int
        ;;(t value) = {js||js}
        ;;{js|BS:6.0.1\x84\x95\xa6\xbe\0\0\0#\0\0\0\r\0\0\0&\0\0\0#\x91\xa0\xa0A\xa0$size@\xa0\xa0A\xa0$root@\xa0\xa0A\xa0'compare@@|js}
        external sizeSet : 'value t -> int -> unit (a:2) = "size"
        ;;{js|BS:6.0.1\x84\x95\xa6\xbe\0\0\0\x15\0\0\0\t\0\0\0\x1a\0\0\0\x19\xb0\xa0\xa0A\x91@\xa0\xa0A\x04\x03@E\x97\xa0$size@|js}
        ;;[|(({js|use sizeGet instead or use {abstract = light} explicitly|js})
            [@ocaml.deprecated ])|]
        external size : 'value t -> int (a:1) = ""
        ;;{js|BS:6.0.1\x84\x95\xa6\xbe\0\0\0\x10\0\0\0\x07\0\0\0\x14\0\0\0\x13\xb0\xa0\xa0A\x91@@A\x98\xa0$size@|js}
        external sizeGet : 'value t -> int (a:1) = ""
        ;;{js|BS:6.0.1\x84\x95\xa6\xbe\0\0\0\x10\0\0\0\x07\0\0\0\x14\0\0\0\x13\xb0\xa0\xa0A\x91@@A\x98\xa0$size@|js}
        external rootSet :
          'value t -> 'value node option -> unit (a:2) = "root"
        ;;{js|BS:6.0.1\x84\x95\xa6\xbe\0\0\0\x15\0\0\0\t\0\0\0\x1a\0\0\0\x19\xb0\xa0\xa0A\x91@\xa0\xa0A\x04\x03@E\x97\xa0$root@|js}
        ;;[|(({js|use rootGet instead or use {abstract = light} explicitly|js})
            [@ocaml.deprecated ])|]
        external root : 'value t -> 'value node option (a:1) = ""
        ;;{js|BS:6.0.1\x84\x95\xa6\xbe\0\0\0\x10\0\0\0\x07\0\0\0\x14\0\0\0\x13\xb0\xa0\xa0A\x91@@A\x98\xa0$root@|js}
        external rootGet : 'value t -> 'value node option (a:1) = ""
        ;;{js|BS:6.0.1\x84\x95\xa6\xbe\0\0\0\x10\0\0\0\x07\0\0\0\x14\0\0\0\x13\xb0\xa0\xa0A\x91@@A\x98\xa0$root@|js}
        ;;[|(({js|use compareGet instead or use {abstract = light} explicitly|js})
            [@ocaml.deprecated ])|]
        external compare :
          'value t -> [ [%rescript.typehole ]] Js.Internal.fn (a:1)
        ;;(({js|Arity_2('value, 'value)], int) =
            ""
            "BS:6.0.1\x84\x95\xa6\xbe\0\0\0\x13\0\0\0\x07\0\0\0\x14\0\0\0\x13\xb0\xa0\xa0A\x91@@A\x98\xa0'compare@";
          external compareGet:
            t('value) => Js.Internal.fn([ | |js})
          [@res.template ])
        ;;Arity_2 (value, value)
        ;;int
        ;;{js||js}
        ;;{js|BS:6.0.1\x84\x95\xa6\xbe\0\0\0\x13\0\0\0\x07\0\0\0\x14\0\0\0\x13\xb0\xa0\xa0A\x91@@A\x98\xa0'compare@|js}
      end
    let has [arity:2]rbt value =
      (!==) (_findNode rbt (rootGet rbt) value) None
    let rec minNode [arity:1]node = [%rescript.exprhole ]
    let findMin [arity:1]rbt = [%rescript.exprhole ]
    let removeNode [arity:2]rbt node =
      ((let nodeToRemove =
          match ((leftGet node), (rightGet node)) with
          | (Some _, Some _) ->
              let successor = castNotOption (minNode (rightGet node)) in
              (valueSet node (valueGet successor);
               heightSet node (heightGet successor);
               successor)
          | _ -> node in
        let successor =
          match leftGet nodeToRemove with
          | None -> rightGet nodeToRemove
          | left -> left in
        let (successor, isLeaf) =
          match successor with
          | None ->
              let leaf =
                createNode ~value:(Js.Internal.raw_expr {js|0|js})
                  ~color:Black ~height:0. in
              let isLeaf = Js.Internal.fn_mk1 (fun [arity:1]x -> x === leaf) in
              (leaf, isLeaf)
          | Some successor ->
              (successor, (Js.Internal.fn_mk1 (fun [arity:1]_ -> false))) in
        let nodeParent = parentGet nodeToRemove in
        parentSet successor nodeParent;
        (match nodeParent with
         | None -> ()
         | Some parent ->
             leftOrRightSet parent ~node:nodeToRemove (Some successor));
        updateSumRecursive rbt successor;
        if (colorGet nodeToRemove) === Black
        then
          (if (colorGet successor) === Red
           then
             (colorSet successor Black;
              if (parentGet successor) === None
              then rootSet rbt (Some successor))
           else
             (let break = ref false in
              let successorRef = ref successor in
              while not break.contents do
                let successor = successorRef.contents in
                match parentGet successor with
                | None ->
                    (rootSet rbt (Some successor); break.contents <- true)
                | Some successorParent ->
                    let sibling = siblingOf successor in
                    (if
                       ((!==) sibling None) &&
                         ((colorGet (castNotOption sibling)) === Red)
                     then
                       (colorSet successorParent Red;
                        colorSet (castNotOption sibling) Black;
                        if isLeft successor
                        then rotateLeft rbt successorParent
                        else rotateRight rbt successorParent);
                     (let sibling = siblingOf successor in
                      let siblingNN = castNotOption sibling in
                      if
                        ((colorGet successorParent) === Black) &&
                          ((sibling === None) ||
                             ((((colorGet siblingNN) === Black) &&
                                 (((leftGet siblingNN) === None) ||
                                    ((colorGet
                                        (castNotOption (leftGet siblingNN)))
                                       === Black)))
                                &&
                                (((rightGet siblingNN) === None) ||
                                   ((colorGet
                                       (castNotOption (rightGet siblingNN)))
                                      === Black))))
                      then
                        (if (!==) sibling None then colorSet siblingNN Red;
                         successorRef.contents <- successorParent)
                      else
                        if
                          ((colorGet successorParent) === Red) &&
                            ((sibling === None) ||
                               ((((colorGet siblingNN) === Black) &&
                                   (((leftGet siblingNN) === None) ||
                                      ((colorGet
                                          (castNotOption (leftGet siblingNN)))
                                         === Black)))
                                  &&
                                  (((rightGet siblingNN) === None) ||
                                     ((colorGet
                                         (castNotOption (rightGet siblingNN)))
                                        === Black))))
                        then
                          (if (!==) sibling None then colorSet siblingNN Red;
                           colorSet successorParent Black;
                           break.contents <- true)
                        else
                          if
                            ((!==) sibling None) &&
                              ((colorGet (castNotOption sibling)) === Black)
                          then
                            (let sibling = castNotOption sibling in
                             if
                               (((isLeft successor) &&
                                   (((rightGet sibling) === None) ||
                                      ((colorGet
                                          (castNotOption (rightGet sibling)))
                                         === Black)))
                                  && ((!==) (leftGet sibling) None))
                                 &&
                                 ((colorGet (castNotOption (leftGet sibling)))
                                    === Red)
                             then
                               (colorSet sibling Red;
                                colorSet (castNotOption (leftGet sibling))
                                  Black;
                                rotateRight rbt sibling)
                             else
                               if
                                 (((not (isLeft successor)) &&
                                     (((leftGet sibling) === None) ||
                                        ((colorGet
                                            (castNotOption (leftGet sibling)))
                                           === Black)))
                                    && ((!==) (rightGet sibling) None))
                                   &&
                                   ((colorGet
                                       (castNotOption (rightGet sibling)))
                                      === Red)
                               then
                                 (colorSet sibling Red;
                                  colorSet (castNotOption (rightGet sibling))
                                    Black;
                                  rotateLeft rbt sibling);
                             break.contents <- true)
                          else
                            (let sibling = siblingOf successor in
                             let sibling = castNotOption sibling in
                             colorSet sibling (colorGet successorParent);
                             if isLeft successor
                             then
                               (colorSet (castNotOption (rightGet sibling))
                                  Black;
                                rotateRight rbt successorParent)
                             else
                               (colorSet (castNotOption (leftGet sibling))
                                  Black;
                                rotateLeft rbt successorParent))))
                done));
        if Js.Internal.fn_run1 isLeaf successor
        then
          (if (rootGet rbt) === (Some successor) then rootSet rbt None;
           (match parentGet successor with
            | None -> ()
            | Some parent -> leftOrRightSet parent ~node:successor None)))
      [@res.braces ])
    let remove [arity:2]rbt value =
      match _findNode rbt (rootGet rbt) value with
      | Some node ->
          (removeNode rbt node;
           sizeSet rbt ((sizeGet rbt) - 1);
           Some (heightGet node))
      | None -> None
    let findThroughCallback [arity:2]rbt cb =
      ((let rec findThroughCallback [arity:3]rbt node cb =
          match node with
          | None -> None
          | Some node ->
              let cmp = Js.Internal.fn_run1 cb (valueGet node) in
              if cmp === 0
              then Some node
              else
                if cmp < 0
                then findThroughCallback rbt (leftGet node) cb
                else findThroughCallback rbt (rightGet node) cb in
        match findThroughCallback rbt (rootGet rbt) cb with
        | None -> None
        | Some node -> Some (valueGet node))
      [@res.braces ])
    let make [arity:1]~compare  = t ~size:0 ~root:None ~compare
    let rec heightOfInterval [arity:4]rbt node lhs rhs =
      match node with
      | None -> 0.
      | Some n ->
          if (lhs === None) && (rhs === None)
          then sumGet n
          else
            if
              ((!==) lhs None) &&
                ((Js.Internal.fn_run2 (compareGet rbt) (valueGet n)
                    (castNotOption lhs))
                   < 0)
            then heightOfInterval rbt (rightGet n) lhs rhs
            else
              if
                ((!==) rhs None) &&
                  ((Js.Internal.fn_run2 (compareGet rbt) (valueGet n)
                      (castNotOption rhs))
                     > 0)
              then heightOfInterval rbt (leftGet n) lhs rhs
              else
                ((heightGet n) +. (heightOfInterval rbt (leftGet n) lhs None))
                  +. (heightOfInterval rbt (rightGet n) None rhs)
    let heightOfInterval [arity:3]rbt lhs rhs =
      heightOfInterval rbt (rootGet rbt) lhs rhs
    let rec firstVisibleNode [arity:2]node offset =
      match node with
      | None -> None
      | Some node ->
          if (sumGet node) <= offset
          then None
          else
            (let nodeHeight = heightGet node in
             let sumLeft =
               match leftGet node with
               | None -> 0.0
               | Some left -> sumGet left in
             if sumLeft > offset
             then firstVisibleNode (leftGet node) offset
             else
               if (sumLeft +. nodeHeight) > offset
               then Some node
               else
                 firstVisibleNode (rightGet node)
                   (offset -. (sumLeft +. nodeHeight)))
    let lastVisibleNode [arity:2]node offset =
      match firstVisibleNode node offset with
      | None -> maxNode node
      | first -> first
    let firstVisible [arity:2]rbt ~offset  =
      match firstVisibleNode (rootGet rbt) offset with
      | None -> None
      | Some node -> Some (valueGet node)
    let rec leftmost [arity:1]node =
      match leftGet node with | None -> node | Some node -> leftmost node
    let rec firstRightParent [arity:1]node =
      match parentGet node with
      | None -> None
      | Some parent ->
          if isLeft node then Some parent else firstRightParent parent
    let nextNode [arity:1]node =
      match rightGet node with
      | None -> firstRightParent node
      | Some right -> Some (leftmost right)
    let rec sumLeftSpine [arity:2]node ~fromRightChild  =
      ((let leftSpine =
          match leftGet node with
          | None -> heightGet node
          | Some left ->
              if fromRightChild
              then (heightGet node) +. (sumGet left)
              else 0.0 in
        match parentGet node with
        | None -> leftSpine
        | Some parent ->
            leftSpine +.
              (sumLeftSpine parent
                 ~fromRightChild:((rightGet parent) === (Some node))))
      [@res.braces ])
    let getY [arity:1]node =
      (sumLeftSpine node ~fromRightChild:true) -. (heightGet node)
    let linearSearch [arity:2]rbt callback =
      ((let rec find [arity:2]node callback =
          if Js.Internal.fn_run1 callback (valueGet node)
          then Some (valueGet node)
          else
            (match nextNode node with
             | None -> None
             | Some node -> find node callback) in
        match minNode (rootGet rbt) with
        | None -> None
        | Some node -> find node callback)
      [@res.braces ])
    let rec iterate [arity:4]~inclusive  firstNode lastNode ~callback  =
      match firstNode with
      | None -> ()
      | Some node ->
          (if inclusive then Js.Internal.fn_run1 callback node;
           if (!==) firstNode lastNode
           then
             (if not inclusive then Js.Internal.fn_run1 callback node;
              iterate ~inclusive (nextNode node) lastNode ~callback))
    let rec iterateWithY [arity:5]?y  ~inclusive  firstNode lastNode
      ~callback  =
      match firstNode with
      | None -> ()
      | Some node ->
          let y = match y with | None -> getY node | Some y -> y in
          (if inclusive then Js.Internal.fn_run2 callback node y;
           if (!==) firstNode lastNode
           then
             (if not inclusive then Js.Internal.fn_run2 callback node y;
              iterateWithY ~y:(y +. (heightGet node)) ~inclusive
                (nextNode node) lastNode ~callback))
    let rec updateSum [arity:2]node ~delta  =
      match node with
      | None -> ()
      | Some node ->
          (sumSet node ((sumGet node) +. delta);
           updateSum (parentGet node) ~delta)
    let setHeight [arity:3]rbt value ~height  =
      match _findNode rbt (rootGet rbt) value with
      | None -> ()
      | Some node ->
          let delta = height -. (heightGet node) in
          (heightSet node height; updateSum (Some node) ~delta)
    type nonrec 'value oldNewVisibleNodes =
      {
      mutable old: 'value array ;
      mutable new_: 'value array }
  end